diff --git a/.eslintignore b/.eslintignore index f1448bf91ba03..8d43ffd8191c3 100644 --- a/.eslintignore +++ b/.eslintignore @@ -18,7 +18,6 @@ bower_components /src/core/lib/kbn_internal_native_observable /packages/*/target /packages/eslint-config-kibana -/packages/eslint-plugin-kibana-custom /packages/kbn-es-query/src/kuery/ast/kuery.js /packages/kbn-es-query/src/kuery/ast/legacy_kuery.js /packages/kbn-pm/dist diff --git a/.eslintrc.js b/.eslintrc.js index 8e1e1e0f7c81a..ea3ad6ec3ccdc 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -34,6 +34,7 @@ const ELASTIC_LICENSE_HEADER = ` module.exports = { extends: ['@elastic/eslint-config-kibana', '@elastic/eslint-config-kibana/jest'], + plugins: ['@kbn/eslint-plugin-eslint'], settings: { 'import/resolver': { @@ -46,6 +47,15 @@ module.exports = { rules: { 'no-restricted-imports': [2, restrictedModules], 'no-restricted-modules': [2, restrictedModules], + '@kbn/eslint/module_migration': [ + 'error', + [ + { + from: 'expect.js', + to: '@kbn/expect', + }, + ], + ], }, overrides: [ @@ -55,7 +65,7 @@ module.exports = { { files: [ '.eslintrc.js', - 'packages/eslint-plugin-kibana-custom/**/*', + 'packages/kbn-eslint-plugin-eslint/**/*', 'packages/kbn-config-schema/**/*', 'packages/kbn-pm/**/*', 'packages/kbn-es/**/*', @@ -87,7 +97,7 @@ module.exports = { { files: ['x-pack/test/functional/apps/**/*', 'x-pack/plugins/apm/**/*'], rules: { - 'kibana-custom/no-default-export': 'off', + '@kbn/eslint/no-default-export': 'off', 'import/no-named-as-default': 'off', }, }, @@ -242,7 +252,7 @@ module.exports = { 'packages/kbn-plugin-generator/**/*', 'packages/kbn-plugin-helpers/**/*', 'packages/kbn-eslint-import-resolver-kibana/**/*', - 'packages/kbn-eslint-plugin-license-header/**/*', + 'packages/kbn-eslint-plugin-eslint/**/*', 'x-pack/gulpfile.js', 'x-pack/dev-tools/mocha/setup_mocha.js', 'x-pack/scripts/*', @@ -267,15 +277,14 @@ module.exports = { */ { files: ['**/*.js'], - plugins: ['@kbn/eslint-plugin-license-header'], rules: { - '@kbn/license-header/require-license-header': [ + '@kbn/eslint/require-license-header': [ 'error', { license: APACHE_2_0_LICENSE_HEADER, }, ], - '@kbn/license-header/disallow-license-headers': [ + '@kbn/eslint/disallow-license-headers': [ 'error', { licenses: [ELASTIC_LICENSE_HEADER], @@ -289,15 +298,14 @@ module.exports = { */ { files: ['x-pack/**/*.js'], - plugins: ['@kbn/eslint-plugin-license-header'], rules: { - '@kbn/license-header/require-license-header': [ + '@kbn/eslint/require-license-header': [ 'error', { license: ELASTIC_LICENSE_HEADER, }, ], - '@kbn/license-header/disallow-license-headers': [ + '@kbn/eslint/disallow-license-headers': [ 'error', { licenses: [APACHE_2_0_LICENSE_HEADER], diff --git a/NOTICE.txt b/NOTICE.txt index cd6f783e530b4..216591e2b4150 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -80,32 +80,6 @@ used. Logarithmic ticks are places at powers of ten and at half those values if there are not to many ticks already (e.g. [1, 5, 10, 50, 100]). For details, see https://github.com/flot/flot/pull/1328 ---- -This product bundles angular-ui-bootstrap@0.12.1 which is available under a -"MIT" license. - -The MIT License - -Copyright (c) 2012-2014 the AngularUI Team, https://github.com/organizations/angular-ui/teams/291112 - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - --- This product bundles bootstrap@3.3.6 which is available under a "MIT" license. diff --git a/TYPESCRIPT.md b/TYPESCRIPT.md index 68cb32ce36c74..66b2fd0e77c68 100644 --- a/TYPESCRIPT.md +++ b/TYPESCRIPT.md @@ -111,7 +111,7 @@ If yarn doesn't find the module it may not have types. For example, our `rison_ 1. Contribute types into the DefinitelyTyped repo itself, or 2. Create a top level `types` folder and point to that in the tsconfig. For example, Infra team already handled this for `rison_node` and added: `x-pack/plugins/infra/types/rison_node.d.ts`. Other code uses it too so we will need to pull it up. Or, -3. Add a `// @ts-ignore` line above the import. This should be used minimally, the above options are better. However, sometimes you have to resort to this method. For example, the `expect.js` module will require this line. We don't have type definitions installed for this library. Installing these types would conflict with the jest typedefs for expect, and since they aren't API compatible with each other, it's not possible to make both test frameworks happy. Since we are moving from mocha => jest, we don't see this is a big issue. +3. Add a `// @ts-ignore` line above the import. This should be used minimally, the above options are better. However, sometimes you have to resort to this method. ### TypeScripting react files diff --git a/docs/CHANGELOG.asciidoc b/docs/CHANGELOG.asciidoc index cac755cad970f..d0c19f8628361 100644 --- a/docs/CHANGELOG.asciidoc +++ b/docs/CHANGELOG.asciidoc @@ -1,8 +1,5 @@ [[release-notes]] -= {kib} Release Notes -++++ -Release Notes -++++ += Release Notes [partintro] -- diff --git a/docs/development/core-development.asciidoc b/docs/development/core-development.asciidoc index 45f52c16ee332..447a4c6d2601b 100644 --- a/docs/development/core-development.asciidoc +++ b/docs/development/core-development.asciidoc @@ -5,6 +5,7 @@ * <> * <> * <> +* <> * <> include::core/development-basepath.asciidoc[] @@ -15,4 +16,6 @@ include::core/development-modules.asciidoc[] include::core/development-elasticsearch.asciidoc[] +include::core/development-unit-tests.asciidoc[] + include::core/development-functional-tests.asciidoc[] diff --git a/docs/development/core/development-functional-tests.asciidoc b/docs/development/core/development-functional-tests.asciidoc index 813c4fa929aa9..8d1238993b7cb 100644 --- a/docs/development/core/development-functional-tests.asciidoc +++ b/docs/development/core/development-functional-tests.asciidoc @@ -82,7 +82,7 @@ Use the `--help` flag for more options. [float] ===== Environment -The tests are written in https://mochajs.org[mocha] using https://github.com/Automattic/expect.js[expect] for assertions. +The tests are written in https://mochajs.org[mocha] using https://github.com/elastic/kibana/tree/master/packages/kbn-expect[@kbn/expect] for assertions. We use https://sites.google.com/a/chromium.org/chromedriver/[chromedriver], https://theintern.github.io/leadfoot[leadfoot], and https://github.com/theintern/digdug[digdug] for automating Chrome. When the `FunctionalTestRunner` launches, digdug opens a `Tunnel` which starts chromedriver and a stripped-down instance of Chrome. It also creates an instance of https://theintern.github.io/leadfoot/module-leadfoot_Command.html[Leadfoot's `Command`] class, which is available via the `remote` service. The `remote` communicates to Chrome through the digdug `Tunnel`. See the https://theintern.github.io/leadfoot/module-leadfoot_Command.html[leadfoot/Command API] docs for all the commands you can use with `remote`. @@ -122,11 +122,11 @@ A test suite is a collection of tests defined by calling `describe()`, and then [float] ===== Anatomy of a test file -The annotated example file below shows the basic structure every test suite uses. It starts by importing https://github.com/Automattic/expect.js[`expect.js`] and defining its default export: an anonymous Test Provider. The test provider then destructures the Provider API for the `getService()` and `getPageObjects()` functions. It uses these functions to collect the dependencies of this suite. The rest of the test file will look pretty normal to mocha.js users. `describe()`, `it()`, `before()` and the lot are used to define suites that happen to automate a browser via services and objects of type `PageObject`. +The annotated example file below shows the basic structure every test suite uses. It starts by importing https://github.com/elastic/kibana/tree/master/packages/kbn-expect[`@kbn/expect`] and defining its default export: an anonymous Test Provider. The test provider then destructures the Provider API for the `getService()` and `getPageObjects()` functions. It uses these functions to collect the dependencies of this suite. The rest of the test file will look pretty normal to mocha.js users. `describe()`, `it()`, `before()` and the lot are used to define suites that happen to automate a browser via services and objects of type `PageObject`. ["source","js"] ---- -import expect from 'expect.js'; +import expect from '@kbn/expect'; // test files must `export default` a function that defines a test suite export default function ({ getService, getPageObject }) { diff --git a/docs/development/core/development-unit-tests.asciidoc b/docs/development/core/development-unit-tests.asciidoc new file mode 100644 index 0000000000000..a738e2cf372d9 --- /dev/null +++ b/docs/development/core/development-unit-tests.asciidoc @@ -0,0 +1,83 @@ +[[development-unit-tests]] +=== Unit Testing + +We use unit tests to make sure that individual software units of {kib} perform as they were designed to. + +[float] +=== Current Frameworks + +{kib} is migrating unit testing from `Mocha` to `Jest`. Legacy unit tests still exist in `Mocha` but all new unit tests should be written in `Jest`. + +[float] +==== Mocha (legacy) + +Mocha tests are contained in `__tests__` directories. + +*Running Mocha Unit Tests* + +["source","shell"] +----------- +yarn test:mocha +----------- + +[float] +==== Jest +Jest tests are stored in the same directory as source code files with the `.test.{js,ts,tsx}` suffix. + +*Running Jest Unit Tests* + +["source","shell"] +----------- +yarn test:jest +----------- + +[float] +===== Writing Jest Unit Tests + +In order to write those tests there are two main things you need to be aware of. +The first one is the different between `jest.mock` and `jest.doMock` +and the second one our `jest mocks file pattern`. As we are running `js` and `ts` +test files with `babel-jest` both techniques are needed +specially for the tests implemented on Typescript in order to benefit from the +auto-inference types feature. + +[float] +===== Jest.mock vs Jest.doMock + +Both methods are essentially the same on their roots however the `jest.mock` +calls will get hoisted to the top of the file and can only reference variables +prefixed with `mock`. On the other hand, `jest.doMock` won't be hoisted and can +reference pretty much any variable we want, however we have to assure those referenced +variables are instantiated at the time we need them which lead us to the next +section where we'll talk about our jest mock files pattern. + +[float] +===== Jest Mock Files Pattern + +Specially on typescript it is pretty common to have in unit tests +`jest.doMock` calls which reference for example imported types. Any error +will thrown from doing that however the test will fail. The reason behind that +is because despite the `jest.doMock` isn't being hoisted by `babel-jest` the +import with the types we are referencing will be hoisted to the top and at the +time we'll call the function that variable would not be defined. + +In order to prevent that we develop a protocol that should be followed: + +- Each module could provide a standard mock in `mymodule.mock.ts` in case +there are other tests that could benefit from using definitions here. +This file would not have any `jest.mock` calls, just dummy objects. + +- Each test defines its mocks in `mymodule.test.mocks.ts`. This file +could import relevant mocks from the generalised module's mocks +file `(*.mock.ts)` and call `jest.mock` for each of them. If there is +any relevant dummy mock objects to generalise (and to be used by +other tests), the dummy objects could be defined directly on this file. + +- Each test would import its mocks from the test mocks +file mymodule.test.mocks.ts. `mymodule.test.ts` has an import +like: `import * as Mocks from './mymodule.test.mocks'`, +`import { mockX } from './mymodule.test.mocks'` +or just `import './mymodule.test.mocks'` if there isn't anything +exported to be used. + + diff --git a/docs/getting-started/tutorial-load-dataset.asciidoc b/docs/getting-started/tutorial-load-dataset.asciidoc index d23d50baed662..c7c12199633ac 100644 --- a/docs/getting-started/tutorial-load-dataset.asciidoc +++ b/docs/getting-started/tutorial-load-dataset.asciidoc @@ -3,12 +3,16 @@ This tutorial requires three data sets: -* The complete works of William Shakespeare, suitably parsed into fields. Download - https://download.elastic.co/demos/kibana/gettingstarted/shakespeare_6.0.json[`shakespeare.json`]. -* A set of fictitious accounts with randomly generated data. Download - https://download.elastic.co/demos/kibana/gettingstarted/accounts.zip[`accounts.zip`]. -* A set of randomly generated log files. Download - https://download.elastic.co/demos/kibana/gettingstarted/logs.jsonl.gz[`logs.jsonl.gz`]. +* The complete works of William Shakespeare, suitably parsed into fields +* A set of fictitious accounts with randomly generated data +* A set of randomly generated log files + +Create a new working directory where you want to download the files. From that directory, run the following commands: + +[source,shell] +curl -O https://download.elastic.co/demos/kibana/gettingstarted/8.x/shakespeare.json +curl -O https://download.elastic.co/demos/kibana/gettingstarted/8.x/accounts.zip +curl -O https://download.elastic.co/demos/kibana/gettingstarted/8.x/logs.jsonl.gz Two of the data sets are compressed. To extract the files, use these commands: @@ -73,16 +77,14 @@ In Kibana *Dev Tools > Console*, set up a mapping for the Shakespeare data set: [source,js] PUT /shakespeare { - "mappings": { - "doc": { - "properties": { + "mappings": { + "properties": { "speaker": {"type": "keyword"}, "play_name": {"type": "keyword"}, "line_id": {"type": "integer"}, "speech_number": {"type": "integer"} - } + } } - } } //CONSOLE @@ -100,13 +102,11 @@ as geographic locations by applying the `geo_point` type. PUT /logstash-2015.05.18 { "mappings": { - "log": { - "properties": { - "geo": { - "properties": { - "coordinates": { - "type": "geo_point" - } + "properties": { + "geo": { + "properties": { + "coordinates": { + "type": "geo_point" } } } @@ -120,13 +120,11 @@ PUT /logstash-2015.05.18 PUT /logstash-2015.05.19 { "mappings": { - "log": { - "properties": { - "geo": { - "properties": { - "coordinates": { - "type": "geo_point" - } + "properties": { + "geo": { + "properties": { + "coordinates": { + "type": "geo_point" } } } @@ -140,13 +138,11 @@ PUT /logstash-2015.05.19 PUT /logstash-2015.05.20 { "mappings": { - "log": { - "properties": { - "geo": { - "properties": { - "coordinates": { - "type": "geo_point" - } + "properties": { + "geo": { + "properties": { + "coordinates": { + "type": "geo_point" } } } @@ -165,13 +161,13 @@ API to load the data sets: [source,shell] curl -H 'Content-Type: application/x-ndjson' -XPOST 'localhost:9200/bank/account/_bulk?pretty' --data-binary @accounts.json -curl -H 'Content-Type: application/x-ndjson' -XPOST 'localhost:9200/shakespeare/doc/_bulk?pretty' --data-binary @shakespeare_6.0.json +curl -H 'Content-Type: application/x-ndjson' -XPOST 'localhost:9200/shakespeare/_bulk?pretty' --data-binary @shakespeare.json curl -H 'Content-Type: application/x-ndjson' -XPOST 'localhost:9200/_bulk?pretty' --data-binary @logs.jsonl Or for Windows users, in Powershell: [source,shell] Invoke-RestMethod "http://localhost:9200/bank/account/_bulk?pretty" -Method Post -ContentType 'application/x-ndjson' -InFile "accounts.json" -Invoke-RestMethod "http://localhost:9200/shakespeare/doc/_bulk?pretty" -Method Post -ContentType 'application/x-ndjson' -InFile "shakespeare_6.0.json" +Invoke-RestMethod "http://localhost:9200/shakespeare/_bulk?pretty" -Method Post -ContentType 'application/x-ndjson' -InFile "shakespeare.json" Invoke-RestMethod "http://localhost:9200/_bulk?pretty" -Method Post -ContentType 'application/x-ndjson' -InFile "logs.jsonl" These commands might take some time to execute, depending on the available computing resources. @@ -187,8 +183,8 @@ Your output should look similar to this: [source,shell] health status index pri rep docs.count docs.deleted store.size pri.store.size -yellow open bank 5 1 1000 0 418.2kb 418.2kb -yellow open shakespeare 5 1 111396 0 17.6mb 17.6mb -yellow open logstash-2015.05.18 5 1 4631 0 15.6mb 15.6mb -yellow open logstash-2015.05.19 5 1 4624 0 15.7mb 15.7mb -yellow open logstash-2015.05.20 5 1 4750 0 16.4mb 16.4mb +yellow open bank 1 1 1000 0 418.2kb 418.2kb +yellow open shakespeare 1 1 111396 0 17.6mb 17.6mb +yellow open logstash-2015.05.18 1 1 4631 0 15.6mb 15.6mb +yellow open logstash-2015.05.19 1 1 4624 0 15.7mb 15.7mb +yellow open logstash-2015.05.20 1 1 4750 0 16.4mb 16.4mb diff --git a/docs/graph/index.asciidoc b/docs/graph/index.asciidoc index b60bd1bc78d12..dca248257e4e0 100644 --- a/docs/graph/index.asciidoc +++ b/docs/graph/index.asciidoc @@ -1,9 +1,6 @@ [role="xpack"] [[xpack-graph]] = Graphing Connections in Your Data -++++ -Graph -++++ [partintro] -- @@ -66,6 +63,7 @@ multi-node clusters and scales with your Elasticsearch deployment. Advanced options let you control how your data is sampled and summarized. You can also set timeouts to prevent graph queries from adversely affecting the cluster. + -- include::getting-started.asciidoc[] diff --git a/docs/index.asciidoc b/docs/index.asciidoc index 1574644752ad5..dd29e95d794a4 100644 --- a/docs/index.asciidoc +++ b/docs/index.asciidoc @@ -50,6 +50,8 @@ include::logs/index.asciidoc[] include::apm/index.asciidoc[] +include::uptime/index.asciidoc[] + include::graph/index.asciidoc[] include::dev-tools.asciidoc[] diff --git a/docs/management/advanced-options.asciidoc b/docs/management/advanced-options.asciidoc index 78b6922927c17..50a229f0b2dd4 100644 --- a/docs/management/advanced-options.asciidoc +++ b/docs/management/advanced-options.asciidoc @@ -41,9 +41,6 @@ working on big documents. Set this property to `false` to disable highlighting. `doc_table:hideTimeColumn`:: Hide the 'Time' column in Discover and in all Saved Searches on Dashboards. `search:includeFrozen`:: Will include {ref}/frozen-indices.html[frozen indices] in results if enabled. Searching through frozen indices might increase the search time. -`courier:maxSegmentCount`:: Kibana splits requests in the Discover app into segments to limit the size of requests sent to -the Elasticsearch cluster. This setting constrains the length of the segment list. Long segment lists can significantly -increase request processing time. `courier:ignoreFilterIfFieldNotInIndex`:: Set this property to `true` to skip filters that apply to fields that don't exist in a visualization's index. Useful when dashboards consist of visualizations from multiple index patterns. `courier:maxConcurrentShardRequests`:: Controls the {ref}/search-multi-search.html[max_concurrent_shard_requests] setting used for _msearch requests sent by Kibana. Set to 0 to disable this config and use the Elasticsearch default. `fields:popularLimit`:: This setting governs how many of the top most popular fields are shown. diff --git a/docs/release-notes/highlights-8.0.0.asciidoc b/docs/release-notes/highlights-8.0.0.asciidoc index ecb6e95d28f45..959a238b5f1a5 100644 --- a/docs/release-notes/highlights-8.0.0.asciidoc +++ b/docs/release-notes/highlights-8.0.0.asciidoc @@ -6,4 +6,12 @@ coming[8.0.0] -See also <> and <>. \ No newline at end of file +See also <> and <>. + + +//NOTE: The notable-highlights tagged regions are re-used in the +//Installation and Upgrade Guide + +// tag::notable-highlights[] + +// end::notable-highlights[] \ No newline at end of file diff --git a/docs/release-notes/highlights.asciidoc b/docs/release-notes/highlights.asciidoc index f490ca2618300..a8e9955964687 100644 --- a/docs/release-notes/highlights.asciidoc +++ b/docs/release-notes/highlights.asciidoc @@ -1,8 +1,5 @@ [[release-highlights]] -= {kib} Release Highlights -++++ -Release Highlights -++++ += Release Highlights [partintro] -- diff --git a/docs/reporting/automating-report-generation.asciidoc b/docs/reporting/automating-report-generation.asciidoc index 070d69c04cc52..02fa2c97f37f2 100644 --- a/docs/reporting/automating-report-generation.asciidoc +++ b/docs/reporting/automating-report-generation.asciidoc @@ -1,11 +1,11 @@ [role="xpack"] [[automating-report-generation]] == Automating Report Generation -You can automatically generate reports with a watch, or by submitting +You can automatically generate reports with {watcher}, or by submitting HTTP POST requests from a script. To automatically generate reports with a watch, you need to configure -{watcher} to trust the Kibana server’s certificate. For more information, +{watcher} to trust the {kib} server’s certificate. For more information, see <>. include::report-intervals.asciidoc[] @@ -13,27 +13,28 @@ include::report-intervals.asciidoc[] To get the URL for triggering a report generation during a given time period: . Load the saved object. -. Use the time-picker to specify a relative or absolute time period. -. Click *Reporting* in the Kibana toolbar. -. Copy the displayed **Generation URL**. +. Use the timepicker to specify a relative or absolute time period. +. Click *Share* in the Kibana toolbar. +. Select *PDF Reports*. +. Click **Copy POST URL**. NOTE: The response from this request with be JSON, and will contain a `path` property with a URL to use to download the generated report. When requesting that path, you will get a 503 response if it's not completed yet. In this case, retry after the -number of seconds in the `Retry-After` header in the response until you get the PDF. +number of seconds in the `Retry-After` header in the response until the PDF is returned. To configure a watch to email reports, you use the `reporting` attachment type in an `email` action. For more information, see -{xpack-ref}/actions-email.html#configuring-email[Configuring Email Accounts]. +{stack-ov}/actions-email.html#configuring-email[Configuring Email Accounts]. include::watch-example.asciidoc[] For more information about configuring watches, see -{xpack-ref}/how-watcher-works.html[How Watcher Works]. +{stack-ov}/how-watcher-works.html[How Watcher Works]. == Deprecated Report URLs -The following is deprecated in 6.0, and you should now use Kibana to get the URL for a +The following is deprecated in 6.0, and you should now use {kib} to get the URL for a particular report. You may request PDF reports optimized for printing through three {reporting} endpoints: diff --git a/docs/reporting/getting-started.asciidoc b/docs/reporting/getting-started.asciidoc index 1c616731f3bba..0bdb9d3d3f9f6 100644 --- a/docs/reporting/getting-started.asciidoc +++ b/docs/reporting/getting-started.asciidoc @@ -49,5 +49,4 @@ image:reporting/images/share-button.png["Reporting Button",link="share-button.pn === Generating a Report Automatically If you want to automatically generate reports from a script or with -{watcher}, use the displayed Generation URL. For more information, see -<> +{watcher}, see <> diff --git a/docs/security/securing-kibana.asciidoc b/docs/security/securing-kibana.asciidoc index 85c71f1c2d4aa..51c796e7fe9e2 100644 --- a/docs/security/securing-kibana.asciidoc +++ b/docs/security/securing-kibana.asciidoc @@ -73,8 +73,7 @@ xpack.security.sessionTimeout: 600000 . Restart {kib}. -[[kibana-roles]] -. Choose an authentication mechanism and grant users the privileges they need to +. [[kibana-roles]]Choose an authentication mechanism and grant users the privileges they need to use {kib}. + -- diff --git a/docs/setup/docker.asciidoc b/docs/setup/docker.asciidoc index a6a1b0ba9915e..0827cf5c73009 100644 --- a/docs/setup/docker.asciidoc +++ b/docs/setup/docker.asciidoc @@ -96,7 +96,7 @@ Some example translations are shown here: `KIBANA_DEFAULTAPPID`:: `kibana.defaultAppId` `XPACK_MONITORING_ENABLED`:: `xpack.monitoring.enabled` -In general, any setting listed in <> or <> can be +In general, any setting listed in <> can be configured with this technique. These variables can be set with +docker-compose+ like this: diff --git a/docs/uptime/images/check-history.png b/docs/uptime/images/check-history.png new file mode 100644 index 0000000000000..de5b8da2e0376 Binary files /dev/null and b/docs/uptime/images/check-history.png differ diff --git a/docs/uptime/images/crosshair-example.png b/docs/uptime/images/crosshair-example.png new file mode 100644 index 0000000000000..a9384419b0cfe Binary files /dev/null and b/docs/uptime/images/crosshair-example.png differ diff --git a/docs/uptime/images/error-list.png b/docs/uptime/images/error-list.png new file mode 100644 index 0000000000000..efdb9d43da34e Binary files /dev/null and b/docs/uptime/images/error-list.png differ diff --git a/docs/uptime/images/filter-bar.png b/docs/uptime/images/filter-bar.png new file mode 100644 index 0000000000000..c64b5c609ab0b Binary files /dev/null and b/docs/uptime/images/filter-bar.png differ diff --git a/docs/uptime/images/monitor-charts.png b/docs/uptime/images/monitor-charts.png new file mode 100644 index 0000000000000..7bc5ecbad4a41 Binary files /dev/null and b/docs/uptime/images/monitor-charts.png differ diff --git a/docs/uptime/images/monitor-list.png b/docs/uptime/images/monitor-list.png new file mode 100644 index 0000000000000..591d94a5e4965 Binary files /dev/null and b/docs/uptime/images/monitor-list.png differ diff --git a/docs/uptime/images/snapshot-view.png b/docs/uptime/images/snapshot-view.png new file mode 100644 index 0000000000000..87a888449af57 Binary files /dev/null and b/docs/uptime/images/snapshot-view.png differ diff --git a/docs/uptime/images/status-bar.png b/docs/uptime/images/status-bar.png new file mode 100644 index 0000000000000..0287ffd9cb2a3 Binary files /dev/null and b/docs/uptime/images/status-bar.png differ diff --git a/docs/uptime/index.asciidoc b/docs/uptime/index.asciidoc new file mode 100644 index 0000000000000..8e0b635d3d6a9 --- /dev/null +++ b/docs/uptime/index.asciidoc @@ -0,0 +1,28 @@ +[role="xpack"] +[[xpack-uptime]] += Uptime + +[partintro] +-- +Use the Uptime UI to monitor the status of network endpoints via HTTP/S, TCP, +and ICMP. You will be able to explore status over time, drill into specific monitors, +and view a high-level snapshot of your environment at a selected point in time. + +[float] +== Add monitors +To get started with Uptime monitoring, you'll need to define some monitors and run Heartbeat. +These monitors will provide the data we will be visualizing in the Uptime UI. +See {heartbeat-ref}/heartbeat-configuration.html[Configure Heartbeat] for instructions +on configuring monitors to begin storing Uptime information in your cluster. + +[float] +== Uptime, Heartbeat, and Kibana +For Uptime to work, it is important you use the same major versions of Heartbeat and Kibana. +For example, version 6.7 of Kibana will expect an index of `heartbeat-6*`, +while Kibana 7.0 requires an index of `heartbeat-7*` (containing documents from Heartbeat 7.0). + +-- + +include::overview.asciidoc[] +include::monitor.asciidoc[] +include::security.asciidoc[] diff --git a/docs/uptime/monitor.asciidoc b/docs/uptime/monitor.asciidoc new file mode 100644 index 0000000000000..d54fd02c7c069 --- /dev/null +++ b/docs/uptime/monitor.asciidoc @@ -0,0 +1,54 @@ +[role="xpack"] +[[uptime-monitor]] +== Monitor + +The Monitor page will help you get further insight into the performance +of a specific network endpoint. You'll see a detailed visualization of +the monitor's request duration over time, as well as the `up`/`down` +status over time. + +[float] +=== Status bar + +[role="screenshot"] +image::uptime/images/status-bar.png[Status bar] + +The Status bar displays a quick summary of the latest information +regarding your monitor. You can view its latest status, click a link to +visit the targeted URL, see its most recent request duration, and determine the +amount of time that has elapsed since the last check. + +You can use the Status bar to get a quick summary of current performance, +beyond simply knowing if the monitor is `up` or `down`. + +[float] +=== Monitor charts + +[role="screenshot"] +image::uptime/images/monitor-charts.png[Monitor charts] + +The Monitor charts visualize information over the time specified in the +date range. These charts can help you gain insight into how quickly requests are being resolved +by the targeted endpoint, and give you a sense of how frequently a host or endpoint +was down in your selected timespan. + +The first chart displays request duration information for your monitor. +The area surrounding the line is the range of request time for the corresponding +bucket. The line is the average time. + +Next, is a graphical representation of the check statuses over time. Hover over +the charts to display crosshairs with more specific numeric data. + +[role="screenshot"] +image::uptime/images/crosshair-example.png[Chart crosshair] + +[float] +=== Check history + +[role="screenshot"] +image::uptime/images/check-history.png[Check history view] + +The Check history displays the total count of this monitor's checks for the selected +date range. You can additionally filter the checks by `status` to help find recent problems +on a per-check basis. This table can help you gain some insight into more granular details +about recent individual data points Heartbeat is logging about your host or endpoint. diff --git a/docs/uptime/overview.asciidoc b/docs/uptime/overview.asciidoc new file mode 100644 index 0000000000000..5a421abb32bbc --- /dev/null +++ b/docs/uptime/overview.asciidoc @@ -0,0 +1,61 @@ +[role="xpack"] +[[uptime-overview]] + +== Overview + +The Uptime overview is intended to help you quickly identify and diagnose outages and +other connectivity issues within your network or environment. There is a date range +selection that is global to the Uptime UI; you can use this selection to highlight +an absolute date range, or a relative one, similar to other areas of Kibana. + +[float] +=== Filter bar + +[role="screenshot"] +image::uptime/images/filter-bar.png[Filter bar] + +The filter bar is designed to let you quickly view specific groups of monitors, or even +an individual monitor, if you have defined many. + +This control allows you to use automated filter options, as well as input custom filter +text to select specific monitors by field, URL, ID, and other attributes. + +[float] +=== Snapshot view + +[role="screenshot"] +image::uptime/images/snapshot-view.png[Snapshot view] + +This view is intended to quickly give you a sense of the overall +status of the environment you're monitoring, or a subset of those monitors. +Here, you can see the total number of detected monitors within the selected +Uptime date range. In addition to the total, the counts for the number of monitors +in an `up` or `down` state are displayed, based on the last check reported by Heartbeat +for each monitor. + +Next to the counts, there is a histogram displaying the change over time throughout the +selected date range. + +[float] +=== Monitor list + +[role="screenshot"] +image::uptime/images/monitor-list.png[Monitor list] + +The Monitor list displays information at the level of individual monitors. +The data shown here will flesh out your individual monitors, and provide a quick +way to navigate to a more in-depth visualization for interesting hosts or endpoints. + +This table includes information like the most recent status, when the monitor was last checked, its +ID and URL, its IP address, and a dedicated sparkline showing its check status over time. + +[float] +=== Error list + +[role="screenshot"] +image::uptime/images/error-list.png[Error list] + +The Error list displays aggregations of errors that Heartbeat has logged. Errors are +displayed by Error type, monitor ID, and message. Clicking a monitor's ID will take you +to the corresponding Monitor view, which can provide you richer information about the individual +data points that are resulting in the displayed errors. diff --git a/docs/uptime/security.asciidoc b/docs/uptime/security.asciidoc new file mode 100644 index 0000000000000..94ac0cf70c4ab --- /dev/null +++ b/docs/uptime/security.asciidoc @@ -0,0 +1,73 @@ +[role="xpack"] +[[uptime-security]] + +== Use with Elasticsearch Security + +If you use Elasticsearch security, you'll need to enable certain privileges for users +that would like to access the Uptime app. Below is an example of creating +a user and support role to implement those privileges. + +[float] +=== Create a role + +You'll need a role that lets you access the Heartbeat indices, which by default are `heartbeat-*`. +You can create this with the following request: + +["source","sh",subs="attributes,callouts"] +--------------------------------------------------------------- +PUT /_security/role/uptime +{ "indices" : [ + { + "names" : [ + "heartbeat-*" + ], + "privileges" : [ + "read", + "view_index_metadata" + ], + "field_security" : { + "grant" : [ + "*" + ] + }, + "allow_restricted_indices" : false + } + ], + "applications" : [ + { + "application" : "kibana-.kibana", + "privileges" : [ + "all" + ], + "resources" : [ + "*" + ] + } + ], + "transient_metadata" : { + "enabled" : true + } +} +--------------------------------------------------------------- +// CONSOLE + +[float] +=== Assign the role to a user + +Next, you'll need to create a user with both the `kibana_user`, and `uptime` roles. +You can do this with the following request: + +["source","sh",subs="attributes,callouts"] +--------------------------------------------------------------- +PUT /_security/user/jacknich +{ + "password" : "j@rV1s", + "roles" : [ "uptime", "kibana_user" ], + "full_name" : "Jack Nicholson", + "email" : "jacknich@example.com", + "metadata" : { + "intelligence" : 7 + } +} +--------------------------------------------------------------- +// CONSOLE \ No newline at end of file diff --git a/package.json b/package.json index d75f904e4233c..7d2906ace0021 100644 --- a/package.json +++ b/package.json @@ -90,13 +90,15 @@ "**/@types/*/**", "**/grunt-*", "**/grunt-*/**", - "x-pack/typescript", - "kbn_tp_*/**" + "x-pack/typescript" ] }, "dependencies": { + "@babel/core": "^7.3.4", + "@babel/polyfill": "^7.2.5", + "@babel/register": "^7.0.0", "@elastic/datemath": "5.0.2", - "@elastic/eui": "9.5.0", + "@elastic/eui": "9.7.1", "@elastic/filesaver": "1.1.2", "@elastic/good": "8.1.1-kibana2", "@elastic/numeral": "2.3.2", @@ -112,6 +114,7 @@ "@kbn/ui-framework": "1.0.0", "@types/json-stable-stringify": "^1.0.32", "@types/lodash.clonedeep": "^4.5.4", + "@types/react-grid-layout": "^0.16.7", "@types/recompose": "^0.30.5", "JSONStream": "1.1.1", "abortcontroller-polyfill": "^1.1.9", @@ -123,10 +126,7 @@ "angular-sanitize": "1.6.5", "angular-sortable-view": "0.0.15", "autoprefixer": "^9.1.0", - "babel-core": "6.26.3", - "babel-loader": "7.1.5", - "babel-polyfill": "6.26.0", - "babel-register": "6.26.0", + "babel-loader": "8.0.5", "bluebird": "3.5.3", "boom": "^7.2.0", "brace": "0.11.1", @@ -253,17 +253,17 @@ "@babel/parser": "^7.3.4", "@babel/types": "^7.3.4", "@elastic/eslint-config-kibana": "0.15.0", - "@elastic/eslint-plugin-kibana-custom": "1.1.0", "@elastic/makelogs": "^4.4.0", "@kbn/es": "1.0.0", "@kbn/eslint-import-resolver-kibana": "2.0.0", - "@kbn/eslint-plugin-license-header": "1.0.0", + "@kbn/eslint-plugin-eslint": "1.0.0", + "@kbn/expect": "1.0.0", "@kbn/plugin-generator": "1.0.0", "@kbn/test": "1.0.0", "@octokit/rest": "^15.10.0", "@types/angular": "1.6.50", "@types/angular-mocks": "^1.7.0", - "@types/babel-core": "^6.25.5", + "@types/babel__core": "^7.1.0", "@types/bluebird": "^3.1.1", "@types/boom": "^7.2.0", "@types/chance": "^1.0.0", @@ -275,7 +275,7 @@ "@types/delete-empty": "^2.0.0", "@types/elasticsearch": "^5.0.30", "@types/enzyme": "^3.1.12", - "@types/eslint": "^4.16.2", + "@types/eslint": "^4.16.6", "@types/execa": "^0.9.0", "@types/fetch-mock": "7.2.1", "@types/getopts": "^2.0.0", @@ -293,6 +293,7 @@ "@types/json5": "^0.0.30", "@types/listr": "^0.13.0", "@types/lodash": "^3.10.1", + "@types/lru-cache": "^5.1.0", "@types/minimatch": "^2.0.29", "@types/mocha": "^5.2.6", "@types/moment-timezone": "^0.5.8", @@ -320,8 +321,8 @@ "@types/zen-observable": "^0.8.0", "angular-mocks": "1.4.7", "archiver": "^3.0.0", - "babel-eslint": "^9.0.0", - "babel-jest": "^23.6.0", + "babel-eslint": "^10.0.1", + "babel-jest": "^24.1.0", "backport": "4.4.1", "chai": "3.5.0", "chance": "1.0.10", @@ -335,18 +336,18 @@ "enzyme-adapter-react-16": "^1.9.0", "enzyme-adapter-utils": "^1.10.0", "enzyme-to-json": "^3.3.4", - "eslint": "^5.6.0", - "eslint-config-prettier": "^3.1.0", - "eslint-plugin-babel": "^5.2.0", - "eslint-plugin-import": "^2.14.0", - "eslint-plugin-jest": "^21.26.2", - "eslint-plugin-jsx-a11y": "^6.1.2", - "eslint-plugin-mocha": "^5.2.0", + "eslint": "^5.15.1", + "eslint-config-prettier": "^4.1.0", + "eslint-plugin-babel": "^5.3.0", + "eslint-plugin-import": "^2.16.0", + "eslint-plugin-jest": "^22.3.0", + "eslint-plugin-jsx-a11y": "^6.2.1", + "eslint-plugin-mocha": "^5.3.0", "eslint-plugin-no-unsanitized": "^3.0.2", "eslint-plugin-prefer-object-spread": "^1.2.1", - "eslint-plugin-prettier": "^2.6.2", - "eslint-plugin-react": "^7.11.1", - "expect.js": "0.3.1", + "eslint-plugin-prettier": "^3.0.1", + "eslint-plugin-react": "^7.12.4", + "eslint-plugin-react-hooks": "^1.6.0", "faker": "1.1.0", "fetch-mock": "7.3.0", "geckodriver": "1.12.2", @@ -357,7 +358,7 @@ "grunt-karma": "2.0.0", "grunt-peg": "^2.0.1", "grunt-run": "0.7.0", - "gulp-babel": "^7.0.1", + "gulp-babel": "^8.0.0", "gulp-sourcemaps": "2.6.4", "has-ansi": "^3.0.0", "image-diff": "1.6.0", @@ -403,9 +404,6 @@ "supertest": "^3.1.0", "supertest-as-promised": "^4.0.2", "tree-kill": "^1.1.0", - "ts-jest": "^23.1.4", - "ts-loader": "^5.2.2", - "ts-node": "^7.0.1", "tslint": "^5.11.0", "tslint-config-prettier": "^1.15.0", "tslint-microsoft-contrib": "^6.0.0", diff --git a/packages/elastic-datemath/.babelrc b/packages/elastic-datemath/.babelrc index e39c0afafdd9b..26138d48b71b7 100644 --- a/packages/elastic-datemath/.babelrc +++ b/packages/elastic-datemath/.babelrc @@ -1,13 +1,16 @@ { - "presets": [["env", { - "targets": { - "node": "current", - "browsers": [ - "last 2 versions", - "> 5%", - "Safari 7", - ] + "presets": [ + ["@babel/preset-env", { + "targets": { + "node": "current", + "browsers": [ + "last 2 versions", + "> 5%", + "Safari 7" + ] + } } - }]], + ] + ], "plugins": ["add-module-exports"] -} \ No newline at end of file +} diff --git a/packages/elastic-datemath/package.json b/packages/elastic-datemath/package.json index 3b626077f5eaf..77c545709a3cf 100644 --- a/packages/elastic-datemath/package.json +++ b/packages/elastic-datemath/package.json @@ -11,9 +11,9 @@ "kbn:watch": "yarn build --watch" }, "devDependencies": { - "babel-cli": "^6.26.0", - "babel-plugin-add-module-exports": "^0.2.1", - "babel-preset-env": "^1.7.0", + "@babel/cli": "^7.2.3", + "@babel/preset-env": "^7.3.4", + "babel-plugin-add-module-exports": "^1.0.0", "moment": "^2.13.0" }, "dependencies": { diff --git a/packages/elastic-datemath/test/index.js b/packages/elastic-datemath/test/index.js index 2028c2c0cedce..582b331eac7e8 100644 --- a/packages/elastic-datemath/test/index.js +++ b/packages/elastic-datemath/test/index.js @@ -20,7 +20,7 @@ import dateMath from '../src/index'; import moment from 'moment'; import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; /** * Require a new instance of the moment library, bypassing the require cache. diff --git a/packages/eslint-config-kibana/.eslintrc.js b/packages/eslint-config-kibana/.eslintrc.js index 9906f9cf8dfe6..0b509d81c5795 100644 --- a/packages/eslint-config-kibana/.eslintrc.js +++ b/packages/eslint-config-kibana/.eslintrc.js @@ -10,6 +10,7 @@ module.exports = { 'mocha', 'babel', 'react', + 'react-hooks', 'import', 'no-unsanitized', 'prefer-object-spread', @@ -127,6 +128,8 @@ module.exports = { arrow: true, }], 'react/jsx-first-prop-new-line': ['error', 'multiline-multiprop'], + 'react-hooks/rules-of-hooks': 'error', // Checks rules of Hooks + 'react-hooks/exhaustive-deps': 'warn', // Checks effect dependencies 'jsx-a11y/accessible-emoji': 'error', 'jsx-a11y/alt-text': 'error', 'jsx-a11y/anchor-has-content': 'error', diff --git a/packages/eslint-config-kibana/package.json b/packages/eslint-config-kibana/package.json index d2e639eebbbe3..4be75ca2bcbe5 100644 --- a/packages/eslint-config-kibana/package.json +++ b/packages/eslint-config-kibana/package.json @@ -15,15 +15,16 @@ }, "homepage": "https://github.com/elastic/eslint-config-kibana#readme", "peerDependencies": { - "babel-eslint": "^9.0.0", - "eslint": "^5.6.0", - "eslint-plugin-babel": "^5.2.0", - "eslint-plugin-jsx-a11y": "^6.1.2", - "eslint-plugin-import": "^2.14.0", - "eslint-plugin-jest": "^21.22.1", - "eslint-plugin-mocha": "^5.2.0", + "babel-eslint": "^10.0.1", + "eslint": "^5.14.1", + "eslint-plugin-babel": "^5.3.0", + "eslint-plugin-jsx-a11y": "^6.2.1", + "eslint-plugin-import": "^2.16.0", + "eslint-plugin-jest": "^22.3.0", + "eslint-plugin-mocha": "^5.3.0", "eslint-plugin-no-unsanitized": "^3.0.2", "eslint-plugin-prefer-object-spread": "^1.2.1", - "eslint-plugin-react": "^7.11.1" + "eslint-plugin-react": "^7.12.4", + "eslint-plugin-react-hooks": "^1.6.0" } } diff --git a/packages/eslint-plugin-kibana-custom/index.js b/packages/eslint-plugin-kibana-custom/index.js deleted file mode 100644 index 3dada3ef3a610..0000000000000 --- a/packages/eslint-plugin-kibana-custom/index.js +++ /dev/null @@ -1,14 +0,0 @@ -module.exports = { - rules: { - 'no-default-export': { - meta: { - schema: [] - }, - create: context => ({ - ExportDefaultDeclaration: (node) => { - context.report(node, 'Default exports not allowed.'); - } - }) - } - } -}; diff --git a/packages/eslint-plugin-kibana-custom/package.json b/packages/eslint-plugin-kibana-custom/package.json deleted file mode 100644 index 51a36e86dce52..0000000000000 --- a/packages/eslint-plugin-kibana-custom/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "@elastic/eslint-plugin-kibana-custom", - "version": "1.1.0", - "license": "Apache-2.0", - "description": "Custom ESLint rules for Kibana", - "repository": { - "type": "git", - "url": "https://github.com/elastic/kibana/tree/master/packages/%40elastic/eslint-plugin-kibana-custom" - } -} diff --git a/packages/kbn-babel-code-parser/package.json b/packages/kbn-babel-code-parser/package.json index 23e7c29f22dfd..addc530285659 100755 --- a/packages/kbn-babel-code-parser/package.json +++ b/packages/kbn-babel-code-parser/package.json @@ -15,7 +15,7 @@ "kbn:watch": "yarn build --watch" }, "devDependencies": { - "babel-cli": "^6.26.0" + "@babel/cli": "^7.2.3" }, "dependencies": { "@kbn/babel-preset": "1.0.0", diff --git a/packages/kbn-babel-preset/common_preset.js b/packages/kbn-babel-preset/common_preset.js index a2d4495adc54b..e67a2db5a3800 100644 --- a/packages/kbn-babel-preset/common_preset.js +++ b/packages/kbn-babel-preset/common_preset.js @@ -19,20 +19,33 @@ module.exports = { presets: [ - require.resolve('babel-preset-react'), + require.resolve('@babel/preset-typescript'), + require.resolve('@babel/preset-react') ], plugins: [ require.resolve('babel-plugin-add-module-exports'), - // stage 3 - require.resolve('babel-plugin-transform-async-generator-functions'), - require.resolve('babel-plugin-transform-object-rest-spread'), - // the class properties proposal was merged with the private fields proposal + // The class properties proposal was merged with the private fields proposal // into the "class fields" proposal. Babel doesn't support this combined // proposal yet, which includes private field, so this transform is // TECHNICALLY stage 2, but for all intents and purposes it's stage 3 // // See https://github.com/babel/proposals/issues/12 for progress - require.resolve('babel-plugin-transform-class-properties'), + require.resolve('@babel/plugin-proposal-class-properties'), ], + overrides: [ + { + // Babel 7 don't support the namespace feature on typescript code. + // With namespaces only used for type declarations, we can securely + // strip them off for babel on x-pack infra plugin + // + // See https://github.com/babel/babel/issues/8244#issuecomment-466548733 + test: /x-pack[\/\\]plugins[\/\\]infra[\/\\].*[\/\\]graphql/, + plugins: [ + [ + require.resolve('babel-plugin-typescript-strip-namespaces'), + ], + ] + } + ] }; diff --git a/packages/kbn-babel-preset/common_preset_7.js b/packages/kbn-babel-preset/common_preset_7.js deleted file mode 100644 index df72f382e2b0a..0000000000000 --- a/packages/kbn-babel-preset/common_preset_7.js +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -module.exports = { - presets: [ - require.resolve('@babel/preset-react'), - require.resolve('@babel/preset-typescript'), - ], - plugins: [ - require.resolve('babel7-plugin-add-module-exports'), - // stage 3 - require.resolve('@babel/plugin-proposal-async-generator-functions'), - require.resolve('@babel/plugin-proposal-object-rest-spread'), - - // the class properties proposal was merged with the private fields proposal - // into the "class fields" proposal. Babel doesn't support this combined - // proposal yet, which includes private field, so this transform is - // TECHNICALLY stage 2, but for all intents and purposes it's stage 3 - // - // See https://github.com/babel/proposals/issues/12 for progress - require.resolve('@babel/plugin-proposal-class-properties'), - ], -}; diff --git a/packages/kbn-babel-preset/node_preset.js b/packages/kbn-babel-preset/node_preset.js index 04d6dd3609e8a..ac4dc17e63803 100644 --- a/packages/kbn-babel-preset/node_preset.js +++ b/packages/kbn-babel-preset/node_preset.js @@ -17,34 +17,37 @@ * under the License. */ -module.exports = { - presets: [ - [ - require.resolve('babel-preset-env'), - { - targets: { - // only applies the necessary transformations based on the - // current node.js processes version. For example: running - // `nvm install 8 && node ./src/cli` will run kibana in node - // version 8 and babel will stop transpiling async/await - // because they are supported in the "current" version of node - node: 'current', - }, +module.exports = () => { + return { + presets: [ + [ + require.resolve('@babel/preset-env'), + { + targets: { + // only applies the necessary transformations based on the + // current node.js processes version. For example: running + // `nvm install 8 && node ./src/cli` will run kibana in node + // version 8 and babel will stop transpiling async/await + // because they are supported in the "current" version of node + node: 'current', + }, - // replaces `import "babel-polyfill"` with a list of require statements - // for just the polyfills that the target versions don't already supply - // on their own - useBuiltIns: true, - }, + // replaces `import "@babel/polyfill"` with a list of require statements + // for just the polyfills that the target versions don't already supply + // on their own + useBuiltIns: 'entry', + modules: 'cjs' + }, + ], + require('./common_preset'), ], - require('./common_preset'), - ], - plugins: [ - [ - require.resolve('babel-plugin-transform-define'), - { - 'global.__BUILT_WITH_BABEL__': 'true' - } + plugins: [ + [ + require.resolve('babel-plugin-transform-define'), + { + 'global.__BUILT_WITH_BABEL__': 'true' + } + ] ] - ] + }; }; diff --git a/packages/kbn-babel-preset/node_preset_7.js b/packages/kbn-babel-preset/node_preset_7.js deleted file mode 100644 index b57dd58dd9f15..0000000000000 --- a/packages/kbn-babel-preset/node_preset_7.js +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -module.exports = () => ({ - presets: [ - [ - require.resolve('@babel/preset-env'), - { - targets: { - // only applies the necessary transformations based on the - // current node.js processes version. For example: running - // `nvm install 8 && node ./src/cli` will run kibana in node - // version 8 and babel will stop transpiling async/await - // because they are supported in the "current" version of node - node: 'current', - }, - - // replaces `import "babel-polyfill"` with a list of require statements - // for just the polyfills that the target versions don't already supply - // on their own - useBuiltIns: 'entry', - }, - ], - require('./common_preset_7'), - ], - plugins: [ - [ - require.resolve('babel-plugin-transform-define'), - { - 'global.__BUILT_WITH_BABEL__': 'true' - } - ] - ] -}); diff --git a/packages/kbn-babel-preset/package.json b/packages/kbn-babel-preset/package.json index 41c03c0542675..79ee6bbe39c0c 100644 --- a/packages/kbn-babel-preset/package.json +++ b/packages/kbn-babel-preset/package.json @@ -4,20 +4,12 @@ "version": "1.0.0", "license": "Apache-2.0", "dependencies": { - "@babel/core": "^7.3.4", - "@babel/plugin-proposal-async-generator-functions": "^7.2.0", "@babel/plugin-proposal-class-properties": "^7.3.4", - "@babel/plugin-proposal-object-rest-spread": "^7.3.4", + "@babel/preset-react":"^7.0.0", "@babel/preset-env": "^7.3.4", - "@babel/preset-react": "^7.0.0", "@babel/preset-typescript": "^7.3.3", - "babel-plugin-add-module-exports": "^0.2.1", - "babel-plugin-transform-async-generator-functions": "^6.24.1", - "babel-plugin-transform-class-properties": "^6.24.1", + "babel-plugin-add-module-exports": "^1.0.0", "babel-plugin-transform-define": "^1.3.1", - "babel-plugin-transform-object-rest-spread": "^6.26.0", - "babel-preset-env": "^1.7.0", - "babel-preset-react": "^6.24.1", - "babel7-plugin-add-module-exports": "npm:babel-plugin-add-module-exports@^1.0.0" + "babel-plugin-typescript-strip-namespaces": "^1.1.1" } } diff --git a/packages/kbn-babel-preset/webpack_preset.js b/packages/kbn-babel-preset/webpack_preset.js index 97bfa44a049d9..df5745bc33f89 100644 --- a/packages/kbn-babel-preset/webpack_preset.js +++ b/packages/kbn-babel-preset/webpack_preset.js @@ -17,21 +17,24 @@ * under the License. */ -module.exports = { - presets: [ - [ - require.resolve('babel-preset-env'), - { - targets: { - browsers: [ - 'last 2 versions', - '> 5%', - 'Safari 7', // for PhantomJS support: https://github.com/elastic/kibana/issues/27136 - ], +module.exports = () => { + return { + presets: [ + [ + require.resolve('@babel/preset-env'), + { + targets: { + browsers: [ + 'last 2 versions', + '> 5%', + 'Safari 7', // for PhantomJS support: https://github.com/elastic/kibana/issues/27136 + ], + }, + useBuiltIns: 'entry', + modules: 'cjs' }, - useBuiltIns: true, - }, - ], - require('./common_preset'), - ] + ], + require('./common_preset'), + ] + }; }; diff --git a/packages/kbn-dev-utils/package.json b/packages/kbn-dev-utils/package.json index 3775cc06d3b11..4fbc80d6e679a 100644 --- a/packages/kbn-dev-utils/package.json +++ b/packages/kbn-dev-utils/package.json @@ -19,9 +19,9 @@ "tslib": "^1.9.3" }, "devDependencies": { + "@babel/cli": "^7.2.3", "@kbn/babel-preset": "1.0.0", - "babel-cli": "^6.26.0", - "chance": "1.0.6", - "expect.js": "0.3.1" + "@kbn/expect": "1.0.0", + "chance": "1.0.6" } } diff --git a/packages/kbn-es-query/package.json b/packages/kbn-es-query/package.json index 09682ae7ede31..ff68adeac8631 100644 --- a/packages/kbn-es-query/package.json +++ b/packages/kbn-es-query/package.json @@ -22,8 +22,8 @@ "@babel/preset-typescript": "^7.3.3", "@kbn/babel-preset": "1.0.0", "@kbn/dev-utils": "1.0.0", + "@kbn/expect": "1.0.0", "del": "^3.0.0", - "expect.js": "0.3.1", "getopts": "^2.2.3", "supports-color": "^6.1.0", "typescript": "^3.3.3333" diff --git a/packages/kbn-es-query/src/es_query/__tests__/_migrate_filter.js b/packages/kbn-es-query/src/es_query/__tests__/_migrate_filter.js index 0faa0d6de6464..d9f559987f58b 100644 --- a/packages/kbn-es-query/src/es_query/__tests__/_migrate_filter.js +++ b/packages/kbn-es-query/src/es_query/__tests__/_migrate_filter.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import _ from 'lodash'; import { migrateFilter } from '../migrate_filter'; diff --git a/packages/kbn-es-query/src/es_query/__tests__/build_es_query.js b/packages/kbn-es-query/src/es_query/__tests__/build_es_query.js index 951a9e03cb9fe..879fb1cd6c45f 100644 --- a/packages/kbn-es-query/src/es_query/__tests__/build_es_query.js +++ b/packages/kbn-es-query/src/es_query/__tests__/build_es_query.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { buildEsQuery } from '../build_es_query'; import indexPattern from '../../__fixtures__/index_pattern_response.json'; import { fromKueryExpression, toElasticsearchQuery } from '../../kuery'; diff --git a/packages/kbn-es-query/src/es_query/__tests__/decorate_query.js b/packages/kbn-es-query/src/es_query/__tests__/decorate_query.js index 5b3e64bb229ad..447a875e9eadc 100644 --- a/packages/kbn-es-query/src/es_query/__tests__/decorate_query.js +++ b/packages/kbn-es-query/src/es_query/__tests__/decorate_query.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { decorateQuery } from '../decorate_query'; describe('Query decorator', function () { diff --git a/packages/kbn-es-query/src/es_query/__tests__/filter_matches_index.js b/packages/kbn-es-query/src/es_query/__tests__/filter_matches_index.js index fe7da03731263..1c43230aeea30 100644 --- a/packages/kbn-es-query/src/es_query/__tests__/filter_matches_index.js +++ b/packages/kbn-es-query/src/es_query/__tests__/filter_matches_index.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { filterMatchesIndex } from '../filter_matches_index'; describe('filterMatchesIndex', function () { diff --git a/packages/kbn-es-query/src/es_query/__tests__/from_filters.js b/packages/kbn-es-query/src/es_query/__tests__/from_filters.js index 8d1b103c8f66c..53016f33dc6cd 100644 --- a/packages/kbn-es-query/src/es_query/__tests__/from_filters.js +++ b/packages/kbn-es-query/src/es_query/__tests__/from_filters.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { buildQueryFromFilters } from '../from_filters'; describe('build query', function () { diff --git a/packages/kbn-es-query/src/es_query/__tests__/from_kuery.js b/packages/kbn-es-query/src/es_query/__tests__/from_kuery.js index 7f4952fbbfc48..7c285a4416abc 100644 --- a/packages/kbn-es-query/src/es_query/__tests__/from_kuery.js +++ b/packages/kbn-es-query/src/es_query/__tests__/from_kuery.js @@ -19,7 +19,7 @@ import { buildQueryFromKuery } from '../from_kuery'; import indexPattern from '../../__fixtures__/index_pattern_response.json'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { fromKueryExpression, toElasticsearchQuery } from '../../kuery'; describe('build query', function () { diff --git a/packages/kbn-es-query/src/es_query/__tests__/from_lucene.js b/packages/kbn-es-query/src/es_query/__tests__/from_lucene.js index 5da5075925dbe..7a4b6f7b359f5 100644 --- a/packages/kbn-es-query/src/es_query/__tests__/from_lucene.js +++ b/packages/kbn-es-query/src/es_query/__tests__/from_lucene.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { buildQueryFromLucene } from '../from_lucene'; import { decorateQuery } from '../decorate_query'; import { luceneStringToDsl } from '../lucene_string_to_dsl'; diff --git a/packages/kbn-es-query/src/es_query/__tests__/lucene_string_to_dsl.js b/packages/kbn-es-query/src/es_query/__tests__/lucene_string_to_dsl.js index 67908f28b7330..04f6209ce6665 100644 --- a/packages/kbn-es-query/src/es_query/__tests__/lucene_string_to_dsl.js +++ b/packages/kbn-es-query/src/es_query/__tests__/lucene_string_to_dsl.js @@ -18,7 +18,7 @@ */ import { luceneStringToDsl } from '../lucene_string_to_dsl'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; describe('build query', function () { diff --git a/packages/kbn-es-query/src/filters/__tests__/phrase.js b/packages/kbn-es-query/src/filters/__tests__/phrase.js index 0fd2a5fbd0760..6b611fdf074f2 100644 --- a/packages/kbn-es-query/src/filters/__tests__/phrase.js +++ b/packages/kbn-es-query/src/filters/__tests__/phrase.js @@ -19,7 +19,7 @@ import { buildInlineScriptForPhraseFilter, buildPhraseFilter } from '../phrase'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import _ from 'lodash'; import indexPattern from '../../__fixtures__/index_pattern_response.json'; import filterSkeleton from '../../__fixtures__/filter_skeleton'; diff --git a/packages/kbn-es-query/src/filters/__tests__/query.js b/packages/kbn-es-query/src/filters/__tests__/query.js index 62f7a898140c1..8b774f05c29d3 100644 --- a/packages/kbn-es-query/src/filters/__tests__/query.js +++ b/packages/kbn-es-query/src/filters/__tests__/query.js @@ -19,7 +19,7 @@ import { buildQueryFilter } from '../query'; import { cloneDeep } from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import indexPattern from '../../__fixtures__/index_pattern_response.json'; import filterSkeleton from '../../__fixtures__/filter_skeleton'; diff --git a/packages/kbn-es-query/src/filters/__tests__/range.js b/packages/kbn-es-query/src/filters/__tests__/range.js index 6fe914475836f..595b386a32ab8 100644 --- a/packages/kbn-es-query/src/filters/__tests__/range.js +++ b/packages/kbn-es-query/src/filters/__tests__/range.js @@ -18,7 +18,7 @@ */ import { buildRangeFilter } from '../range'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import _ from 'lodash'; import indexPattern from '../../__fixtures__/index_pattern_response.json'; import filterSkeleton from '../../__fixtures__/filter_skeleton'; diff --git a/packages/kbn-es-query/src/kuery/ast/__tests__/ast.js b/packages/kbn-es-query/src/kuery/ast/__tests__/ast.js index 1107d1eea04d6..96039526752d4 100644 --- a/packages/kbn-es-query/src/kuery/ast/__tests__/ast.js +++ b/packages/kbn-es-query/src/kuery/ast/__tests__/ast.js @@ -18,7 +18,7 @@ */ import * as ast from '../ast'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { nodeTypes } from '../../node_types/index'; import indexPatternResponse from '../../../__fixtures__/index_pattern_response.json'; diff --git a/packages/kbn-es-query/src/kuery/filter_migration/__tests__/exists.js b/packages/kbn-es-query/src/kuery/filter_migration/__tests__/exists.js index e4eff469933db..6c149b6b8a98d 100644 --- a/packages/kbn-es-query/src/kuery/filter_migration/__tests__/exists.js +++ b/packages/kbn-es-query/src/kuery/filter_migration/__tests__/exists.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { convertExistsFilter } from '../exists'; describe('filter to kuery migration', function () { diff --git a/packages/kbn-es-query/src/kuery/filter_migration/__tests__/filter_to_kuery.js b/packages/kbn-es-query/src/kuery/filter_migration/__tests__/filter_to_kuery.js index f21675fdd7de4..1e5656f85eb89 100644 --- a/packages/kbn-es-query/src/kuery/filter_migration/__tests__/filter_to_kuery.js +++ b/packages/kbn-es-query/src/kuery/filter_migration/__tests__/filter_to_kuery.js @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { filterToKueryAST } from '../filter_to_kuery'; describe('filter to kuery migration', function () { diff --git a/packages/kbn-es-query/src/kuery/filter_migration/__tests__/geo_bounding_box.js b/packages/kbn-es-query/src/kuery/filter_migration/__tests__/geo_bounding_box.js index 6842e2b8a3dd0..e4cb6d30bbf48 100644 --- a/packages/kbn-es-query/src/kuery/filter_migration/__tests__/geo_bounding_box.js +++ b/packages/kbn-es-query/src/kuery/filter_migration/__tests__/geo_bounding_box.js @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { convertGeoBoundingBox } from '../geo_bounding_box'; describe('filter to kuery migration', function () { diff --git a/packages/kbn-es-query/src/kuery/filter_migration/__tests__/geo_polygon.js b/packages/kbn-es-query/src/kuery/filter_migration/__tests__/geo_polygon.js index 0228a73a99512..e1b2a09edaba3 100644 --- a/packages/kbn-es-query/src/kuery/filter_migration/__tests__/geo_polygon.js +++ b/packages/kbn-es-query/src/kuery/filter_migration/__tests__/geo_polygon.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { convertGeoPolygon } from '../geo_polygon'; describe('filter to kuery migration', function () { diff --git a/packages/kbn-es-query/src/kuery/filter_migration/__tests__/phrase.js b/packages/kbn-es-query/src/kuery/filter_migration/__tests__/phrase.js index 4e3df8d6ddec4..b2a7c097a3f95 100644 --- a/packages/kbn-es-query/src/kuery/filter_migration/__tests__/phrase.js +++ b/packages/kbn-es-query/src/kuery/filter_migration/__tests__/phrase.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { convertPhraseFilter } from '../phrase'; describe('filter to kuery migration', function () { diff --git a/packages/kbn-es-query/src/kuery/filter_migration/__tests__/range.js b/packages/kbn-es-query/src/kuery/filter_migration/__tests__/range.js index 5583a585e35eb..2cad37cc0ad3a 100644 --- a/packages/kbn-es-query/src/kuery/filter_migration/__tests__/range.js +++ b/packages/kbn-es-query/src/kuery/filter_migration/__tests__/range.js @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { convertRangeFilter } from '../range'; describe('filter to kuery migration', function () { diff --git a/packages/kbn-es-query/src/kuery/functions/__tests__/and.js b/packages/kbn-es-query/src/kuery/functions/__tests__/and.js index 2a29e01d2b50b..5a0d3a9cd58b2 100644 --- a/packages/kbn-es-query/src/kuery/functions/__tests__/and.js +++ b/packages/kbn-es-query/src/kuery/functions/__tests__/and.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import * as and from '../and'; import { nodeTypes } from '../../node_types'; import * as ast from '../../ast'; diff --git a/packages/kbn-es-query/src/kuery/functions/__tests__/exists.js b/packages/kbn-es-query/src/kuery/functions/__tests__/exists.js index 694c044bd49ff..0eaa69a3243e0 100644 --- a/packages/kbn-es-query/src/kuery/functions/__tests__/exists.js +++ b/packages/kbn-es-query/src/kuery/functions/__tests__/exists.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import * as exists from '../exists'; import { nodeTypes } from '../../node_types'; import _ from 'lodash'; diff --git a/packages/kbn-es-query/src/kuery/functions/__tests__/geo_bounding_box.js b/packages/kbn-es-query/src/kuery/functions/__tests__/geo_bounding_box.js index 28aee22dd94d9..2f8b784d6f6e8 100644 --- a/packages/kbn-es-query/src/kuery/functions/__tests__/geo_bounding_box.js +++ b/packages/kbn-es-query/src/kuery/functions/__tests__/geo_bounding_box.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import * as geoBoundingBox from '../geo_bounding_box'; import { nodeTypes } from '../../node_types'; import indexPatternResponse from '../../../__fixtures__/index_pattern_response.json'; diff --git a/packages/kbn-es-query/src/kuery/functions/__tests__/geo_polygon.js b/packages/kbn-es-query/src/kuery/functions/__tests__/geo_polygon.js index 7f01b84eef93d..1c6a2e0e47fde 100644 --- a/packages/kbn-es-query/src/kuery/functions/__tests__/geo_polygon.js +++ b/packages/kbn-es-query/src/kuery/functions/__tests__/geo_polygon.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import * as geoPolygon from '../geo_polygon'; import { nodeTypes } from '../../node_types'; import indexPatternResponse from '../../../__fixtures__/index_pattern_response.json'; diff --git a/packages/kbn-es-query/src/kuery/functions/__tests__/is.js b/packages/kbn-es-query/src/kuery/functions/__tests__/is.js index 5018b18c2e8c2..7ceac9b605db4 100644 --- a/packages/kbn-es-query/src/kuery/functions/__tests__/is.js +++ b/packages/kbn-es-query/src/kuery/functions/__tests__/is.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import * as is from '../is'; import { nodeTypes } from '../../node_types'; import indexPatternResponse from '../../../__fixtures__/index_pattern_response.json'; diff --git a/packages/kbn-es-query/src/kuery/functions/__tests__/not.js b/packages/kbn-es-query/src/kuery/functions/__tests__/not.js index f397382b543e8..6b5b50e15524d 100644 --- a/packages/kbn-es-query/src/kuery/functions/__tests__/not.js +++ b/packages/kbn-es-query/src/kuery/functions/__tests__/not.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import * as not from '../not'; import { nodeTypes } from '../../node_types'; import * as ast from '../../ast'; diff --git a/packages/kbn-es-query/src/kuery/functions/__tests__/or.js b/packages/kbn-es-query/src/kuery/functions/__tests__/or.js index 49a2b21446b02..3b5bf27f2d8cb 100644 --- a/packages/kbn-es-query/src/kuery/functions/__tests__/or.js +++ b/packages/kbn-es-query/src/kuery/functions/__tests__/or.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import * as or from '../or'; import { nodeTypes } from '../../node_types'; import * as ast from '../../ast'; diff --git a/packages/kbn-es-query/src/kuery/functions/__tests__/range.js b/packages/kbn-es-query/src/kuery/functions/__tests__/range.js index 92108a8fb8674..a8c0b8157405d 100644 --- a/packages/kbn-es-query/src/kuery/functions/__tests__/range.js +++ b/packages/kbn-es-query/src/kuery/functions/__tests__/range.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import * as range from '../range'; import { nodeTypes } from '../../node_types'; import indexPatternResponse from '../../../__fixtures__/index_pattern_response.json'; diff --git a/packages/kbn-es-query/src/kuery/functions/__tests__/utils/get_fields.js b/packages/kbn-es-query/src/kuery/functions/__tests__/utils/get_fields.js index 501f61a92b5e2..7718479130a8a 100644 --- a/packages/kbn-es-query/src/kuery/functions/__tests__/utils/get_fields.js +++ b/packages/kbn-es-query/src/kuery/functions/__tests__/utils/get_fields.js @@ -18,7 +18,7 @@ */ import { getFields } from '../../utils/get_fields'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import indexPatternResponse from '../../../../__fixtures__/index_pattern_response.json'; import { nodeTypes } from '../../..'; diff --git a/packages/kbn-es-query/src/kuery/node_types/__tests__/function.js b/packages/kbn-es-query/src/kuery/node_types/__tests__/function.js index 4e7e1d9254365..2ccb3bd5991d8 100644 --- a/packages/kbn-es-query/src/kuery/node_types/__tests__/function.js +++ b/packages/kbn-es-query/src/kuery/node_types/__tests__/function.js @@ -19,7 +19,7 @@ import * as functionType from '../function'; import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import * as isFunction from '../../functions/is'; import indexPatternResponse from '../../../__fixtures__/index_pattern_response.json'; diff --git a/packages/kbn-es-query/src/kuery/node_types/__tests__/literal.js b/packages/kbn-es-query/src/kuery/node_types/__tests__/literal.js index 570e21dbf3899..25fe2bcc45a45 100644 --- a/packages/kbn-es-query/src/kuery/node_types/__tests__/literal.js +++ b/packages/kbn-es-query/src/kuery/node_types/__tests__/literal.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import * as literal from '../literal'; describe('kuery node types', function () { diff --git a/packages/kbn-es-query/src/kuery/node_types/__tests__/named_arg.js b/packages/kbn-es-query/src/kuery/node_types/__tests__/named_arg.js index 6a7d8cb3abb81..cfb8f6d5274db 100644 --- a/packages/kbn-es-query/src/kuery/node_types/__tests__/named_arg.js +++ b/packages/kbn-es-query/src/kuery/node_types/__tests__/named_arg.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import * as namedArg from '../named_arg'; import { nodeTypes } from '../../node_types'; diff --git a/packages/kbn-es-query/src/kuery/node_types/__tests__/wildcard.js b/packages/kbn-es-query/src/kuery/node_types/__tests__/wildcard.js index f9ad1bf1dccb6..0c4379378c6d6 100644 --- a/packages/kbn-es-query/src/kuery/node_types/__tests__/wildcard.js +++ b/packages/kbn-es-query/src/kuery/node_types/__tests__/wildcard.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import * as wildcard from '../wildcard'; describe('kuery node types', function () { diff --git a/packages/eslint-plugin-kibana-custom/README.md b/packages/kbn-eslint-plugin-eslint/README.md similarity index 100% rename from packages/eslint-plugin-kibana-custom/README.md rename to packages/kbn-eslint-plugin-eslint/README.md diff --git a/packages/kbn-eslint-plugin-license-header/index.js b/packages/kbn-eslint-plugin-eslint/index.js similarity index 89% rename from packages/kbn-eslint-plugin-license-header/index.js rename to packages/kbn-eslint-plugin-eslint/index.js index 003c89b0c5f3b..2840986ddf17c 100644 --- a/packages/kbn-eslint-plugin-license-header/index.js +++ b/packages/kbn-eslint-plugin-eslint/index.js @@ -21,5 +21,7 @@ module.exports = { rules: { 'require-license-header': require('./rules/require_license_header'), 'disallow-license-headers': require('./rules/disallow_license_headers'), + 'no-default-export': require('./rules/no_default_export'), + module_migration: require('./rules/module_migration'), }, }; diff --git a/packages/kbn-eslint-plugin-license-header/lib.js b/packages/kbn-eslint-plugin-eslint/lib.js similarity index 93% rename from packages/kbn-eslint-plugin-license-header/lib.js rename to packages/kbn-eslint-plugin-eslint/lib.js index 5d632b7c328c3..56684746c479f 100644 --- a/packages/kbn-eslint-plugin-license-header/lib.js +++ b/packages/kbn-eslint-plugin-eslint/lib.js @@ -31,14 +31,14 @@ exports.normalizeWhitespace = function normalizeWhitespace(string) { return string.replace(/\s+/g, ' '); }; -exports.init = function (context, program, initStep) { +exports.init = function(context, program, initStep) { try { return initStep(); } catch (error) { if (error.failedAssertion) { context.report({ node: program, - message: error.message + message: error.message, }); } else { throw error; diff --git a/packages/kbn-eslint-plugin-license-header/package.json b/packages/kbn-eslint-plugin-eslint/package.json similarity index 59% rename from packages/kbn-eslint-plugin-license-header/package.json rename to packages/kbn-eslint-plugin-eslint/package.json index 2c62a4232cf18..e2024b54a620c 100644 --- a/packages/kbn-eslint-plugin-license-header/package.json +++ b/packages/kbn-eslint-plugin-eslint/package.json @@ -1,11 +1,11 @@ { - "name": "@kbn/eslint-plugin-license-header", + "name": "@kbn/eslint-plugin-eslint", "version": "1.0.0", "private": true, "license": "Apache-2.0", "peerDependencies": { - "eslint": "^5.6.0", - "babel-eslint": "^9.0.0" + "eslint": "^5.14.1", + "babel-eslint": "^10.0.1" }, "dependencies": { "dedent": "^0.7.0" diff --git a/packages/kbn-eslint-plugin-license-header/rules/__tests__/disallow_license_headers.js b/packages/kbn-eslint-plugin-eslint/rules/__tests__/disallow_license_headers.js similarity index 73% rename from packages/kbn-eslint-plugin-license-header/rules/__tests__/disallow_license_headers.js rename to packages/kbn-eslint-plugin-eslint/rules/__tests__/disallow_license_headers.js index 2ae6111166089..61fc1c112b8b2 100644 --- a/packages/kbn-eslint-plugin-license-header/rules/__tests__/disallow_license_headers.js +++ b/packages/kbn-eslint-plugin-eslint/rules/__tests__/disallow_license_headers.js @@ -21,15 +21,14 @@ const { RuleTester } = require('eslint'); const rule = require('../disallow_license_headers'); const dedent = require('dedent'); -const RULE_NAME = '@kbn/license-header/disallow-license-headers'; - const ruleTester = new RuleTester({ parser: 'babel-eslint', parserOptions: { - ecmaVersion: 2015 - } + ecmaVersion: 2015, + }, }); -ruleTester.run(RULE_NAME, rule, { + +ruleTester.run('@kbn/eslint/disallow-license-headers', rule, { valid: [ { code: dedent` @@ -38,11 +37,11 @@ ruleTester.run(RULE_NAME, rule, { console.log('foo') `, - options: [{ - licenses: [ - '// license' - ] - }], + options: [ + { + licenses: ['// license'], + }, + ], }, { code: dedent` @@ -51,12 +50,12 @@ ruleTester.run(RULE_NAME, rule, { console.log('foo') `, - options: [{ - licenses: [ - '/* license */', - ] - }], - } + options: [ + { + licenses: ['/* license */'], + }, + ], + }, ], invalid: [ @@ -70,8 +69,8 @@ ruleTester.run(RULE_NAME, rule, { errors: [ { message: '"licenses" option is required', - } - ] + }, + ], }, // license cannot contain multiple block comments @@ -80,16 +79,16 @@ ruleTester.run(RULE_NAME, rule, { console.log('foo') `, - options: [{ - licenses: [ - '/* one *//* two */' - ] - }], + options: [ + { + licenses: ['/* one *//* two */'], + }, + ], errors: [ { message: '"licenses[0]" option must only include a single comment', - } - ] + }, + ], }, // license cannot contain multiple line comments @@ -98,16 +97,16 @@ ruleTester.run(RULE_NAME, rule, { console.log('foo') `, - options: [{ - licenses: [ - `// one\n// two` - ] - }], + options: [ + { + licenses: [`// one\n// two`], + }, + ], errors: [ { message: '"licenses[0]" option must only include a single comment', - } - ] + }, + ], }, // license cannot contain expressions @@ -116,20 +115,22 @@ ruleTester.run(RULE_NAME, rule, { console.log('foo') `, - options: [{ - licenses: [ - '// old license', - dedent` + options: [ + { + licenses: [ + '// old license', + dedent` /* license */ console.log('hello world'); - ` - ] - }], + `, + ], + }, + ], errors: [ { message: '"licenses[1]" option must only include a single comment', - } - ] + }, + ], }, // license is not a single comment @@ -138,18 +139,16 @@ ruleTester.run(RULE_NAME, rule, { console.log('foo') `, - options: [{ - licenses: [ - '// old license', - '// older license', - `console.log('hello world');` - ] - }], + options: [ + { + licenses: ['// old license', '// older license', `console.log('hello world');`], + }, + ], errors: [ { message: '"licenses[2]" option must only include a single comment', - } - ] + }, + ], }, - ] + ], }); diff --git a/packages/kbn-eslint-plugin-license-header/rules/__tests__/require_license_header.js b/packages/kbn-eslint-plugin-eslint/rules/__tests__/require_license_header.js similarity index 87% rename from packages/kbn-eslint-plugin-license-header/rules/__tests__/require_license_header.js rename to packages/kbn-eslint-plugin-eslint/rules/__tests__/require_license_header.js index 86c7ea3244541..491ceb2290be1 100644 --- a/packages/kbn-eslint-plugin-license-header/rules/__tests__/require_license_header.js +++ b/packages/kbn-eslint-plugin-eslint/rules/__tests__/require_license_header.js @@ -21,15 +21,14 @@ const { RuleTester } = require('eslint'); const rule = require('../require_license_header'); const dedent = require('dedent'); -const RULE_NAME = '@kbn/license-header/require-license-header'; - const ruleTester = new RuleTester({ parser: 'babel-eslint', parserOptions: { - ecmaVersion: 2015 - } + ecmaVersion: 2015, + }, }); -ruleTester.run(RULE_NAME, rule, { + +ruleTester.run('@kbn/eslint/require-license-header', rule, { valid: [ { code: dedent` @@ -48,7 +47,7 @@ ruleTester.run(RULE_NAME, rule, { `, options: [{ license: '// license' }], - } + }, ], invalid: [ @@ -62,8 +61,8 @@ ruleTester.run(RULE_NAME, rule, { errors: [ { message: '"license" option is required', - } - ] + }, + ], }, // content cannot contain multiple block comments @@ -72,14 +71,12 @@ ruleTester.run(RULE_NAME, rule, { console.log('foo') `, - options: [ - { license: '/* one *//* two */' } - ], + options: [{ license: '/* one *//* two */' }], errors: [ { message: '"license" option must only include a single comment', - } - ] + }, + ], }, // content cannot contain multiple line comments @@ -88,14 +85,12 @@ ruleTester.run(RULE_NAME, rule, { console.log('foo') `, - options: [ - { license: `// one\n// two` } - ], + options: [{ license: `// one\n// two` }], errors: [ { message: '"license" option must only include a single comment', - } - ] + }, + ], }, // content cannot contain expressions @@ -109,14 +104,14 @@ ruleTester.run(RULE_NAME, rule, { license: dedent` /* license */ console.log('hello world'); - ` - } + `, + }, ], errors: [ { message: '"license" option must only include a single comment', - } - ] + }, + ], }, // content is not a single comment @@ -125,14 +120,12 @@ ruleTester.run(RULE_NAME, rule, { console.log('foo') `, - options: [ - { license: `console.log('hello world');` } - ], + options: [{ license: `console.log('hello world');` }], errors: [ { message: '"license" option must only include a single comment', - } - ] + }, + ], }, // missing license header @@ -145,19 +138,21 @@ ruleTester.run(RULE_NAME, rule, { errors: [ { message: 'File must start with a license header', - } + }, ], output: dedent` /* license */ console.log('foo') - ` + `, }, // strips newlines before the license comment { - code: '\n\n' + dedent` + code: + '\n\n' + + dedent` /* license */ console.log('foo') @@ -167,14 +162,14 @@ ruleTester.run(RULE_NAME, rule, { errors: [ { message: 'License header must be at the very beginning of the file', - } + }, ], output: dedent` /* license */ console.log('foo') - ` + `, }, // moves license header before other nodes if necessary @@ -189,7 +184,7 @@ ruleTester.run(RULE_NAME, rule, { errors: [ { message: 'License header must be at the very beginning of the file', - } + }, ], output: dedent` @@ -198,7 +193,7 @@ ruleTester.run(RULE_NAME, rule, { /* not license */ console.log('foo') - ` + `, }, - ] + ], }); diff --git a/packages/kbn-eslint-plugin-license-header/rules/disallow_license_headers.js b/packages/kbn-eslint-plugin-eslint/rules/disallow_license_headers.js similarity index 77% rename from packages/kbn-eslint-plugin-license-header/rules/disallow_license_headers.js rename to packages/kbn-eslint-plugin-eslint/rules/disallow_license_headers.js index f7bd6fb68a785..0567307d18968 100644 --- a/packages/kbn-eslint-plugin-license-header/rules/disallow_license_headers.js +++ b/packages/kbn-eslint-plugin-eslint/rules/disallow_license_headers.js @@ -24,18 +24,20 @@ const { assert, normalizeWhitespace, init } = require('../lib'); module.exports = { meta: { fixable: 'code', - schema: [{ - type: 'object', - properties: { - licenses: { - type: 'array', - items: { - type: 'string' - } + schema: [ + { + type: 'object', + properties: { + licenses: { + type: 'array', + items: { + type: 'string', + }, + }, }, + additionalProperties: false, }, - additionalProperties: false, - }] + ], }, create: context => { return { @@ -49,8 +51,14 @@ module.exports = { return licenses.map((license, i) => { const parsed = babelEslint.parse(license); - assert(!parsed.body.length, `"licenses[${i}]" option must only include a single comment`); - assert(parsed.comments.length === 1, `"licenses[${i}]" option must only include a single comment`); + assert( + !parsed.body.length, + `"licenses[${i}]" option must only include a single comment` + ); + assert( + parsed.comments.length === 1, + `"licenses[${i}]" option must only include a single comment` + ); return normalizeWhitespace(parsed.comments[0].value); }); @@ -69,10 +77,10 @@ module.exports = { message: 'This license header is not allowed in this file.', fix(fixer) { return fixer.remove(node); - } + }, }); }); }, }; - } + }, }; diff --git a/packages/kbn-eslint-plugin-eslint/rules/module_migration.js b/packages/kbn-eslint-plugin-eslint/rules/module_migration.js new file mode 100644 index 0000000000000..4f4f1b0f31c96 --- /dev/null +++ b/packages/kbn-eslint-plugin-eslint/rules/module_migration.js @@ -0,0 +1,82 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +function checkModuleNameNode(context, mappings, node) { + const mapping = mappings.find( + mapping => mapping.from === node.value || mapping.from.startsWith(node.value + '/') + ); + + if (!mapping) { + return; + } + + const newSource = node.value.replace(mapping.from, mapping.to); + context.report({ + message: `Imported module "${node.value}" should be "${newSource}"`, + loc: node.loc, + fix(fixer) { + return fixer.replaceText(node, `'${newSource}'`); + }, + }); +} + +module.exports = { + meta: { + fixable: 'code', + schema: [ + { + type: 'array', + items: { + type: 'object', + properties: { + from: { + type: 'string', + }, + to: { + type: 'string', + }, + }, + required: ['from', 'to'], + additionalProperties: false, + }, + default: [], + minItems: 1, + }, + ], + }, + create: context => { + const mappings = context.options[0]; + + return { + ImportDeclaration(node) { + checkModuleNameNode(context, mappings, node.source); + }, + CallExpression(node) { + if ( + node.callee.type === 'Identifier' && + node.callee.name === 'require' && + node.arguments.length === 1 && + node.arguments[0].type === 'Literal' + ) { + checkModuleNameNode(context, mappings, node.arguments[0]); + } + }, + }; + }, +}; diff --git a/packages/kbn-eslint-plugin-eslint/rules/no_default_export.js b/packages/kbn-eslint-plugin-eslint/rules/no_default_export.js new file mode 100644 index 0000000000000..660b9f8bb8b3c --- /dev/null +++ b/packages/kbn-eslint-plugin-eslint/rules/no_default_export.js @@ -0,0 +1,29 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +module.exports = { + meta: { + schema: [], + }, + create: context => ({ + ExportDefaultDeclaration: node => { + context.report(node, 'Default exports not allowed.'); + }, + }), +}; diff --git a/packages/kbn-eslint-plugin-license-header/rules/require_license_header.js b/packages/kbn-eslint-plugin-eslint/rules/require_license_header.js similarity index 81% rename from packages/kbn-eslint-plugin-license-header/rules/require_license_header.js rename to packages/kbn-eslint-plugin-eslint/rules/require_license_header.js index 6aa1a6223b628..f3c9fcef1985e 100644 --- a/packages/kbn-eslint-plugin-license-header/rules/require_license_header.js +++ b/packages/kbn-eslint-plugin-eslint/rules/require_license_header.js @@ -28,20 +28,22 @@ function isHashbang(text) { module.exports = { meta: { fixable: 'code', - schema: [{ - type: 'object', - properties: { - license: { - type: 'string', + schema: [ + { + type: 'object', + properties: { + license: { + type: 'string', + }, }, + additionalProperties: false, }, - additionalProperties: false, - }] + ], }, create: context => { return { Program(program) { - const license = init(context, program, function () { + const license = init(context, program, function() { const options = context.options[0] || {}; const license = options.license; @@ -49,11 +51,14 @@ module.exports = { const parsed = babelEslint.parse(license); assert(!parsed.body.length, '"license" option must only include a single comment'); - assert(parsed.comments.length === 1, '"license" option must only include a single comment'); + assert( + parsed.comments.length === 1, + '"license" option must only include a single comment' + ); return { source: license, - nodeValue: normalizeWhitespace(parsed.comments[0].value) + nodeValue: normalizeWhitespace(parsed.comments[0].value), }; }); @@ -62,9 +67,9 @@ module.exports = { } const sourceCode = context.getSourceCode(); - const comment = sourceCode.getAllComments().find(node => ( - normalizeWhitespace(node.value) === license.nodeValue - )); + const comment = sourceCode + .getAllComments() + .find(node => normalizeWhitespace(node.value) === license.nodeValue); // no licence comment if (!comment) { @@ -72,7 +77,7 @@ module.exports = { message: 'File must start with a license header', loc: { start: { line: 1, column: 0 }, - end: { line: 1, column: sourceCode.lines[0].length - 1 } + end: { line: 1, column: sourceCode.lines[0].length - 1 }, }, fix(fixer) { if (isHashbang(sourceCode.lines[0])) { @@ -80,13 +85,15 @@ module.exports = { } return fixer.replaceTextRange([0, 0], license.source + '\n\n'); - } + }, }); return; } // ensure there is nothing before the comment - const sourceBeforeNode = sourceCode.getText().slice(0, sourceCode.getIndexFromLoc(comment.loc.start)); + const sourceBeforeNode = sourceCode + .getText() + .slice(0, sourceCode.getIndexFromLoc(comment.loc.start)); if (sourceBeforeNode.length && !isHashbang(sourceBeforeNode)) { context.report({ node: comment, @@ -103,10 +110,10 @@ module.exports = { fixer.remove(comment), fixer.replaceTextRange([0, 0], license.source + '\n\n'), ]; - } + }, }); } }, }; - } + }, }; diff --git a/packages/kbn-expect/LICENSE.txt b/packages/kbn-expect/LICENSE.txt new file mode 100644 index 0000000000000..0f4acd44d7655 --- /dev/null +++ b/packages/kbn-expect/LICENSE.txt @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2011 Guillermo Rauch + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/kbn-expect/README.md b/packages/kbn-expect/README.md new file mode 100644 index 0000000000000..51cf5bcf2ee52 --- /dev/null +++ b/packages/kbn-expect/README.md @@ -0,0 +1,191 @@ +> NOTE: This is a local fork of https://github.com/Automattic/expect.js + +# @kbn/expect + +Minimalistic BDD assertion toolkit based on +[should.js](http://github.com/visionmedia/should.js) + +```js +expect(window.r).to.be(undefined); +expect({ a: 'b' }).to.eql({ a: 'b' }) +expect(5).to.be.a('number'); +expect([]).to.be.an('array'); +expect(window).not.to.be.an(Image); +``` + +## Features + +- Cross-browser: works on IE6+, Firefox, Safari, Chrome, Opera. +- Compatible with all test frameworks. +- Node.JS ready (`require('@kbn/expect')`). + +## API + +**ok**: asserts that the value is _truthy_ or not + +```js +expect(1).to.be.ok(); +expect(true).to.be.ok(); +expect({}).to.be.ok(); +expect(0).to.not.be.ok(); +``` + +**be** / **equal**: asserts `===` equality + +```js +expect(1).to.be(1) +expect(NaN).not.to.equal(NaN); +expect(1).not.to.be(true) +expect('1').to.not.be(1); +``` + +**eql**: asserts loose equality that works with objects + +```js +expect({ a: 'b' }).to.eql({ a: 'b' }); +expect(1).to.eql('1'); +``` + +**a**/**an**: asserts `typeof` with support for `array` type and `instanceof` + +```js +// typeof with optional `array` +expect(5).to.be.a('number'); +expect([]).to.be.an('array'); // works +expect([]).to.be.an('object'); // works too, since it uses `typeof` + +// constructors +expect([]).to.be.an(Array); +expect(tobi).to.be.a(Ferret); +expect(person).to.be.a(Mammal); +``` + +**match**: asserts `String` regular expression match + +```js +expect(program.version).to.match(/[0-9]+\.[0-9]+\.[0-9]+/); +``` + +**contain**: asserts indexOf for an array or string + +```js +expect([1, 2]).to.contain(1); +expect('hello world').to.contain('world'); +``` + +**length**: asserts array `.length` + +```js +expect([]).to.have.length(0); +expect([1,2,3]).to.have.length(3); +``` + +**empty**: asserts that an array is empty or not + +```js +expect([]).to.be.empty(); +expect({}).to.be.empty(); +expect({ length: 0, duck: 'typing' }).to.be.empty(); +expect({ my: 'object' }).to.not.be.empty(); +expect([1,2,3]).to.not.be.empty(); +``` + +**property**: asserts presence of an own property (and value optionally) + +```js +expect(window).to.have.property('expect') +expect(window).to.have.property('expect', expect) +expect({a: 'b'}).to.have.property('a'); +``` + +**key**/**keys**: asserts the presence of a key. Supports the `only` modifier + +```js +expect({ a: 'b' }).to.have.key('a'); +expect({ a: 'b', c: 'd' }).to.only.have.keys('a', 'c'); +expect({ a: 'b', c: 'd' }).to.only.have.keys(['a', 'c']); +expect({ a: 'b', c: 'd' }).to.not.only.have.key('a'); +``` + +**throw**/**throwException**/**throwError**: asserts that the `Function` throws or not when called + +```js +expect(fn).to.throw(); // synonym of throwException +expect(fn).to.throwError(); // synonym of throwException +expect(fn).to.throwException(function (e) { // get the exception object + expect(e).to.be.a(SyntaxError); +}); +expect(fn).to.throwException(/matches the exception message/); +expect(fn2).to.not.throwException(); +``` + +**withArgs**: creates anonymous function to call fn with arguments + +```js +expect(fn).withArgs(invalid, arg).to.throwException(); +expect(fn).withArgs(valid, arg).to.not.throwException(); +``` + +**within**: asserts a number within a range + +```js +expect(1).to.be.within(0, Infinity); +``` + +**greaterThan**/**above**: asserts `>` + +```js +expect(3).to.be.above(0); +expect(5).to.be.greaterThan(3); +``` + +**lessThan**/**below**: asserts `<` + +```js +expect(0).to.be.below(3); +expect(1).to.be.lessThan(3); +``` + +**fail**: explicitly forces failure. + +```js +expect().fail() +expect().fail("Custom failure message") +``` + +## Using with a test framework + +For example, if you create a test suite with +[mocha](http://github.com/visionmedia/mocha). + +Let's say we wanted to test the following program: + +**math.js** + +```js +function add (a, b) { return a + b; }; +``` + +Our test file would look like this: + +```js +describe('test suite', function () { + it('should expose a function', function () { + expect(add).to.be.a('function'); + }); + + it('should do math', function () { + expect(add(1, 3)).to.equal(4); + }); +}); +``` + +If a certain expectation fails, an exception will be raised which gets captured +and shown/processed by the test runner. + +## Differences with should.js + +- No need for static `should` methods like `should.strictEqual`. For example, + `expect(obj).to.be(undefined)` works well. +- Some API simplifications / changes. +- API changes related to browser compatibility. diff --git a/packages/kbn-expect/expect.js b/packages/kbn-expect/expect.js new file mode 100644 index 0000000000000..8dc8af4cab894 --- /dev/null +++ b/packages/kbn-expect/expect.js @@ -0,0 +1,971 @@ +/* eslint-disable */ + +var exports = module.exports; + +/** + * Exports. + */ + +module.exports = expect; +expect.Assertion = Assertion; + +/** + * Exports version. + */ + +expect.version = '0.3.1'; + +/** + * Possible assertion flags. + */ + +var flags = { + not: ['to', 'be', 'have', 'include', 'only'] + , to: ['be', 'have', 'include', 'only', 'not'] + , only: ['have'] + , have: ['own'] + , be: ['an'] +}; + +function expect (obj) { + return new Assertion(obj); +} + +/** + * Constructor + * + * @api private + */ + +function Assertion (obj, flag, parent) { + this.obj = obj; + this.flags = {}; + + if (undefined != parent) { + this.flags[flag] = true; + + for (var i in parent.flags) { + if (parent.flags.hasOwnProperty(i)) { + this.flags[i] = true; + } + } + } + + var $flags = flag ? flags[flag] : keys(flags) + , self = this; + + if ($flags) { + for (var i = 0, l = $flags.length; i < l; i++) { + // avoid recursion + if (this.flags[$flags[i]]) continue; + + var name = $flags[i] + , assertion = new Assertion(this.obj, name, this) + + if ('function' == typeof Assertion.prototype[name]) { + // clone the function, make sure we dont touch the prot reference + var old = this[name]; + this[name] = function () { + return old.apply(self, arguments); + }; + + for (var fn in Assertion.prototype) { + if (Assertion.prototype.hasOwnProperty(fn) && fn != name) { + if (typeof this[name] === 'function' && fn === 'length') { + continue; + } + + this[name][fn] = bind(assertion[fn], assertion); + } + } + } else { + this[name] = assertion; + } + } + } +} + +/** + * Performs an assertion + * + * @api private + */ + +Assertion.prototype.assert = function (truth, msg, error, expected) { + var msg = this.flags.not ? error : msg + , ok = this.flags.not ? !truth : truth + , err; + + if (!ok) { + err = new Error(msg.call(this)); + if (arguments.length > 3) { + err.actual = this.obj; + err.expected = expected; + err.showDiff = true; + } + throw err; + } + + this.and = new Assertion(this.obj); +}; + +/** + * Check if the value is truthy + * + * @api public + */ + +Assertion.prototype.ok = function () { + this.assert( + !!this.obj + , function(){ return 'expected ' + i(this.obj) + ' to be truthy' } + , function(){ return 'expected ' + i(this.obj) + ' to be falsy' }); +}; + +/** + * Creates an anonymous function which calls fn with arguments. + * + * @api public + */ + +Assertion.prototype.withArgs = function() { + expect(this.obj).to.be.a('function'); + var fn = this.obj; + var args = Array.prototype.slice.call(arguments); + return expect(function() { fn.apply(null, args); }); +}; + +/** + * Assert that the function throws. + * + * @param {Function|RegExp} callback, or regexp to match error string against + * @api public + */ + +Assertion.prototype['throw'] = +Assertion.prototype.throwError = +Assertion.prototype.throwException = function (fn) { + expect(this.obj).to.be.a('function'); + + var thrown = false + , not = this.flags.not; + + try { + this.obj(); + } catch (e) { + if (isRegExp(fn)) { + var subject = 'string' == typeof e ? e : e.message; + if (not) { + expect(subject).to.not.match(fn); + } else { + expect(subject).to.match(fn); + } + } else if ('function' == typeof fn) { + fn(e); + } + thrown = true; + } + + if (isRegExp(fn) && not) { + // in the presence of a matcher, ensure the `not` only applies to + // the matching. + this.flags.not = false; + } + + var name = this.obj.name || 'fn'; + this.assert( + thrown + , function(){ return 'expected ' + name + ' to throw an exception' } + , function(){ return 'expected ' + name + ' not to throw an exception' }); +}; + +/** + * Checks if the array is empty. + * + * @api public + */ + +Assertion.prototype.empty = function () { + var expectation; + + if ('object' == typeof this.obj && null !== this.obj && !isArray(this.obj)) { + if ('number' == typeof this.obj.length) { + expectation = !this.obj.length; + } else { + expectation = !keys(this.obj).length; + } + } else { + if ('string' != typeof this.obj) { + expect(this.obj).to.be.an('object'); + } + + expect(this.obj).to.have.property('length'); + expectation = !this.obj.length; + } + + this.assert( + expectation + , function(){ return 'expected ' + i(this.obj) + ' to be empty' } + , function(){ return 'expected ' + i(this.obj) + ' to not be empty' }); + return this; +}; + +/** + * Checks if the obj exactly equals another. + * + * @api public + */ + +Assertion.prototype.be = +Assertion.prototype.equal = function (obj) { + this.assert( + obj === this.obj + , function(){ return 'expected ' + i(this.obj) + ' to equal ' + i(obj) } + , function(){ return 'expected ' + i(this.obj) + ' to not equal ' + i(obj) }); + return this; +}; + +/** + * Checks if the obj sortof equals another. + * + * @api public + */ + +Assertion.prototype.eql = function (obj) { + this.assert( + expect.eql(this.obj, obj) + , function(){ return 'expected ' + i(this.obj) + ' to sort of equal ' + i(obj) } + , function(){ return 'expected ' + i(this.obj) + ' to sort of not equal ' + i(obj) } + , obj); + return this; +}; + +/** + * Assert within start to finish (inclusive). + * + * @param {Number} start + * @param {Number} finish + * @api public + */ + +Assertion.prototype.within = function (start, finish) { + var range = start + '..' + finish; + this.assert( + this.obj >= start && this.obj <= finish + , function(){ return 'expected ' + i(this.obj) + ' to be within ' + range } + , function(){ return 'expected ' + i(this.obj) + ' to not be within ' + range }); + return this; +}; + +/** + * Assert typeof / instance of + * + * @api public + */ + +Assertion.prototype.a = +Assertion.prototype.an = function (type) { + if ('string' == typeof type) { + // proper english in error msg + var n = /^[aeiou]/.test(type) ? 'n' : ''; + + // typeof with support for 'array' + this.assert( + 'array' == type ? isArray(this.obj) : + 'regexp' == type ? isRegExp(this.obj) : + 'object' == type + ? 'object' == typeof this.obj && null !== this.obj + : type == typeof this.obj + , function(){ return 'expected ' + i(this.obj) + ' to be a' + n + ' ' + type } + , function(){ return 'expected ' + i(this.obj) + ' not to be a' + n + ' ' + type }); + } else { + // instanceof + var name = type.name || 'supplied constructor'; + this.assert( + this.obj instanceof type + , function(){ return 'expected ' + i(this.obj) + ' to be an instance of ' + name } + , function(){ return 'expected ' + i(this.obj) + ' not to be an instance of ' + name }); + } + + return this; +}; + +/** + * Assert numeric value above _n_. + * + * @param {Number} n + * @api public + */ + +Assertion.prototype.greaterThan = +Assertion.prototype.above = function (n) { + this.assert( + this.obj > n + , function(){ return 'expected ' + i(this.obj) + ' to be above ' + n } + , function(){ return 'expected ' + i(this.obj) + ' to be below ' + n }); + return this; +}; + +/** + * Assert numeric value below _n_. + * + * @param {Number} n + * @api public + */ + +Assertion.prototype.lessThan = +Assertion.prototype.below = function (n) { + this.assert( + this.obj < n + , function(){ return 'expected ' + i(this.obj) + ' to be below ' + n } + , function(){ return 'expected ' + i(this.obj) + ' to be above ' + n }); + return this; +}; + +/** + * Assert string value matches _regexp_. + * + * @param {RegExp} regexp + * @api public + */ + +Assertion.prototype.match = function (regexp) { + this.assert( + regexp.exec(this.obj) + , function(){ return 'expected ' + i(this.obj) + ' to match ' + regexp } + , function(){ return 'expected ' + i(this.obj) + ' not to match ' + regexp }); + return this; +}; + +/** + * Assert property "length" exists and has value of _n_. + * + * @param {Number} n + * @api public + */ + +Assertion.prototype.length = function (n) { + expect(this.obj).to.have.property('length'); + var len = this.obj.length; + this.assert( + n == len + , function(){ return 'expected ' + i(this.obj) + ' to have a length of ' + n + ' but got ' + len } + , function(){ return 'expected ' + i(this.obj) + ' to not have a length of ' + len }); + return this; +}; + +/** + * Assert property _name_ exists, with optional _val_. + * + * @param {String} name + * @param {Mixed} val + * @api public + */ + +Assertion.prototype.property = function (name, val) { + if (this.flags.own) { + this.assert( + Object.prototype.hasOwnProperty.call(this.obj, name) + , function(){ return 'expected ' + i(this.obj) + ' to have own property ' + i(name) } + , function(){ return 'expected ' + i(this.obj) + ' to not have own property ' + i(name) }); + return this; + } + + if (this.flags.not && undefined !== val) { + if (undefined === this.obj[name]) { + throw new Error(i(this.obj) + ' has no property ' + i(name)); + } + } else { + var hasProp; + try { + hasProp = name in this.obj + } catch (e) { + hasProp = undefined !== this.obj[name] + } + + this.assert( + hasProp + , function(){ return 'expected ' + i(this.obj) + ' to have a property ' + i(name) } + , function(){ return 'expected ' + i(this.obj) + ' to not have a property ' + i(name) }); + } + + if (undefined !== val) { + this.assert( + val === this.obj[name] + , function(){ return 'expected ' + i(this.obj) + ' to have a property ' + i(name) + + ' of ' + i(val) + ', but got ' + i(this.obj[name]) } + , function(){ return 'expected ' + i(this.obj) + ' to not have a property ' + i(name) + + ' of ' + i(val) }); + } + + this.obj = this.obj[name]; + return this; +}; + +/** + * Assert that the array contains _obj_ or string contains _obj_. + * + * @param {Mixed} obj|string + * @api public + */ + +Assertion.prototype.string = +Assertion.prototype.contain = function (obj) { + if ('string' == typeof this.obj) { + this.assert( + ~this.obj.indexOf(obj) + , function(){ return 'expected ' + i(this.obj) + ' to contain ' + i(obj) } + , function(){ return 'expected ' + i(this.obj) + ' to not contain ' + i(obj) }); + } else { + this.assert( + ~indexOf(this.obj, obj) + , function(){ return 'expected ' + i(this.obj) + ' to contain ' + i(obj) } + , function(){ return 'expected ' + i(this.obj) + ' to not contain ' + i(obj) }); + } + return this; +}; + +/** + * Assert exact keys or inclusion of keys by using + * the `.own` modifier. + * + * @param {Array|String ...} keys + * @api public + */ + +Assertion.prototype.key = +Assertion.prototype.keys = function ($keys) { + var str + , ok = true; + + $keys = isArray($keys) + ? $keys + : Array.prototype.slice.call(arguments); + + if (!$keys.length) throw new Error('keys required'); + + var actual = keys(this.obj) + , len = $keys.length; + + // Inclusion + ok = every($keys, function (key) { + return ~indexOf(actual, key); + }); + + // Strict + if (!this.flags.not && this.flags.only) { + ok = ok && $keys.length == actual.length; + } + + // Key string + if (len > 1) { + $keys = map($keys, function (key) { + return i(key); + }); + var last = $keys.pop(); + str = $keys.join(', ') + ', and ' + last; + } else { + str = i($keys[0]); + } + + // Form + str = (len > 1 ? 'keys ' : 'key ') + str; + + // Have / include + str = (!this.flags.only ? 'include ' : 'only have ') + str; + + // Assertion + this.assert( + ok + , function(){ return 'expected ' + i(this.obj) + ' to ' + str } + , function(){ return 'expected ' + i(this.obj) + ' to not ' + str }); + + return this; +}; + +/** + * Assert a failure. + * + * @param {String ...} custom message + * @api public + */ +Assertion.prototype.fail = function (msg) { + var error = function() { return msg || "explicit failure"; } + this.assert(false, error, error); + return this; +}; + +/** + * Function bind implementation. + */ + +function bind (fn, scope) { + return function () { + return fn.apply(scope, arguments); + } +} + +/** + * Array every compatibility + * + * @see bit.ly/5Fq1N2 + * @api public + */ + +function every (arr, fn, thisObj) { + var scope = thisObj || global; + for (var i = 0, j = arr.length; i < j; ++i) { + if (!fn.call(scope, arr[i], i, arr)) { + return false; + } + } + return true; +} + +/** + * Array indexOf compatibility. + * + * @see bit.ly/a5Dxa2 + * @api public + */ + +function indexOf (arr, o, i) { + if (Array.prototype.indexOf) { + return Array.prototype.indexOf.call(arr, o, i); + } + + if (arr.length === undefined) { + return -1; + } + + for (var j = arr.length, i = i < 0 ? i + j < 0 ? 0 : i + j : i || 0 + ; i < j && arr[i] !== o; i++); + + return j <= i ? -1 : i; +} + +// https://gist.github.com/1044128/ +var getOuterHTML = function(element) { + if ('outerHTML' in element) return element.outerHTML; + var ns = "http://www.w3.org/1999/xhtml"; + var container = document.createElementNS(ns, '_'); + var xmlSerializer = new XMLSerializer(); + var html; + if (document.xmlVersion) { + return xmlSerializer.serializeToString(element); + } else { + container.appendChild(element.cloneNode(false)); + html = container.innerHTML.replace('><', '>' + element.innerHTML + '<'); + container.innerHTML = ''; + return html; + } +}; + +// Returns true if object is a DOM element. +var isDOMElement = function (object) { + if (typeof HTMLElement === 'object') { + return object instanceof HTMLElement; + } else { + return object && + typeof object === 'object' && + object.nodeType === 1 && + typeof object.nodeName === 'string'; + } +}; + +/** + * Inspects an object. + * + * @see taken from node.js `util` module (copyright Joyent, MIT license) + * @api private + */ + +function i (obj, showHidden, depth) { + var seen = []; + + function stylize (str) { + return str; + } + + function format (value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (value && typeof value.inspect === 'function' && + // Filter out the util module, it's inspect function is special + value !== exports && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + return value.inspect(recurseTimes); + } + + // Primitive types cannot have properties + switch (typeof value) { + case 'undefined': + return stylize('undefined', 'undefined'); + + case 'string': + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return stylize(simple, 'string'); + + case 'number': + return stylize('' + value, 'number'); + + case 'boolean': + return stylize('' + value, 'boolean'); + } + // For some reason typeof null is "object", so special case here. + if (value === null) { + return stylize('null', 'null'); + } + + if (isDOMElement(value)) { + return getOuterHTML(value); + } + + // Look up the keys of the object. + var visible_keys = keys(value); + var $keys = showHidden ? Object.getOwnPropertyNames(value) : visible_keys; + + // Functions without properties can be shortcutted. + if (typeof value === 'function' && $keys.length === 0) { + if (isRegExp(value)) { + return stylize('' + value, 'regexp'); + } else { + var name = value.name ? ': ' + value.name : ''; + return stylize('[Function' + name + ']', 'special'); + } + } + + // Dates without properties can be shortcutted + if (isDate(value) && $keys.length === 0) { + return stylize(value.toUTCString(), 'date'); + } + + // Error objects can be shortcutted + if (value instanceof Error) { + return stylize("["+value.toString()+"]", 'Error'); + } + + var base, type, braces; + // Determine the object type + if (isArray(value)) { + type = 'Array'; + braces = ['[', ']']; + } else { + type = 'Object'; + braces = ['{', '}']; + } + + // Make functions say that they are functions + if (typeof value === 'function') { + var n = value.name ? ': ' + value.name : ''; + base = (isRegExp(value)) ? ' ' + value : ' [Function' + n + ']'; + } else { + base = ''; + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + value.toUTCString(); + } + + if ($keys.length === 0) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return stylize('' + value, 'regexp'); + } else { + return stylize('[Object]', 'special'); + } + } + + seen.push(value); + + var output = map($keys, function (key) { + var name, str; + if (value.__lookupGetter__) { + if (value.__lookupGetter__(key)) { + if (value.__lookupSetter__(key)) { + str = stylize('[Getter/Setter]', 'special'); + } else { + str = stylize('[Getter]', 'special'); + } + } else { + if (value.__lookupSetter__(key)) { + str = stylize('[Setter]', 'special'); + } + } + } + if (indexOf(visible_keys, key) < 0) { + name = '[' + key + ']'; + } + if (!str) { + if (indexOf(seen, value[key]) < 0) { + if (recurseTimes === null) { + str = format(value[key]); + } else { + str = format(value[key], recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (isArray(value)) { + str = map(str.split('\n'), function (line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + map(str.split('\n'), function (line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = stylize('[Circular]', 'special'); + } + } + if (typeof name === 'undefined') { + if (type === 'Array' && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = stylize(name, 'string'); + } + } + + return name + ': ' + str; + }); + + seen.pop(); + + var numLinesEst = 0; + var length = reduce(output, function (prev, cur) { + numLinesEst++; + if (indexOf(cur, '\n') >= 0) numLinesEst++; + return prev + cur.length + 1; + }, 0); + + if (length > 50) { + output = braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + + } else { + output = braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; + } + + return output; + } + return format(obj, (typeof depth === 'undefined' ? 2 : depth)); +} + +expect.stringify = i; + +function isArray (ar) { + return Object.prototype.toString.call(ar) === '[object Array]'; +} + +function isRegExp(re) { + var s; + try { + s = '' + re; + } catch (e) { + return false; + } + + return re instanceof RegExp || // easy case + // duck-type for context-switching evalcx case + typeof(re) === 'function' && + re.constructor.name === 'RegExp' && + re.compile && + re.test && + re.exec && + s.match(/^\/.*\/[gim]{0,3}$/); +} + +function isDate(d) { + return d instanceof Date; +} + +function keys (obj) { + if (Object.keys) { + return Object.keys(obj); + } + + var keys = []; + + for (var i in obj) { + if (Object.prototype.hasOwnProperty.call(obj, i)) { + keys.push(i); + } + } + + return keys; +} + +function map (arr, mapper, that) { + if (Array.prototype.map) { + return Array.prototype.map.call(arr, mapper, that); + } + + var other= new Array(arr.length); + + for (var i= 0, n = arr.length; i= 2) { + var rv = arguments[1]; + } else { + do { + if (i in this) { + rv = this[i++]; + break; + } + + // if array contains no values, no initial value to return + if (++i >= len) + throw new TypeError(); + } while (true); + } + + for (; i < len; i++) { + if (i in this) + rv = fun.call(null, rv, this[i], i, this); + } + + return rv; +} + +/** + * Asserts deep equality + * + * @see taken from node.js `assert` module (copyright Joyent, MIT license) + * @api private + */ + +expect.eql = function eql(actual, expected) { + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; + } else if ('undefined' != typeof Buffer + && Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) { + if (actual.length != expected.length) return false; + + for (var i = 0; i < actual.length; i++) { + if (actual[i] !== expected[i]) return false; + } + + return true; + + // 7.2. If the expected value is a Date object, the actual value is + // equivalent if it is also a Date object that refers to the same time. + } else if (actual instanceof Date && expected instanceof Date) { + return actual.getTime() === expected.getTime(); + + // 7.3. Other pairs that do not both pass typeof value == "object", + // equivalence is determined by ==. + } else if (typeof actual != 'object' && typeof expected != 'object') { + return actual == expected; + // If both are regular expression use the special `regExpEquiv` method + // to determine equivalence. + } else if (isRegExp(actual) && isRegExp(expected)) { + return regExpEquiv(actual, expected); + // 7.4. For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical "prototype" property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected); + } +}; + +function isUndefinedOrNull (value) { + return value === null || value === undefined; +} + +function isArguments (object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; +} + +function regExpEquiv (a, b) { + return a.source === b.source && a.global === b.global && + a.ignoreCase === b.ignoreCase && a.multiline === b.multiline; +} + +function objEquiv (a, b) { + if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) + return false; + // an identical "prototype" property. + if (a.prototype !== b.prototype) return false; + //~~~I've managed to break Object.keys through screwy arguments passing. + // Converting to array solves the problem. + if (isArguments(a)) { + if (!isArguments(b)) { + return false; + } + a = pSlice.call(a); + b = pSlice.call(b); + return expect.eql(a, b); + } + try{ + var ka = keys(a), + kb = keys(b), + key, i; + } catch (e) {//happens when one is a string literal and the other isn't + return false; + } + // having the same number of owned properties (keys incorporates hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!expect.eql(a[key], b[key])) + return false; + } + return true; +} diff --git a/packages/kbn-expect/expect.js.d.ts b/packages/kbn-expect/expect.js.d.ts new file mode 100644 index 0000000000000..9e0b069499030 --- /dev/null +++ b/packages/kbn-expect/expect.js.d.ts @@ -0,0 +1,221 @@ +// tslint:disable + +// Type definitions for expect.js 0.3.1 +// Project: https://github.com/Automattic/expect.js +// Definitions by: Teppei Sato +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// License: MIT + +export default function expect(target?: any): Root; + +interface Assertion { + /** + * Assert typeof / instanceof. + */ + an: An; + /** + * Check if the value is truthy + */ + ok(): void; + + /** + * Creates an anonymous function which calls fn with arguments. + */ + withArgs(...args: any[]): Root; + + /** + * Assert that the function throws. + * + * @param fn callback to match error string against + */ + throwError(fn?: (exception: any) => void): void; + + /** + * Assert that the function throws. + * + * @param fn callback to match error string against + */ + throwException(fn?: (exception: any) => void): void; + + /** + * Assert that the function throws. + * + * @param regexp regexp to match error string against + */ + throwError(regexp: RegExp): void; + + /** + * Assert that the function throws. + * + * @param fn callback to match error string against + */ + throwException(regexp: RegExp): void; + + /** + * Checks if the array is empty. + */ + empty(): Assertion; + + /** + * Checks if the obj exactly equals another. + */ + equal(obj: any): Assertion; + + /** + * Checks if the obj sortof equals another. + */ + eql(obj: any): Assertion; + + /** + * Assert within start to finish (inclusive). + * + * @param start + * @param finish + */ + within(start: number, finish: number): Assertion; + + /** + * Assert typeof. + */ + a(type: string): Assertion; + + /** + * Assert instanceof. + */ + a(type: Function): Assertion; + + /** + * Assert numeric value above n. + */ + greaterThan(n: number): Assertion; + + /** + * Assert numeric value above n. + */ + above(n: number): Assertion; + + /** + * Assert numeric value below n. + */ + lessThan(n: number): Assertion; + + /** + * Assert numeric value below n. + */ + below(n: number): Assertion; + + /** + * Assert string value matches regexp. + * + * @param regexp + */ + match(regexp: RegExp): Assertion; + + /** + * Assert property "length" exists and has value of n. + * + * @param n + */ + length(n: number): Assertion; + + /** + * Assert property name exists, with optional val. + * + * @param name + * @param val + */ + property(name: string, val?: any): Assertion; + + /** + * Assert that string contains str. + */ + contain(str: string): Assertion; + string(str: string): Assertion; + + /** + * Assert that the array contains obj. + */ + contain(obj: any): Assertion; + string(obj: any): Assertion; + + /** + * Assert exact keys or inclusion of keys by using the `.own` modifier. + */ + key(keys: string[]): Assertion; + /** + * Assert exact keys or inclusion of keys by using the `.own` modifier. + */ + key(...keys: string[]): Assertion; + /** + * Assert exact keys or inclusion of keys by using the `.own` modifier. + */ + keys(keys: string[]): Assertion; + /** + * Assert exact keys or inclusion of keys by using the `.own` modifier. + */ + keys(...keys: string[]): Assertion; + + /** + * Assert a failure. + */ + fail(message?: string): Assertion; +} + +interface Root extends Assertion { + not: Not; + to: To; + only: Only; + have: Have; + be: Be; +} + +interface Be extends Assertion { + /** + * Checks if the obj exactly equals another. + */ + (obj: any): Assertion; + + an: An; +} + +interface An extends Assertion { + /** + * Assert typeof. + */ + (type: string): Assertion; + + /** + * Assert instanceof. + */ + (type: Function): Assertion; +} + +interface Not extends NotBase { + to: ToBase; +} + +interface NotBase extends Assertion { + be: Be; + have: Have; + include: Assertion; + only: Only; +} + +interface To extends ToBase { + not: NotBase; +} + +interface ToBase extends Assertion { + be: Be; + have: Have; + include: Assertion; + only: Only; +} + +interface Only extends Assertion { + have: Have; +} + +interface Have extends Assertion { + own: Assertion; +} diff --git a/packages/kbn-expect/package.json b/packages/kbn-expect/package.json new file mode 100644 index 0000000000000..0975f5762fa1c --- /dev/null +++ b/packages/kbn-expect/package.json @@ -0,0 +1,7 @@ +{ + "name": "@kbn/expect", + "main": "./expect.js", + "version": "1.0.0", + "license": "MIT", + "private": true +} diff --git a/packages/kbn-expect/tsconfig.json b/packages/kbn-expect/tsconfig.json new file mode 100644 index 0000000000000..a09ae2d7ae641 --- /dev/null +++ b/packages/kbn-expect/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "../../tsconfig.json", + "include": [ + "expect.js.d.ts" + ] +} diff --git a/packages/kbn-i18n/tsconfig.json b/packages/kbn-i18n/tsconfig.json index 3b757d1240bdc..d3dae3078c1d7 100644 --- a/packages/kbn-i18n/tsconfig.json +++ b/packages/kbn-i18n/tsconfig.json @@ -1,20 +1,20 @@ -{ - "extends": "../../tsconfig.json", - "include": [ - "src/**/*.ts", - "src/**/*.tsx", - "types/intl_format_cache.d.ts", - "types/intl_relativeformat.d.ts" - ], - "exclude": [ - "target" - ], - "compilerOptions": { - "declaration": true, - "declarationDir": "./target/types", - "types": [ - "jest", - "node" - ] - } -} +{ + "extends": "../../tsconfig.json", + "include": [ + "src/**/*.ts", + "src/**/*.tsx", + "types/intl_format_cache.d.ts", + "types/intl_relativeformat.d.ts" + ], + "exclude": [ + "target" + ], + "compilerOptions": { + "declaration": true, + "declarationDir": "./target/types", + "types": [ + "jest", + "node" + ] + } +} diff --git a/packages/kbn-interpreter/.babelrc b/packages/kbn-interpreter/.babelrc index 57a5cc3669eb4..875cbcde9d0e1 100644 --- a/packages/kbn-interpreter/.babelrc +++ b/packages/kbn-interpreter/.babelrc @@ -1,8 +1,7 @@ { "presets": ["@kbn/babel-preset/webpack_preset"], "plugins": [ - ["babel-plugin-transform-runtime", { - "polyfill": false, + ["@babel/plugin-transform-runtime", { "regenerator": true }] ] diff --git a/packages/kbn-interpreter/package.json b/packages/kbn-interpreter/package.json index 290e02cb2b2e7..ded8f38bff492 100644 --- a/packages/kbn-interpreter/package.json +++ b/packages/kbn-interpreter/package.json @@ -9,19 +9,20 @@ "kbn:watch": "node scripts/build --dev --watch" }, "dependencies": { + "@babel/runtime": "^7.3.4", "@kbn/i18n": "1.0.0", "lodash": "npm:@elastic/lodash@3.10.1-kibana1", "lodash.clone": "^4.5.0", "uuid": "3.0.1" }, "devDependencies": { + "@babel/cli": "^7.2.3", + "@babel/core": "7.3.4", + "@babel/plugin-transform-runtime": "^7.3.4", + "@babel/polyfill": "7.2.5", "@kbn/babel-preset": "1.0.0", "@kbn/dev-utils": "1.0.0", - "babel-cli": "^6.26.0", - "babel-core": "6.26.3", - "babel-loader": "7.1.5", - "babel-plugin-transform-runtime": "^6.23.0", - "babel-polyfill": "6.20.0", + "babel-loader": "8.0.5", "copy-webpack-plugin": "^4.6.0", "css-loader": "1.0.0", "del": "^3.0.0", diff --git a/packages/kbn-interpreter/tasks/build/server_code_transformer.js b/packages/kbn-interpreter/tasks/build/server_code_transformer.js index 5db4dc13640cb..b1185f4752196 100644 --- a/packages/kbn-interpreter/tasks/build/server_code_transformer.js +++ b/packages/kbn-interpreter/tasks/build/server_code_transformer.js @@ -19,7 +19,7 @@ const { extname } = require('path'); -const { transform } = require('babel-core'); +const { transform } = require('@babel/core'); exports.createServerCodeTransformer = (sourceMaps) => { return (content, path) => { diff --git a/packages/kbn-interpreter/tasks/build/server_code_transformer.test.js b/packages/kbn-interpreter/tasks/build/server_code_transformer.test.js index 01dc9323352ae..519e529c20bf5 100644 --- a/packages/kbn-interpreter/tasks/build/server_code_transformer.test.js +++ b/packages/kbn-interpreter/tasks/build/server_code_transformer.test.js @@ -28,15 +28,14 @@ describe('js support', () => { it('transpiles js file', () => { const transformer = createServerCodeTransformer(); expect(transformer(JS_FIXTURE, JS_FIXTURE_PATH)).toMatchInlineSnapshot(` -"'use strict'; +"\\"use strict\\"; -var _util = require('util'); - -var _util2 = _interopRequireDefault(_util); +var _util = _interopRequireDefault(require(\\"util\\")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -console.log(_util2.default.format('hello world')); /* eslint-disable */" +/* eslint-disable */ +console.log(_util.default.format('hello world'));" `); }); diff --git a/packages/kbn-plugin-generator/sao_template/template/package_template.json b/packages/kbn-plugin-generator/sao_template/template/package_template.json index a3641c9c1a942..e70755efef7fd 100644 --- a/packages/kbn-plugin-generator/sao_template/template/package_template.json +++ b/packages/kbn-plugin-generator/sao_template/template/package_template.json @@ -8,9 +8,9 @@ "templateVersion": "<%= templateVersion %>" }, "scripts": { - "preinstall": "node ../../kibana/preinstall_check", - "kbn": "node ../../kibana/scripts/kbn", - "es": "node ../../kibana/scripts/es", + "preinstall": "node ../../preinstall_check", + "kbn": "node ../../scripts/kbn", + "es": "node ../../scripts/es", "lint": "eslint .", "start": "plugin-helpers start", "test:server": "plugin-helpers test:server", @@ -19,23 +19,23 @@ }, <%_ if (generateTranslations) { _%> "dependencies": { - "@kbn/i18n": "link:../../kibana/packages/kbn-i18n" + "@kbn/i18n": "link:../../packages/kbn-i18n" }, <%_ } _%> "devDependencies": { - "@elastic/eslint-config-kibana": "link:../../kibana/packages/eslint-config-kibana", - "@elastic/eslint-import-resolver-kibana": "link:../../kibana/packages/kbn-eslint-import-resolver-kibana", - "@kbn/plugin-helpers": "link:../../kibana/packages/kbn-plugin-helpers", - "babel-eslint": "^9.0.0", - "eslint": "^5.6.0", - "eslint-plugin-babel": "^5.2.0", - "eslint-plugin-import": "^2.14.0", - "eslint-plugin-jest": "^21.26.2", - "eslint-plugin-jsx-a11y": "^6.1.2", - "eslint-plugin-mocha": "^5.2.0", + "@elastic/eslint-config-kibana": "link:../../packages/eslint-config-kibana", + "@elastic/eslint-import-resolver-kibana": "link:../../packages/kbn-eslint-import-resolver-kibana", + "@kbn/expect": "1.0.0", + "@kbn/plugin-helpers": "link:../../packages/kbn-plugin-helpers", + "babel-eslint": "^10.0.1", + "eslint": "^5.14.1", + "eslint-plugin-babel": "^5.3.0", + "eslint-plugin-import": "^2.16.0", + "eslint-plugin-jest": "^22.3.0", + "eslint-plugin-jsx-a11y": "^6.2.1", + "eslint-plugin-mocha": "^5.3.0", "eslint-plugin-no-unsanitized": "^3.0.2", "eslint-plugin-prefer-object-spread": "^1.2.1", - "eslint-plugin-react": "^7.11.1", - "expect.js": "^0.3.1" + "eslint-plugin-react": "^7.12.4" } } diff --git a/packages/kbn-plugin-generator/sao_template/template/public/__tests__/index.js b/packages/kbn-plugin-generator/sao_template/template/public/__tests__/index.js index f1e0ae8fb6f3d..9320bd7b028a8 100755 --- a/packages/kbn-plugin-generator/sao_template/template/public/__tests__/index.js +++ b/packages/kbn-plugin-generator/sao_template/template/public/__tests__/index.js @@ -1,4 +1,4 @@ -import expect from 'expect.js'; +import expect from '@kbn/expect'; describe('suite', () => { it('is a test', () => { diff --git a/packages/kbn-plugin-generator/sao_template/template/server/__tests__/index.js b/packages/kbn-plugin-generator/sao_template/template/server/__tests__/index.js index f1e0ae8fb6f3d..9320bd7b028a8 100755 --- a/packages/kbn-plugin-generator/sao_template/template/server/__tests__/index.js +++ b/packages/kbn-plugin-generator/sao_template/template/server/__tests__/index.js @@ -1,4 +1,4 @@ -import expect from 'expect.js'; +import expect from '@kbn/expect'; describe('suite', () => { it('is a test', () => { diff --git a/packages/kbn-plugin-helpers/lib/utils.js b/packages/kbn-plugin-helpers/lib/utils.js index ee82b9a8fd57d..d9a5b9148208f 100644 --- a/packages/kbn-plugin-helpers/lib/utils.js +++ b/packages/kbn-plugin-helpers/lib/utils.js @@ -25,7 +25,7 @@ function babelRegister() { const plugin = pluginConfig(); try { - // add support for moved babel-register source: https://github.com/elastic/kibana/pull/13973 + // add support for moved @babel/register source: https://github.com/elastic/kibana/pull/13973 require(resolve(plugin.kibanaRoot, 'src/setup_node_env/babel_register')); // eslint-disable-line import/no-dynamic-require } catch (error) { if (error.code === 'MODULE_NOT_FOUND') { diff --git a/packages/kbn-pm/.babelrc b/packages/kbn-pm/.babelrc index f34e55f9b7ba6..1ca768097a7ee 100644 --- a/packages/kbn-pm/.babelrc +++ b/packages/kbn-pm/.babelrc @@ -1,10 +1,14 @@ { "presets": [ - "stage-3", - ["env", { + "@babel/typescript", + ["@babel/preset-env", { "targets": { "node": "current" } }] + ], + "plugins": [ + "@babel/proposal-class-properties", + "@babel/proposal-object-rest-spread" ] -} \ No newline at end of file +} diff --git a/packages/kbn-pm/dist/index.js b/packages/kbn-pm/dist/index.js index 7ba71fb12f30e..808f72116f815 100644 --- a/packages/kbn-pm/dist/index.js +++ b/packages/kbn-pm/dist/index.js @@ -87,146 +87,90 @@ module.exports = /************************************************************************/ /******/ ([ /* 0 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _cli__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "run", function() { return _cli__WEBPACK_IMPORTED_MODULE_0__["run"]; }); +/* harmony import */ var _production__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(367); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return _production__WEBPACK_IMPORTED_MODULE_1__["buildProductionProjects"]; }); -Object.defineProperty(exports, "__esModule", { - value: true -}); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "prepareExternalProjectDependencies", function() { return _production__WEBPACK_IMPORTED_MODULE_1__["prepareExternalProjectDependencies"]; }); -var _cli = __webpack_require__(1); +/* harmony import */ var _utils_workspaces__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(131); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "copyWorkspacePackages", function() { return _utils_workspaces__WEBPACK_IMPORTED_MODULE_2__["copyWorkspacePackages"]; }); -Object.defineProperty(exports, 'run', { - enumerable: true, - get: function () { - return _cli.run; - } -}); - -var _production = __webpack_require__(367); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -Object.defineProperty(exports, 'buildProductionProjects', { - enumerable: true, - get: function () { - return _production.buildProductionProjects; - } -}); -Object.defineProperty(exports, 'prepareExternalProjectDependencies', { - enumerable: true, - get: function () { - return _production.prepareExternalProjectDependencies; - } -}); -var _workspaces = __webpack_require__(131); -Object.defineProperty(exports, 'copyWorkspacePackages', { - enumerable: true, - get: function () { - return _workspaces.copyWorkspacePackages; - } -}); /***/ }), /* 1 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "run", function() { return run; }); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var dedent__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(14); +/* harmony import */ var dedent__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(dedent__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var getopts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(15); +/* harmony import */ var getopts__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(getopts__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(16); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_3__); +/* harmony import */ var _commands__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(17); +/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(357); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(33); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.run = undefined; - -let run = exports.run = (() => { - var _ref = _asyncToGenerator(function* (argv) { - // We can simplify this setup (and remove this extra handling) once Yarn - // starts forwarding the `--` directly to this script, see - // https://github.com/yarnpkg/yarn/blob/b2d3e1a8fe45ef376b716d597cc79b38702a9320/src/cli/index.js#L174-L182 - if (argv.includes('--')) { - _log.log.write(_chalk2.default.red(`Using "--" is not allowed, as it doesn't work with 'yarn kbn'.`)); - process.exit(1); - } - const options = (0, _getopts2.default)(argv, { - alias: { - e: 'exclude', - h: 'help', - i: 'include' - }, - boolean: ['prefer-offline', 'frozen-lockfile'] - }); - const args = options._; - if (options.help || args.length === 0) { - help(); - return; - } - // This `rootPath` is relative to `./dist/` as that's the location of the - // built version of this tool. - const rootPath = (0, _path.resolve)(__dirname, '../../../'); - const commandName = args[0]; - const extraArgs = args.slice(1); - const commandOptions = { options, extraArgs, rootPath }; - const command = _commands.commands[commandName]; - if (command === undefined) { - _log.log.write(_chalk2.default.red(`[${commandName}] is not a valid command, see 'kbn --help'`)); - process.exit(1); - } - yield (0, _run.runCommand)(command, commandOptions); - }); - - return function run(_x) { - return _ref.apply(this, arguments); - }; -})(); - -var _chalk = __webpack_require__(2); - -var _chalk2 = _interopRequireDefault(_chalk); - -var _dedent = __webpack_require__(14); - -var _dedent2 = _interopRequireDefault(_dedent); - -var _getopts = __webpack_require__(15); - -var _getopts2 = _interopRequireDefault(_getopts); - -var _path = __webpack_require__(16); - -var _commands = __webpack_require__(17); -var _run = __webpack_require__(357); -var _log = __webpack_require__(33); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ function help() { - const availableCommands = Object.keys(_commands.commands).map(commandName => _commands.commands[commandName]).map(command => `${command.name} - ${command.description}`); - _log.log.write(_dedent2.default` + const availableCommands = Object.keys(_commands__WEBPACK_IMPORTED_MODULE_4__["commands"]).map(commandName => _commands__WEBPACK_IMPORTED_MODULE_4__["commands"][commandName]).map(command => `${command.name} - ${command.description}`); + _utils_log__WEBPACK_IMPORTED_MODULE_6__["log"].write(dedent__WEBPACK_IMPORTED_MODULE_1___default.a` usage: kbn [] By default commands are run for Kibana itself, all packages in the 'packages/' @@ -245,6 +189,50 @@ function help() { `); } +async function run(argv) { + // We can simplify this setup (and remove this extra handling) once Yarn + // starts forwarding the `--` directly to this script, see + // https://github.com/yarnpkg/yarn/blob/b2d3e1a8fe45ef376b716d597cc79b38702a9320/src/cli/index.js#L174-L182 + if (argv.includes('--')) { + _utils_log__WEBPACK_IMPORTED_MODULE_6__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.red(`Using "--" is not allowed, as it doesn't work with 'yarn kbn'.`)); + process.exit(1); + } + + const options = getopts__WEBPACK_IMPORTED_MODULE_2___default()(argv, { + alias: { + e: 'exclude', + h: 'help', + i: 'include' + }, + boolean: ['prefer-offline', 'frozen-lockfile'] + }); + const args = options._; + + if (options.help || args.length === 0) { + help(); + return; + } // This `rootPath` is relative to `./dist/` as that's the location of the + // built version of this tool. + + + const rootPath = Object(path__WEBPACK_IMPORTED_MODULE_3__["resolve"])(__dirname, '../../../'); + const commandName = args[0]; + const extraArgs = args.slice(1); + const commandOptions = { + options, + extraArgs, + rootPath + }; + const command = _commands__WEBPACK_IMPORTED_MODULE_4__["commands"][commandName]; + + if (command === undefined) { + _utils_log__WEBPACK_IMPORTED_MODULE_6__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.red(`[${commandName}] is not a valid command, see 'kbn --help'`)); + process.exit(1); + } + + await Object(_run__WEBPACK_IMPORTED_MODULE_5__["runCommand"])(command, commandOptions); +} + /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { @@ -2452,24 +2440,15 @@ module.exports = require("path"); /***/ }), /* 17 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.commands = undefined; - -var _bootstrap = __webpack_require__(18); - -var _clean = __webpack_require__(133); - -var _run = __webpack_require__(155); - -var _watch = __webpack_require__(156); - +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "commands", function() { return commands; }); +/* harmony import */ var _bootstrap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(18); +/* harmony import */ var _clean__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(133); +/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(155); +/* harmony import */ var _watch__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(156); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -2488,117 +2467,137 @@ var _watch = __webpack_require__(156); * specific language governing permissions and limitations * under the License. */ -const commands = exports.commands = { - bootstrap: _bootstrap.BootstrapCommand, - clean: _clean.CleanCommand, - run: _run.RunCommand, - watch: _watch.WatchCommand + + + + +const commands = { + bootstrap: _bootstrap__WEBPACK_IMPORTED_MODULE_0__["BootstrapCommand"], + clean: _clean__WEBPACK_IMPORTED_MODULE_1__["CleanCommand"], + run: _run__WEBPACK_IMPORTED_MODULE_2__["RunCommand"], + watch: _watch__WEBPACK_IMPORTED_MODULE_3__["WatchCommand"] }; /***/ }), /* 18 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BootstrapCommand", function() { return BootstrapCommand; }); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _utils_link_project_executables__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(19); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(33); +/* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(34); +/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(35); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.BootstrapCommand = undefined; - -var _chalk = __webpack_require__(2); - -var _chalk2 = _interopRequireDefault(_chalk); - -var _link_project_executables = __webpack_require__(19); -var _log = __webpack_require__(33); -var _parallelize = __webpack_require__(34); -var _projects = __webpack_require__(35); +const BootstrapCommand = { + description: 'Install dependencies and crosslink projects', + name: 'bootstrap', -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + async run(projects, projectGraph, { + options + }) { + const batchedProjectsByWorkspace = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_4__["topologicallyBatchProjects"])(projects, projectGraph, { + batchByWorkspace: true + }); + const batchedProjects = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_4__["topologicallyBatchProjects"])(projects, projectGraph); + const extraArgs = [...(options['frozen-lockfile'] === true ? ['--frozen-lockfile'] : []), ...(options['prefer-offline'] === true ? ['--prefer-offline'] : [])]; + _utils_log__WEBPACK_IMPORTED_MODULE_2__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold('\nRunning installs in topological order:')); + + for (const batch of batchedProjectsByWorkspace) { + for (const project of batch) { + if (project.isWorkspaceProject) { + _utils_log__WEBPACK_IMPORTED_MODULE_2__["log"].write(`Skipping workspace project: ${project.name}`); + continue; + } -function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ + if (project.hasDependencies()) { + await project.installDependencies({ + extraArgs + }); + } + } + } + _utils_log__WEBPACK_IMPORTED_MODULE_2__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold('\nInstalls completed, linking package executables:\n')); + await Object(_utils_link_project_executables__WEBPACK_IMPORTED_MODULE_1__["linkProjectExecutables"])(projects, projectGraph); + /** + * At the end of the bootstrapping process we call all `kbn:bootstrap` scripts + * in the list of projects. We do this because some projects need to be + * transpiled before they can be used. Ideally we shouldn't do this unless we + * have to, as it will slow down the bootstrapping process. + */ -const BootstrapCommand = exports.BootstrapCommand = { - description: 'Install dependencies and crosslink projects', - name: 'bootstrap', - run(projects, projectGraph, { options }) { - return _asyncToGenerator(function* () { - const batchedProjectsByWorkspace = (0, _projects.topologicallyBatchProjects)(projects, projectGraph, { - batchByWorkspace: true - }); - const batchedProjects = (0, _projects.topologicallyBatchProjects)(projects, projectGraph); - const extraArgs = [...(options['frozen-lockfile'] === true ? ['--frozen-lockfile'] : []), ...(options['prefer-offline'] === true ? ['--prefer-offline'] : [])]; - _log.log.write(_chalk2.default.bold('\nRunning installs in topological order:')); - for (const batch of batchedProjectsByWorkspace) { - for (const project of batch) { - if (project.isWorkspaceProject) { - _log.log.write(`Skipping workspace project: ${project.name}`); - continue; - } - if (project.hasDependencies()) { - yield project.installDependencies({ extraArgs }); - } - } - } - _log.log.write(_chalk2.default.bold('\nInstalls completed, linking package executables:\n')); - yield (0, _link_project_executables.linkProjectExecutables)(projects, projectGraph); - /** - * At the end of the bootstrapping process we call all `kbn:bootstrap` scripts - * in the list of projects. We do this because some projects need to be - * transpiled before they can be used. Ideally we shouldn't do this unless we - * have to, as it will slow down the bootstrapping process. - */ - _log.log.write(_chalk2.default.bold('\nLinking executables completed, running `kbn:bootstrap` scripts\n')); - yield (0, _parallelize.parallelizeBatches)(batchedProjects, (() => { - var _ref = _asyncToGenerator(function* (pkg) { - if (pkg.hasScript('kbn:bootstrap')) { - yield pkg.runScriptStreaming('kbn:bootstrap'); - } - }); + _utils_log__WEBPACK_IMPORTED_MODULE_2__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold('\nLinking executables completed, running `kbn:bootstrap` scripts\n')); + await Object(_utils_parallelize__WEBPACK_IMPORTED_MODULE_3__["parallelizeBatches"])(batchedProjects, async pkg => { + if (pkg.hasScript('kbn:bootstrap')) { + await pkg.runScriptStreaming('kbn:bootstrap'); + } + }); + _utils_log__WEBPACK_IMPORTED_MODULE_2__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green.bold('\nBootstrapping completed!\n')); + } - return function (_x) { - return _ref.apply(this, arguments); - }; - })()); - _log.log.write(_chalk2.default.green.bold('\nBootstrapping completed!\n')); - })(); - } }; /***/ }), /* 19 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "linkProjectExecutables", function() { return linkProjectExecutables; }); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(16); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var _fs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(20); +/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(33); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.linkProjectExecutables = undefined; /** * Yarn does not link the executables from dependencies that are installed @@ -2608,130 +2607,122 @@ exports.linkProjectExecutables = undefined; * dependencies, and manually linking their executables if defined. The logic * for linking was mostly adapted from lerna: https://github.com/lerna/lerna/blob/1d7eb9eeff65d5a7de64dea73613b1bf6bfa8d57/src/PackageUtilities.js#L348 */ -let linkProjectExecutables = exports.linkProjectExecutables = (() => { - var _ref = _asyncToGenerator(function* (projectsByName, projectGraph) { - for (const [projectName, projectDeps] of projectGraph) { - const project = projectsByName.get(projectName); - const binsDir = (0, _path.resolve)(project.nodeModulesLocation, '.bin'); - for (const projectDep of projectDeps) { - const executables = projectDep.getExecutables(); - for (const name of Object.keys(executables)) { - const srcPath = executables[name]; - // existing logic from lerna -- ensure that the bin we are going to - // point to exists or ignore it - if (!(yield (0, _fs.isFile)(srcPath))) { - continue; - } - const dest = (0, _path.resolve)(binsDir, name); - // Get relative project path with normalized path separators. - const projectRelativePath = (0, _path.relative)(project.path, srcPath).split(_path.sep).join('/'); - _log.log.write(_chalk2.default`{dim [${project.name}]} ${name} -> {dim ${projectRelativePath}}`); - yield (0, _fs.mkdirp)((0, _path.dirname)(dest)); - yield (0, _fs.createSymlink)(srcPath, dest, 'exec'); - yield (0, _fs.chmod)(dest, '755'); - } - } - } - }); - - return function linkProjectExecutables(_x, _x2) { - return _ref.apply(this, arguments); - }; -})(); +async function linkProjectExecutables(projectsByName, projectGraph) { + for (const [projectName, projectDeps] of projectGraph) { + const project = projectsByName.get(projectName); + const binsDir = Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(project.nodeModulesLocation, '.bin'); -var _path = __webpack_require__(16); + for (const projectDep of projectDeps) { + const executables = projectDep.getExecutables(); -var _chalk = __webpack_require__(2); + for (const name of Object.keys(executables)) { + const srcPath = executables[name]; // existing logic from lerna -- ensure that the bin we are going to + // point to exists or ignore it -var _chalk2 = _interopRequireDefault(_chalk); - -var _fs = __webpack_require__(20); - -var _log = __webpack_require__(33); + if (!(await Object(_fs__WEBPACK_IMPORTED_MODULE_2__["isFile"])(srcPath))) { + continue; + } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + const dest = Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(binsDir, name); // Get relative project path with normalized path separators. -function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ + const projectRelativePath = Object(path__WEBPACK_IMPORTED_MODULE_0__["relative"])(project.path, srcPath).split(path__WEBPACK_IMPORTED_MODULE_0__["sep"]).join('/'); + _log__WEBPACK_IMPORTED_MODULE_3__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_1___default.a`{dim [${project.name}]} ${name} -> {dim ${projectRelativePath}}`); + await Object(_fs__WEBPACK_IMPORTED_MODULE_2__["mkdirp"])(Object(path__WEBPACK_IMPORTED_MODULE_0__["dirname"])(dest)); + await Object(_fs__WEBPACK_IMPORTED_MODULE_2__["createSymlink"])(srcPath, dest, 'exec'); + await Object(_fs__WEBPACK_IMPORTED_MODULE_2__["chmod"])(dest, '755'); + } + } + } +} /***/ }), /* 20 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "unlink", function() { return unlink; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "copyDirectory", function() { return copyDirectory; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "chmod", function() { return chmod; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "readFile", function() { return readFile; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mkdirp", function() { return mkdirp; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isDirectory", function() { return isDirectory; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isFile", function() { return isFile; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createSymlink", function() { return createSymlink; }); +/* harmony import */ var cmd_shim__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(21); +/* harmony import */ var cmd_shim__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(cmd_shim__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(23); +/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var mkdirp__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(31); +/* harmony import */ var mkdirp__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(mkdirp__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var ncp__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(32); +/* harmony import */ var ncp__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(ncp__WEBPACK_IMPORTED_MODULE_3__); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(16); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_4__); +/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(29); +/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_5__); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.createSymlink = exports.isFile = exports.isDirectory = exports.mkdirp = exports.readFile = exports.chmod = exports.copyDirectory = exports.unlink = undefined; -let statTest = (() => { - var _ref = _asyncToGenerator(function* (path, block) { - try { - return block((yield stat(path))); - } catch (e) { - if (e.code === 'ENOENT') { - return false; - } - throw e; - } - }); - return function statTest(_x, _x2) { - return _ref.apply(this, arguments); - }; -})(); + + +const stat = Object(util__WEBPACK_IMPORTED_MODULE_5__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_1___default.a.stat); +const readFile = Object(util__WEBPACK_IMPORTED_MODULE_5__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_1___default.a.readFile); +const symlink = Object(util__WEBPACK_IMPORTED_MODULE_5__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_1___default.a.symlink); +const chmod = Object(util__WEBPACK_IMPORTED_MODULE_5__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_1___default.a.chmod); +const cmdShim = Object(util__WEBPACK_IMPORTED_MODULE_5__["promisify"])(cmd_shim__WEBPACK_IMPORTED_MODULE_0___default.a); +const mkdirp = Object(util__WEBPACK_IMPORTED_MODULE_5__["promisify"])(mkdirp__WEBPACK_IMPORTED_MODULE_2___default.a); +const unlink = Object(util__WEBPACK_IMPORTED_MODULE_5__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_1___default.a.unlink); +const copyDirectory = Object(util__WEBPACK_IMPORTED_MODULE_5__["promisify"])(ncp__WEBPACK_IMPORTED_MODULE_3__["ncp"]); + + +async function statTest(path, block) { + try { + return block((await stat(path))); + } catch (e) { + if (e.code === 'ENOENT') { + return false; + } + + throw e; + } +} /** * Test if a path points to a directory. * @param path */ -let isDirectory = exports.isDirectory = (() => { - var _ref2 = _asyncToGenerator(function* (path) { - return yield statTest(path, function (stats) { - return stats.isDirectory(); - }); - }); - - return function isDirectory(_x3) { - return _ref2.apply(this, arguments); - }; -})(); +async function isDirectory(path) { + return await statTest(path, stats => stats.isDirectory()); +} /** * Test if a path points to a regular file. * @param path */ - -let isFile = exports.isFile = (() => { - var _ref3 = _asyncToGenerator(function* (path) { - return yield statTest(path, function (stats) { - return stats.isFile(); - }); - }); - - return function isFile(_x4) { - return _ref3.apply(this, arguments); - }; -})(); +async function isFile(path) { + return await statTest(path, stats => stats.isFile()); +} /** * Create a symlink at dest that points to src. Adapted from * https://github.com/lerna/lerna/blob/2f1b87d9e2295f587e4ac74269f714271d8ed428/src/FileSystemUtilities.js#L103. @@ -2743,96 +2734,32 @@ let isFile = exports.isFile = (() => { * for executable files on windows. */ +async function createSymlink(src, dest, type) { + if (process.platform === 'win32') { + if (type === 'exec') { + await cmdShim(src, dest); + } else { + await forceCreate(src, dest, type); + } + } else { + const posixType = type === 'exec' ? 'file' : type; + const relativeSource = Object(path__WEBPACK_IMPORTED_MODULE_4__["relative"])(Object(path__WEBPACK_IMPORTED_MODULE_4__["dirname"])(dest), src); + await forceCreate(relativeSource, dest, posixType); + } +} -let createSymlink = exports.createSymlink = (() => { - var _ref4 = _asyncToGenerator(function* (src, dest, type) { - if (process.platform === 'win32') { - if (type === 'exec') { - yield cmdShim(src, dest); - } else { - yield forceCreate(src, dest, type); - } - } else { - const posixType = type === 'exec' ? 'file' : type; - const relativeSource = (0, _path.relative)((0, _path.dirname)(dest), src); - yield forceCreate(relativeSource, dest, posixType); - } - }); - - return function createSymlink(_x5, _x6, _x7) { - return _ref4.apply(this, arguments); - }; -})(); - -let forceCreate = (() => { - var _ref5 = _asyncToGenerator(function* (src, dest, type) { - try { - // If something exists at `dest` we need to remove it first. - yield unlink(dest); - } catch (error) { - if (error.code !== 'ENOENT') { - throw error; - } - } - yield symlink(src, dest, type); - }); - - return function forceCreate(_x8, _x9, _x10) { - return _ref5.apply(this, arguments); - }; -})(); - -var _cmdShim = __webpack_require__(21); - -var _cmdShim2 = _interopRequireDefault(_cmdShim); - -var _fs = __webpack_require__(23); - -var _fs2 = _interopRequireDefault(_fs); - -var _mkdirp = __webpack_require__(31); - -var _mkdirp2 = _interopRequireDefault(_mkdirp); - -var _ncp = __webpack_require__(32); - -var _path = __webpack_require__(16); - -var _util = __webpack_require__(29); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - +async function forceCreate(src, dest, type) { + try { + // If something exists at `dest` we need to remove it first. + await unlink(dest); + } catch (error) { + if (error.code !== 'ENOENT') { + throw error; + } + } -const stat = (0, _util.promisify)(_fs2.default.stat); -const readFile = (0, _util.promisify)(_fs2.default.readFile); -const symlink = (0, _util.promisify)(_fs2.default.symlink); -const chmod = (0, _util.promisify)(_fs2.default.chmod); -const cmdShim = (0, _util.promisify)(_cmdShim2.default); -const mkdirp = (0, _util.promisify)(_mkdirp2.default); -const unlink = exports.unlink = (0, _util.promisify)(_fs2.default.unlink); -const copyDirectory = exports.copyDirectory = (0, _util.promisify)(_ncp.ncp); -exports.chmod = chmod; -exports.readFile = readFile; -exports.mkdirp = mkdirp; + await symlink(src, dest, type); +} /***/ }), /* 21 */ @@ -4179,14 +4106,11 @@ function ncp (source, dest, options, callback) { /***/ }), /* 33 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "log", function() { return log; }); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -4205,7 +4129,7 @@ Object.defineProperty(exports, "__esModule", { * specific language governing permissions and limitations * under the License. */ -const log = exports.log = { +const log = { /** * Log something to the console. Ideally we would use a real logger in * kbn-pm, but that's a pretty big change for now. @@ -4215,19 +4139,94 @@ const log = exports.log = { // tslint:disable no-console console.log(...args); } + }; /***/ }), /* 34 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parallelizeBatches", function() { return parallelizeBatches; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parallelize", function() { return parallelize; }); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +async function parallelizeBatches(batches, fn) { + for (const batch of batches) { + // We need to make sure the entire batch has completed before we can move on + // to the next batch + await parallelize(batch, fn); + } +} +async function parallelize(items, fn, concurrency = 4) { + if (items.length === 0) { + return; + } + return new Promise((resolve, reject) => { + let activePromises = 0; + const values = items.slice(0); -Object.defineProperty(exports, "__esModule", { - value: true -}); + async function scheduleItem(item) { + activePromises++; + + try { + await fn(item); + activePromises--; + + if (values.length > 0) { + // We have more work to do, so we schedule the next promise + scheduleItem(values.shift()); + } else if (activePromises === 0) { + // We have no more values left, and all items have completed, so we've + // completed all the work. + resolve(); + } + } catch (error) { + reject(error); + } + } + + values.splice(0, concurrency).map(scheduleItem); + }); +} + +/***/ }), +/* 35 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getProjects", function() { return getProjects; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "buildProjectGraph", function() { return buildProjectGraph; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "topologicallyBatchProjects", function() { return topologicallyBatchProjects; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "includeTransitiveProjects", function() { return includeTransitiveProjects; }); +/* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); +/* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(glob__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(16); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(29); +/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(52); +/* harmony import */ var _project__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(53); +/* harmony import */ var _workspaces__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(131); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -4246,252 +4245,181 @@ Object.defineProperty(exports, "__esModule", { * specific language governing permissions and limitations * under the License. */ -let parallelizeBatches = exports.parallelizeBatches = (() => { - var _ref = _asyncToGenerator(function* (batches, fn) { - for (const batch of batches) { - // We need to make sure the entire batch has completed before we can move on - // to the next batch - yield parallelize(batch, fn); - } + + + + + + +const glob = Object(util__WEBPACK_IMPORTED_MODULE_2__["promisify"])(glob__WEBPACK_IMPORTED_MODULE_0___default.a); +async function getProjects(rootPath, projectsPathsPatterns, { + include = [], + exclude = [] +} = {}) { + const projects = new Map(); + const workspaceProjectsPaths = await Object(_workspaces__WEBPACK_IMPORTED_MODULE_5__["workspacePackagePaths"])(rootPath); + + for (const pattern of projectsPathsPatterns) { + const pathsToProcess = await packagesFromGlobPattern({ + pattern, + rootPath }); - return function parallelizeBatches(_x, _x2) { - return _ref.apply(this, arguments); - }; -})(); + for (const filePath of pathsToProcess) { + const projectConfigPath = normalize(filePath); + const projectDir = path__WEBPACK_IMPORTED_MODULE_1___default.a.dirname(projectConfigPath); + const project = await _project__WEBPACK_IMPORTED_MODULE_4__["Project"].fromPath(projectDir); -let parallelize = exports.parallelize = (() => { - var _ref2 = _asyncToGenerator(function* (items, fn, concurrency = 4) { - if (items.length === 0) { - return; - } - return new Promise(function (resolve, reject) { - let scheduleItem = (() => { - var _ref3 = _asyncToGenerator(function* (item) { - activePromises++; - try { - yield fn(item); - activePromises--; - if (values.length > 0) { - // We have more work to do, so we schedule the next promise - scheduleItem(values.shift()); - } else if (activePromises === 0) { - // We have no more values left, and all items have completed, so we've - // completed all the work. - resolve(); - } - } catch (error) { - reject(error); - } - }); + if (workspaceProjectsPaths.indexOf(filePath) >= 0) { + project.isWorkspaceProject = true; + } - return function scheduleItem(_x5) { - return _ref3.apply(this, arguments); - }; - })(); + const excludeProject = exclude.includes(project.name) || include.length > 0 && !include.includes(project.name); - let activePromises = 0; - const values = items.slice(0); + if (excludeProject) { + continue; + } - values.splice(0, concurrency).map(scheduleItem); + if (projects.has(project.name)) { + throw new _errors__WEBPACK_IMPORTED_MODULE_3__["CliError"](`There are multiple projects with the same name [${project.name}]`, { + name: project.name, + paths: [project.path, projects.get(project.name).path] }); - }); + } - return function parallelize(_x3, _x4) { - return _ref2.apply(this, arguments); - }; -})(); + projects.set(project.name, project); + } + } -function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } + return projects; +} -/***/ }), -/* 35 */ -/***/ (function(module, exports, __webpack_require__) { +function packagesFromGlobPattern({ + pattern, + rootPath +}) { + const globOptions = { + cwd: rootPath, + // Should throw in case of unusual errors when reading the file system + strict: true, + // Always returns absolute paths for matched files + absolute: true, + // Do not match ** against multiple filenames + // (This is only specified because we currently don't have a need for it.) + noglobstar: true + }; + return glob(path__WEBPACK_IMPORTED_MODULE_1___default.a.join(pattern, 'package.json'), globOptions); +} // https://github.com/isaacs/node-glob/blob/master/common.js#L104 +// glob always returns "\\" as "/" in windows, so everyone +// gets normalized because we can't have nice things. -"use strict"; +function normalize(dir) { + return path__WEBPACK_IMPORTED_MODULE_1___default.a.normalize(dir); +} -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.getProjects = undefined; - -let getProjects = exports.getProjects = (() => { - var _ref = _asyncToGenerator(function* (rootPath, projectsPathsPatterns, { include = [], exclude = [] } = {}) { - const projects = new Map(); - const workspaceProjectsPaths = yield (0, _workspaces.workspacePackagePaths)(rootPath); - for (const pattern of projectsPathsPatterns) { - const pathsToProcess = yield packagesFromGlobPattern({ pattern, rootPath }); - for (const filePath of pathsToProcess) { - const projectConfigPath = normalize(filePath); - const projectDir = _path2.default.dirname(projectConfigPath); - const project = yield _project.Project.fromPath(projectDir); - if (workspaceProjectsPaths.indexOf(filePath) >= 0) { - project.isWorkspaceProject = true; - } - const excludeProject = exclude.includes(project.name) || include.length > 0 && !include.includes(project.name); - if (excludeProject) { - continue; - } - if (projects.has(project.name)) { - throw new _errors.CliError(`There are multiple projects with the same name [${project.name}]`, { - name: project.name, - paths: [project.path, projects.get(project.name).path] - }); - } - projects.set(project.name, project); - } - } - return projects; - }); +function buildProjectGraph(projects) { + const projectGraph = new Map(); - return function getProjects(_x, _x2) { - return _ref.apply(this, arguments); - }; -})(); + for (const project of projects.values()) { + const projectDeps = []; + const dependencies = project.allDependencies; -exports.buildProjectGraph = buildProjectGraph; -exports.topologicallyBatchProjects = topologicallyBatchProjects; -exports.includeTransitiveProjects = includeTransitiveProjects; + for (const depName of Object.keys(dependencies)) { + if (projects.has(depName)) { + const dep = projects.get(depName); + const dependentProjectIsInWorkspace = project.isWorkspaceProject || project.json.name === 'kibana'; + project.ensureValidProjectDependency(dep, dependentProjectIsInWorkspace); + projectDeps.push(dep); + } + } -var _glob = __webpack_require__(36); + projectGraph.set(project.name, projectDeps); + } -var _glob2 = _interopRequireDefault(_glob); + return projectGraph; +} +function topologicallyBatchProjects(projectsToBatch, projectGraph, { + batchByWorkspace = false +} = {}) { + // We're going to be chopping stuff out of this list, so copy it. + const projectsLeftToBatch = new Set(projectsToBatch.keys()); + const batches = []; -var _path = __webpack_require__(16); + if (batchByWorkspace) { + const workspaceRootProject = Array.from(projectsToBatch.values()).find(p => p.isWorkspaceRoot); -var _path2 = _interopRequireDefault(_path); + if (!workspaceRootProject) { + throw new _errors__WEBPACK_IMPORTED_MODULE_3__["CliError"](`There was no yarn workspace root found.`); + } // Push in the workspace root first. -var _util = __webpack_require__(29); -var _errors = __webpack_require__(52); + batches.push([workspaceRootProject]); + projectsLeftToBatch.delete(workspaceRootProject.name); // In the next batch, push in all workspace projects. -var _project = __webpack_require__(53); + const workspaceBatch = []; -var _workspaces = __webpack_require__(131); + for (const projectName of projectsLeftToBatch) { + const project = projectsToBatch.get(projectName); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + if (project.isWorkspaceProject) { + workspaceBatch.push(project); + projectsLeftToBatch.delete(projectName); + } + } -function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ + batches.push(workspaceBatch); + } + while (projectsLeftToBatch.size > 0) { + // Get all projects that have no remaining dependencies within the repo + // that haven't yet been picked. + const batch = []; -const glob = (0, _util.promisify)(_glob2.default); + for (const projectName of projectsLeftToBatch) { + const projectDeps = projectGraph.get(projectName); + const needsDependenciesBatched = projectDeps.some(dep => projectsLeftToBatch.has(dep.name)); -function packagesFromGlobPattern({ pattern, rootPath }) { - const globOptions = { - cwd: rootPath, - // Should throw in case of unusual errors when reading the file system - strict: true, - // Always returns absolute paths for matched files - absolute: true, - // Do not match ** against multiple filenames - // (This is only specified because we currently don't have a need for it.) - noglobstar: true - }; - return glob(_path2.default.join(pattern, 'package.json'), globOptions); -} -// https://github.com/isaacs/node-glob/blob/master/common.js#L104 -// glob always returns "\\" as "/" in windows, so everyone -// gets normalized because we can't have nice things. -function normalize(dir) { - return _path2.default.normalize(dir); -} -function buildProjectGraph(projects) { - const projectGraph = new Map(); - for (const project of projects.values()) { - const projectDeps = []; - const dependencies = project.allDependencies; - for (const depName of Object.keys(dependencies)) { - if (projects.has(depName)) { - const dep = projects.get(depName); - const dependentProjectIsInWorkspace = project.isWorkspaceProject || project.json.name === 'kibana'; - project.ensureValidProjectDependency(dep, dependentProjectIsInWorkspace); - projectDeps.push(dep); - } - } - projectGraph.set(project.name, projectDeps); - } - return projectGraph; -} -function topologicallyBatchProjects(projectsToBatch, projectGraph, { batchByWorkspace = false } = {}) { - // We're going to be chopping stuff out of this list, so copy it. - const projectsLeftToBatch = new Set(projectsToBatch.keys()); - const batches = []; - if (batchByWorkspace) { - const workspaceRootProject = Array.from(projectsToBatch.values()).find(p => p.isWorkspaceRoot); - if (!workspaceRootProject) { - throw new _errors.CliError(`There was no yarn workspace root found.`); - } - // Push in the workspace root first. - batches.push([workspaceRootProject]); - projectsLeftToBatch.delete(workspaceRootProject.name); - // In the next batch, push in all workspace projects. - const workspaceBatch = []; - for (const projectName of projectsLeftToBatch) { - const project = projectsToBatch.get(projectName); - if (project.isWorkspaceProject) { - workspaceBatch.push(project); - projectsLeftToBatch.delete(projectName); - } - } - batches.push(workspaceBatch); - } - while (projectsLeftToBatch.size > 0) { - // Get all projects that have no remaining dependencies within the repo - // that haven't yet been picked. - const batch = []; - for (const projectName of projectsLeftToBatch) { - const projectDeps = projectGraph.get(projectName); - const needsDependenciesBatched = projectDeps.some(dep => projectsLeftToBatch.has(dep.name)); - if (!needsDependenciesBatched) { - batch.push(projectsToBatch.get(projectName)); - } - } - // If we weren't able to find a project with no remaining dependencies, - // then we've encountered a cycle in the dependency graph. - const hasCycles = batch.length === 0; - if (hasCycles) { - const cycleProjectNames = [...projectsLeftToBatch]; - const message = 'Encountered a cycle in the dependency graph. Projects in cycle are:\n' + cycleProjectNames.join(', '); - throw new _errors.CliError(message); - } - batches.push(batch); - batch.forEach(project => projectsLeftToBatch.delete(project.name)); - } - return batches; -} -function includeTransitiveProjects(subsetOfProjects, allProjects, { onlyProductionDependencies = false } = {}) { - const dependentProjects = new Map(); - // the current list of packages we are expanding using breadth-first-search - const toProcess = [...subsetOfProjects]; - while (toProcess.length > 0) { - const project = toProcess.shift(); - const dependencies = onlyProductionDependencies ? project.productionDependencies : project.allDependencies; - Object.keys(dependencies).forEach(dep => { - if (allProjects.has(dep)) { - toProcess.push(allProjects.get(dep)); - } - }); - dependentProjects.set(project.name, project); + if (!needsDependenciesBatched) { + batch.push(projectsToBatch.get(projectName)); + } + } // If we weren't able to find a project with no remaining dependencies, + // then we've encountered a cycle in the dependency graph. + + + const hasCycles = batch.length === 0; + + if (hasCycles) { + const cycleProjectNames = [...projectsLeftToBatch]; + const message = 'Encountered a cycle in the dependency graph. Projects in cycle are:\n' + cycleProjectNames.join(', '); + throw new _errors__WEBPACK_IMPORTED_MODULE_3__["CliError"](message); } - return dependentProjects; + + batches.push(batch); + batch.forEach(project => projectsLeftToBatch.delete(project.name)); + } + + return batches; +} +function includeTransitiveProjects(subsetOfProjects, allProjects, { + onlyProductionDependencies = false +} = {}) { + const dependentProjects = new Map(); // the current list of packages we are expanding using breadth-first-search + + const toProcess = [...subsetOfProjects]; + + while (toProcess.length > 0) { + const project = toProcess.shift(); + const dependencies = onlyProductionDependencies ? project.productionDependencies : project.allDependencies; + Object.keys(dependencies).forEach(dep => { + if (allProjects.has(dep)) { + toProcess.push(allProjects.get(dep)); + } + }); + dependentProjects.set(project.name, project); + } + + return dependentProjects; } /***/ }), @@ -7854,14 +7782,11 @@ function onceStrict (fn) { /***/ }), /* 52 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CliError", function() { return CliError; }); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -7881,208 +7806,227 @@ Object.defineProperty(exports, "__esModule", { * under the License. */ class CliError extends Error { - constructor(message, meta = {}) { - super(message); - this.meta = meta; - } + constructor(message, meta = {}) { + super(message); + this.meta = meta; + } + } -exports.CliError = CliError; /***/ }), /* 53 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Project", function() { return Project; }); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(16); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(29); +/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(52); +/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(33); +/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(54); +/* harmony import */ var _scripts__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(92); +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.Project = undefined; -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -var _chalk = __webpack_require__(2); -var _chalk2 = _interopRequireDefault(_chalk); -var _path = __webpack_require__(16); -var _util = __webpack_require__(29); +class Project { + static async fromPath(path) { + const pkgJson = await Object(_package_json__WEBPACK_IMPORTED_MODULE_5__["readPackageJson"])(path); + return new Project(pkgJson, path); + } -var _errors = __webpack_require__(52); + constructor(packageJson, projectPath) { + _defineProperty(this, "json", void 0); -var _log = __webpack_require__(33); + _defineProperty(this, "packageJsonLocation", void 0); -var _package_json = __webpack_require__(54); + _defineProperty(this, "nodeModulesLocation", void 0); -var _scripts = __webpack_require__(92); + _defineProperty(this, "targetLocation", void 0); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + _defineProperty(this, "path", void 0); -function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } + _defineProperty(this, "allDependencies", void 0); -class Project { - constructor(packageJson, projectPath) { - this.isWorkspaceRoot = false; - this.isWorkspaceProject = false; - this.json = Object.freeze(packageJson); - this.path = projectPath; - this.packageJsonLocation = (0, _path.resolve)(this.path, 'package.json'); - this.nodeModulesLocation = (0, _path.resolve)(this.path, 'node_modules'); - this.targetLocation = (0, _path.resolve)(this.path, 'target'); - this.productionDependencies = this.json.dependencies || {}; - this.devDependencies = this.json.devDependencies || {}; - this.allDependencies = _extends({}, this.devDependencies, this.productionDependencies); - this.isWorkspaceRoot = this.json.hasOwnProperty('workspaces'); - this.scripts = this.json.scripts || {}; - } - static fromPath(path) { - return _asyncToGenerator(function* () { - const pkgJson = yield (0, _package_json.readPackageJson)(path); - return new Project(pkgJson, path); - })(); - } - get name() { - return this.json.name; - } - ensureValidProjectDependency(project, dependentProjectIsInWorkspace) { - const versionInPackageJson = this.allDependencies[project.name]; - let expectedVersionInPackageJson; - if (dependentProjectIsInWorkspace) { - expectedVersionInPackageJson = project.json.version; - } else { - const relativePathToProject = normalizePath((0, _path.relative)(this.path, project.path)); - expectedVersionInPackageJson = `link:${relativePathToProject}`; - } - // No issues! - if (versionInPackageJson === expectedVersionInPackageJson) { - return; - } - let problemMsg; - if ((0, _package_json.isLinkDependency)(versionInPackageJson) && dependentProjectIsInWorkspace) { - problemMsg = `but should be using a workspace`; - } else if ((0, _package_json.isLinkDependency)(versionInPackageJson)) { - problemMsg = `using 'link:', but the path is wrong`; - } else { - problemMsg = `but it's not using the local package`; - } - throw new _errors.CliError(`[${this.name}] depends on [${project.name}] ${problemMsg}. Update its package.json to the expected value below.`, { - actual: `"${project.name}": "${versionInPackageJson}"`, - expected: `"${project.name}": "${expectedVersionInPackageJson}"`, - package: `${this.name} (${this.packageJsonLocation})` - }); - } - getBuildConfig() { - return this.json.kibana && this.json.kibana.build || {}; - } - /** - * Returns the directory that should be copied into the Kibana build artifact. - * This config can be specified to only include the project's build artifacts - * instead of everything located in the project directory. - */ - getIntermediateBuildDirectory() { - return (0, _path.resolve)(this.path, this.getBuildConfig().intermediateBuildDirectory || '.'); - } - getCleanConfig() { - return this.json.kibana && this.json.kibana.clean || {}; - } - hasScript(name) { - return name in this.scripts; - } - getExecutables() { - const raw = this.json.bin; - if (!raw) { - return {}; - } - if (typeof raw === 'string') { - return { - [this.name]: (0, _path.resolve)(this.path, raw) - }; - } - if (typeof raw === 'object') { - const binsConfig = {}; - for (const binName of Object.keys(raw)) { - binsConfig[binName] = (0, _path.resolve)(this.path, raw[binName]); - } - return binsConfig; - } - throw new _errors.CliError(`[${this.name}] has an invalid "bin" field in its package.json, ` + `expected an object or a string`, { - binConfig: (0, _util.inspect)(raw), - package: `${this.name} (${this.packageJsonLocation})` - }); - } - runScript(scriptName, args = []) { - var _this = this; + _defineProperty(this, "productionDependencies", void 0); + + _defineProperty(this, "devDependencies", void 0); + + _defineProperty(this, "scripts", void 0); - return _asyncToGenerator(function* () { - _log.log.write(_chalk2.default.bold(`\n\nRunning script [${_chalk2.default.green(scriptName)}] in [${_chalk2.default.green(_this.name)}]:\n`)); - return (0, _scripts.runScriptInPackage)(scriptName, args, _this); - })(); + _defineProperty(this, "isWorkspaceRoot", false); + + _defineProperty(this, "isWorkspaceProject", false); + + this.json = Object.freeze(packageJson); + this.path = projectPath; + this.packageJsonLocation = Object(path__WEBPACK_IMPORTED_MODULE_1__["resolve"])(this.path, 'package.json'); + this.nodeModulesLocation = Object(path__WEBPACK_IMPORTED_MODULE_1__["resolve"])(this.path, 'node_modules'); + this.targetLocation = Object(path__WEBPACK_IMPORTED_MODULE_1__["resolve"])(this.path, 'target'); + this.productionDependencies = this.json.dependencies || {}; + this.devDependencies = this.json.devDependencies || {}; + this.allDependencies = _objectSpread({}, this.devDependencies, this.productionDependencies); + this.isWorkspaceRoot = this.json.hasOwnProperty('workspaces'); + this.scripts = this.json.scripts || {}; + } + + get name() { + return this.json.name; + } + + ensureValidProjectDependency(project, dependentProjectIsInWorkspace) { + const versionInPackageJson = this.allDependencies[project.name]; + let expectedVersionInPackageJson; + + if (dependentProjectIsInWorkspace) { + expectedVersionInPackageJson = project.json.version; + } else { + const relativePathToProject = normalizePath(Object(path__WEBPACK_IMPORTED_MODULE_1__["relative"])(this.path, project.path)); + expectedVersionInPackageJson = `link:${relativePathToProject}`; + } // No issues! + + + if (versionInPackageJson === expectedVersionInPackageJson) { + return; } - runScriptStreaming(scriptName, args = []) { - return (0, _scripts.runScriptInPackageStreaming)(scriptName, args, this); + + let problemMsg; + + if (Object(_package_json__WEBPACK_IMPORTED_MODULE_5__["isLinkDependency"])(versionInPackageJson) && dependentProjectIsInWorkspace) { + problemMsg = `but should be using a workspace`; + } else if (Object(_package_json__WEBPACK_IMPORTED_MODULE_5__["isLinkDependency"])(versionInPackageJson)) { + problemMsg = `using 'link:', but the path is wrong`; + } else { + problemMsg = `but it's not using the local package`; } - hasDependencies() { - return Object.keys(this.allDependencies).length > 0; + + throw new _errors__WEBPACK_IMPORTED_MODULE_3__["CliError"](`[${this.name}] depends on [${project.name}] ${problemMsg}. Update its package.json to the expected value below.`, { + actual: `"${project.name}": "${versionInPackageJson}"`, + expected: `"${project.name}": "${expectedVersionInPackageJson}"`, + package: `${this.name} (${this.packageJsonLocation})` + }); + } + + getBuildConfig() { + return this.json.kibana && this.json.kibana.build || {}; + } + /** + * Returns the directory that should be copied into the Kibana build artifact. + * This config can be specified to only include the project's build artifacts + * instead of everything located in the project directory. + */ + + + getIntermediateBuildDirectory() { + return Object(path__WEBPACK_IMPORTED_MODULE_1__["resolve"])(this.path, this.getBuildConfig().intermediateBuildDirectory || '.'); + } + + getCleanConfig() { + return this.json.kibana && this.json.kibana.clean || {}; + } + + hasScript(name) { + return name in this.scripts; + } + + getExecutables() { + const raw = this.json.bin; + + if (!raw) { + return {}; } - installDependencies({ extraArgs }) { - var _this2 = this; - return _asyncToGenerator(function* () { - _log.log.write(_chalk2.default.bold(`\n\nInstalling dependencies in [${_chalk2.default.green(_this2.name)}]:\n`)); - return (0, _scripts.installInDir)(_this2.path, extraArgs); - })(); + if (typeof raw === 'string') { + return { + [this.name]: Object(path__WEBPACK_IMPORTED_MODULE_1__["resolve"])(this.path, raw) + }; } -} -exports.Project = Project; // We normalize all path separators to `/` in generated files -function normalizePath(path) { - return path.replace(/[\\\/]+/g, '/'); -} + if (typeof raw === 'object') { + const binsConfig = {}; -/***/ }), -/* 54 */ -/***/ (function(module, exports, __webpack_require__) { + for (const binName of Object.keys(raw)) { + binsConfig[binName] = Object(path__WEBPACK_IMPORTED_MODULE_1__["resolve"])(this.path, raw[binName]); + } -"use strict"; + return binsConfig; + } + throw new _errors__WEBPACK_IMPORTED_MODULE_3__["CliError"](`[${this.name}] has an invalid "bin" field in its package.json, ` + `expected an object or a string`, { + binConfig: Object(util__WEBPACK_IMPORTED_MODULE_2__["inspect"])(raw), + package: `${this.name} (${this.packageJsonLocation})` + }); + } -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.isLinkDependency = undefined; -exports.readPackageJson = readPackageJson; -exports.writePackageJson = writePackageJson; + async runScript(scriptName, args = []) { + _log__WEBPACK_IMPORTED_MODULE_4__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold(`\n\nRunning script [${chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green(scriptName)}] in [${chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green(this.name)}]:\n`)); + return Object(_scripts__WEBPACK_IMPORTED_MODULE_6__["runScriptInPackage"])(scriptName, args, this); + } -var _readPkg = __webpack_require__(55); + runScriptStreaming(scriptName, args = []) { + return Object(_scripts__WEBPACK_IMPORTED_MODULE_6__["runScriptInPackageStreaming"])(scriptName, args, this); + } -var _readPkg2 = _interopRequireDefault(_readPkg); + hasDependencies() { + return Object.keys(this.allDependencies).length > 0; + } -var _writePkg = __webpack_require__(82); + async installDependencies({ + extraArgs + }) { + _log__WEBPACK_IMPORTED_MODULE_4__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold(`\n\nInstalling dependencies in [${chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green(this.name)}]:\n`)); + return Object(_scripts__WEBPACK_IMPORTED_MODULE_6__["installInDir"])(this.path, extraArgs); + } -var _writePkg2 = _interopRequireDefault(_writePkg); +} // We normalize all path separators to `/` in generated files -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +function normalizePath(path) { + return path.replace(/[\\\/]+/g, '/'); +} +/***/ }), +/* 54 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "readPackageJson", function() { return readPackageJson; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "writePackageJson", function() { return writePackageJson; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isLinkDependency", function() { return isLinkDependency; }); +/* harmony import */ var read_pkg__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(55); +/* harmony import */ var read_pkg__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(read_pkg__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var write_pkg__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(82); +/* harmony import */ var write_pkg__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(write_pkg__WEBPACK_IMPORTED_MODULE_1__); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -8101,13 +8045,17 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de * specific language governing permissions and limitations * under the License. */ + + function readPackageJson(dir) { - return (0, _readPkg2.default)(dir, { normalize: false }); + return read_pkg__WEBPACK_IMPORTED_MODULE_0___default()(dir, { + normalize: false + }); } function writePackageJson(path, json) { - return (0, _writePkg2.default)(path, json); + return write_pkg__WEBPACK_IMPORTED_MODULE_1___default()(path, json); } -const isLinkDependency = exports.isLinkDependency = depVersion => depVersion.startsWith('link:'); +const isLinkDependency = depVersion => depVersion.startsWith('link:'); /***/ }), /* 55 */ @@ -13496,165 +13444,141 @@ module.exports = str => { /***/ }), /* 92 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "installInDir", function() { return installInDir; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "runScriptInPackage", function() { return runScriptInPackage; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "runScriptInPackageStreaming", function() { return runScriptInPackageStreaming; }); +/* harmony import */ var _child_process__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(93); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.runScriptInPackage = exports.installInDir = undefined; - /** * Install all dependencies in the given directory */ -let installInDir = exports.installInDir = (() => { - var _ref = _asyncToGenerator(function* (directory, extraArgs = []) { - const options = ['install', '--non-interactive', ...extraArgs]; - // We pass the mutex flag to ensure only one instance of yarn runs at any - // given time (e.g. to avoid conflicts). - yield (0, _child_process.spawn)('yarn', options, { - cwd: directory - }); - }); +async function installInDir(directory, extraArgs = []) { + const options = ['install', '--non-interactive', ...extraArgs]; // We pass the mutex flag to ensure only one instance of yarn runs at any + // given time (e.g. to avoid conflicts). - return function installInDir(_x) { - return _ref.apply(this, arguments); - }; -})(); + await Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawn"])('yarn', options, { + cwd: directory + }); +} /** * Run script in the given directory */ - -let runScriptInPackage = exports.runScriptInPackage = (() => { - var _ref2 = _asyncToGenerator(function* (script, args, pkg) { - const execOpts = { - cwd: pkg.path - }; - yield (0, _child_process.spawn)('yarn', ['run', script, ...args], execOpts); - }); - - return function runScriptInPackage(_x2, _x3, _x4) { - return _ref2.apply(this, arguments); - }; -})(); +async function runScriptInPackage(script, args, pkg) { + const execOpts = { + cwd: pkg.path + }; + await Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawn"])('yarn', ['run', script, ...args], execOpts); +} /** * Run script in the given directory */ - -exports.runScriptInPackageStreaming = runScriptInPackageStreaming; - -var _child_process = __webpack_require__(93); - -function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - - function runScriptInPackageStreaming(script, args, pkg) { - const execOpts = { - cwd: pkg.path - }; - return (0, _child_process.spawnStreaming)('yarn', ['run', script, ...args], execOpts, { - prefix: pkg.name - }); + const execOpts = { + cwd: pkg.path + }; + return Object(_child_process__WEBPACK_IMPORTED_MODULE_0__["spawnStreaming"])('yarn', ['run', script, ...args], execOpts, { + prefix: pkg.name + }); } /***/ }), /* 93 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "spawn", function() { return spawn; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "spawnStreaming", function() { return spawnStreaming; }); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(94); +/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(execa__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var log_symbols__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(122); +/* harmony import */ var log_symbols__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(log_symbols__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var strong_log_transformer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(123); +/* harmony import */ var strong_log_transformer__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(strong_log_transformer__WEBPACK_IMPORTED_MODULE_3__); +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - - -exports.spawn = spawn; -exports.spawnStreaming = spawnStreaming; - -var _chalk = __webpack_require__(2); - -var _chalk2 = _interopRequireDefault(_chalk); - -var _execa = __webpack_require__(94); - -var _execa2 = _interopRequireDefault(_execa); - -var _logSymbols = __webpack_require__(122); - -var _logSymbols2 = _interopRequireDefault(_logSymbols); -var _strongLogTransformer = __webpack_require__(123); -var _strongLogTransformer2 = _interopRequireDefault(_strongLogTransformer); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function generateColors() { - const colorWheel = [_chalk2.default.cyan, _chalk2.default.magenta, _chalk2.default.blue, _chalk2.default.yellow, _chalk2.default.green]; - const count = colorWheel.length; - let children = 0; - return () => colorWheel[children++ % count]; + const colorWheel = [chalk__WEBPACK_IMPORTED_MODULE_0___default.a.cyan, chalk__WEBPACK_IMPORTED_MODULE_0___default.a.magenta, chalk__WEBPACK_IMPORTED_MODULE_0___default.a.blue, chalk__WEBPACK_IMPORTED_MODULE_0___default.a.yellow, chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green]; + const count = colorWheel.length; + let children = 0; + return () => colorWheel[children++ % count]; } + function spawn(command, args, opts) { - return (0, _execa2.default)(command, args, _extends({}, opts, { - stdio: 'inherit' - })); + return execa__WEBPACK_IMPORTED_MODULE_1___default()(command, args, _objectSpread({}, opts, { + stdio: 'inherit' + })); } const nextColor = generateColors(); -function spawnStreaming(command, args, opts, { prefix }) { - const spawned = (0, _execa2.default)(command, args, _extends({}, opts, { - stdio: ['ignore', 'pipe', 'pipe'] - })); - const color = nextColor(); - const prefixedStdout = (0, _strongLogTransformer2.default)({ tag: `${color.bold(prefix)}:` }); - const prefixedStderr = (0, _strongLogTransformer2.default)({ - mergeMultiline: true, - tag: `${_logSymbols2.default.error} ${color.bold(prefix)}:` - }); - spawned.stdout.pipe(prefixedStdout).pipe(process.stdout); - spawned.stderr.pipe(prefixedStderr).pipe(process.stderr); - return spawned; +function spawnStreaming(command, args, opts, { + prefix +}) { + const spawned = execa__WEBPACK_IMPORTED_MODULE_1___default()(command, args, _objectSpread({}, opts, { + stdio: ['ignore', 'pipe', 'pipe'] + })); + const color = nextColor(); + const prefixedStdout = strong_log_transformer__WEBPACK_IMPORTED_MODULE_3___default()({ + tag: `${color.bold(prefix)}:` + }); + const prefixedStderr = strong_log_transformer__WEBPACK_IMPORTED_MODULE_3___default()({ + mergeMultiline: true, + tag: `${log_symbols__WEBPACK_IMPORTED_MODULE_2___default.a.error} ${color.bold(prefix)}:` + }); + spawned.stdout.pipe(prefixedStdout).pipe(process.stdout); + spawned.stderr.pipe(prefixedStderr).pipe(process.stderr); + return spawned; } /***/ }), @@ -17429,305 +17353,290 @@ module.exports = {"name":"strong-log-transformer","version":"2.1.0","description /***/ }), /* 131 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "workspacePackagePaths", function() { return workspacePackagePaths; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "copyWorkspacePackages", function() { return copyWorkspacePackages; }); +/* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); +/* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(glob__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(16); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(29); +/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(132); +/* harmony import */ var _fs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(20); +/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(54); +/* harmony import */ var _projects__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(35); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.copyWorkspacePackages = exports.workspacePackagePaths = undefined; - -let workspacePackagePaths = exports.workspacePackagePaths = (() => { - var _ref = _asyncToGenerator(function* (rootPath) { - const rootPkgJson = yield (0, _package_json.readPackageJson)(_path2.default.join(rootPath, 'package.json')); - if (!rootPkgJson.workspaces) { - return []; - } - const workspacesPathsPatterns = rootPkgJson.workspaces.packages; - let workspaceProjectsPaths = []; - for (const pattern of workspacesPathsPatterns) { - workspaceProjectsPaths = workspaceProjectsPaths.concat((yield packagesFromGlobPattern({ pattern, rootPath }))); - } - // Filter out exclude glob patterns - for (const pattern of workspacesPathsPatterns) { - if (pattern.startsWith('!')) { - const pathToRemove = _path2.default.join(rootPath, pattern.slice(1), 'package.json'); - workspaceProjectsPaths = workspaceProjectsPaths.filter(function (p) { - return p !== pathToRemove; - }); - } - } - return workspaceProjectsPaths; - }); - - return function workspacePackagePaths(_x) { - return _ref.apply(this, arguments); - }; -})(); -let copyWorkspacePackages = exports.copyWorkspacePackages = (() => { - var _ref2 = _asyncToGenerator(function* (rootPath) { - const workspaceProjects = yield getWorkspaceProjects(rootPath); - for (const project of workspaceProjects.values()) { - const dest = _path2.default.resolve(rootPath, 'node_modules', project.name); - // Remove the symlink - yield (0, _fs.unlink)(dest); - // Copy in the package - yield (0, _fs.copyDirectory)(project.path, dest); - } - }); - return function copyWorkspacePackages(_x2) { - return _ref2.apply(this, arguments); - }; -})(); -let getWorkspaceProjects = (() => { - var _ref3 = _asyncToGenerator(function* (rootPath) { - const projectPaths = (0, _config.getProjectPaths)(rootPath, {}); - const projects = yield (0, _projects.getProjects)(rootPath, projectPaths); - for (const [key, project] of projects.entries()) { - if (!project.isWorkspaceProject) { - projects.delete(key); - } - } - return projects; - }); - return function getWorkspaceProjects(_x3) { - return _ref3.apply(this, arguments); - }; -})(); -var _glob = __webpack_require__(36); +const glob = Object(util__WEBPACK_IMPORTED_MODULE_2__["promisify"])(glob__WEBPACK_IMPORTED_MODULE_0___default.a); +async function workspacePackagePaths(rootPath) { + const rootPkgJson = await Object(_package_json__WEBPACK_IMPORTED_MODULE_5__["readPackageJson"])(path__WEBPACK_IMPORTED_MODULE_1___default.a.join(rootPath, 'package.json')); -var _glob2 = _interopRequireDefault(_glob); + if (!rootPkgJson.workspaces) { + return []; + } -var _path = __webpack_require__(16); + const workspacesPathsPatterns = rootPkgJson.workspaces.packages; + let workspaceProjectsPaths = []; -var _path2 = _interopRequireDefault(_path); + for (const pattern of workspacesPathsPatterns) { + workspaceProjectsPaths = workspaceProjectsPaths.concat((await packagesFromGlobPattern({ + pattern, + rootPath + }))); + } // Filter out exclude glob patterns -var _util = __webpack_require__(29); -var _config = __webpack_require__(132); + for (const pattern of workspacesPathsPatterns) { + if (pattern.startsWith('!')) { + const pathToRemove = path__WEBPACK_IMPORTED_MODULE_1___default.a.join(rootPath, pattern.slice(1), 'package.json'); + workspaceProjectsPaths = workspaceProjectsPaths.filter(p => p !== pathToRemove); + } + } -var _fs = __webpack_require__(20); + return workspaceProjectsPaths; +} +async function copyWorkspacePackages(rootPath) { + const workspaceProjects = await getWorkspaceProjects(rootPath); -var _package_json = __webpack_require__(54); + for (const project of workspaceProjects.values()) { + const dest = path__WEBPACK_IMPORTED_MODULE_1___default.a.resolve(rootPath, 'node_modules', project.name); // Remove the symlink -var _projects = __webpack_require__(35); + await Object(_fs__WEBPACK_IMPORTED_MODULE_4__["unlink"])(dest); // Copy in the package -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + await Object(_fs__WEBPACK_IMPORTED_MODULE_4__["copyDirectory"])(project.path, dest); + } +} -function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ +async function getWorkspaceProjects(rootPath) { + const projectPaths = Object(_config__WEBPACK_IMPORTED_MODULE_3__["getProjectPaths"])(rootPath, {}); + const projects = await Object(_projects__WEBPACK_IMPORTED_MODULE_6__["getProjects"])(rootPath, projectPaths); + for (const [key, project] of projects.entries()) { + if (!project.isWorkspaceProject) { + projects.delete(key); + } + } -const glob = (0, _util.promisify)(_glob2.default); + return projects; +} -function packagesFromGlobPattern({ pattern, rootPath }) { - const globOptions = { - cwd: rootPath, - // Should throw in case of unusual errors when reading the file system - strict: true, - // Always returns absolute paths for matched files - absolute: true, - // Do not match ** against multiple filenames - // (This is only specified because we currently don't have a need for it.) - noglobstar: true - }; - return glob(_path2.default.join(pattern, 'package.json'), globOptions); +function packagesFromGlobPattern({ + pattern, + rootPath +}) { + const globOptions = { + cwd: rootPath, + // Should throw in case of unusual errors when reading the file system + strict: true, + // Always returns absolute paths for matched files + absolute: true, + // Do not match ** against multiple filenames + // (This is only specified because we currently don't have a need for it.) + noglobstar: true + }; + return glob(path__WEBPACK_IMPORTED_MODULE_1___default.a.join(pattern, 'package.json'), globOptions); } /***/ }), /* 132 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getProjectPaths", function() { return getProjectPaths; }); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(16); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_0__); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.getProjectPaths = getProjectPaths; - -var _path = __webpack_require__(16); - /** * Returns all the paths where plugins are located */ function getProjectPaths(rootPath, options) { - const skipKibanaPlugins = Boolean(options['skip-kibana-plugins']); - const ossOnly = Boolean(options.oss); - const projectPaths = [rootPath, (0, _path.resolve)(rootPath, 'packages/*')]; - // This is needed in order to install the dependencies for the declared - // plugin functional used in the selenium functional tests. - // As we are now using the webpack dll for the client vendors dependencies - // when we run the plugin functional tests against the distributable - // dependencies used by such plugins like @eui, react and react-dom can't - // be loaded from the dll as the context is different from the one declared - // into the webpack dll reference plugin. - // In anyway, have a plugin declaring their own dependencies is the - // correct and the expect behavior. - projectPaths.push((0, _path.resolve)(rootPath, 'test/plugin_functional/plugins/*')); - if (!ossOnly) { - projectPaths.push((0, _path.resolve)(rootPath, 'x-pack')); - projectPaths.push((0, _path.resolve)(rootPath, 'x-pack/plugins/*')); - } - if (!skipKibanaPlugins) { - projectPaths.push((0, _path.resolve)(rootPath, '../kibana-extra/*')); - projectPaths.push((0, _path.resolve)(rootPath, '../kibana-extra/*/packages/*')); - projectPaths.push((0, _path.resolve)(rootPath, '../kibana-extra/*/plugins/*')); - projectPaths.push((0, _path.resolve)(rootPath, 'plugins/*')); - projectPaths.push((0, _path.resolve)(rootPath, 'plugins/*/packages/*')); - projectPaths.push((0, _path.resolve)(rootPath, 'plugins/*/plugins/*')); - } - return projectPaths; -} /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ + const skipKibanaPlugins = Boolean(options['skip-kibana-plugins']); + const ossOnly = Boolean(options.oss); + const projectPaths = [rootPath, Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'packages/*')]; // This is needed in order to install the dependencies for the declared + // plugin functional used in the selenium functional tests. + // As we are now using the webpack dll for the client vendors dependencies + // when we run the plugin functional tests against the distributable + // dependencies used by such plugins like @eui, react and react-dom can't + // be loaded from the dll as the context is different from the one declared + // into the webpack dll reference plugin. + // In anyway, have a plugin declaring their own dependencies is the + // correct and the expect behavior. -/***/ }), -/* 133 */ -/***/ (function(module, exports, __webpack_require__) { + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'test/plugin_functional/plugins/*')); + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'test/interpreter_functional/plugins/*')); -"use strict"; + if (!ossOnly) { + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'x-pack')); + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'x-pack/plugins/*')); + } + if (!skipKibanaPlugins) { + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, '../kibana-extra/*')); + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, '../kibana-extra/*/packages/*')); + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, '../kibana-extra/*/plugins/*')); + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'plugins/*')); + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'plugins/*/packages/*')); + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'plugins/*/plugins/*')); + } -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.CleanCommand = undefined; + return projectPaths; +} -var _chalk = __webpack_require__(2); +/***/ }), +/* 133 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CleanCommand", function() { return CleanCommand; }); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(134); +/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(del__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(148); +/* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(ora__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(16); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_3__); +/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(20); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(33); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -var _chalk2 = _interopRequireDefault(_chalk); -var _del = __webpack_require__(134); -var _del2 = _interopRequireDefault(_del); -var _ora = __webpack_require__(148); -var _ora2 = _interopRequireDefault(_ora); -var _path = __webpack_require__(16); +const CleanCommand = { + description: 'Remove the node_modules and target directories from all projects.', + name: 'clean', -var _fs = __webpack_require__(20); + async run(projects) { + const toDelete = []; -var _log = __webpack_require__(33); + for (const project of projects.values()) { + if (await Object(_utils_fs__WEBPACK_IMPORTED_MODULE_4__["isDirectory"])(project.nodeModulesLocation)) { + toDelete.push({ + cwd: project.path, + pattern: Object(path__WEBPACK_IMPORTED_MODULE_3__["relative"])(project.path, project.nodeModulesLocation) + }); + } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + if (await Object(_utils_fs__WEBPACK_IMPORTED_MODULE_4__["isDirectory"])(project.targetLocation)) { + toDelete.push({ + cwd: project.path, + pattern: Object(path__WEBPACK_IMPORTED_MODULE_3__["relative"])(project.path, project.targetLocation) + }); + } -function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ + const { + extraPatterns + } = project.getCleanConfig(); + if (extraPatterns) { + toDelete.push({ + cwd: project.path, + pattern: extraPatterns + }); + } + } -const CleanCommand = exports.CleanCommand = { - description: 'Remove the node_modules and target directories from all projects.', - name: 'clean', - run(projects) { - return _asyncToGenerator(function* () { - const toDelete = []; - for (const project of projects.values()) { - if (yield (0, _fs.isDirectory)(project.nodeModulesLocation)) { - toDelete.push({ - cwd: project.path, - pattern: (0, _path.relative)(project.path, project.nodeModulesLocation) - }); - } - if (yield (0, _fs.isDirectory)(project.targetLocation)) { - toDelete.push({ - cwd: project.path, - pattern: (0, _path.relative)(project.path, project.targetLocation) - }); - } - const { extraPatterns } = project.getCleanConfig(); - if (extraPatterns) { - toDelete.push({ - cwd: project.path, - pattern: extraPatterns - }); - } - } - if (toDelete.length === 0) { - _log.log.write(_chalk2.default.bold.green('\n\nNothing to delete')); - } else { - _log.log.write(_chalk2.default.bold.red('\n\nDeleting:\n')); - /** - * In order to avoid patterns like `/build` in packages from accidentally - * impacting files outside the package we use `process.chdir()` to change - * the cwd to the package and execute `del()` without the `force` option - * so it will check that each file being deleted is within the package. - * - * `del()` does support a `cwd` option, but it's only for resolving the - * patterns and does not impact the cwd check. - */ - const originalCwd = process.cwd(); - try { - for (const _ref of toDelete) { - const { pattern, cwd } = _ref; + if (toDelete.length === 0) { + _utils_log__WEBPACK_IMPORTED_MODULE_5__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold.green('\n\nNothing to delete')); + } else { + _utils_log__WEBPACK_IMPORTED_MODULE_5__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold.red('\n\nDeleting:\n')); + /** + * In order to avoid patterns like `/build` in packages from accidentally + * impacting files outside the package we use `process.chdir()` to change + * the cwd to the package and execute `del()` without the `force` option + * so it will check that each file being deleted is within the package. + * + * `del()` does support a `cwd` option, but it's only for resolving the + * patterns and does not impact the cwd check. + */ + + const originalCwd = process.cwd(); - process.chdir(cwd); - const promise = (0, _del2.default)(pattern); - _ora2.default.promise(promise, (0, _path.relative)(originalCwd, (0, _path.join)(cwd, String(pattern)))); - yield promise; - } - } finally { - process.chdir(originalCwd); - } - } - })(); + try { + for (const _ref of toDelete) { + const { + pattern, + cwd + } = _ref; + process.chdir(cwd); + const promise = del__WEBPACK_IMPORTED_MODULE_1___default()(pattern); + ora__WEBPACK_IMPORTED_MODULE_2___default.a.promise(promise, Object(path__WEBPACK_IMPORTED_MODULE_3__["relative"])(originalCwd, Object(path__WEBPACK_IMPORTED_MODULE_3__["join"])(cwd, String(pattern)))); + await promise; + } + } finally { + process.chdir(originalCwd); + } } + } + }; /***/ }), @@ -19287,120 +19196,99 @@ module.exports = {"dots":{"interval":80,"frames":["⠋","⠙","⠹","⠸","⠼", /***/ }), /* 155 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RunCommand", function() { return RunCommand; }); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(33); +/* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(34); +/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(35); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.RunCommand = undefined; - -var _chalk = __webpack_require__(2); - -var _chalk2 = _interopRequireDefault(_chalk); - -var _log = __webpack_require__(33); - -var _parallelize = __webpack_require__(34); - -var _projects = __webpack_require__(35); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - - -const RunCommand = exports.RunCommand = { - description: 'Run script defined in package.json in each package that contains that script.', - name: 'run', - run(projects, projectGraph, { extraArgs }) { - return _asyncToGenerator(function* () { - const batchedProjects = (0, _projects.topologicallyBatchProjects)(projects, projectGraph); - if (extraArgs.length === 0) { - _log.log.write(_chalk2.default.red.bold('\nNo script specified')); - process.exit(1); - } - const scriptName = extraArgs[0]; - const scriptArgs = extraArgs.slice(1); - _log.log.write(_chalk2.default.bold(`\nRunning script [${_chalk2.default.green(scriptName)}] in batched topological order\n`)); - yield (0, _parallelize.parallelizeBatches)(batchedProjects, (() => { - var _ref = _asyncToGenerator(function* (pkg) { - if (pkg.hasScript(scriptName)) { - yield pkg.runScriptStreaming(scriptName, scriptArgs); - } - }); - - return function (_x) { - return _ref.apply(this, arguments); - }; - })()); - })(); - } -}; -/***/ }), -/* 156 */ -/***/ (function(module, exports, __webpack_require__) { -"use strict"; +const RunCommand = { + description: 'Run script defined in package.json in each package that contains that script.', + name: 'run', + async run(projects, projectGraph, { + extraArgs + }) { + const batchedProjects = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_3__["topologicallyBatchProjects"])(projects, projectGraph); -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.WatchCommand = undefined; + if (extraArgs.length === 0) { + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.red.bold('\nNo script specified')); + process.exit(1); + } -var _chalk = __webpack_require__(2); + const scriptName = extraArgs[0]; + const scriptArgs = extraArgs.slice(1); + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold(`\nRunning script [${chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green(scriptName)}] in batched topological order\n`)); + await Object(_utils_parallelize__WEBPACK_IMPORTED_MODULE_2__["parallelizeBatches"])(batchedProjects, async pkg => { + if (pkg.hasScript(scriptName)) { + await pkg.runScriptStreaming(scriptName, scriptArgs); + } + }); + } -var _chalk2 = _interopRequireDefault(_chalk); +}; -var _log = __webpack_require__(33); +/***/ }), +/* 156 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -var _parallelize = __webpack_require__(34); +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WatchCommand", function() { return WatchCommand; }); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(33); +/* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(34); +/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(35); +/* harmony import */ var _utils_watch__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(157); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -var _projects = __webpack_require__(35); -var _watch = __webpack_require__(157); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ /** @@ -19410,6 +19298,7 @@ const watchScriptName = 'kbn:watch'; /** * Name of the Kibana project. */ + const kibanaProjectName = 'kibana'; /** * Command that traverses through list of available projects/packages that have `kbn:watch` script in their @@ -19421,68 +19310,54 @@ const kibanaProjectName = 'kibana'; * the `kbn:watch` script and eventually for the entire batch. Currently we support completion "markers" for * `webpack` and `tsc` only, for the rest we rely on predefined timeouts. */ -const WatchCommand = exports.WatchCommand = { - description: 'Runs `kbn:watch` script for every project.', - name: 'watch', - run(projects, projectGraph) { - return _asyncToGenerator(function* () { - const projectsToWatch = new Map(); - for (const project of projects.values()) { - // We can't watch project that doesn't have `kbn:watch` script. - if (project.hasScript(watchScriptName)) { - projectsToWatch.set(project.name, project); - } - } - if (projectsToWatch.size === 0) { - _log.log.write(_chalk2.default.red(`\nThere are no projects to watch found. Make sure that projects define 'kbn:watch' script in 'package.json'.\n`)); - return; - } - const projectNames = Array.from(projectsToWatch.keys()); - _log.log.write(_chalk2.default.bold(_chalk2.default.green(`Running ${watchScriptName} scripts for [${projectNames.join(', ')}].`))); - // Kibana should always be run the last, so we don't rely on automatic - // topological batching and push it to the last one-entry batch manually. - const shouldWatchKibanaProject = projectsToWatch.delete(kibanaProjectName); - const batchedProjects = (0, _projects.topologicallyBatchProjects)(projectsToWatch, projectGraph); - if (shouldWatchKibanaProject) { - batchedProjects.push([projects.get(kibanaProjectName)]); - } - yield (0, _parallelize.parallelizeBatches)(batchedProjects, (() => { - var _ref = _asyncToGenerator(function* (pkg) { - const completionHint = yield (0, _watch.waitUntilWatchIsReady)(pkg.runScriptStreaming(watchScriptName).stdout); - _log.log.write(_chalk2.default.bold(`[${_chalk2.default.green(pkg.name)}] Initial build completed (${completionHint}).`)); - }); - return function (_x) { - return _ref.apply(this, arguments); - }; - })()); - })(); - } -}; +const WatchCommand = { + description: 'Runs `kbn:watch` script for every project.', + name: 'watch', -/***/ }), -/* 157 */ -/***/ (function(module, exports, __webpack_require__) { + async run(projects, projectGraph) { + const projectsToWatch = new Map(); -"use strict"; + for (const project of projects.values()) { + // We can't watch project that doesn't have `kbn:watch` script. + if (project.hasScript(watchScriptName)) { + projectsToWatch.set(project.name, project); + } + } + if (projectsToWatch.size === 0) { + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.red(`\nThere are no projects to watch found. Make sure that projects define 'kbn:watch' script in 'package.json'.\n`)); + return; + } -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.waitUntilWatchIsReady = waitUntilWatchIsReady; + const projectNames = Array.from(projectsToWatch.keys()); + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green(`Running ${watchScriptName} scripts for [${projectNames.join(', ')}].`))); // Kibana should always be run the last, so we don't rely on automatic + // topological batching and push it to the last one-entry batch manually. -var _rxjs = __webpack_require__(158); + const shouldWatchKibanaProject = projectsToWatch.delete(kibanaProjectName); + const batchedProjects = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_3__["topologicallyBatchProjects"])(projectsToWatch, projectGraph); -var Rx = _interopRequireWildcard(_rxjs); + if (shouldWatchKibanaProject) { + batchedProjects.push([projects.get(kibanaProjectName)]); + } -var _operators = __webpack_require__(257); + await Object(_utils_parallelize__WEBPACK_IMPORTED_MODULE_2__["parallelizeBatches"])(batchedProjects, async pkg => { + const completionHint = await Object(_utils_watch__WEBPACK_IMPORTED_MODULE_4__["waitUntilWatchIsReady"])(pkg.runScriptStreaming(watchScriptName).stdout); + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold(`[${chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green(pkg.name)}] Initial build completed (${completionHint}).`)); + }); + } -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } +}; -/** - * Number of milliseconds we wait before we fall back to the default watch handler. - */ +/***/ }), +/* 157 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "waitUntilWatchIsReady", function() { return waitUntilWatchIsReady; }); +/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(158); +/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(257); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -19501,27 +19376,46 @@ function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; * specific language governing permissions and limitations * under the License. */ + + +/** + * Number of milliseconds we wait before we fall back to the default watch handler. + */ + const defaultHandlerDelay = 3000; /** * If default watch handler is used, then it's the number of milliseconds we wait for * any build output before we consider watch task ready. */ + const defaultHandlerReadinessTimeout = 2000; -function getWatchHandlers(buildOutput$, { handlerDelay = defaultHandlerDelay, handlerReadinessTimeout = defaultHandlerReadinessTimeout }) { - const typescriptHandler = buildOutput$.pipe((0, _operators.first)(data => data.includes('$ tsc')), (0, _operators.map)(() => buildOutput$.pipe((0, _operators.first)(data => data.includes('Compilation complete.')), (0, _operators.mapTo)('tsc')))); - const webpackHandler = buildOutput$.pipe((0, _operators.first)(data => data.includes('$ webpack')), (0, _operators.map)(() => buildOutput$.pipe((0, _operators.first)(data => data.includes('Chunk Names')), (0, _operators.mapTo)('webpack')))); - const defaultHandler = Rx.of(undefined).pipe((0, _operators.delay)(handlerReadinessTimeout), (0, _operators.map)(() => buildOutput$.pipe((0, _operators.timeout)(handlerDelay), (0, _operators.catchError)(() => Rx.of('timeout'))))); +/** + * Describes configurable watch options. + */ + +function getWatchHandlers(buildOutput$, { + handlerDelay = defaultHandlerDelay, + handlerReadinessTimeout = defaultHandlerReadinessTimeout +}) { + const typescriptHandler = buildOutput$.pipe(Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["first"])(data => data.includes('$ tsc')), Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["map"])(() => buildOutput$.pipe(Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["first"])(data => data.includes('Compilation complete.')), Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["mapTo"])('tsc')))); + const webpackHandler = buildOutput$.pipe(Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["first"])(data => data.includes('$ webpack')), Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["map"])(() => buildOutput$.pipe(Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["first"])(data => data.includes('Chunk Names')), Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["mapTo"])('webpack')))); + const defaultHandler = rxjs__WEBPACK_IMPORTED_MODULE_0__["of"](undefined).pipe(Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["delay"])(handlerReadinessTimeout), Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["map"])(() => buildOutput$.pipe(Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["timeout"])(handlerDelay), Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["catchError"])(() => rxjs__WEBPACK_IMPORTED_MODULE_0__["of"]('timeout'))))); return [typescriptHandler, webpackHandler, defaultHandler]; } + function waitUntilWatchIsReady(stream, opts = {}) { - const buildOutput$ = new Rx.Subject(); + const buildOutput$ = new rxjs__WEBPACK_IMPORTED_MODULE_0__["Subject"](); + const onDataListener = data => buildOutput$.next(data.toString('utf-8')); + const onEndListener = () => buildOutput$.complete(); + const onErrorListener = e => buildOutput$.error(e); + stream.once('end', onEndListener); stream.once('error', onErrorListener); stream.on('data', onDataListener); - return Rx.race(getWatchHandlers(buildOutput$, opts)).pipe((0, _operators.mergeMap)(whenReady => whenReady), (0, _operators.finalize)(() => { + return rxjs__WEBPACK_IMPORTED_MODULE_0__["race"](getWatchHandlers(buildOutput$, opts)).pipe(Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["mergeMap"])(whenReady => whenReady), Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["finalize"])(() => { stream.removeListener('data', onDataListener); stream.removeListener('end', onEndListener); stream.removeListener('error', onErrorListener); @@ -31109,108 +31003,96 @@ function zipAll(project) { /***/ }), /* 357 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "runCommand", function() { return runCommand; }); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var indent_string__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(358); +/* harmony import */ var indent_string__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(indent_string__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var wrap_ansi__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(359); +/* harmony import */ var wrap_ansi__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(wrap_ansi__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(132); +/* harmony import */ var _utils_errors__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(52); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(33); +/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(35); +/* harmony import */ var _utils_projects_tree__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(366); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.runCommand = undefined; - -let runCommand = exports.runCommand = (() => { - var _ref = _asyncToGenerator(function* (command, config) { - try { - _log.log.write(_chalk2.default.bold(`Running [${_chalk2.default.green(command.name)}] command from [${_chalk2.default.yellow(config.rootPath)}]:\n`)); - const projectPaths = (0, _config.getProjectPaths)(config.rootPath, config.options); - const projects = yield (0, _projects.getProjects)(config.rootPath, projectPaths, { - exclude: toArray(config.options.exclude), - include: toArray(config.options.include) - }); - if (projects.size === 0) { - _log.log.write(_chalk2.default.red(`There are no projects found. Double check project name(s) in '-i/--include' and '-e/--exclude' filters.\n`)); - return process.exit(1); - } - const projectGraph = (0, _projects.buildProjectGraph)(projects); - _log.log.write(_chalk2.default.bold(`Found [${_chalk2.default.green(projects.size.toString())}] projects:\n`)); - _log.log.write((0, _projects_tree.renderProjectsTree)(config.rootPath, projects)); - yield command.run(projects, projectGraph, config); - } catch (e) { - _log.log.write(_chalk2.default.bold.red(`\n[${command.name}] failed:\n`)); - if (e instanceof _errors.CliError) { - const msg = _chalk2.default.red(`CliError: ${e.message}\n`); - _log.log.write((0, _wrapAnsi2.default)(msg, 80)); - const keys = Object.keys(e.meta); - if (keys.length > 0) { - const metaOutput = keys.map(function (key) { - const value = e.meta[key]; - return `${key}: ${value}`; - }); - _log.log.write('Additional debugging info:\n'); - _log.log.write((0, _indentString2.default)(metaOutput.join('\n'), 3)); - } - } else { - _log.log.write(e.stack); - } - process.exit(1); - } - }); - - return function runCommand(_x, _x2) { - return _ref.apply(this, arguments); - }; -})(); - -var _chalk = __webpack_require__(2); - -var _chalk2 = _interopRequireDefault(_chalk); - -var _indentString = __webpack_require__(358); -var _indentString2 = _interopRequireDefault(_indentString); -var _wrapAnsi = __webpack_require__(359); -var _wrapAnsi2 = _interopRequireDefault(_wrapAnsi); -var _config = __webpack_require__(132); -var _errors = __webpack_require__(52); -var _log = __webpack_require__(33); +async function runCommand(command, config) { + try { + _utils_log__WEBPACK_IMPORTED_MODULE_5__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold(`Running [${chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green(command.name)}] command from [${chalk__WEBPACK_IMPORTED_MODULE_0___default.a.yellow(config.rootPath)}]:\n`)); + const projectPaths = Object(_config__WEBPACK_IMPORTED_MODULE_3__["getProjectPaths"])(config.rootPath, config.options); + const projects = await Object(_utils_projects__WEBPACK_IMPORTED_MODULE_6__["getProjects"])(config.rootPath, projectPaths, { + exclude: toArray(config.options.exclude), + include: toArray(config.options.include) + }); -var _projects = __webpack_require__(35); + if (projects.size === 0) { + _utils_log__WEBPACK_IMPORTED_MODULE_5__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.red(`There are no projects found. Double check project name(s) in '-i/--include' and '-e/--exclude' filters.\n`)); + return process.exit(1); + } -var _projects_tree = __webpack_require__(366); + const projectGraph = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_6__["buildProjectGraph"])(projects); + _utils_log__WEBPACK_IMPORTED_MODULE_5__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold(`Found [${chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green(projects.size.toString())}] projects:\n`)); + _utils_log__WEBPACK_IMPORTED_MODULE_5__["log"].write(Object(_utils_projects_tree__WEBPACK_IMPORTED_MODULE_7__["renderProjectsTree"])(config.rootPath, projects)); + await command.run(projects, projectGraph, config); + } catch (e) { + _utils_log__WEBPACK_IMPORTED_MODULE_5__["log"].write(chalk__WEBPACK_IMPORTED_MODULE_0___default.a.bold.red(`\n[${command.name}] failed:\n`)); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + if (e instanceof _utils_errors__WEBPACK_IMPORTED_MODULE_4__["CliError"]) { + const msg = chalk__WEBPACK_IMPORTED_MODULE_0___default.a.red(`CliError: ${e.message}\n`); + _utils_log__WEBPACK_IMPORTED_MODULE_5__["log"].write(wrap_ansi__WEBPACK_IMPORTED_MODULE_2___default()(msg, 80)); + const keys = Object.keys(e.meta); -function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ + if (keys.length > 0) { + const metaOutput = keys.map(key => { + const value = e.meta[key]; + return `${key}: ${value}`; + }); + _utils_log__WEBPACK_IMPORTED_MODULE_5__["log"].write('Additional debugging info:\n'); + _utils_log__WEBPACK_IMPORTED_MODULE_5__["log"].write(indent_string__WEBPACK_IMPORTED_MODULE_1___default()(metaOutput.join('\n'), 3)); + } + } else { + _utils_log__WEBPACK_IMPORTED_MODULE_5__["log"].write(e.stack); + } + process.exit(1); + } +} function toArray(value) { - if (value == null) { - return []; - } - return Array.isArray(value) ? value : [value]; + if (value == null) { + return []; + } + + return Array.isArray(value) ? value : [value]; } /***/ }), @@ -31601,26 +31483,15 @@ module.exports = () => { /***/ }), /* 366 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.renderProjectsTree = renderProjectsTree; - -var _chalk = __webpack_require__(2); - -var _chalk2 = _interopRequireDefault(_chalk); - -var _path = __webpack_require__(16); - -var _path2 = _interopRequireDefault(_path); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "renderProjectsTree", function() { return renderProjectsTree; }); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(16); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -31639,173 +31510,228 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de * specific language governing permissions and limitations * under the License. */ + + const projectKey = Symbol('__project'); function renderProjectsTree(rootPath, projects) { - const projectsTree = buildProjectsTree(rootPath, projects); - return treeToString(createTreeStructure(projectsTree)); + const projectsTree = buildProjectsTree(rootPath, projects); + return treeToString(createTreeStructure(projectsTree)); } + function treeToString(tree) { - return [tree.name].concat(childrenToStrings(tree.children, '')).join('\n'); + return [tree.name].concat(childrenToStrings(tree.children, '')).join('\n'); } + function childrenToStrings(tree, treePrefix) { - if (tree === undefined) { - return []; - } - let strings = []; - tree.forEach((node, index) => { - const isLastNode = tree.length - 1 === index; - const nodePrefix = isLastNode ? '└── ' : '├── '; - const childPrefix = isLastNode ? ' ' : '│ '; - const childrenPrefix = treePrefix + childPrefix; - strings.push(`${treePrefix}${nodePrefix}${node.name}`); - strings = strings.concat(childrenToStrings(node.children, childrenPrefix)); - }); - return strings; + if (tree === undefined) { + return []; + } + + let strings = []; + tree.forEach((node, index) => { + const isLastNode = tree.length - 1 === index; + const nodePrefix = isLastNode ? '└── ' : '├── '; + const childPrefix = isLastNode ? ' ' : '│ '; + const childrenPrefix = treePrefix + childPrefix; + strings.push(`${treePrefix}${nodePrefix}${node.name}`); + strings = strings.concat(childrenToStrings(node.children, childrenPrefix)); + }); + return strings; } + function createTreeStructure(tree) { - let name; - const children = []; - for (const [dir, project] of tree.entries()) { - // This is a leaf node (aka a project) - if (typeof project === 'string') { - name = _chalk2.default.green(project); - continue; - } - // If there's only one project and the key indicates it's a leaf node, we - // know that we're at a package folder that contains a package.json, so we - // "inline it" so we don't get unnecessary levels, i.e. we'll just see - // `foo` instead of `foo -> foo`. - if (project.size === 1 && project.has(projectKey)) { - const projectName = project.get(projectKey); - children.push({ - children: [], - name: dirOrProjectName(dir, projectName) - }); - continue; - } - const subtree = createTreeStructure(project); - // If the name is specified, we know there's a package at the "root" of the - // subtree itself. - if (subtree.name !== undefined) { - const projectName = subtree.name; - children.push({ - children: subtree.children, - name: dirOrProjectName(dir, projectName) - }); - continue; - } - // Special-case whenever we have one child, so we don't get unnecessary - // folders in the output. E.g. instead of `foo -> bar -> baz` we get - // `foo/bar/baz` instead. - if (subtree.children && subtree.children.length === 1) { - const child = subtree.children[0]; - const newName = _chalk2.default.dim(_path2.default.join(dir.toString(), child.name)); - children.push({ - children: child.children, - name: newName - }); - continue; - } - children.push({ - children: subtree.children, - name: _chalk2.default.dim(dir.toString()) - }); + let name; + const children = []; + + for (const [dir, project] of tree.entries()) { + // This is a leaf node (aka a project) + if (typeof project === 'string') { + name = chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green(project); + continue; + } // If there's only one project and the key indicates it's a leaf node, we + // know that we're at a package folder that contains a package.json, so we + // "inline it" so we don't get unnecessary levels, i.e. we'll just see + // `foo` instead of `foo -> foo`. + + + if (project.size === 1 && project.has(projectKey)) { + const projectName = project.get(projectKey); + children.push({ + children: [], + name: dirOrProjectName(dir, projectName) + }); + continue; + } + + const subtree = createTreeStructure(project); // If the name is specified, we know there's a package at the "root" of the + // subtree itself. + + if (subtree.name !== undefined) { + const projectName = subtree.name; + children.push({ + children: subtree.children, + name: dirOrProjectName(dir, projectName) + }); + continue; + } // Special-case whenever we have one child, so we don't get unnecessary + // folders in the output. E.g. instead of `foo -> bar -> baz` we get + // `foo/bar/baz` instead. + + + if (subtree.children && subtree.children.length === 1) { + const child = subtree.children[0]; + const newName = chalk__WEBPACK_IMPORTED_MODULE_0___default.a.dim(path__WEBPACK_IMPORTED_MODULE_1___default.a.join(dir.toString(), child.name)); + children.push({ + children: child.children, + name: newName + }); + continue; } - return { name, children }; + + children.push({ + children: subtree.children, + name: chalk__WEBPACK_IMPORTED_MODULE_0___default.a.dim(dir.toString()) + }); + } + + return { + name, + children + }; } + function dirOrProjectName(dir, projectName) { - return dir === projectName ? _chalk2.default.green(dir) : _chalk2.default`{dim ${dir.toString()} ({reset.green ${projectName}})}`; + return dir === projectName ? chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green(dir) : chalk__WEBPACK_IMPORTED_MODULE_0___default.a`{dim ${dir.toString()} ({reset.green ${projectName}})}`; } + function buildProjectsTree(rootPath, projects) { - const tree = new Map(); - for (const project of projects.values()) { - if (rootPath === project.path) { - tree.set(projectKey, project.name); - } else { - const relativeProjectPath = _path2.default.relative(rootPath, project.path); - addProjectToTree(tree, relativeProjectPath.split(_path2.default.sep), project); - } + const tree = new Map(); + + for (const project of projects.values()) { + if (rootPath === project.path) { + tree.set(projectKey, project.name); + } else { + const relativeProjectPath = path__WEBPACK_IMPORTED_MODULE_1___default.a.relative(rootPath, project.path); + addProjectToTree(tree, relativeProjectPath.split(path__WEBPACK_IMPORTED_MODULE_1___default.a.sep), project); } - return tree; + } + + return tree; } + function addProjectToTree(tree, pathParts, project) { - if (pathParts.length === 0) { - tree.set(projectKey, project.name); - } else { - const [currentDir, ...rest] = pathParts; - if (!tree.has(currentDir)) { - tree.set(currentDir, new Map()); - } - const subtree = tree.get(currentDir); - addProjectToTree(subtree, rest, project); + if (pathParts.length === 0) { + tree.set(projectKey, project.name); + } else { + const [currentDir, ...rest] = pathParts; + + if (!tree.has(currentDir)) { + tree.set(currentDir, new Map()); } + + const subtree = tree.get(currentDir); + addProjectToTree(subtree, rest, project); + } } /***/ }), /* 367 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _build_production_projects__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(368); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return _build_production_projects__WEBPACK_IMPORTED_MODULE_0__["buildProductionProjects"]; }); +/* harmony import */ var _prepare_project_dependencies__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(547); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "prepareExternalProjectDependencies", function() { return _prepare_project_dependencies__WEBPACK_IMPORTED_MODULE_1__["prepareExternalProjectDependencies"]; }); -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _build_production_projects = __webpack_require__(368); - -Object.defineProperty(exports, 'buildProductionProjects', { - enumerable: true, - get: function () { - return _build_production_projects.buildProductionProjects; - } -}); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -var _prepare_project_dependencies = __webpack_require__(585); -Object.defineProperty(exports, 'prepareExternalProjectDependencies', { - enumerable: true, - get: function () { - return _prepare_project_dependencies.prepareExternalProjectDependencies; - } -}); /***/ }), /* 368 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return buildProductionProjects; }); +/* harmony import */ var cpy__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(369); +/* harmony import */ var cpy__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(cpy__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(134); +/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(del__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(16); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(132); +/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(20); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(33); +/* harmony import */ var _utils_package_json__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(54); +/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(35); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.buildProductionProjects = undefined; - -let buildProductionProjects = exports.buildProductionProjects = (() => { - var _ref = _asyncToGenerator(function* ({ kibanaRoot, buildRoots }) { - const projects = yield getProductionProjects(kibanaRoot); - const projectGraph = (0, _projects.buildProjectGraph)(projects); - const batchedProjects = (0, _projects.topologicallyBatchProjects)(projects, projectGraph); - const projectNames = [...projects.values()].map(function (project) { - return project.name; - }); - _log.log.write(`Preparing production build for [${projectNames.join(', ')}]`); - for (const batch of batchedProjects) { - for (const project of batch) { - yield deleteTarget(project); - yield buildProject(project); - for (const buildRoot of buildRoots) { - yield copyToBuild(project, kibanaRoot, buildRoot); - } - } - } - }); - return function buildProductionProjects(_x) { - return _ref.apply(this, arguments); - }; -})(); + + + + + +async function buildProductionProjects({ + kibanaRoot, + buildRoots +}) { + const projects = await getProductionProjects(kibanaRoot); + const projectGraph = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_7__["buildProjectGraph"])(projects); + const batchedProjects = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_7__["topologicallyBatchProjects"])(projects, projectGraph); + const projectNames = [...projects.values()].map(project => project.name); + _utils_log__WEBPACK_IMPORTED_MODULE_5__["log"].write(`Preparing production build for [${projectNames.join(', ')}]`); + + for (const batch of batchedProjects) { + for (const project of batch) { + await deleteTarget(project); + await buildProject(project); + + for (const buildRoot of buildRoots) { + await copyToBuild(project, kibanaRoot, buildRoot); + } + } + } +} /** * Returns the subset of projects that should be built into the production * bundle. As we copy these into Kibana's `node_modules` during the build step, @@ -31813,48 +31739,32 @@ let buildProductionProjects = exports.buildProductionProjects = (() => { * we only include Kibana's transitive _production_ dependencies. */ +async function getProductionProjects(rootPath) { + const projectPaths = Object(_config__WEBPACK_IMPORTED_MODULE_3__["getProjectPaths"])(rootPath, {}); + const projects = await Object(_utils_projects__WEBPACK_IMPORTED_MODULE_7__["getProjects"])(rootPath, projectPaths); + const productionProjects = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_7__["includeTransitiveProjects"])([projects.get('kibana')], projects, { + onlyProductionDependencies: true + }); // We remove Kibana, as we're already building Kibana -let getProductionProjects = (() => { - var _ref2 = _asyncToGenerator(function* (rootPath) { - const projectPaths = (0, _config.getProjectPaths)(rootPath, {}); - const projects = yield (0, _projects.getProjects)(rootPath, projectPaths); - const productionProjects = (0, _projects.includeTransitiveProjects)([projects.get('kibana')], projects, { - onlyProductionDependencies: true - }); - // We remove Kibana, as we're already building Kibana - productionProjects.delete('kibana'); - return productionProjects; - }); - - return function getProductionProjects(_x2) { - return _ref2.apply(this, arguments); - }; -})(); - -let deleteTarget = (() => { - var _ref3 = _asyncToGenerator(function* (project) { - const targetDir = project.targetLocation; - if (yield (0, _fs.isDirectory)(targetDir)) { - yield (0, _del2.default)(targetDir, { force: true }); - } - }); + productionProjects.delete('kibana'); + return productionProjects; +} - return function deleteTarget(_x3) { - return _ref3.apply(this, arguments); - }; -})(); +async function deleteTarget(project) { + const targetDir = project.targetLocation; -let buildProject = (() => { - var _ref4 = _asyncToGenerator(function* (project) { - if (project.hasScript('build')) { - yield project.runScript('build'); - } + if (await Object(_utils_fs__WEBPACK_IMPORTED_MODULE_4__["isDirectory"])(targetDir)) { + await del__WEBPACK_IMPORTED_MODULE_1___default()(targetDir, { + force: true }); + } +} - return function buildProject(_x4) { - return _ref4.apply(this, arguments); - }; -})(); +async function buildProject(project) { + if (project.hasScript('build')) { + await project.runScript('build'); + } +} /** * Copy all the project's files from its "intermediate build directory" and * into the build. The intermediate directory can either be the root of the @@ -31868,73 +31778,26 @@ let buildProject = (() => { */ -let copyToBuild = (() => { - var _ref5 = _asyncToGenerator(function* (project, kibanaRoot, buildRoot) { - // We want the package to have the same relative location within the build - const relativeProjectPath = (0, _path.relative)(kibanaRoot, project.path); - const buildProjectPath = (0, _path.resolve)(buildRoot, relativeProjectPath); - yield (0, _cpy2.default)(['**/*', '!node_modules/**'], buildProjectPath, { - cwd: project.getIntermediateBuildDirectory(), - dot: true, - nodir: true, - parents: true - }); - // If a project is using an intermediate build directory, we special-case our - // handling of `package.json`, as the project build process might have copied - // (a potentially modified) `package.json` into the intermediate build - // directory already. If so, we want to use that `package.json` as the basis - // for creating the production-ready `package.json`. If it's not present in - // the intermediate build, we fall back to using the project's already defined - // `package.json`. - const packageJson = (yield (0, _fs.isFile)((0, _path.join)(buildProjectPath, 'package.json'))) ? yield (0, _package_json.readPackageJson)(buildProjectPath) : project.json; - yield (0, _package_json.writePackageJson)(buildProjectPath, packageJson); - }); - - return function copyToBuild(_x5, _x6, _x7) { - return _ref5.apply(this, arguments); - }; -})(); - -var _cpy = __webpack_require__(369); - -var _cpy2 = _interopRequireDefault(_cpy); - -var _del = __webpack_require__(134); - -var _del2 = _interopRequireDefault(_del); - -var _path = __webpack_require__(16); - -var _config = __webpack_require__(132); - -var _fs = __webpack_require__(20); - -var _log = __webpack_require__(33); - -var _package_json = __webpack_require__(54); - -var _projects = __webpack_require__(35); +async function copyToBuild(project, kibanaRoot, buildRoot) { + // We want the package to have the same relative location within the build + const relativeProjectPath = Object(path__WEBPACK_IMPORTED_MODULE_2__["relative"])(kibanaRoot, project.path); + const buildProjectPath = Object(path__WEBPACK_IMPORTED_MODULE_2__["resolve"])(buildRoot, relativeProjectPath); + await cpy__WEBPACK_IMPORTED_MODULE_0___default()(['**/*', '!node_modules/**'], buildProjectPath, { + cwd: project.getIntermediateBuildDirectory(), + dot: true, + nodir: true, + parents: true + }); // If a project is using an intermediate build directory, we special-case our + // handling of `package.json`, as the project build process might have copied + // (a potentially modified) `package.json` into the intermediate build + // directory already. If so, we want to use that `package.json` as the basis + // for creating the production-ready `package.json`. If it's not present in + // the intermediate build, we fall back to using the project's already defined + // `package.json`. -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ + const packageJson = (await Object(_utils_fs__WEBPACK_IMPORTED_MODULE_4__["isFile"])(Object(path__WEBPACK_IMPORTED_MODULE_2__["join"])(buildProjectPath, 'package.json'))) ? await Object(_utils_package_json__WEBPACK_IMPORTED_MODULE_6__["readPackageJson"])(buildProjectPath) : project.json; + await Object(_utils_package_json__WEBPACK_IMPORTED_MODULE_6__["writePackageJson"])(buildProjectPath, packageJson); +} /***/ }), /* 369 */ @@ -31946,8 +31809,8 @@ const EventEmitter = __webpack_require__(45); const path = __webpack_require__(16); const arrify = __webpack_require__(370); const globby = __webpack_require__(371); -const cpFile = __webpack_require__(577); -const CpyError = __webpack_require__(584); +const cpFile = __webpack_require__(539); +const CpyError = __webpack_require__(546); const preprocessSrcPath = (srcPath, options) => options.cwd ? path.resolve(options.cwd, srcPath) : srcPath; @@ -32069,8 +31932,8 @@ module.exports = function (val) { const arrayUnion = __webpack_require__(138); const glob = __webpack_require__(36); const fastGlob = __webpack_require__(372); -const dirGlob = __webpack_require__(573); -const gitignore = __webpack_require__(574); +const dirGlob = __webpack_require__(535); +const gitignore = __webpack_require__(536); const DEFAULT_FILTER = () => false; @@ -32219,10 +32082,10 @@ Object.defineProperty(exports, "__esModule", { value: true }); var merge2 = __webpack_require__(374); var optionsManager = __webpack_require__(375); var taskManager = __webpack_require__(376); -var reader_async_1 = __webpack_require__(552); -var reader_stream_1 = __webpack_require__(571); -var reader_sync_1 = __webpack_require__(572); -var arrayUtils = __webpack_require__(568); +var reader_async_1 = __webpack_require__(514); +var reader_stream_1 = __webpack_require__(533); +var reader_sync_1 = __webpack_require__(534); +var arrayUtils = __webpack_require__(530); /** * Returns a set of works based on provided tasks and class of the reader. */ @@ -32948,10 +32811,10 @@ var extend = __webpack_require__(394); * Local dependencies */ -var compilers = __webpack_require__(520); -var parsers = __webpack_require__(548); -var cache = __webpack_require__(549); -var utils = __webpack_require__(550); +var compilers = __webpack_require__(488); +var parsers = __webpack_require__(510); +var cache = __webpack_require__(511); +var utils = __webpack_require__(512); var MAX_LENGTH = 1024 * 64; /** @@ -33828,16 +33691,15 @@ module.exports = micromatch; var toRegex = __webpack_require__(385); var unique = __webpack_require__(397); var extend = __webpack_require__(394); -var define = __webpack_require__(398); /** * Local dependencies */ -var compilers = __webpack_require__(405); -var parsers = __webpack_require__(420); +var compilers = __webpack_require__(398); +var parsers = __webpack_require__(413); var Braces = __webpack_require__(423); -var utils = __webpack_require__(406); +var utils = __webpack_require__(399); var MAX_LENGTH = 1024 * 64; var cache = {}; @@ -33940,8 +33802,9 @@ braces.create = function(pattern, options) { throw new TypeError('expected a string'); } - if (pattern.length >= MAX_LENGTH) { - throw new Error('expected pattern to be less than ' + MAX_LENGTH + ' characters'); + var maxLength = (options && options.maxLength) || MAX_LENGTH; + if (pattern.length >= maxLength) { + throw new Error('expected pattern to be less than ' + maxLength + ' characters'); } function create() { @@ -33975,7 +33838,11 @@ braces.create = function(pattern, options) { arr = unique(arr); } - define(arr, 'result', result); + Object.defineProperty(arr, 'result', { + enumerable: false, + value: result + }); + return arr; } @@ -34002,8 +33869,9 @@ braces.makeRe = function(pattern, options) { throw new TypeError('expected a string'); } - if (pattern.length >= MAX_LENGTH) { - throw new Error('expected pattern to be less than ' + MAX_LENGTH + ' characters'); + var maxLength = (options && options.maxLength) || MAX_LENGTH; + if (pattern.length >= maxLength) { + throw new Error('expected pattern to be less than ' + maxLength + ' characters'); } function makeRe() { @@ -35106,1234 +34974,1043 @@ module.exports.immutable = function uniqueImmutable(arr) { /***/ (function(module, exports, __webpack_require__) { "use strict"; -/*! - * define-property - * - * Copyright (c) 2015, 2017, Jon Schlinkert. - * Released under the MIT License. - */ +var utils = __webpack_require__(399); -var isDescriptor = __webpack_require__(399); +module.exports = function(braces, options) { + braces.compiler -module.exports = function defineProperty(obj, prop, val) { - if (typeof obj !== 'object' && typeof obj !== 'function') { - throw new TypeError('expected an object or function.'); - } + /** + * bos + */ - if (typeof prop !== 'string') { - throw new TypeError('expected `prop` to be a string.'); - } + .set('bos', function() { + if (this.output) return; + this.ast.queue = isEscaped(this.ast) ? [this.ast.val] : []; + this.ast.count = 1; + }) - if (isDescriptor(val) && ('set' in val || 'get' in val)) { - return Object.defineProperty(obj, prop, val); - } + /** + * Square brackets + */ - return Object.defineProperty(obj, prop, { - configurable: true, - enumerable: false, - writable: true, - value: val - }); -}; + .set('bracket', function(node) { + var close = node.close; + var open = !node.escaped ? '[' : '\\['; + var negated = node.negated; + var inner = node.inner; + inner = inner.replace(/\\(?=[\\\w]|$)/g, '\\\\'); + if (inner === ']-') { + inner = '\\]\\-'; + } -/***/ }), -/* 399 */ -/***/ (function(module, exports, __webpack_require__) { + if (negated && inner.indexOf('.') === -1) { + inner += '.'; + } + if (negated && inner.indexOf('/') === -1) { + inner += '/'; + } -"use strict"; -/*! - * is-descriptor - * - * Copyright (c) 2015-2017, Jon Schlinkert. - * Released under the MIT License. - */ + var val = open + negated + inner + close; + var queue = node.parent.queue; + var last = utils.arrayify(queue.pop()); + queue.push(utils.join(last, val)); + queue.push.apply(queue, []); + }) + /** + * Brace + */ -var typeOf = __webpack_require__(400); -var isAccessor = __webpack_require__(401); -var isData = __webpack_require__(403); + .set('brace', function(node) { + node.queue = isEscaped(node) ? [node.val] : []; + node.count = 1; + return this.mapVisit(node.nodes); + }) -module.exports = function isDescriptor(obj, key) { - if (typeOf(obj) !== 'object') { - return false; - } - if ('get' in obj) { - return isAccessor(obj, key); - } - return isData(obj, key); -}; + /** + * Open + */ + .set('brace.open', function(node) { + node.parent.open = node.val; + }) -/***/ }), -/* 400 */ -/***/ (function(module, exports) { + /** + * Inner + */ -var toString = Object.prototype.toString; + .set('text', function(node) { + var queue = node.parent.queue; + var escaped = node.escaped; + var segs = [node.val]; -module.exports = function kindOf(val) { - if (val === void 0) return 'undefined'; - if (val === null) return 'null'; + if (node.optimize === false) { + options = utils.extend({}, options, {optimize: false}); + } - var type = typeof val; - if (type === 'boolean') return 'boolean'; - if (type === 'string') return 'string'; - if (type === 'number') return 'number'; - if (type === 'symbol') return 'symbol'; - if (type === 'function') { - return isGeneratorFn(val) ? 'generatorfunction' : 'function'; - } + if (node.multiplier > 1) { + node.parent.count *= node.multiplier; + } - if (isArray(val)) return 'array'; - if (isBuffer(val)) return 'buffer'; - if (isArguments(val)) return 'arguments'; - if (isDate(val)) return 'date'; - if (isError(val)) return 'error'; - if (isRegexp(val)) return 'regexp'; + if (options.quantifiers === true && utils.isQuantifier(node.val)) { + escaped = true; - switch (ctorName(val)) { - case 'Symbol': return 'symbol'; - case 'Promise': return 'promise'; + } else if (node.val.length > 1) { + if (isType(node.parent, 'brace') && !isEscaped(node)) { + var expanded = utils.expand(node.val, options); + segs = expanded.segs; - // Set, Map, WeakSet, WeakMap - case 'WeakMap': return 'weakmap'; - case 'WeakSet': return 'weakset'; - case 'Map': return 'map'; - case 'Set': return 'set'; + if (expanded.isOptimized) { + node.parent.isOptimized = true; + } - // 8-bit typed arrays - case 'Int8Array': return 'int8array'; - case 'Uint8Array': return 'uint8array'; - case 'Uint8ClampedArray': return 'uint8clampedarray'; + // if nothing was expanded, we probably have a literal brace + if (!segs.length) { + var val = (expanded.val || node.val); + if (options.unescape !== false) { + // unescape unexpanded brace sequence/set separators + val = val.replace(/\\([,.])/g, '$1'); + // strip quotes + val = val.replace(/["'`]/g, ''); + } - // 16-bit typed arrays - case 'Int16Array': return 'int16array'; - case 'Uint16Array': return 'uint16array'; + segs = [val]; + escaped = true; + } + } - // 32-bit typed arrays - case 'Int32Array': return 'int32array'; - case 'Uint32Array': return 'uint32array'; - case 'Float32Array': return 'float32array'; - case 'Float64Array': return 'float64array'; - } + } else if (node.val === ',') { + if (options.expand) { + node.parent.queue.push(['']); + segs = ['']; + } else { + segs = ['|']; + } + } else { + escaped = true; + } - if (isGeneratorObj(val)) { - return 'generator'; - } + if (escaped && isType(node.parent, 'brace')) { + if (node.parent.nodes.length <= 4 && node.parent.count === 1) { + node.parent.escaped = true; + } else if (node.parent.length <= 3) { + node.parent.escaped = true; + } + } - // Non-plain objects - type = toString.call(val); - switch (type) { - case '[object Object]': return 'object'; - // iterators - case '[object Map Iterator]': return 'mapiterator'; - case '[object Set Iterator]': return 'setiterator'; - case '[object String Iterator]': return 'stringiterator'; - case '[object Array Iterator]': return 'arrayiterator'; - } + if (!hasQueue(node.parent)) { + node.parent.queue = segs; + return; + } - // other - return type.slice(8, -1).toLowerCase().replace(/\s/g, ''); -}; + var last = utils.arrayify(queue.pop()); + if (node.parent.count > 1 && options.expand) { + last = multiply(last, node.parent.count); + node.parent.count = 1; + } -function ctorName(val) { - return val.constructor ? val.constructor.name : null; -} + queue.push(utils.join(utils.flatten(last), segs.shift())); + queue.push.apply(queue, segs); + }) -function isArray(val) { - if (Array.isArray) return Array.isArray(val); - return val instanceof Array; -} + /** + * Close + */ -function isError(val) { - return val instanceof Error || (typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number'); -} + .set('brace.close', function(node) { + var queue = node.parent.queue; + var prev = node.parent.parent; + var last = prev.queue.pop(); + var open = node.parent.open; + var close = node.val; -function isDate(val) { - if (val instanceof Date) return true; - return typeof val.toDateString === 'function' - && typeof val.getDate === 'function' - && typeof val.setDate === 'function'; -} + if (open && close && isOptimized(node, options)) { + open = '('; + close = ')'; + } -function isRegexp(val) { - if (val instanceof RegExp) return true; - return typeof val.flags === 'string' - && typeof val.ignoreCase === 'boolean' - && typeof val.multiline === 'boolean' - && typeof val.global === 'boolean'; -} + // if a close brace exists, and the previous segment is one character + // don't wrap the result in braces or parens + var ele = utils.last(queue); + if (node.parent.count > 1 && options.expand) { + ele = multiply(queue.pop(), node.parent.count); + node.parent.count = 1; + queue.push(ele); + } -function isGeneratorFn(name, val) { - return ctorName(name) === 'GeneratorFunction'; -} + if (close && typeof ele === 'string' && ele.length === 1) { + open = ''; + close = ''; + } -function isGeneratorObj(val) { - return typeof val.throw === 'function' - && typeof val.return === 'function' - && typeof val.next === 'function'; -} + if ((isLiteralBrace(node, options) || noInner(node)) && !node.parent.hasEmpty) { + queue.push(utils.join(open, queue.pop() || '')); + queue = utils.flatten(utils.join(queue, close)); + } -function isArguments(val) { - try { - if (typeof val.length === 'number' && typeof val.callee === 'function') { - return true; - } - } catch (err) { - if (err.message.indexOf('callee') !== -1) { - return true; - } - } - return false; -} + if (typeof last === 'undefined') { + prev.queue = [queue]; + } else { + prev.queue.push(utils.flatten(utils.join(last, queue))); + } + }) -/** - * If you need to support Safari 5-7 (8-10 yr-old browser), - * take a look at https://github.com/feross/is-buffer - */ + /** + * eos + */ -function isBuffer(val) { - if (val.constructor && typeof val.constructor.isBuffer === 'function') { - return val.constructor.isBuffer(val); - } - return false; -} + .set('eos', function(node) { + if (this.input) return; + if (options.optimize !== false) { + this.output = utils.last(utils.flatten(this.ast.queue)); + } else if (Array.isArray(utils.last(this.ast.queue))) { + this.output = utils.flatten(this.ast.queue.pop()); + } else { + this.output = utils.flatten(this.ast.queue); + } -/***/ }), -/* 401 */ -/***/ (function(module, exports, __webpack_require__) { + if (node.parent.count > 1 && options.expand) { + this.output = multiply(this.output, node.parent.count); + } -"use strict"; -/*! - * is-accessor-descriptor - * - * Copyright (c) 2015-2017, Jon Schlinkert. - * Released under the MIT License. - */ + this.output = utils.arrayify(this.output); + this.ast.queue = []; + }); +}; +/** + * Multiply the segments in the current brace level + */ -var typeOf = __webpack_require__(402); - -// accessor descriptor properties -var accessor = { - get: 'function', - set: 'function', - configurable: 'boolean', - enumerable: 'boolean' -}; +function multiply(queue, n, options) { + return utils.flatten(utils.repeat(utils.arrayify(queue), n)); +} -function isAccessorDescriptor(obj, prop) { - if (typeof prop === 'string') { - var val = Object.getOwnPropertyDescriptor(obj, prop); - return typeof val !== 'undefined'; - } +/** + * Return true if `node` is escaped + */ - if (typeOf(obj) !== 'object') { - return false; - } +function isEscaped(node) { + return node.escaped === true; +} - if (has(obj, 'value') || has(obj, 'writable')) { - return false; - } +/** + * Returns true if regex parens should be used for sets. If the parent `type` + * is not `brace`, then we're on a root node, which means we should never + * expand segments and open/close braces should be `{}` (since this indicates + * a brace is missing from the set) + */ - if (!has(obj, 'get') || typeof obj.get !== 'function') { - return false; - } +function isOptimized(node, options) { + if (node.parent.isOptimized) return true; + return isType(node.parent, 'brace') + && !isEscaped(node.parent) + && options.expand !== true; +} - // tldr: it's valid to have "set" be undefined - // "set" might be undefined if `Object.getOwnPropertyDescriptor` - // was used to get the value, and only `get` was defined by the user - if (has(obj, 'set') && typeof obj[key] !== 'function' && typeof obj[key] !== 'undefined') { - return false; - } +/** + * Returns true if the value in `node` should be wrapped in a literal brace. + * @return {Boolean} + */ - for (var key in obj) { - if (!accessor.hasOwnProperty(key)) { - continue; - } +function isLiteralBrace(node, options) { + return isEscaped(node.parent) || options.optimize !== false; +} - if (typeOf(obj[key]) === accessor[key]) { - continue; - } +/** + * Returns true if the given `node` does not have an inner value. + * @return {Boolean} + */ - if (typeof obj[key] !== 'undefined') { - return false; - } +function noInner(node, type) { + if (node.parent.queue.length === 1) { + return true; } - return true; + var nodes = node.parent.nodes; + return nodes.length === 3 + && isType(nodes[0], 'brace.open') + && !isType(nodes[1], 'text') + && isType(nodes[2], 'brace.close'); } -function has(obj, key) { - return {}.hasOwnProperty.call(obj, key); +/** + * Returns true if the given `node` is the given `type` + * @return {Boolean} + */ + +function isType(node, type) { + return typeof node !== 'undefined' && node.type === type; } /** - * Expose `isAccessorDescriptor` + * Returns true if the given `node` has a non-empty queue. + * @return {Boolean} */ -module.exports = isAccessorDescriptor; +function hasQueue(node) { + return Array.isArray(node.queue) && node.queue.length; +} /***/ }), -/* 402 */ -/***/ (function(module, exports) { +/* 399 */ +/***/ (function(module, exports, __webpack_require__) { -var toString = Object.prototype.toString; +"use strict"; -module.exports = function kindOf(val) { - if (val === void 0) return 'undefined'; - if (val === null) return 'null'; - var type = typeof val; - if (type === 'boolean') return 'boolean'; - if (type === 'string') return 'string'; - if (type === 'number') return 'number'; - if (type === 'symbol') return 'symbol'; - if (type === 'function') { - return isGeneratorFn(val) ? 'generatorfunction' : 'function'; - } +var splitString = __webpack_require__(400); +var utils = module.exports; - if (isArray(val)) return 'array'; - if (isBuffer(val)) return 'buffer'; - if (isArguments(val)) return 'arguments'; - if (isDate(val)) return 'date'; - if (isError(val)) return 'error'; - if (isRegexp(val)) return 'regexp'; +/** + * Module dependencies + */ - switch (ctorName(val)) { - case 'Symbol': return 'symbol'; - case 'Promise': return 'promise'; +utils.extend = __webpack_require__(394); +utils.flatten = __webpack_require__(406); +utils.isObject = __webpack_require__(404); +utils.fillRange = __webpack_require__(407); +utils.repeat = __webpack_require__(412); +utils.unique = __webpack_require__(397); - // Set, Map, WeakSet, WeakMap - case 'WeakMap': return 'weakmap'; - case 'WeakSet': return 'weakset'; - case 'Map': return 'map'; - case 'Set': return 'set'; +utils.define = function(obj, key, val) { + Object.defineProperty(obj, key, { + writable: true, + configurable: true, + enumerable: false, + value: val + }); +}; - // 8-bit typed arrays - case 'Int8Array': return 'int8array'; - case 'Uint8Array': return 'uint8array'; - case 'Uint8ClampedArray': return 'uint8clampedarray'; +/** + * Returns true if the given string contains only empty brace sets. + */ - // 16-bit typed arrays - case 'Int16Array': return 'int16array'; - case 'Uint16Array': return 'uint16array'; +utils.isEmptySets = function(str) { + return /^(?:\{,\})+$/.test(str); +}; - // 32-bit typed arrays - case 'Int32Array': return 'int32array'; - case 'Uint32Array': return 'uint32array'; - case 'Float32Array': return 'float32array'; - case 'Float64Array': return 'float64array'; - } +/** + * Returns true if the given string contains only empty brace sets. + */ - if (isGeneratorObj(val)) { - return 'generator'; +utils.isQuotedString = function(str) { + var open = str.charAt(0); + if (open === '\'' || open === '"' || open === '`') { + return str.slice(-1) === open; } + return false; +}; - // Non-plain objects - type = toString.call(val); - switch (type) { - case '[object Object]': return 'object'; - // iterators - case '[object Map Iterator]': return 'mapiterator'; - case '[object Set Iterator]': return 'setiterator'; - case '[object String Iterator]': return 'stringiterator'; - case '[object Array Iterator]': return 'arrayiterator'; - } +/** + * Create the key to use for memoization. The unique key is generated + * by iterating over the options and concatenating key-value pairs + * to the pattern string. + */ - // other - return type.slice(8, -1).toLowerCase().replace(/\s/g, ''); +utils.createKey = function(pattern, options) { + var id = pattern; + if (typeof options === 'undefined') { + return id; + } + var keys = Object.keys(options); + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + id += ';' + key + '=' + String(options[key]); + } + return id; }; -function ctorName(val) { - return val.constructor ? val.constructor.name : null; -} - -function isArray(val) { - if (Array.isArray) return Array.isArray(val); - return val instanceof Array; -} +/** + * Normalize options + */ -function isError(val) { - return val instanceof Error || (typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number'); -} +utils.createOptions = function(options) { + var opts = utils.extend.apply(null, arguments); + if (typeof opts.expand === 'boolean') { + opts.optimize = !opts.expand; + } + if (typeof opts.optimize === 'boolean') { + opts.expand = !opts.optimize; + } + if (opts.optimize === true) { + opts.makeRe = true; + } + return opts; +}; -function isDate(val) { - if (val instanceof Date) return true; - return typeof val.toDateString === 'function' - && typeof val.getDate === 'function' - && typeof val.setDate === 'function'; -} +/** + * Join patterns in `a` to patterns in `b` + */ -function isRegexp(val) { - if (val instanceof RegExp) return true; - return typeof val.flags === 'string' - && typeof val.ignoreCase === 'boolean' - && typeof val.multiline === 'boolean' - && typeof val.global === 'boolean'; -} +utils.join = function(a, b, options) { + options = options || {}; + a = utils.arrayify(a); + b = utils.arrayify(b); -function isGeneratorFn(name, val) { - return ctorName(name) === 'GeneratorFunction'; -} + if (!a.length) return b; + if (!b.length) return a; -function isGeneratorObj(val) { - return typeof val.throw === 'function' - && typeof val.return === 'function' - && typeof val.next === 'function'; -} + var len = a.length; + var idx = -1; + var arr = []; -function isArguments(val) { - try { - if (typeof val.length === 'number' && typeof val.callee === 'function') { - return true; + while (++idx < len) { + var val = a[idx]; + if (Array.isArray(val)) { + for (var i = 0; i < val.length; i++) { + val[i] = utils.join(val[i], b, options); + } + arr.push(val); + continue; } - } catch (err) { - if (err.message.indexOf('callee') !== -1) { - return true; + + for (var j = 0; j < b.length; j++) { + var bval = b[j]; + + if (Array.isArray(bval)) { + arr.push(utils.join(val, bval, options)); + } else { + arr.push(val + bval); + } } } - return false; -} + return arr; +}; /** - * If you need to support Safari 5-7 (8-10 yr-old browser), - * take a look at https://github.com/feross/is-buffer + * Split the given string on `,` if not escaped. */ -function isBuffer(val) { - if (val.constructor && typeof val.constructor.isBuffer === 'function') { - return val.constructor.isBuffer(val); +utils.split = function(str, options) { + var opts = utils.extend({sep: ','}, options); + if (typeof opts.keepQuotes !== 'boolean') { + opts.keepQuotes = true; } - return false; -} - - -/***/ }), -/* 403 */ -/***/ (function(module, exports, __webpack_require__) { + if (opts.unescape === false) { + opts.keepEscaping = true; + } + return splitString(str, opts, utils.escapeBrackets(opts)); +}; -"use strict"; -/*! - * is-data-descriptor +/** + * Expand ranges or sets in the given `pattern`. * - * Copyright (c) 2015-2017, Jon Schlinkert. - * Released under the MIT License. + * @param {String} `str` + * @param {Object} `options` + * @return {Object} */ +utils.expand = function(str, options) { + var opts = utils.extend({rangeLimit: 10000}, options); + var segs = utils.split(str, opts); + var tok = { segs: segs }; - -var typeOf = __webpack_require__(404); - -module.exports = function isDataDescriptor(obj, prop) { - // data descriptor properties - var data = { - configurable: 'boolean', - enumerable: 'boolean', - writable: 'boolean' - }; - - if (typeOf(obj) !== 'object') { - return false; - } - - if (typeof prop === 'string') { - var val = Object.getOwnPropertyDescriptor(obj, prop); - return typeof val !== 'undefined'; + if (utils.isQuotedString(str)) { + return tok; } - if (!('value' in obj) && !('writable' in obj)) { - return false; + if (opts.rangeLimit === true) { + opts.rangeLimit = 10000; } - for (var key in obj) { - if (key === 'value') continue; - - if (!data.hasOwnProperty(key)) { - continue; + if (segs.length > 1) { + if (opts.optimize === false) { + tok.val = segs[0]; + return tok; } - if (typeOf(obj[key]) === data[key]) { - continue; + tok.segs = utils.stringifyArray(tok.segs); + } else if (segs.length === 1) { + var arr = str.split('..'); + + if (arr.length === 1) { + tok.val = tok.segs[tok.segs.length - 1] || tok.val || str; + tok.segs = []; + return tok; } - if (typeof obj[key] !== 'undefined') { - return false; + if (arr.length === 2 && arr[0] === arr[1]) { + tok.escaped = true; + tok.val = arr[0]; + tok.segs = []; + return tok; } - } - return true; -}; + if (arr.length > 1) { + if (opts.optimize !== false) { + opts.optimize = true; + delete opts.expand; + } -/***/ }), -/* 404 */ -/***/ (function(module, exports) { + if (opts.optimize !== true) { + var min = Math.min(arr[0], arr[1]); + var max = Math.max(arr[0], arr[1]); + var step = arr[2] || 1; -var toString = Object.prototype.toString; + if (opts.rangeLimit !== false && ((max - min) / step >= opts.rangeLimit)) { + throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.'); + } + } -module.exports = function kindOf(val) { - if (val === void 0) return 'undefined'; - if (val === null) return 'null'; + arr.push(opts); + tok.segs = utils.fillRange.apply(null, arr); - var type = typeof val; - if (type === 'boolean') return 'boolean'; - if (type === 'string') return 'string'; - if (type === 'number') return 'number'; - if (type === 'symbol') return 'symbol'; - if (type === 'function') { - return isGeneratorFn(val) ? 'generatorfunction' : 'function'; - } + if (!tok.segs.length) { + tok.escaped = true; + tok.val = str; + return tok; + } - if (isArray(val)) return 'array'; - if (isBuffer(val)) return 'buffer'; - if (isArguments(val)) return 'arguments'; - if (isDate(val)) return 'date'; - if (isError(val)) return 'error'; - if (isRegexp(val)) return 'regexp'; + if (opts.optimize === true) { + tok.segs = utils.stringifyArray(tok.segs); + } - switch (ctorName(val)) { - case 'Symbol': return 'symbol'; - case 'Promise': return 'promise'; + if (tok.segs === '') { + tok.val = str; + } else { + tok.val = tok.segs[0]; + } + return tok; + } + } else { + tok.val = str; + } + return tok; +}; - // Set, Map, WeakSet, WeakMap - case 'WeakMap': return 'weakmap'; - case 'WeakSet': return 'weakset'; - case 'Map': return 'map'; - case 'Set': return 'set'; +/** + * Ensure commas inside brackets and parens are not split. + * @param {Object} `tok` Token from the `split-string` module + * @return {undefined} + */ - // 8-bit typed arrays - case 'Int8Array': return 'int8array'; - case 'Uint8Array': return 'uint8array'; - case 'Uint8ClampedArray': return 'uint8clampedarray'; +utils.escapeBrackets = function(options) { + return function(tok) { + if (tok.escaped && tok.val === 'b') { + tok.val = '\\b'; + return; + } - // 16-bit typed arrays - case 'Int16Array': return 'int16array'; - case 'Uint16Array': return 'uint16array'; + if (tok.val !== '(' && tok.val !== '[') return; + var opts = utils.extend({}, options); + var brackets = []; + var parens = []; + var stack = []; + var val = tok.val; + var str = tok.str; + var i = tok.idx - 1; - // 32-bit typed arrays - case 'Int32Array': return 'int32array'; - case 'Uint32Array': return 'uint32array'; - case 'Float32Array': return 'float32array'; - case 'Float64Array': return 'float64array'; - } + while (++i < str.length) { + var ch = str[i]; - if (isGeneratorObj(val)) { - return 'generator'; - } + if (ch === '\\') { + val += (opts.keepEscaping === false ? '' : ch) + str[++i]; + continue; + } - // Non-plain objects - type = toString.call(val); - switch (type) { - case '[object Object]': return 'object'; - // iterators - case '[object Map Iterator]': return 'mapiterator'; - case '[object Set Iterator]': return 'setiterator'; - case '[object String Iterator]': return 'stringiterator'; - case '[object Array Iterator]': return 'arrayiterator'; - } + if (ch === '(') { + parens.push(ch); + stack.push(ch); + } - // other - return type.slice(8, -1).toLowerCase().replace(/\s/g, ''); -}; + if (ch === '[') { + brackets.push(ch); + stack.push(ch); + } -function ctorName(val) { - return val.constructor ? val.constructor.name : null; -} + if (ch === ')') { + parens.pop(); + stack.pop(); + if (!stack.length) { + val += ch; + break; + } + } -function isArray(val) { - if (Array.isArray) return Array.isArray(val); - return val instanceof Array; -} - -function isError(val) { - return val instanceof Error || (typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number'); -} + if (ch === ']') { + brackets.pop(); + stack.pop(); + if (!stack.length) { + val += ch; + break; + } + } + val += ch; + } -function isDate(val) { - if (val instanceof Date) return true; - return typeof val.toDateString === 'function' - && typeof val.getDate === 'function' - && typeof val.setDate === 'function'; -} + tok.split = false; + tok.val = val.slice(1); + tok.idx = i; + }; +}; -function isRegexp(val) { - if (val instanceof RegExp) return true; - return typeof val.flags === 'string' - && typeof val.ignoreCase === 'boolean' - && typeof val.multiline === 'boolean' - && typeof val.global === 'boolean'; -} +/** + * Returns true if the given string looks like a regex quantifier + * @return {Boolean} + */ -function isGeneratorFn(name, val) { - return ctorName(name) === 'GeneratorFunction'; -} +utils.isQuantifier = function(str) { + return /^(?:[0-9]?,[0-9]|[0-9],)$/.test(str); +}; -function isGeneratorObj(val) { - return typeof val.throw === 'function' - && typeof val.return === 'function' - && typeof val.next === 'function'; -} +/** + * Cast `val` to an array. + * @param {*} `val` + */ -function isArguments(val) { - try { - if (typeof val.length === 'number' && typeof val.callee === 'function') { - return true; - } - } catch (err) { - if (err.message.indexOf('callee') !== -1) { - return true; - } - } - return false; -} +utils.stringifyArray = function(arr) { + return [utils.arrayify(arr).join('|')]; +}; /** - * If you need to support Safari 5-7 (8-10 yr-old browser), - * take a look at https://github.com/feross/is-buffer + * Cast `val` to an array. + * @param {*} `val` */ -function isBuffer(val) { - if (val.constructor && typeof val.constructor.isBuffer === 'function') { - return val.constructor.isBuffer(val); +utils.arrayify = function(arr) { + if (typeof arr === 'undefined') { + return []; } - return false; -} - - -/***/ }), -/* 405 */ -/***/ (function(module, exports, __webpack_require__) { + if (typeof arr === 'string') { + return [arr]; + } + return arr; +}; -"use strict"; +/** + * Returns true if the given `str` is a non-empty string + * @return {Boolean} + */ +utils.isString = function(str) { + return str != null && typeof str === 'string'; +}; -var utils = __webpack_require__(406); +/** + * Get the last element from `array` + * @param {Array} `array` + * @return {*} + */ -module.exports = function(braces, options) { - braces.compiler +utils.last = function(arr, n) { + return arr[arr.length - (n || 1)]; +}; - /** - * bos - */ +utils.escapeRegex = function(str) { + return str.replace(/\\?([!^*?()[\]{}+?/])/g, '\\$1'); +}; - .set('bos', function() { - if (this.output) return; - this.ast.queue = isEscaped(this.ast) ? [this.ast.val] : []; - this.ast.count = 1; - }) - /** - * Square brackets - */ +/***/ }), +/* 400 */ +/***/ (function(module, exports, __webpack_require__) { - .set('bracket', function(node) { - var close = node.close; - var open = !node.escaped ? '[' : '\\['; - var negated = node.negated; - var inner = node.inner; +"use strict"; +/*! + * split-string + * + * Copyright (c) 2015-2017, Jon Schlinkert. + * Released under the MIT License. + */ - inner = inner.replace(/\\(?=[\\\w]|$)/g, '\\\\'); - if (inner === ']-') { - inner = '\\]\\-'; - } - if (negated && inner.indexOf('.') === -1) { - inner += '.'; - } - if (negated && inner.indexOf('/') === -1) { - inner += '/'; - } - var val = open + negated + inner + close; - var queue = node.parent.queue; - var last = utils.arrayify(queue.pop()); +var extend = __webpack_require__(401); - queue.push(utils.join(last, val)); - queue.push.apply(queue, []); - }) +module.exports = function(str, options, fn) { + if (typeof str !== 'string') { + throw new TypeError('expected a string'); + } - /** - * Brace - */ + if (typeof options === 'function') { + fn = options; + options = null; + } - .set('brace', function(node) { - node.queue = isEscaped(node) ? [node.val] : []; - node.count = 1; - return this.mapVisit(node.nodes); - }) + // allow separator to be defined as a string + if (typeof options === 'string') { + options = { sep: options }; + } - /** - * Open - */ + var opts = extend({sep: '.'}, options); + var quotes = opts.quotes || ['"', "'", '`']; + var brackets; - .set('brace.open', function(node) { - node.parent.open = node.val; - }) + if (opts.brackets === true) { + brackets = { + '<': '>', + '(': ')', + '[': ']', + '{': '}' + }; + } else if (opts.brackets) { + brackets = opts.brackets; + } - /** - * Inner - */ + var tokens = []; + var stack = []; + var arr = ['']; + var sep = opts.sep; + var len = str.length; + var idx = -1; + var closeIdx; - .set('text', function(node) { - var queue = node.parent.queue; - var escaped = node.escaped; - var segs = [node.val]; + function expected() { + if (brackets && stack.length) { + return brackets[stack[stack.length - 1]]; + } + } - if (node.optimize === false) { - options = utils.extend({}, options, {optimize: false}); - } + while (++idx < len) { + var ch = str[idx]; + var next = str[idx + 1]; + var tok = { val: ch, idx: idx, arr: arr, str: str }; + tokens.push(tok); - if (node.multiplier > 1) { - node.parent.count *= node.multiplier; + if (ch === '\\') { + tok.val = keepEscaping(opts, str, idx) === true ? (ch + next) : next; + tok.escaped = true; + if (typeof fn === 'function') { + fn(tok); } + arr[arr.length - 1] += tok.val; + idx++; + continue; + } - if (options.quantifiers === true && utils.isQuantifier(node.val)) { - escaped = true; + if (brackets && brackets[ch]) { + stack.push(ch); + var e = expected(); + var i = idx + 1; - } else if (node.val.length > 1) { - if (isType(node.parent, 'brace') && !isEscaped(node)) { - var expanded = utils.expand(node.val, options); - segs = expanded.segs; + if (str.indexOf(e, i + 1) !== -1) { + while (stack.length && i < len) { + var s = str[++i]; + if (s === '\\') { + s++; + continue; + } - if (expanded.isOptimized) { - node.parent.isOptimized = true; + if (quotes.indexOf(s) !== -1) { + i = getClosingQuote(str, s, i + 1); + continue; } - // if nothing was expanded, we probably have a literal brace - if (!segs.length) { - var val = (expanded.val || node.val); - if (options.unescape !== false) { - // unescape unexpanded brace sequence/set separators - val = val.replace(/\\([,.])/g, '$1'); - // strip quotes - val = val.replace(/["'`]/g, ''); - } + e = expected(); + if (stack.length && str.indexOf(e, i + 1) === -1) { + break; + } - segs = [val]; - escaped = true; + if (brackets[s]) { + stack.push(s); + continue; } - } - } else if (node.val === ',') { - if (options.expand) { - node.parent.queue.push(['']); - segs = ['']; - } else { - segs = ['|']; + if (e === s) { + stack.pop(); + } } - } else { - escaped = true; } - if (escaped && isType(node.parent, 'brace')) { - if (node.parent.nodes.length <= 4 && node.parent.count === 1) { - node.parent.escaped = true; - } else if (node.parent.length <= 3) { - node.parent.escaped = true; - } + closeIdx = i; + if (closeIdx === -1) { + arr[arr.length - 1] += ch; + continue; } - if (!hasQueue(node.parent)) { - node.parent.queue = segs; - return; + ch = str.slice(idx, closeIdx + 1); + tok.val = ch; + tok.idx = idx = closeIdx; + } + + if (quotes.indexOf(ch) !== -1) { + closeIdx = getClosingQuote(str, ch, idx + 1); + if (closeIdx === -1) { + arr[arr.length - 1] += ch; + continue; } - var last = utils.arrayify(queue.pop()); - if (node.parent.count > 1 && options.expand) { - last = multiply(last, node.parent.count); - node.parent.count = 1; + if (keepQuotes(ch, opts) === true) { + ch = str.slice(idx, closeIdx + 1); + } else { + ch = str.slice(idx + 1, closeIdx); } - queue.push(utils.join(utils.flatten(last), segs.shift())); - queue.push.apply(queue, segs); - }) + tok.val = ch; + tok.idx = idx = closeIdx; + } - /** - * Close - */ + if (typeof fn === 'function') { + fn(tok, tokens); + ch = tok.val; + idx = tok.idx; + } - .set('brace.close', function(node) { - var queue = node.parent.queue; - var prev = node.parent.parent; - var last = prev.queue.pop(); - var open = node.parent.open; - var close = node.val; + if (tok.val === sep && tok.split !== false) { + arr.push(''); + continue; + } - if (open && close && isOptimized(node, options)) { - open = '('; - close = ')'; - } + arr[arr.length - 1] += tok.val; + } - // if a close brace exists, and the previous segment is one character - // don't wrap the result in braces or parens - var ele = utils.last(queue); - if (node.parent.count > 1 && options.expand) { - ele = multiply(queue.pop(), node.parent.count); - node.parent.count = 1; - queue.push(ele); - } + return arr; +}; - if (close && typeof ele === 'string' && ele.length === 1) { - open = ''; - close = ''; - } +function getClosingQuote(str, ch, i, brackets) { + var idx = str.indexOf(ch, i); + if (str.charAt(idx - 1) === '\\') { + return getClosingQuote(str, ch, idx + 1); + } + return idx; +} - if ((isLiteralBrace(node, options) || noInner(node)) && !node.parent.hasEmpty) { - queue.push(utils.join(open, queue.pop() || '')); - queue = utils.flatten(utils.join(queue, close)); - } +function keepQuotes(ch, opts) { + if (opts.keepDoubleQuotes === true && ch === '"') return true; + if (opts.keepSingleQuotes === true && ch === "'") return true; + return opts.keepQuotes; +} - if (typeof last === 'undefined') { - prev.queue = [queue]; - } else { - prev.queue.push(utils.flatten(utils.join(last, queue))); - } - }) +function keepEscaping(opts, str, idx) { + if (typeof opts.keepEscaping === 'function') { + return opts.keepEscaping(str, idx); + } + return opts.keepEscaping === true || str[idx + 1] === '\\'; +} - /** - * eos - */ - .set('eos', function(node) { - if (this.input) return; +/***/ }), +/* 401 */ +/***/ (function(module, exports, __webpack_require__) { - if (options.optimize !== false) { - this.output = utils.last(utils.flatten(this.ast.queue)); - } else if (Array.isArray(utils.last(this.ast.queue))) { - this.output = utils.flatten(this.ast.queue.pop()); - } else { - this.output = utils.flatten(this.ast.queue); - } +"use strict"; - if (node.parent.count > 1 && options.expand) { - this.output = multiply(this.output, node.parent.count); - } - this.output = utils.arrayify(this.output); - this.ast.queue = []; - }); +var isExtendable = __webpack_require__(402); +var assignSymbols = __webpack_require__(405); +module.exports = Object.assign || function(obj/*, objects*/) { + if (obj === null || typeof obj === 'undefined') { + throw new TypeError('Cannot convert undefined or null to object'); + } + if (!isObject(obj)) { + obj = {}; + } + for (var i = 1; i < arguments.length; i++) { + var val = arguments[i]; + if (isString(val)) { + val = toObject(val); + } + if (isObject(val)) { + assign(obj, val); + assignSymbols(obj, val); + } + } + return obj; }; -/** - * Multiply the segments in the current brace level - */ - -function multiply(queue, n, options) { - return utils.flatten(utils.repeat(utils.arrayify(queue), n)); -} - -/** - * Return true if `node` is escaped - */ - -function isEscaped(node) { - return node.escaped === true; +function assign(a, b) { + for (var key in b) { + if (hasOwn(b, key)) { + a[key] = b[key]; + } + } } -/** - * Returns true if regex parens should be used for sets. If the parent `type` - * is not `brace`, then we're on a root node, which means we should never - * expand segments and open/close braces should be `{}` (since this indicates - * a brace is missing from the set) - */ - -function isOptimized(node, options) { - if (node.parent.isOptimized) return true; - return isType(node.parent, 'brace') - && !isEscaped(node.parent) - && options.expand !== true; +function isString(val) { + return (val && typeof val === 'string'); } -/** - * Returns true if the value in `node` should be wrapped in a literal brace. - * @return {Boolean} - */ - -function isLiteralBrace(node, options) { - return isEscaped(node.parent) || options.optimize !== false; +function toObject(str) { + var obj = {}; + for (var i in str) { + obj[i] = str[i]; + } + return obj; } -/** - * Returns true if the given `node` does not have an inner value. - * @return {Boolean} - */ - -function noInner(node, type) { - if (node.parent.queue.length === 1) { - return true; - } - var nodes = node.parent.nodes; - return nodes.length === 3 - && isType(nodes[0], 'brace.open') - && !isType(nodes[1], 'text') - && isType(nodes[2], 'brace.close'); +function isObject(val) { + return (val && typeof val === 'object') || isExtendable(val); } /** - * Returns true if the given `node` is the given `type` - * @return {Boolean} + * Returns true if the given `key` is an own property of `obj`. */ -function isType(node, type) { - return typeof node !== 'undefined' && node.type === type; +function hasOwn(obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key); } -/** - * Returns true if the given `node` has a non-empty queue. - * @return {Boolean} - */ - -function hasQueue(node) { - return Array.isArray(node.queue) && node.queue.length; +function isEnum(obj, key) { + return Object.prototype.propertyIsEnumerable.call(obj, key); } /***/ }), -/* 406 */ +/* 402 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - - -var splitString = __webpack_require__(407); -var utils = module.exports; - -/** - * Module dependencies +/*! + * is-extendable + * + * Copyright (c) 2015-2017, Jon Schlinkert. + * Released under the MIT License. */ -utils.define = __webpack_require__(398); -utils.extend = __webpack_require__(394); -utils.flatten = __webpack_require__(413); -utils.isObject = __webpack_require__(411); -utils.fillRange = __webpack_require__(414); -utils.repeat = __webpack_require__(419); -utils.unique = __webpack_require__(397); - -/** - * Returns true if the given string contains only empty brace sets. - */ -utils.isEmptySets = function(str) { - return /^(?:\{,\})+$/.test(str); -}; -/** - * Returns true if the given string contains only empty brace sets. - */ +var isPlainObject = __webpack_require__(403); -utils.isQuotedString = function(str) { - var open = str.charAt(0); - if (open === '\'' || open === '"' || open === '`') { - return str.slice(-1) === open; - } - return false; +module.exports = function isExtendable(val) { + return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); }; -/** - * Create the key to use for memoization. The unique key is generated - * by iterating over the options and concatenating key-value pairs - * to the pattern string. - */ -utils.createKey = function(pattern, options) { - var id = pattern; - if (typeof options === 'undefined') { - return id; - } - var keys = Object.keys(options); - for (var i = 0; i < keys.length; i++) { - var key = keys[i]; - id += ';' + key + '=' + String(options[key]); - } - return id; -}; +/***/ }), +/* 403 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Normalize options +"use strict"; +/*! + * is-plain-object + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. */ -utils.createOptions = function(options) { - var opts = utils.extend.apply(null, arguments); - if (typeof opts.expand === 'boolean') { - opts.optimize = !opts.expand; - } - if (typeof opts.optimize === 'boolean') { - opts.expand = !opts.optimize; - } - if (opts.optimize === true) { - opts.makeRe = true; - } - return opts; -}; -/** - * Join patterns in `a` to patterns in `b` - */ -utils.join = function(a, b, options) { - options = options || {}; - a = utils.arrayify(a); - b = utils.arrayify(b); +var isObject = __webpack_require__(404); - if (!a.length) return b; - if (!b.length) return a; +function isObjectObject(o) { + return isObject(o) === true + && Object.prototype.toString.call(o) === '[object Object]'; +} - var len = a.length; - var idx = -1; - var arr = []; +module.exports = function isPlainObject(o) { + var ctor,prot; - while (++idx < len) { - var val = a[idx]; - if (Array.isArray(val)) { - for (var i = 0; i < val.length; i++) { - val[i] = utils.join(val[i], b, options); - } - arr.push(val); - continue; - } + if (isObjectObject(o) === false) return false; - for (var j = 0; j < b.length; j++) { - var bval = b[j]; + // If has modified constructor + ctor = o.constructor; + if (typeof ctor !== 'function') return false; - if (Array.isArray(bval)) { - arr.push(utils.join(val, bval, options)); - } else { - arr.push(val + bval); - } - } + // If has modified prototype + prot = ctor.prototype; + if (isObjectObject(prot) === false) return false; + + // If constructor does not have an Object-specific method + if (prot.hasOwnProperty('isPrototypeOf') === false) { + return false; } - return arr; + + // Most likely a plain Object + return true; }; -/** - * Split the given string on `,` if not escaped. - */ -utils.split = function(str, options) { - var opts = utils.extend({sep: ','}, options); - if (typeof opts.keepQuotes !== 'boolean') { - opts.keepQuotes = true; - } - if (opts.unescape === false) { - opts.keepEscaping = true; - } - return splitString(str, opts, utils.escapeBrackets(opts)); -}; +/***/ }), +/* 404 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Expand ranges or sets in the given `pattern`. +"use strict"; +/*! + * isobject * - * @param {String} `str` - * @param {Object} `options` - * @return {Object} + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. */ -utils.expand = function(str, options) { - var opts = utils.extend({rangeLimit: 10000}, options); - var segs = utils.split(str, opts); - var tok = { segs: segs }; - - if (utils.isQuotedString(str)) { - return tok; - } - - if (opts.rangeLimit === true) { - opts.rangeLimit = 10000; - } - - if (segs.length > 1) { - if (opts.optimize === false) { - tok.val = segs[0]; - return tok; - } - - tok.segs = utils.stringifyArray(tok.segs); - } else if (segs.length === 1) { - var arr = str.split('..'); - - if (arr.length === 1) { - tok.val = tok.segs[tok.segs.length - 1] || tok.val || str; - tok.segs = []; - return tok; - } - if (arr.length === 2 && arr[0] === arr[1]) { - tok.escaped = true; - tok.val = arr[0]; - tok.segs = []; - return tok; - } - if (arr.length > 1) { - if (opts.optimize !== false) { - opts.optimize = true; - delete opts.expand; - } +module.exports = function isObject(val) { + return val != null && typeof val === 'object' && Array.isArray(val) === false; +}; - if (opts.optimize !== true) { - var min = Math.min(arr[0], arr[1]); - var max = Math.max(arr[0], arr[1]); - var step = arr[2] || 1; - if (opts.rangeLimit !== false && ((max - min) / step >= opts.rangeLimit)) { - throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.'); - } - } +/***/ }), +/* 405 */ +/***/ (function(module, exports, __webpack_require__) { - arr.push(opts); - tok.segs = utils.fillRange.apply(null, arr); +"use strict"; +/*! + * assign-symbols + * + * Copyright (c) 2015, Jon Schlinkert. + * Licensed under the MIT License. + */ - if (!tok.segs.length) { - tok.escaped = true; - tok.val = str; - return tok; - } - if (opts.optimize === true) { - tok.segs = utils.stringifyArray(tok.segs); - } - if (tok.segs === '') { - tok.val = str; - } else { - tok.val = tok.segs[0]; - } - return tok; - } - } else { - tok.val = str; +module.exports = function(receiver, objects) { + if (receiver === null || typeof receiver === 'undefined') { + throw new TypeError('expected first argument to be an object.'); } - return tok; -}; - -/** - * Ensure commas inside brackets and parens are not split. - * @param {Object} `tok` Token from the `split-string` module - * @return {undefined} - */ - -utils.escapeBrackets = function(options) { - return function(tok) { - if (tok.escaped && tok.val === 'b') { - tok.val = '\\b'; - return; - } - if (tok.val !== '(' && tok.val !== '[') return; - var opts = utils.extend({}, options); - var brackets = []; - var parens = []; - var stack = []; - var val = tok.val; - var str = tok.str; - var i = tok.idx - 1; - - while (++i < str.length) { - var ch = str[i]; + if (typeof objects === 'undefined' || typeof Symbol === 'undefined') { + return receiver; + } - if (ch === '\\') { - val += (opts.keepEscaping === false ? '' : ch) + str[++i]; - continue; - } + if (typeof Object.getOwnPropertySymbols !== 'function') { + return receiver; + } - if (ch === '(') { - parens.push(ch); - stack.push(ch); - } + var isEnumerable = Object.prototype.propertyIsEnumerable; + var target = Object(receiver); + var len = arguments.length, i = 0; - if (ch === '[') { - brackets.push(ch); - stack.push(ch); - } + while (++i < len) { + var provider = Object(arguments[i]); + var names = Object.getOwnPropertySymbols(provider); - if (ch === ')') { - parens.pop(); - stack.pop(); - if (!stack.length) { - val += ch; - break; - } - } + for (var j = 0; j < names.length; j++) { + var key = names[j]; - if (ch === ']') { - brackets.pop(); - stack.pop(); - if (!stack.length) { - val += ch; - break; - } + if (isEnumerable.call(provider, key)) { + target[key] = provider[key]; } - val += ch; } - - tok.split = false; - tok.val = val.slice(1); - tok.idx = i; - }; -}; - -/** - * Returns true if the given string looks like a regex quantifier - * @return {Boolean} - */ - -utils.isQuantifier = function(str) { - return /^(?:[0-9]?,[0-9]|[0-9],)$/.test(str); -}; - -/** - * Cast `val` to an array. - * @param {*} `val` - */ - -utils.stringifyArray = function(arr) { - return [utils.arrayify(arr).join('|')]; + } + return target; }; -/** - * Cast `val` to an array. - * @param {*} `val` - */ -utils.arrayify = function(arr) { - if (typeof arr === 'undefined') { - return []; - } - if (typeof arr === 'string') { - return [arr]; - } - return arr; -}; +/***/ }), +/* 406 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Returns true if the given `str` is a non-empty string - * @return {Boolean} +"use strict"; +/*! + * arr-flatten + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. */ -utils.isString = function(str) { - return str != null && typeof str === 'string'; -}; -/** - * Get the last element from `array` - * @param {Array} `array` - * @return {*} - */ -utils.last = function(arr, n) { - return arr[arr.length - (n || 1)]; +module.exports = function (arr) { + return flat(arr, []); }; -utils.escapeRegex = function(str) { - return str.replace(/\\?([!^*?()\[\]{}+?/])/g, '\\$1'); -}; +function flat(arr, res) { + var i = 0, cur; + var len = arr.length; + for (; i < len; i++) { + cur = arr[i]; + Array.isArray(cur) ? flat(cur, res) : res.push(cur); + } + return res; +} /***/ }), @@ -36342,504 +36019,99 @@ utils.escapeRegex = function(str) { "use strict"; /*! - * split-string + * fill-range * - * Copyright (c) 2015-2017, Jon Schlinkert. + * Copyright (c) 2014-2015, 2017, Jon Schlinkert. * Released under the MIT License. */ -var extend = __webpack_require__(408); +var util = __webpack_require__(29); +var isNumber = __webpack_require__(408); +var extend = __webpack_require__(394); +var repeat = __webpack_require__(410); +var toRegex = __webpack_require__(411); -module.exports = function(str, options, fn) { - if (typeof str !== 'string') { - throw new TypeError('expected a string'); - } +/** + * Return a range of numbers or letters. + * + * @param {String} `start` Start of the range + * @param {String} `stop` End of the range + * @param {String} `step` Increment or decrement to use. + * @param {Function} `fn` Custom function to modify each element in the range. + * @return {Array} + */ - if (typeof options === 'function') { - fn = options; - options = null; +function fillRange(start, stop, step, options) { + if (typeof start === 'undefined') { + return []; } - // allow separator to be defined as a string - if (typeof options === 'string') { - options = { sep: options }; + if (typeof stop === 'undefined' || start === stop) { + // special case, for handling negative zero + var isString = typeof start === 'string'; + if (isNumber(start) && !toNumber(start)) { + return [isString ? '0' : 0]; + } + return [start]; } - var opts = extend({sep: '.'}, options); - var quotes = opts.quotes || ['"', "'", '`']; - var brackets; - - if (opts.brackets === true) { - brackets = { - '<': '>', - '(': ')', - '[': ']', - '{': '}' - }; - } else if (opts.brackets) { - brackets = opts.brackets; + if (typeof step !== 'number' && typeof step !== 'string') { + options = step; + step = undefined; } - var tokens = []; - var stack = []; - var arr = ['']; - var sep = opts.sep; - var len = str.length; - var idx = -1; - var closeIdx; + if (typeof options === 'function') { + options = { transform: options }; + } - function expected() { - if (brackets && stack.length) { - return brackets[stack[stack.length - 1]]; + var opts = extend({step: step}, options); + if (opts.step && !isValidNumber(opts.step)) { + if (opts.strictRanges === true) { + throw new TypeError('expected options.step to be a number'); } + return []; } - while (++idx < len) { - var ch = str[idx]; - var next = str[idx + 1]; - var tok = { val: ch, idx: idx, arr: arr, str: str }; - tokens.push(tok); - - if (ch === '\\') { - tok.val = keepEscaping(opts, str, idx) === true ? (ch + next) : next; - tok.escaped = true; - if (typeof fn === 'function') { - fn(tok); - } - arr[arr.length - 1] += tok.val; - idx++; - continue; + opts.isNumber = isValidNumber(start) && isValidNumber(stop); + if (!opts.isNumber && !isValid(start, stop)) { + if (opts.strictRanges === true) { + throw new RangeError('invalid range arguments: ' + util.inspect([start, stop])); } + return []; + } - if (brackets && brackets[ch]) { - stack.push(ch); - var e = expected(); - var i = idx + 1; + opts.isPadded = isPadded(start) || isPadded(stop); + opts.toString = opts.stringify + || typeof opts.step === 'string' + || typeof start === 'string' + || typeof stop === 'string' + || !opts.isNumber; - if (str.indexOf(e, i + 1) !== -1) { - while (stack.length && i < len) { - var s = str[++i]; - if (s === '\\') { - s++; - continue; - } + if (opts.isPadded) { + opts.maxLength = Math.max(String(start).length, String(stop).length); + } - if (quotes.indexOf(s) !== -1) { - i = getClosingQuote(str, s, i + 1); - continue; - } + // support legacy minimatch/fill-range options + if (typeof opts.optimize === 'boolean') opts.toRegex = opts.optimize; + if (typeof opts.makeRe === 'boolean') opts.toRegex = opts.makeRe; + return expand(start, stop, opts); +} - e = expected(); - if (stack.length && str.indexOf(e, i + 1) === -1) { - break; - } +function expand(start, stop, options) { + var a = options.isNumber ? toNumber(start) : start.charCodeAt(0); + var b = options.isNumber ? toNumber(stop) : stop.charCodeAt(0); - if (brackets[s]) { - stack.push(s); - continue; - } + var step = Math.abs(toNumber(options.step)) || 1; + if (options.toRegex && step === 1) { + return toRange(a, b, start, stop, options); + } - if (e === s) { - stack.pop(); - } - } - } - - closeIdx = i; - if (closeIdx === -1) { - arr[arr.length - 1] += ch; - continue; - } - - ch = str.slice(idx, closeIdx + 1); - tok.val = ch; - tok.idx = idx = closeIdx; - } - - if (quotes.indexOf(ch) !== -1) { - closeIdx = getClosingQuote(str, ch, idx + 1); - if (closeIdx === -1) { - arr[arr.length - 1] += ch; - continue; - } - - if (keepQuotes(ch, opts) === true) { - ch = str.slice(idx, closeIdx + 1); - } else { - ch = str.slice(idx + 1, closeIdx); - } - - tok.val = ch; - tok.idx = idx = closeIdx; - } - - if (typeof fn === 'function') { - fn(tok, tokens); - ch = tok.val; - idx = tok.idx; - } - - if (tok.val === sep && tok.split !== false) { - arr.push(''); - continue; - } - - arr[arr.length - 1] += tok.val; - } - - return arr; -}; - -function getClosingQuote(str, ch, i, brackets) { - var idx = str.indexOf(ch, i); - if (str.charAt(idx - 1) === '\\') { - return getClosingQuote(str, ch, idx + 1); - } - return idx; -} - -function keepQuotes(ch, opts) { - if (opts.keepDoubleQuotes === true && ch === '"') return true; - if (opts.keepSingleQuotes === true && ch === "'") return true; - return opts.keepQuotes; -} - -function keepEscaping(opts, str, idx) { - if (typeof opts.keepEscaping === 'function') { - return opts.keepEscaping(str, idx); - } - return opts.keepEscaping === true || str[idx + 1] === '\\'; -} - - -/***/ }), -/* 408 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var isExtendable = __webpack_require__(409); -var assignSymbols = __webpack_require__(412); - -module.exports = Object.assign || function(obj/*, objects*/) { - if (obj === null || typeof obj === 'undefined') { - throw new TypeError('Cannot convert undefined or null to object'); - } - if (!isObject(obj)) { - obj = {}; - } - for (var i = 1; i < arguments.length; i++) { - var val = arguments[i]; - if (isString(val)) { - val = toObject(val); - } - if (isObject(val)) { - assign(obj, val); - assignSymbols(obj, val); - } - } - return obj; -}; - -function assign(a, b) { - for (var key in b) { - if (hasOwn(b, key)) { - a[key] = b[key]; - } - } -} - -function isString(val) { - return (val && typeof val === 'string'); -} - -function toObject(str) { - var obj = {}; - for (var i in str) { - obj[i] = str[i]; - } - return obj; -} - -function isObject(val) { - return (val && typeof val === 'object') || isExtendable(val); -} - -/** - * Returns true if the given `key` is an own property of `obj`. - */ - -function hasOwn(obj, key) { - return Object.prototype.hasOwnProperty.call(obj, key); -} - -function isEnum(obj, key) { - return Object.prototype.propertyIsEnumerable.call(obj, key); -} - - -/***/ }), -/* 409 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * is-extendable - * - * Copyright (c) 2015-2017, Jon Schlinkert. - * Released under the MIT License. - */ - - - -var isPlainObject = __webpack_require__(410); - -module.exports = function isExtendable(val) { - return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); -}; - - -/***/ }), -/* 410 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * is-plain-object - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ - - - -var isObject = __webpack_require__(411); - -function isObjectObject(o) { - return isObject(o) === true - && Object.prototype.toString.call(o) === '[object Object]'; -} - -module.exports = function isPlainObject(o) { - var ctor,prot; - - if (isObjectObject(o) === false) return false; - - // If has modified constructor - ctor = o.constructor; - if (typeof ctor !== 'function') return false; - - // If has modified prototype - prot = ctor.prototype; - if (isObjectObject(prot) === false) return false; - - // If constructor does not have an Object-specific method - if (prot.hasOwnProperty('isPrototypeOf') === false) { - return false; - } - - // Most likely a plain Object - return true; -}; - - -/***/ }), -/* 411 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * isobject - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ - - - -module.exports = function isObject(val) { - return val != null && typeof val === 'object' && Array.isArray(val) === false; -}; - - -/***/ }), -/* 412 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * assign-symbols - * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. - */ - - - -module.exports = function(receiver, objects) { - if (receiver === null || typeof receiver === 'undefined') { - throw new TypeError('expected first argument to be an object.'); - } - - if (typeof objects === 'undefined' || typeof Symbol === 'undefined') { - return receiver; - } - - if (typeof Object.getOwnPropertySymbols !== 'function') { - return receiver; - } - - var isEnumerable = Object.prototype.propertyIsEnumerable; - var target = Object(receiver); - var len = arguments.length, i = 0; - - while (++i < len) { - var provider = Object(arguments[i]); - var names = Object.getOwnPropertySymbols(provider); - - for (var j = 0; j < names.length; j++) { - var key = names[j]; - - if (isEnumerable.call(provider, key)) { - target[key] = provider[key]; - } - } - } - return target; -}; - - -/***/ }), -/* 413 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * arr-flatten - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ - - - -module.exports = function (arr) { - return flat(arr, []); -}; - -function flat(arr, res) { - var i = 0, cur; - var len = arr.length; - for (; i < len; i++) { - cur = arr[i]; - Array.isArray(cur) ? flat(cur, res) : res.push(cur); - } - return res; -} - - -/***/ }), -/* 414 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * fill-range - * - * Copyright (c) 2014-2015, 2017, Jon Schlinkert. - * Released under the MIT License. - */ - - - -var util = __webpack_require__(29); -var isNumber = __webpack_require__(415); -var extend = __webpack_require__(394); -var repeat = __webpack_require__(417); -var toRegex = __webpack_require__(418); - -/** - * Return a range of numbers or letters. - * - * @param {String} `start` Start of the range - * @param {String} `stop` End of the range - * @param {String} `step` Increment or decrement to use. - * @param {Function} `fn` Custom function to modify each element in the range. - * @return {Array} - */ - -function fillRange(start, stop, step, options) { - if (typeof start === 'undefined') { - return []; - } - - if (typeof stop === 'undefined' || start === stop) { - // special case, for handling negative zero - var isString = typeof start === 'string'; - if (isNumber(start) && !toNumber(start)) { - return [isString ? '0' : 0]; - } - return [start]; - } - - if (typeof step !== 'number' && typeof step !== 'string') { - options = step; - step = undefined; - } - - if (typeof options === 'function') { - options = { transform: options }; - } - - var opts = extend({step: step}, options); - if (opts.step && !isValidNumber(opts.step)) { - if (opts.strictRanges === true) { - throw new TypeError('expected options.step to be a number'); - } - return []; - } - - opts.isNumber = isValidNumber(start) && isValidNumber(stop); - if (!opts.isNumber && !isValid(start, stop)) { - if (opts.strictRanges === true) { - throw new RangeError('invalid range arguments: ' + util.inspect([start, stop])); - } - return []; - } - - opts.isPadded = isPadded(start) || isPadded(stop); - opts.toString = opts.stringify - || typeof opts.step === 'string' - || typeof start === 'string' - || typeof stop === 'string' - || !opts.isNumber; - - if (opts.isPadded) { - opts.maxLength = Math.max(String(start).length, String(stop).length); - } - - // support legacy minimatch/fill-range options - if (typeof opts.optimize === 'boolean') opts.toRegex = opts.optimize; - if (typeof opts.makeRe === 'boolean') opts.toRegex = opts.makeRe; - return expand(start, stop, opts); -} - -function expand(start, stop, options) { - var a = options.isNumber ? toNumber(start) : start.charCodeAt(0); - var b = options.isNumber ? toNumber(stop) : stop.charCodeAt(0); - - var step = Math.abs(toNumber(options.step)) || 1; - if (options.toRegex && step === 1) { - return toRange(a, b, start, stop, options); - } - - var zero = {greater: [], lesser: []}; - var asc = a < b; - var arr = new Array(Math.round((asc ? b - a : a - b) / step)); - var idx = 0; + var zero = {greater: [], lesser: []}; + var asc = a < b; + var arr = new Array(Math.round((asc ? b - a : a - b) / step)); + var idx = 0; while (asc ? a <= b : a >= b) { var val = options.isNumber ? a : String.fromCharCode(a); @@ -36957,7 +36229,7 @@ module.exports = fillRange; /***/ }), -/* 415 */ +/* 408 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -36970,7 +36242,7 @@ module.exports = fillRange; -var typeOf = __webpack_require__(416); +var typeOf = __webpack_require__(409); module.exports = function isNumber(num) { var type = typeOf(num); @@ -36986,7 +36258,7 @@ module.exports = function isNumber(num) { /***/ }), -/* 416 */ +/* 409 */ /***/ (function(module, exports, __webpack_require__) { var isBuffer = __webpack_require__(391); @@ -37108,7 +36380,7 @@ module.exports = function kindOf(val) { /***/ }), -/* 417 */ +/* 410 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -37185,7 +36457,7 @@ function repeat(str, num) { /***/ }), -/* 418 */ +/* 411 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -37198,8 +36470,8 @@ function repeat(str, num) { -var repeat = __webpack_require__(417); -var isNumber = __webpack_require__(415); +var repeat = __webpack_require__(410); +var isNumber = __webpack_require__(408); var cache = {}; function toRegexRange(min, max, options) { @@ -37486,7 +36758,7 @@ module.exports = toRegexRange; /***/ }), -/* 419 */ +/* 412 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -37511,14 +36783,14 @@ module.exports = function repeat(ele, num) { /***/ }), -/* 420 */ +/* 413 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var Node = __webpack_require__(421); -var utils = __webpack_require__(406); +var Node = __webpack_require__(414); +var utils = __webpack_require__(399); /** * Braces parsers @@ -37593,7 +36865,7 @@ module.exports = function(braces, options) { .set('bracket', function() { var isInside = this.isInside('brace'); var pos = this.position(); - var m = this.match(/^(?:\[([!^]?)([^\]]{2,}|\]\-)(\]|[^*+?]+)|\[)/); + var m = this.match(/^(?:\[([!^]?)([^\]]{2,}|\]-)(\]|[^*+?]+)|\[)/); if (!m) return; var prev = this.prev(); @@ -37644,7 +36916,7 @@ module.exports = function(braces, options) { .set('multiplier', function() { var isInside = this.isInside('brace'); var pos = this.position(); - var m = this.match(/^\{(,+(?:(\{,+\})*),*|,*(?:(\{,+\})*),+)\}/); + var m = this.match(/^\{((?:,|\{,+\})+)\}/); if (!m) return; this.multiplier = true; @@ -37795,7 +37067,7 @@ module.exports = function(braces, options) { .set('text', function() { var isInside = this.isInside('brace'); var pos = this.position(); - var m = this.match(/^((?!\\)[^${}\[\]])+/); + var m = this.match(/^((?!\\)[^${}[\]])+/); if (!m) return; var prev = this.prev(); @@ -37878,14 +37150,14 @@ function concatNodes(pos, node, parent, options) { /***/ }), -/* 421 */ +/* 414 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(411); -var define = __webpack_require__(398); +var isObject = __webpack_require__(404); +var define = __webpack_require__(415); var utils = __webpack_require__(422); var ownNames; @@ -38377,4486 +37649,2972 @@ exports = module.exports = Node; /***/ }), -/* 422 */ +/* 415 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - - -var typeOf = __webpack_require__(416); -var utils = module.exports; - -/** - * Returns true if the given value is a node. +/*! + * define-property * - * ```js - * var Node = require('snapdragon-node'); - * var node = new Node({type: 'foo'}); - * console.log(utils.isNode(node)); //=> true - * console.log(utils.isNode({})); //=> false - * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @returns {Boolean} - * @api public + * Copyright (c) 2015, 2017, Jon Schlinkert. + * Released under the MIT License. */ -utils.isNode = function(node) { - return typeOf(node) === 'object' && node.isNode === true; -}; -/** - * Emit an empty string for the given `node`. - * - * ```js - * // do nothing for beginning-of-string - * snapdragon.compiler.set('bos', utils.noop); - * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @returns {undefined} - * @api public - */ -utils.noop = function(node) { - append(this, '', node); -}; +var isDescriptor = __webpack_require__(416); -/** - * Appdend `node.val` to `compiler.output`, exactly as it was created - * by the parser. - * - * ```js - * snapdragon.compiler.set('text', utils.identity); - * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @returns {undefined} - * @api public - */ +module.exports = function defineProperty(obj, prop, val) { + if (typeof obj !== 'object' && typeof obj !== 'function') { + throw new TypeError('expected an object or function.'); + } -utils.identity = function(node) { - append(this, node.val, node); -}; + if (typeof prop !== 'string') { + throw new TypeError('expected `prop` to be a string.'); + } -/** - * Previously named `.emit`, this method appends the given `val` - * to `compiler.output` for the given node. Useful when you know - * what value should be appended advance, regardless of the actual - * value of `node.val`. - * - * ```js - * snapdragon.compiler - * .set('i', function(node) { - * this.mapVisit(node); - * }) - * .set('i.open', utils.append('')) - * .set('i.close', utils.append('')) - * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @returns {Function} Returns a compiler middleware function. - * @api public - */ + if (isDescriptor(val) && ('set' in val || 'get' in val)) { + return Object.defineProperty(obj, prop, val); + } -utils.append = function(val) { - return function(node) { - append(this, val, node); - }; + return Object.defineProperty(obj, prop, { + configurable: true, + enumerable: false, + writable: true, + value: val + }); }; -/** - * Used in compiler middleware, this onverts an AST node into - * an empty `text` node and deletes `node.nodes` if it exists. - * The advantage of this method is that, as opposed to completely - * removing the node, indices will not need to be re-calculated - * in sibling nodes, and nothing is appended to the output. - * - * ```js - * utils.toNoop(node); - * // convert `node.nodes` to the given value instead of deleting it - * utils.toNoop(node, []); - * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @param {Array} `nodes` Optionally pass a new `nodes` value, to replace the existing `node.nodes` array. - * @api public - */ -utils.toNoop = function(node, nodes) { - if (nodes) { - node.nodes = nodes; - } else { - delete node.nodes; - node.type = 'text'; - node.val = ''; - } -}; +/***/ }), +/* 416 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Visit `node` with the given `fn`. The built-in `.visit` method in snapdragon - * automatically calls registered compilers, this allows you to pass a visitor - * function. +"use strict"; +/*! + * is-descriptor * - * ```js - * snapdragon.compiler.set('i', function(node) { - * utils.visit(node, function(childNode) { - * // do stuff with "childNode" - * return childNode; - * }); - * }); - * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @param {Function} `fn` - * @return {Object} returns the node after recursively visiting all child nodes. - * @api public + * Copyright (c) 2015-2017, Jon Schlinkert. + * Released under the MIT License. */ -utils.visit = function(node, fn) { - assert(utils.isNode(node), 'expected node to be an instance of Node'); - assert(isFunction(fn), 'expected a visitor function'); - fn(node); - return node.nodes ? utils.mapVisit(node, fn) : node; -}; -/** - * Map [visit](#visit) the given `fn` over `node.nodes`. This is called by - * [visit](#visit), use this method if you do not want `fn` to be called on - * the first node. - * - * ```js - * snapdragon.compiler.set('i', function(node) { - * utils.mapVisit(node, function(childNode) { - * // do stuff with "childNode" - * return childNode; - * }); - * }); - * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @param {Object} `options` - * @param {Function} `fn` - * @return {Object} returns the node - * @api public - */ -utils.mapVisit = function(node, fn) { - assert(utils.isNode(node), 'expected node to be an instance of Node'); - assert(isArray(node.nodes), 'expected node.nodes to be an array'); - assert(isFunction(fn), 'expected a visitor function'); +var typeOf = __webpack_require__(417); +var isAccessor = __webpack_require__(418); +var isData = __webpack_require__(420); - for (var i = 0; i < node.nodes.length; i++) { - utils.visit(node.nodes[i], fn); +module.exports = function isDescriptor(obj, key) { + if (typeOf(obj) !== 'object') { + return false; } - return node; + if ('get' in obj) { + return isAccessor(obj, key); + } + return isData(obj, key); }; -/** - * Unshift an `*.open` node onto `node.nodes`. - * - * ```js - * var Node = require('snapdragon-node'); - * snapdragon.parser.set('brace', function(node) { - * var match = this.match(/^{/); - * if (match) { - * var parent = new Node({type: 'brace'}); - * utils.addOpen(parent, Node); - * console.log(parent.nodes[0]): - * // { type: 'brace.open', val: '' }; - * - * // push the parent "brace" node onto the stack - * this.push(parent); - * - * // return the parent node, so it's also added to the AST - * return brace; - * } - * }); - * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @param {Function} `Node` (required) Node constructor function from [snapdragon-node][]. - * @param {Function} `filter` Optionaly specify a filter function to exclude the node. - * @return {Object} Returns the created opening node. - * @api public - */ -utils.addOpen = function(node, Node, val, filter) { - assert(utils.isNode(node), 'expected node to be an instance of Node'); - assert(isFunction(Node), 'expected Node to be a constructor function'); +/***/ }), +/* 417 */ +/***/ (function(module, exports) { - if (typeof val === 'function') { - filter = val; - val = ''; - } +var toString = Object.prototype.toString; - if (typeof filter === 'function' && !filter(node)) return; - var open = new Node({ type: node.type + '.open', val: val}); - var unshift = node.unshift || node.unshiftNode; - if (typeof unshift === 'function') { - unshift.call(node, open); - } else { - utils.unshiftNode(node, open); +module.exports = function kindOf(val) { + if (val === void 0) return 'undefined'; + if (val === null) return 'null'; + + var type = typeof val; + if (type === 'boolean') return 'boolean'; + if (type === 'string') return 'string'; + if (type === 'number') return 'number'; + if (type === 'symbol') return 'symbol'; + if (type === 'function') { + return isGeneratorFn(val) ? 'generatorfunction' : 'function'; } - return open; -}; -/** - * Push a `*.close` node onto `node.nodes`. - * - * ```js - * var Node = require('snapdragon-node'); - * snapdragon.parser.set('brace', function(node) { - * var match = this.match(/^}/); - * if (match) { - * var parent = this.parent(); - * if (parent.type !== 'brace') { - * throw new Error('missing opening: ' + '}'); - * } - * - * utils.addClose(parent, Node); - * console.log(parent.nodes[parent.nodes.length - 1]): - * // { type: 'brace.close', val: '' }; - * - * // no need to return a node, since the parent - * // was already added to the AST - * return; - * } - * }); - * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @param {Function} `Node` (required) Node constructor function from [snapdragon-node][]. - * @param {Function} `filter` Optionaly specify a filter function to exclude the node. - * @return {Object} Returns the created closing node. - * @api public - */ + if (isArray(val)) return 'array'; + if (isBuffer(val)) return 'buffer'; + if (isArguments(val)) return 'arguments'; + if (isDate(val)) return 'date'; + if (isError(val)) return 'error'; + if (isRegexp(val)) return 'regexp'; -utils.addClose = function(node, Node, val, filter) { - assert(utils.isNode(node), 'expected node to be an instance of Node'); - assert(isFunction(Node), 'expected Node to be a constructor function'); + switch (ctorName(val)) { + case 'Symbol': return 'symbol'; + case 'Promise': return 'promise'; - if (typeof val === 'function') { - filter = val; - val = ''; - } + // Set, Map, WeakSet, WeakMap + case 'WeakMap': return 'weakmap'; + case 'WeakSet': return 'weakset'; + case 'Map': return 'map'; + case 'Set': return 'set'; - if (typeof filter === 'function' && !filter(node)) return; - var close = new Node({ type: node.type + '.close', val: val}); - var push = node.push || node.pushNode; - if (typeof push === 'function') { - push.call(node, close); - } else { - utils.pushNode(node, close); + // 8-bit typed arrays + case 'Int8Array': return 'int8array'; + case 'Uint8Array': return 'uint8array'; + case 'Uint8ClampedArray': return 'uint8clampedarray'; + + // 16-bit typed arrays + case 'Int16Array': return 'int16array'; + case 'Uint16Array': return 'uint16array'; + + // 32-bit typed arrays + case 'Int32Array': return 'int32array'; + case 'Uint32Array': return 'uint32array'; + case 'Float32Array': return 'float32array'; + case 'Float64Array': return 'float64array'; } - return close; -}; -/** - * Wraps the given `node` with `*.open` and `*.close` nodes. - * - * @param {Object} `node` Instance of [snapdragon-node][] - * @param {Function} `Node` (required) Node constructor function from [snapdragon-node][]. - * @param {Function} `filter` Optionaly specify a filter function to exclude the node. - * @return {Object} Returns the node - * @api public - */ + if (isGeneratorObj(val)) { + return 'generator'; + } -utils.wrapNodes = function(node, Node, filter) { - assert(utils.isNode(node), 'expected node to be an instance of Node'); - assert(isFunction(Node), 'expected Node to be a constructor function'); + // Non-plain objects + type = toString.call(val); + switch (type) { + case '[object Object]': return 'object'; + // iterators + case '[object Map Iterator]': return 'mapiterator'; + case '[object Set Iterator]': return 'setiterator'; + case '[object String Iterator]': return 'stringiterator'; + case '[object Array Iterator]': return 'arrayiterator'; + } - utils.addOpen(node, Node, filter); - utils.addClose(node, Node, filter); - return node; + // other + return type.slice(8, -1).toLowerCase().replace(/\s/g, ''); }; -/** - * Push the given `node` onto `parent.nodes`, and set `parent` as `node.parent. - * - * ```js - * var parent = new Node({type: 'foo'}); - * var node = new Node({type: 'bar'}); - * utils.pushNode(parent, node); - * console.log(parent.nodes[0].type) // 'bar' - * console.log(node.parent.type) // 'foo' - * ``` - * @param {Object} `parent` - * @param {Object} `node` Instance of [snapdragon-node][] - * @return {Object} Returns the child node - * @api public - */ +function ctorName(val) { + return val.constructor ? val.constructor.name : null; +} -utils.pushNode = function(parent, node) { - assert(utils.isNode(parent), 'expected parent node to be an instance of Node'); - assert(utils.isNode(node), 'expected node to be an instance of Node'); +function isArray(val) { + if (Array.isArray) return Array.isArray(val); + return val instanceof Array; +} - node.define('parent', parent); - parent.nodes = parent.nodes || []; - parent.nodes.push(node); - return node; -}; +function isError(val) { + return val instanceof Error || (typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number'); +} -/** - * Unshift `node` onto `parent.nodes`, and set `parent` as `node.parent. - * - * ```js - * var parent = new Node({type: 'foo'}); - * var node = new Node({type: 'bar'}); - * utils.unshiftNode(parent, node); - * console.log(parent.nodes[0].type) // 'bar' - * console.log(node.parent.type) // 'foo' - * ``` - * @param {Object} `parent` - * @param {Object} `node` Instance of [snapdragon-node][] - * @return {undefined} - * @api public - */ +function isDate(val) { + if (val instanceof Date) return true; + return typeof val.toDateString === 'function' + && typeof val.getDate === 'function' + && typeof val.setDate === 'function'; +} -utils.unshiftNode = function(parent, node) { - assert(utils.isNode(parent), 'expected parent node to be an instance of Node'); - assert(utils.isNode(node), 'expected node to be an instance of Node'); +function isRegexp(val) { + if (val instanceof RegExp) return true; + return typeof val.flags === 'string' + && typeof val.ignoreCase === 'boolean' + && typeof val.multiline === 'boolean' + && typeof val.global === 'boolean'; +} - node.define('parent', parent); - parent.nodes = parent.nodes || []; - parent.nodes.unshift(node); -}; +function isGeneratorFn(name, val) { + return ctorName(name) === 'GeneratorFunction'; +} -/** - * Pop the last `node` off of `parent.nodes`. The advantage of - * using this method is that it checks for `node.nodes` and works - * with any version of `snapdragon-node`. - * - * ```js - * var parent = new Node({type: 'foo'}); - * utils.pushNode(parent, new Node({type: 'foo'})); - * utils.pushNode(parent, new Node({type: 'bar'})); - * utils.pushNode(parent, new Node({type: 'baz'})); - * console.log(parent.nodes.length); //=> 3 - * utils.popNode(parent); - * console.log(parent.nodes.length); //=> 2 - * ``` - * @param {Object} `parent` - * @param {Object} `node` Instance of [snapdragon-node][] - * @return {Number|Undefined} Returns the length of `node.nodes` or undefined. - * @api public - */ +function isGeneratorObj(val) { + return typeof val.throw === 'function' + && typeof val.return === 'function' + && typeof val.next === 'function'; +} -utils.popNode = function(node) { - assert(utils.isNode(node), 'expected node to be an instance of Node'); - if (typeof node.pop === 'function') { - return node.pop(); +function isArguments(val) { + try { + if (typeof val.length === 'number' && typeof val.callee === 'function') { + return true; + } + } catch (err) { + if (err.message.indexOf('callee') !== -1) { + return true; + } } - return node.nodes && node.nodes.pop(); -}; + return false; +} /** - * Shift the first `node` off of `parent.nodes`. The advantage of - * using this method is that it checks for `node.nodes` and works - * with any version of `snapdragon-node`. - * - * ```js - * var parent = new Node({type: 'foo'}); - * utils.pushNode(parent, new Node({type: 'foo'})); - * utils.pushNode(parent, new Node({type: 'bar'})); - * utils.pushNode(parent, new Node({type: 'baz'})); - * console.log(parent.nodes.length); //=> 3 - * utils.shiftNode(parent); - * console.log(parent.nodes.length); //=> 2 - * ``` - * @param {Object} `parent` - * @param {Object} `node` Instance of [snapdragon-node][] - * @return {Number|Undefined} Returns the length of `node.nodes` or undefined. - * @api public + * If you need to support Safari 5-7 (8-10 yr-old browser), + * take a look at https://github.com/feross/is-buffer */ -utils.shiftNode = function(node) { - assert(utils.isNode(node), 'expected node to be an instance of Node'); - if (typeof node.shift === 'function') { - return node.shift(); +function isBuffer(val) { + if (val.constructor && typeof val.constructor.isBuffer === 'function') { + return val.constructor.isBuffer(val); } - return node.nodes && node.nodes.shift(); -}; + return false; +} -/** - * Remove the specified `node` from `parent.nodes`. + +/***/ }), +/* 418 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/*! + * is-accessor-descriptor * - * ```js - * var parent = new Node({type: 'abc'}); - * var foo = new Node({type: 'foo'}); - * utils.pushNode(parent, foo); - * utils.pushNode(parent, new Node({type: 'bar'})); - * utils.pushNode(parent, new Node({type: 'baz'})); - * console.log(parent.nodes.length); //=> 3 - * utils.removeNode(parent, foo); - * console.log(parent.nodes.length); //=> 2 - * ``` - * @param {Object} `parent` - * @param {Object} `node` Instance of [snapdragon-node][] - * @return {Object|undefined} Returns the removed node, if successful, or undefined if it does not exist on `parent.nodes`. - * @api public + * Copyright (c) 2015-2017, Jon Schlinkert. + * Released under the MIT License. */ -utils.removeNode = function(parent, node) { - assert(utils.isNode(parent), 'expected parent.node to be an instance of Node'); - assert(utils.isNode(node), 'expected node to be an instance of Node'); - if (!parent.nodes) { - return null; + +var typeOf = __webpack_require__(419); + +// accessor descriptor properties +var accessor = { + get: 'function', + set: 'function', + configurable: 'boolean', + enumerable: 'boolean' +}; + +function isAccessorDescriptor(obj, prop) { + if (typeof prop === 'string') { + var val = Object.getOwnPropertyDescriptor(obj, prop); + return typeof val !== 'undefined'; } - if (typeof parent.remove === 'function') { - return parent.remove(node); + if (typeOf(obj) !== 'object') { + return false; } - var idx = parent.nodes.indexOf(node); - if (idx !== -1) { - return parent.nodes.splice(idx, 1); + if (has(obj, 'value') || has(obj, 'writable')) { + return false; } -}; -/** - * Returns true if `node.type` matches the given `type`. Throws a - * `TypeError` if `node` is not an instance of `Node`. - * - * ```js - * var Node = require('snapdragon-node'); - * var node = new Node({type: 'foo'}); - * console.log(utils.isType(node, 'foo')); // false - * console.log(utils.isType(node, 'bar')); // true - * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @param {String} `type` - * @return {Boolean} - * @api public - */ + if (!has(obj, 'get') || typeof obj.get !== 'function') { + return false; + } -utils.isType = function(node, type) { - assert(utils.isNode(node), 'expected node to be an instance of Node'); - switch (typeOf(type)) { - case 'array': - var types = type.slice(); - for (var i = 0; i < types.length; i++) { - if (utils.isType(node, types[i])) { - return true; - } - } - return false; - case 'string': - return node.type === type; - case 'regexp': - return type.test(node.type); - default: { - throw new TypeError('expected "type" to be an array, string or regexp'); - } + // tldr: it's valid to have "set" be undefined + // "set" might be undefined if `Object.getOwnPropertyDescriptor` + // was used to get the value, and only `get` was defined by the user + if (has(obj, 'set') && typeof obj[key] !== 'function' && typeof obj[key] !== 'undefined') { + return false; } -}; -/** - * Returns true if the given `node` has the given `type` in `node.nodes`. - * Throws a `TypeError` if `node` is not an instance of `Node`. - * - * ```js - * var Node = require('snapdragon-node'); - * var node = new Node({ - * type: 'foo', - * nodes: [ - * new Node({type: 'bar'}), - * new Node({type: 'baz'}) - * ] - * }); - * console.log(utils.hasType(node, 'xyz')); // false - * console.log(utils.hasType(node, 'baz')); // true - * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @param {String} `type` - * @return {Boolean} - * @api public - */ + for (var key in obj) { + if (!accessor.hasOwnProperty(key)) { + continue; + } -utils.hasType = function(node, type) { - assert(utils.isNode(node), 'expected node to be an instance of Node'); - if (!Array.isArray(node.nodes)) return false; - for (var i = 0; i < node.nodes.length; i++) { - if (utils.isType(node.nodes[i], type)) { - return true; + if (typeOf(obj[key]) === accessor[key]) { + continue; + } + + if (typeof obj[key] !== 'undefined') { + return false; } } - return false; -}; + return true; +} + +function has(obj, key) { + return {}.hasOwnProperty.call(obj, key); +} /** - * Returns the first node from `node.nodes` of the given `type` - * - * ```js - * var node = new Node({ - * type: 'foo', - * nodes: [ - * new Node({type: 'text', val: 'abc'}), - * new Node({type: 'text', val: 'xyz'}) - * ] - * }); - * - * var textNode = utils.firstOfType(node.nodes, 'text'); - * console.log(textNode.val); - * //=> 'abc' - * ``` - * @param {Array} `nodes` - * @param {String} `type` - * @return {Object|undefined} Returns the first matching node or undefined. - * @api public + * Expose `isAccessorDescriptor` */ -utils.firstOfType = function(nodes, type) { - for (var i = 0; i < nodes.length; i++) { - var node = nodes[i]; - if (utils.isType(node, type)) { - return node; - } +module.exports = isAccessorDescriptor; + + +/***/ }), +/* 419 */ +/***/ (function(module, exports) { + +var toString = Object.prototype.toString; + +module.exports = function kindOf(val) { + if (val === void 0) return 'undefined'; + if (val === null) return 'null'; + + var type = typeof val; + if (type === 'boolean') return 'boolean'; + if (type === 'string') return 'string'; + if (type === 'number') return 'number'; + if (type === 'symbol') return 'symbol'; + if (type === 'function') { + return isGeneratorFn(val) ? 'generatorfunction' : 'function'; } -}; -/** - * Returns the node at the specified index, or the first node of the - * given `type` from `node.nodes`. - * - * ```js - * var node = new Node({ - * type: 'foo', - * nodes: [ - * new Node({type: 'text', val: 'abc'}), - * new Node({type: 'text', val: 'xyz'}) - * ] - * }); - * - * var nodeOne = utils.findNode(node.nodes, 'text'); - * console.log(nodeOne.val); - * //=> 'abc' - * - * var nodeTwo = utils.findNode(node.nodes, 1); - * console.log(nodeTwo.val); - * //=> 'xyz' - * ``` - * - * @param {Array} `nodes` - * @param {String|Number} `type` Node type or index. - * @return {Object} Returns a node or undefined. - * @api public - */ + if (isArray(val)) return 'array'; + if (isBuffer(val)) return 'buffer'; + if (isArguments(val)) return 'arguments'; + if (isDate(val)) return 'date'; + if (isError(val)) return 'error'; + if (isRegexp(val)) return 'regexp'; -utils.findNode = function(nodes, type) { - if (!Array.isArray(nodes)) { - return null; + switch (ctorName(val)) { + case 'Symbol': return 'symbol'; + case 'Promise': return 'promise'; + + // Set, Map, WeakSet, WeakMap + case 'WeakMap': return 'weakmap'; + case 'WeakSet': return 'weakset'; + case 'Map': return 'map'; + case 'Set': return 'set'; + + // 8-bit typed arrays + case 'Int8Array': return 'int8array'; + case 'Uint8Array': return 'uint8array'; + case 'Uint8ClampedArray': return 'uint8clampedarray'; + + // 16-bit typed arrays + case 'Int16Array': return 'int16array'; + case 'Uint16Array': return 'uint16array'; + + // 32-bit typed arrays + case 'Int32Array': return 'int32array'; + case 'Uint32Array': return 'uint32array'; + case 'Float32Array': return 'float32array'; + case 'Float64Array': return 'float64array'; } - if (typeof type === 'number') { - return nodes[type]; + + if (isGeneratorObj(val)) { + return 'generator'; } - return utils.firstOfType(nodes, type); -}; -/** - * Returns true if the given node is an "*.open" node. - * - * ```js - * var Node = require('snapdragon-node'); - * var brace = new Node({type: 'brace'}); - * var open = new Node({type: 'brace.open'}); - * var close = new Node({type: 'brace.close'}); - * - * console.log(utils.isOpen(brace)); // false - * console.log(utils.isOpen(open)); // true - * console.log(utils.isOpen(close)); // false - * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @return {Boolean} - * @api public - */ + // Non-plain objects + type = toString.call(val); + switch (type) { + case '[object Object]': return 'object'; + // iterators + case '[object Map Iterator]': return 'mapiterator'; + case '[object Set Iterator]': return 'setiterator'; + case '[object String Iterator]': return 'stringiterator'; + case '[object Array Iterator]': return 'arrayiterator'; + } -utils.isOpen = function(node) { - assert(utils.isNode(node), 'expected node to be an instance of Node'); - return node.type.slice(-5) === '.open'; + // other + return type.slice(8, -1).toLowerCase().replace(/\s/g, ''); }; -/** - * Returns true if the given node is a "*.close" node. - * - * ```js - * var Node = require('snapdragon-node'); - * var brace = new Node({type: 'brace'}); - * var open = new Node({type: 'brace.open'}); - * var close = new Node({type: 'brace.close'}); - * - * console.log(utils.isClose(brace)); // false - * console.log(utils.isClose(open)); // false - * console.log(utils.isClose(close)); // true - * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @return {Boolean} - * @api public - */ +function ctorName(val) { + return val.constructor ? val.constructor.name : null; +} -utils.isClose = function(node) { - assert(utils.isNode(node), 'expected node to be an instance of Node'); - return node.type.slice(-6) === '.close'; -}; +function isArray(val) { + if (Array.isArray) return Array.isArray(val); + return val instanceof Array; +} -/** - * Returns true if `node.nodes` **has** an `.open` node - * - * ```js - * var Node = require('snapdragon-node'); - * var brace = new Node({ - * type: 'brace', - * nodes: [] - * }); - * - * var open = new Node({type: 'brace.open'}); - * console.log(utils.hasOpen(brace)); // false - * - * brace.pushNode(open); - * console.log(utils.hasOpen(brace)); // true - * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @return {Boolean} - * @api public - */ +function isError(val) { + return val instanceof Error || (typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number'); +} -utils.hasOpen = function(node) { - assert(utils.isNode(node), 'expected node to be an instance of Node'); - var first = node.first || node.nodes ? node.nodes[0] : null; - if (utils.isNode(first)) { - return first.type === node.type + '.open'; +function isDate(val) { + if (val instanceof Date) return true; + return typeof val.toDateString === 'function' + && typeof val.getDate === 'function' + && typeof val.setDate === 'function'; +} + +function isRegexp(val) { + if (val instanceof RegExp) return true; + return typeof val.flags === 'string' + && typeof val.ignoreCase === 'boolean' + && typeof val.multiline === 'boolean' + && typeof val.global === 'boolean'; +} + +function isGeneratorFn(name, val) { + return ctorName(name) === 'GeneratorFunction'; +} + +function isGeneratorObj(val) { + return typeof val.throw === 'function' + && typeof val.return === 'function' + && typeof val.next === 'function'; +} + +function isArguments(val) { + try { + if (typeof val.length === 'number' && typeof val.callee === 'function') { + return true; + } + } catch (err) { + if (err.message.indexOf('callee') !== -1) { + return true; + } } return false; -}; +} /** - * Returns true if `node.nodes` **has** a `.close` node - * - * ```js - * var Node = require('snapdragon-node'); - * var brace = new Node({ - * type: 'brace', - * nodes: [] - * }); - * - * var close = new Node({type: 'brace.close'}); - * console.log(utils.hasClose(brace)); // false - * - * brace.pushNode(close); - * console.log(utils.hasClose(brace)); // true - * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @return {Boolean} - * @api public + * If you need to support Safari 5-7 (8-10 yr-old browser), + * take a look at https://github.com/feross/is-buffer */ -utils.hasClose = function(node) { - assert(utils.isNode(node), 'expected node to be an instance of Node'); - var last = node.last || node.nodes ? node.nodes[node.nodes.length - 1] : null; - if (utils.isNode(last)) { - return last.type === node.type + '.close'; +function isBuffer(val) { + if (val.constructor && typeof val.constructor.isBuffer === 'function') { + return val.constructor.isBuffer(val); } return false; -}; +} -/** - * Returns true if `node.nodes` has both `.open` and `.close` nodes - * - * ```js - * var Node = require('snapdragon-node'); - * var brace = new Node({ - * type: 'brace', - * nodes: [] - * }); - * - * var open = new Node({type: 'brace.open'}); - * var close = new Node({type: 'brace.close'}); - * console.log(utils.hasOpen(brace)); // false - * console.log(utils.hasClose(brace)); // false - * - * brace.pushNode(open); - * brace.pushNode(close); - * console.log(utils.hasOpen(brace)); // true - * console.log(utils.hasClose(brace)); // true - * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @return {Boolean} - * @api public - */ -utils.hasOpenAndClose = function(node) { - return utils.hasOpen(node) && utils.hasClose(node); -}; +/***/ }), +/* 420 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Push the given `node` onto the `state.inside` array for the - * given type. This array is used as a specialized "stack" for - * only the given `node.type`. +"use strict"; +/*! + * is-data-descriptor * - * ```js - * var state = { inside: {}}; - * var node = new Node({type: 'brace'}); - * utils.addType(state, node); - * console.log(state.inside); - * //=> { brace: [{type: 'brace'}] } - * ``` - * @param {Object} `state` The `compiler.state` object or custom state object. - * @param {Object} `node` Instance of [snapdragon-node][] - * @return {Array} Returns the `state.inside` stack for the given type. - * @api public + * Copyright (c) 2015-2017, Jon Schlinkert. + * Released under the MIT License. */ -utils.addType = function(state, node) { - assert(utils.isNode(node), 'expected node to be an instance of Node'); - assert(isObject(state), 'expected state to be an object'); - var type = node.parent - ? node.parent.type - : node.type.replace(/\.open$/, ''); - if (!state.hasOwnProperty('inside')) { - state.inside = {}; +var typeOf = __webpack_require__(421); + +module.exports = function isDataDescriptor(obj, prop) { + // data descriptor properties + var data = { + configurable: 'boolean', + enumerable: 'boolean', + writable: 'boolean' + }; + + if (typeOf(obj) !== 'object') { + return false; } - if (!state.inside.hasOwnProperty(type)) { - state.inside[type] = []; + + if (typeof prop === 'string') { + var val = Object.getOwnPropertyDescriptor(obj, prop); + return typeof val !== 'undefined'; } - var arr = state.inside[type]; - arr.push(node); - return arr; -}; + if (!('value' in obj) && !('writable' in obj)) { + return false; + } -/** - * Remove the given `node` from the `state.inside` array for the - * given type. This array is used as a specialized "stack" for - * only the given `node.type`. - * - * ```js - * var state = { inside: {}}; - * var node = new Node({type: 'brace'}); - * utils.addType(state, node); - * console.log(state.inside); - * //=> { brace: [{type: 'brace'}] } - * utils.removeType(state, node); - * //=> { brace: [] } - * ``` - * @param {Object} `state` The `compiler.state` object or custom state object. - * @param {Object} `node` Instance of [snapdragon-node][] - * @return {Array} Returns the `state.inside` stack for the given type. - * @api public - */ + for (var key in obj) { + if (key === 'value') continue; -utils.removeType = function(state, node) { - assert(utils.isNode(node), 'expected node to be an instance of Node'); - assert(isObject(state), 'expected state to be an object'); + if (!data.hasOwnProperty(key)) { + continue; + } - var type = node.parent - ? node.parent.type - : node.type.replace(/\.close$/, ''); + if (typeOf(obj[key]) === data[key]) { + continue; + } - if (state.inside.hasOwnProperty(type)) { - return state.inside[type].pop(); + if (typeof obj[key] !== 'undefined') { + return false; + } } + return true; }; -/** - * Returns true if `node.val` is an empty string, or `node.nodes` does - * not contain any non-empty text nodes. - * - * ```js - * var node = new Node({type: 'text'}); - * utils.isEmpty(node); //=> true - * node.val = 'foo'; - * utils.isEmpty(node); //=> false - * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @param {Function} `fn` - * @return {Boolean} - * @api public - */ - -utils.isEmpty = function(node, fn) { - assert(utils.isNode(node), 'expected node to be an instance of Node'); - - if (!Array.isArray(node.nodes)) { - if (node.type !== 'text') { - return true; - } - if (typeof fn === 'function') { - return fn(node, node.parent); - } - return !utils.trim(node.val); - } - - for (var i = 0; i < node.nodes.length; i++) { - var child = node.nodes[i]; - if (utils.isOpen(child) || utils.isClose(child)) { - continue; - } - if (!utils.isEmpty(child, fn)) { - return false; - } - } - return true; -}; +/***/ }), +/* 421 */ +/***/ (function(module, exports) { -/** - * Returns true if the `state.inside` stack for the given type exists - * and has one or more nodes on it. - * - * ```js - * var state = { inside: {}}; - * var node = new Node({type: 'brace'}); - * console.log(utils.isInsideType(state, 'brace')); //=> false - * utils.addType(state, node); - * console.log(utils.isInsideType(state, 'brace')); //=> true - * utils.removeType(state, node); - * console.log(utils.isInsideType(state, 'brace')); //=> false - * ``` - * @param {Object} `state` - * @param {String} `type` - * @return {Boolean} - * @api public - */ +var toString = Object.prototype.toString; -utils.isInsideType = function(state, type) { - assert(isObject(state), 'expected state to be an object'); - assert(isString(type), 'expected type to be a string'); +module.exports = function kindOf(val) { + if (val === void 0) return 'undefined'; + if (val === null) return 'null'; - if (!state.hasOwnProperty('inside')) { - return false; + var type = typeof val; + if (type === 'boolean') return 'boolean'; + if (type === 'string') return 'string'; + if (type === 'number') return 'number'; + if (type === 'symbol') return 'symbol'; + if (type === 'function') { + return isGeneratorFn(val) ? 'generatorfunction' : 'function'; } - if (!state.inside.hasOwnProperty(type)) { - return false; - } + if (isArray(val)) return 'array'; + if (isBuffer(val)) return 'buffer'; + if (isArguments(val)) return 'arguments'; + if (isDate(val)) return 'date'; + if (isError(val)) return 'error'; + if (isRegexp(val)) return 'regexp'; - return state.inside[type].length > 0; -}; + switch (ctorName(val)) { + case 'Symbol': return 'symbol'; + case 'Promise': return 'promise'; -/** - * Returns true if `node` is either a child or grand-child of the given `type`, - * or `state.inside[type]` is a non-empty array. - * - * ```js - * var state = { inside: {}}; - * var node = new Node({type: 'brace'}); - * var open = new Node({type: 'brace.open'}); - * console.log(utils.isInside(state, open, 'brace')); //=> false - * utils.pushNode(node, open); - * console.log(utils.isInside(state, open, 'brace')); //=> true - * ``` - * @param {Object} `state` Either the `compiler.state` object, if it exists, or a user-supplied state object. - * @param {Object} `node` Instance of [snapdragon-node][] - * @param {String} `type` The `node.type` to check for. - * @return {Boolean} - * @api public - */ + // Set, Map, WeakSet, WeakMap + case 'WeakMap': return 'weakmap'; + case 'WeakSet': return 'weakset'; + case 'Map': return 'map'; + case 'Set': return 'set'; -utils.isInside = function(state, node, type) { - assert(utils.isNode(node), 'expected node to be an instance of Node'); - assert(isObject(state), 'expected state to be an object'); + // 8-bit typed arrays + case 'Int8Array': return 'int8array'; + case 'Uint8Array': return 'uint8array'; + case 'Uint8ClampedArray': return 'uint8clampedarray'; - if (Array.isArray(type)) { - for (var i = 0; i < type.length; i++) { - if (utils.isInside(state, node, type[i])) { - return true; - } - } - return false; - } + // 16-bit typed arrays + case 'Int16Array': return 'int16array'; + case 'Uint16Array': return 'uint16array'; - var parent = node.parent; - if (typeof type === 'string') { - return (parent && parent.type === type) || utils.isInsideType(state, type); + // 32-bit typed arrays + case 'Int32Array': return 'int32array'; + case 'Uint32Array': return 'uint32array'; + case 'Float32Array': return 'float32array'; + case 'Float64Array': return 'float64array'; } - if (typeOf(type) === 'regexp') { - if (parent && parent.type && type.test(parent.type)) { - return true; - } - - var keys = Object.keys(state.inside); - var len = keys.length; - var idx = -1; - while (++idx < len) { - var key = keys[idx]; - var val = state.inside[key]; - - if (Array.isArray(val) && val.length !== 0 && type.test(key)) { - return true; - } - } + if (isGeneratorObj(val)) { + return 'generator'; } - return false; -}; - -/** - * Get the last `n` element from the given `array`. Used for getting - * a node from `node.nodes.` - * - * @param {Array} `array` - * @param {Number} `n` - * @return {undefined} - * @api public - */ -utils.last = function(arr, n) { - return arr[arr.length - (n || 1)]; -}; - -/** - * Cast the given `val` to an array. - * - * ```js - * console.log(utils.arrayify('')); - * //=> [] - * console.log(utils.arrayify('foo')); - * //=> ['foo'] - * console.log(utils.arrayify(['foo'])); - * //=> ['foo'] - * ``` - * @param {any} `val` - * @return {Array} - * @api public - */ - -utils.arrayify = function(val) { - if (typeof val === 'string' && val !== '') { - return [val]; - } - if (!Array.isArray(val)) { - return []; + // Non-plain objects + type = toString.call(val); + switch (type) { + case '[object Object]': return 'object'; + // iterators + case '[object Map Iterator]': return 'mapiterator'; + case '[object Set Iterator]': return 'setiterator'; + case '[object String Iterator]': return 'stringiterator'; + case '[object Array Iterator]': return 'arrayiterator'; } - return val; -}; - -/** - * Convert the given `val` to a string by joining with `,`. Useful - * for creating a cheerio/CSS/DOM-style selector from a list of strings. - * - * @param {any} `val` - * @return {Array} - * @api public - */ - -utils.stringify = function(val) { - return utils.arrayify(val).join(','); -}; - -/** - * Ensure that the given value is a string and call `.trim()` on it, - * or return an empty string. - * - * @param {String} `str` - * @return {String} - * @api public - */ -utils.trim = function(str) { - return typeof str === 'string' ? str.trim() : ''; + // other + return type.slice(8, -1).toLowerCase().replace(/\s/g, ''); }; -/** - * Return true if val is an object - */ - -function isObject(val) { - return typeOf(val) === 'object'; +function ctorName(val) { + return val.constructor ? val.constructor.name : null; } -/** - * Return true if val is a string - */ - -function isString(val) { - return typeof val === 'string'; +function isArray(val) { + if (Array.isArray) return Array.isArray(val); + return val instanceof Array; } -/** - * Return true if val is a function - */ +function isError(val) { + return val instanceof Error || (typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number'); +} -function isFunction(val) { - return typeof val === 'function'; +function isDate(val) { + if (val instanceof Date) return true; + return typeof val.toDateString === 'function' + && typeof val.getDate === 'function' + && typeof val.setDate === 'function'; } -/** - * Return true if val is an array - */ +function isRegexp(val) { + if (val instanceof RegExp) return true; + return typeof val.flags === 'string' + && typeof val.ignoreCase === 'boolean' + && typeof val.multiline === 'boolean' + && typeof val.global === 'boolean'; +} -function isArray(val) { - return Array.isArray(val); +function isGeneratorFn(name, val) { + return ctorName(name) === 'GeneratorFunction'; } -/** - * Shim to ensure the `.append` methods work with any version of snapdragon - */ +function isGeneratorObj(val) { + return typeof val.throw === 'function' + && typeof val.return === 'function' + && typeof val.next === 'function'; +} -function append(compiler, val, node) { - if (typeof compiler.append !== 'function') { - return compiler.emit(val, node); +function isArguments(val) { + try { + if (typeof val.length === 'number' && typeof val.callee === 'function') { + return true; + } + } catch (err) { + if (err.message.indexOf('callee') !== -1) { + return true; + } } - return compiler.append(val, node); + return false; } /** - * Simplified assertion. Throws an error is `val` is falsey. + * If you need to support Safari 5-7 (8-10 yr-old browser), + * take a look at https://github.com/feross/is-buffer */ -function assert(val, message) { - if (!val) throw new Error(message); +function isBuffer(val) { + if (val.constructor && typeof val.constructor.isBuffer === 'function') { + return val.constructor.isBuffer(val); + } + return false; } /***/ }), -/* 423 */ +/* 422 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var Snapdragon = __webpack_require__(424); -var compilers = __webpack_require__(405); -var parsers = __webpack_require__(420); -var utils = __webpack_require__(406); +var typeOf = __webpack_require__(409); +var utils = module.exports; /** - * Customize Snapdragon parser and renderer + * Returns true if the given value is a node. + * + * ```js + * var Node = require('snapdragon-node'); + * var node = new Node({type: 'foo'}); + * console.log(utils.isNode(node)); //=> true + * console.log(utils.isNode({})); //=> false + * ``` + * @param {Object} `node` Instance of [snapdragon-node][] + * @returns {Boolean} + * @api public */ -function Braces(options) { - this.options = utils.extend({}, options); -} +utils.isNode = function(node) { + return typeOf(node) === 'object' && node.isNode === true; +}; /** - * Initialize braces + * Emit an empty string for the given `node`. + * + * ```js + * // do nothing for beginning-of-string + * snapdragon.compiler.set('bos', utils.noop); + * ``` + * @param {Object} `node` Instance of [snapdragon-node][] + * @returns {undefined} + * @api public */ -Braces.prototype.init = function(options) { - var opts = utils.createOptions({}, this.options, options); - this.snapdragon = this.options.snapdragon || new Snapdragon(opts); - this.compiler = this.snapdragon.compiler; - this.parser = this.snapdragon.parser; - - compilers(this.snapdragon, opts); - parsers(this.snapdragon, opts); - - /** - * Call Snapdragon `.parse` method. When AST is returned, we check to - * see if any unclosed braces are left on the stack and, if so, we iterate - * over the stack and correct the AST so that compilers are called in the correct - * order and unbalance braces are properly escaped. - */ - - utils.define(this.snapdragon, 'parse', function(pattern, options) { - var parsed = Snapdragon.prototype.parse.apply(this, arguments); - this.parser.ast.input = pattern; - - var stack = this.parser.stack; - while (stack.length) { - addParent({type: 'brace.close', val: ''}, stack.pop()); - } - - function addParent(node, parent) { - utils.define(node, 'parent', parent); - parent.nodes.push(node); - } - - // add non-enumerable parser reference - utils.define(parsed, 'parser', this.parser); - return parsed; - }); +utils.noop = function(node) { + append(this, '', node); }; /** - * Lazily initialize braces + * Appdend `node.val` to `compiler.output`, exactly as it was created + * by the parser. + * + * ```js + * snapdragon.compiler.set('text', utils.identity); + * ``` + * @param {Object} `node` Instance of [snapdragon-node][] + * @returns {undefined} + * @api public */ -Braces.prototype.lazyInit = function(options) { - if (!this.isInitialized) { - this.isInitialized = true; - this.init(options); - } +utils.identity = function(node) { + append(this, node.val, node); }; /** - * Decorate `.parse` method + * Previously named `.emit`, this method appends the given `val` + * to `compiler.output` for the given node. Useful when you know + * what value should be appended advance, regardless of the actual + * value of `node.val`. + * + * ```js + * snapdragon.compiler + * .set('i', function(node) { + * this.mapVisit(node); + * }) + * .set('i.open', utils.append('')) + * .set('i.close', utils.append('')) + * ``` + * @param {Object} `node` Instance of [snapdragon-node][] + * @returns {Function} Returns a compiler middleware function. + * @api public */ -Braces.prototype.parse = function(ast, options) { - if (utils.isObject(ast) && ast.nodes) return ast; - this.lazyInit(options); - return this.snapdragon.parse(ast, options); +utils.append = function(val) { + return function(node) { + append(this, val, node); + }; }; /** - * Decorate `.compile` method + * Used in compiler middleware, this onverts an AST node into + * an empty `text` node and deletes `node.nodes` if it exists. + * The advantage of this method is that, as opposed to completely + * removing the node, indices will not need to be re-calculated + * in sibling nodes, and nothing is appended to the output. + * + * ```js + * utils.toNoop(node); + * // convert `node.nodes` to the given value instead of deleting it + * utils.toNoop(node, []); + * ``` + * @param {Object} `node` Instance of [snapdragon-node][] + * @param {Array} `nodes` Optionally pass a new `nodes` value, to replace the existing `node.nodes` array. + * @api public */ -Braces.prototype.compile = function(ast, options) { - if (typeof ast === 'string') { - ast = this.parse(ast, options); +utils.toNoop = function(node, nodes) { + if (nodes) { + node.nodes = nodes; } else { - this.lazyInit(options); + delete node.nodes; + node.type = 'text'; + node.val = ''; } - var res = this.snapdragon.compile(ast, options); - return res; -}; - -/** - * Expand - */ - -Braces.prototype.expand = function(pattern) { - var ast = this.parse(pattern, {expand: true}); - return this.compile(ast, {expand: true}); }; /** - * Optimize + * Visit `node` with the given `fn`. The built-in `.visit` method in snapdragon + * automatically calls registered compilers, this allows you to pass a visitor + * function. + * + * ```js + * snapdragon.compiler.set('i', function(node) { + * utils.visit(node, function(childNode) { + * // do stuff with "childNode" + * return childNode; + * }); + * }); + * ``` + * @param {Object} `node` Instance of [snapdragon-node][] + * @param {Function} `fn` + * @return {Object} returns the node after recursively visiting all child nodes. + * @api public */ -Braces.prototype.optimize = function(pattern) { - var ast = this.parse(pattern, {optimize: true}); - return this.compile(ast, {optimize: true}); +utils.visit = function(node, fn) { + assert(utils.isNode(node), 'expected node to be an instance of Node'); + assert(isFunction(fn), 'expected a visitor function'); + fn(node); + return node.nodes ? utils.mapVisit(node, fn) : node; }; /** - * Expose `Braces` - */ - -module.exports = Braces; - - -/***/ }), -/* 424 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var Base = __webpack_require__(425); -var define = __webpack_require__(473); -var Compiler = __webpack_require__(480); -var Parser = __webpack_require__(517); -var utils = __webpack_require__(497); -var regexCache = {}; -var cache = {}; - -/** - * Create a new instance of `Snapdragon` with the given `options`. + * Map [visit](#visit) the given `fn` over `node.nodes`. This is called by + * [visit](#visit), use this method if you do not want `fn` to be called on + * the first node. * * ```js - * var snapdragon = new Snapdragon(); + * snapdragon.compiler.set('i', function(node) { + * utils.mapVisit(node, function(childNode) { + * // do stuff with "childNode" + * return childNode; + * }); + * }); * ``` - * + * @param {Object} `node` Instance of [snapdragon-node][] * @param {Object} `options` + * @param {Function} `fn` + * @return {Object} returns the node * @api public */ -function Snapdragon(options) { - Base.call(this, null, options); - this.options = utils.extend({source: 'string'}, this.options); - this.compiler = new Compiler(this.options); - this.parser = new Parser(this.options); - - Object.defineProperty(this, 'compilers', { - get: function() { - return this.compiler.compilers; - } - }); +utils.mapVisit = function(node, fn) { + assert(utils.isNode(node), 'expected node to be an instance of Node'); + assert(isArray(node.nodes), 'expected node.nodes to be an array'); + assert(isFunction(fn), 'expected a visitor function'); - Object.defineProperty(this, 'parsers', { - get: function() { - return this.parser.parsers; - } - }); - - Object.defineProperty(this, 'regex', { - get: function() { - return this.parser.regex; - } - }); -} + for (var i = 0; i < node.nodes.length; i++) { + utils.visit(node.nodes[i], fn); + } + return node; +}; /** - * Inherit Base + * Unshift an `*.open` node onto `node.nodes`. + * + * ```js + * var Node = require('snapdragon-node'); + * snapdragon.parser.set('brace', function(node) { + * var match = this.match(/^{/); + * if (match) { + * var parent = new Node({type: 'brace'}); + * utils.addOpen(parent, Node); + * console.log(parent.nodes[0]): + * // { type: 'brace.open', val: '' }; + * + * // push the parent "brace" node onto the stack + * this.push(parent); + * + * // return the parent node, so it's also added to the AST + * return brace; + * } + * }); + * ``` + * @param {Object} `node` Instance of [snapdragon-node][] + * @param {Function} `Node` (required) Node constructor function from [snapdragon-node][]. + * @param {Function} `filter` Optionaly specify a filter function to exclude the node. + * @return {Object} Returns the created opening node. + * @api public */ -Base.extend(Snapdragon); +utils.addOpen = function(node, Node, val, filter) { + assert(utils.isNode(node), 'expected node to be an instance of Node'); + assert(isFunction(Node), 'expected Node to be a constructor function'); + + if (typeof val === 'function') { + filter = val; + val = ''; + } + + if (typeof filter === 'function' && !filter(node)) return; + var open = new Node({ type: node.type + '.open', val: val}); + var unshift = node.unshift || node.unshiftNode; + if (typeof unshift === 'function') { + unshift.call(node, open); + } else { + utils.unshiftNode(node, open); + } + return open; +}; /** - * Add a parser to `snapdragon.parsers` for capturing the given `type` using - * the specified regex or parser function. A function is useful if you need - * to customize how the token is created and/or have access to the parser - * instance to check options, etc. + * Push a `*.close` node onto `node.nodes`. * * ```js - * snapdragon - * .capture('slash', /^\//) - * .capture('dot', function() { - * var pos = this.position(); - * var m = this.match(/^\./); - * if (!m) return; - * return pos({ - * type: 'dot', - * val: m[0] - * }); - * }); + * var Node = require('snapdragon-node'); + * snapdragon.parser.set('brace', function(node) { + * var match = this.match(/^}/); + * if (match) { + * var parent = this.parent(); + * if (parent.type !== 'brace') { + * throw new Error('missing opening: ' + '}'); + * } + * + * utils.addClose(parent, Node); + * console.log(parent.nodes[parent.nodes.length - 1]): + * // { type: 'brace.close', val: '' }; + * + * // no need to return a node, since the parent + * // was already added to the AST + * return; + * } + * }); * ``` - * @param {String} `type` - * @param {RegExp|Function} `regex` - * @return {Object} Returns the parser instance for chaining + * @param {Object} `node` Instance of [snapdragon-node][] + * @param {Function} `Node` (required) Node constructor function from [snapdragon-node][]. + * @param {Function} `filter` Optionaly specify a filter function to exclude the node. + * @return {Object} Returns the created closing node. * @api public */ -Snapdragon.prototype.capture = function() { - return this.parser.capture.apply(this.parser, arguments); +utils.addClose = function(node, Node, val, filter) { + assert(utils.isNode(node), 'expected node to be an instance of Node'); + assert(isFunction(Node), 'expected Node to be a constructor function'); + + if (typeof val === 'function') { + filter = val; + val = ''; + } + + if (typeof filter === 'function' && !filter(node)) return; + var close = new Node({ type: node.type + '.close', val: val}); + var push = node.push || node.pushNode; + if (typeof push === 'function') { + push.call(node, close); + } else { + utils.pushNode(node, close); + } + return close; }; /** - * Register a plugin `fn`. + * Wraps the given `node` with `*.open` and `*.close` nodes. * - * ```js - * var snapdragon = new Snapdgragon([options]); - * snapdragon.use(function() { - * console.log(this); //<= snapdragon instance - * console.log(this.parser); //<= parser instance - * console.log(this.compiler); //<= compiler instance - * }); - * ``` - * @param {Object} `fn` + * @param {Object} `node` Instance of [snapdragon-node][] + * @param {Function} `Node` (required) Node constructor function from [snapdragon-node][]. + * @param {Function} `filter` Optionaly specify a filter function to exclude the node. + * @return {Object} Returns the node * @api public */ -Snapdragon.prototype.use = function(fn) { - fn.call(this, this); - return this; +utils.wrapNodes = function(node, Node, filter) { + assert(utils.isNode(node), 'expected node to be an instance of Node'); + assert(isFunction(Node), 'expected Node to be a constructor function'); + + utils.addOpen(node, Node, filter); + utils.addClose(node, Node, filter); + return node; }; /** - * Parse the given `str`. + * Push the given `node` onto `parent.nodes`, and set `parent` as `node.parent. * * ```js - * var snapdragon = new Snapdgragon([options]); - * // register parsers - * snapdragon.parser.use(function() {}); - * - * // parse - * var ast = snapdragon.parse('foo/bar'); - * console.log(ast); + * var parent = new Node({type: 'foo'}); + * var node = new Node({type: 'bar'}); + * utils.pushNode(parent, node); + * console.log(parent.nodes[0].type) // 'bar' + * console.log(node.parent.type) // 'foo' * ``` - * @param {String} `str` - * @param {Object} `options` Set `options.sourcemap` to true to enable source maps. - * @return {Object} Returns an AST. + * @param {Object} `parent` + * @param {Object} `node` Instance of [snapdragon-node][] + * @return {Object} Returns the child node * @api public */ -Snapdragon.prototype.parse = function(str, options) { - this.options = utils.extend({}, this.options, options); - var parsed = this.parser.parse(str, this.options); +utils.pushNode = function(parent, node) { + assert(utils.isNode(parent), 'expected parent node to be an instance of Node'); + assert(utils.isNode(node), 'expected node to be an instance of Node'); - // add non-enumerable parser reference - define(parsed, 'parser', this.parser); - return parsed; + node.define('parent', parent); + parent.nodes = parent.nodes || []; + parent.nodes.push(node); + return node; }; /** - * Compile the given `AST`. + * Unshift `node` onto `parent.nodes`, and set `parent` as `node.parent. * * ```js - * var snapdragon = new Snapdgragon([options]); - * // register plugins - * snapdragon.use(function() {}); - * // register parser plugins - * snapdragon.parser.use(function() {}); - * // register compiler plugins - * snapdragon.compiler.use(function() {}); - * - * // parse - * var ast = snapdragon.parse('foo/bar'); - * - * // compile - * var res = snapdragon.compile(ast); - * console.log(res.output); + * var parent = new Node({type: 'foo'}); + * var node = new Node({type: 'bar'}); + * utils.unshiftNode(parent, node); + * console.log(parent.nodes[0].type) // 'bar' + * console.log(node.parent.type) // 'foo' * ``` - * @param {Object} `ast` - * @param {Object} `options` - * @return {Object} Returns an object with an `output` property with the rendered string. + * @param {Object} `parent` + * @param {Object} `node` Instance of [snapdragon-node][] + * @return {undefined} * @api public */ -Snapdragon.prototype.compile = function(ast, options) { - this.options = utils.extend({}, this.options, options); - var compiled = this.compiler.compile(ast, this.options); +utils.unshiftNode = function(parent, node) { + assert(utils.isNode(parent), 'expected parent node to be an instance of Node'); + assert(utils.isNode(node), 'expected node to be an instance of Node'); - // add non-enumerable compiler reference - define(compiled, 'compiler', this.compiler); - return compiled; + node.define('parent', parent); + parent.nodes = parent.nodes || []; + parent.nodes.unshift(node); }; /** - * Expose `Snapdragon` + * Pop the last `node` off of `parent.nodes`. The advantage of + * using this method is that it checks for `node.nodes` and works + * with any version of `snapdragon-node`. + * + * ```js + * var parent = new Node({type: 'foo'}); + * utils.pushNode(parent, new Node({type: 'foo'})); + * utils.pushNode(parent, new Node({type: 'bar'})); + * utils.pushNode(parent, new Node({type: 'baz'})); + * console.log(parent.nodes.length); //=> 3 + * utils.popNode(parent); + * console.log(parent.nodes.length); //=> 2 + * ``` + * @param {Object} `parent` + * @param {Object} `node` Instance of [snapdragon-node][] + * @return {Number|Undefined} Returns the length of `node.nodes` or undefined. + * @api public */ -module.exports = Snapdragon; +utils.popNode = function(node) { + assert(utils.isNode(node), 'expected node to be an instance of Node'); + if (typeof node.pop === 'function') { + return node.pop(); + } + return node.nodes && node.nodes.pop(); +}; /** - * Expose `Parser` and `Compiler` + * Shift the first `node` off of `parent.nodes`. The advantage of + * using this method is that it checks for `node.nodes` and works + * with any version of `snapdragon-node`. + * + * ```js + * var parent = new Node({type: 'foo'}); + * utils.pushNode(parent, new Node({type: 'foo'})); + * utils.pushNode(parent, new Node({type: 'bar'})); + * utils.pushNode(parent, new Node({type: 'baz'})); + * console.log(parent.nodes.length); //=> 3 + * utils.shiftNode(parent); + * console.log(parent.nodes.length); //=> 2 + * ``` + * @param {Object} `parent` + * @param {Object} `node` Instance of [snapdragon-node][] + * @return {Number|Undefined} Returns the length of `node.nodes` or undefined. + * @api public */ -module.exports.Compiler = Compiler; -module.exports.Parser = Parser; +utils.shiftNode = function(node) { + assert(utils.isNode(node), 'expected node to be an instance of Node'); + if (typeof node.shift === 'function') { + return node.shift(); + } + return node.nodes && node.nodes.shift(); +}; +/** + * Remove the specified `node` from `parent.nodes`. + * + * ```js + * var parent = new Node({type: 'abc'}); + * var foo = new Node({type: 'foo'}); + * utils.pushNode(parent, foo); + * utils.pushNode(parent, new Node({type: 'bar'})); + * utils.pushNode(parent, new Node({type: 'baz'})); + * console.log(parent.nodes.length); //=> 3 + * utils.removeNode(parent, foo); + * console.log(parent.nodes.length); //=> 2 + * ``` + * @param {Object} `parent` + * @param {Object} `node` Instance of [snapdragon-node][] + * @return {Object|undefined} Returns the removed node, if successful, or undefined if it does not exist on `parent.nodes`. + * @api public + */ -/***/ }), -/* 425 */ -/***/ (function(module, exports, __webpack_require__) { +utils.removeNode = function(parent, node) { + assert(utils.isNode(parent), 'expected parent.node to be an instance of Node'); + assert(utils.isNode(node), 'expected node to be an instance of Node'); -"use strict"; + if (!parent.nodes) { + return null; + } + if (typeof parent.remove === 'function') { + return parent.remove(node); + } -var util = __webpack_require__(29); -var define = __webpack_require__(398); -var CacheBase = __webpack_require__(426); -var Emitter = __webpack_require__(427); -var isObject = __webpack_require__(411); -var merge = __webpack_require__(445); -var pascal = __webpack_require__(448); -var cu = __webpack_require__(449); + var idx = parent.nodes.indexOf(node); + if (idx !== -1) { + return parent.nodes.splice(idx, 1); + } +}; /** - * Optionally define a custom `cache` namespace to use. + * Returns true if `node.type` matches the given `type`. Throws a + * `TypeError` if `node` is not an instance of `Node`. + * + * ```js + * var Node = require('snapdragon-node'); + * var node = new Node({type: 'foo'}); + * console.log(utils.isType(node, 'foo')); // false + * console.log(utils.isType(node, 'bar')); // true + * ``` + * @param {Object} `node` Instance of [snapdragon-node][] + * @param {String} `type` + * @return {Boolean} + * @api public */ -function namespace(name) { - var Cache = name ? CacheBase.namespace(name) : CacheBase; - var fns = []; +utils.isType = function(node, type) { + assert(utils.isNode(node), 'expected node to be an instance of Node'); + switch (typeOf(type)) { + case 'array': + var types = type.slice(); + for (var i = 0; i < types.length; i++) { + if (utils.isType(node, types[i])) { + return true; + } + } + return false; + case 'string': + return node.type === type; + case 'regexp': + return type.test(node.type); + default: { + throw new TypeError('expected "type" to be an array, string or regexp'); + } + } +}; - /** - * Create an instance of `Base` with the given `config` and `options`. - * - * ```js - * // initialize with `config` and `options` - * var app = new Base({isApp: true}, {abc: true}); - * app.set('foo', 'bar'); - * - * // values defined with the given `config` object will be on the root of the instance - * console.log(app.baz); //=> undefined - * console.log(app.foo); //=> 'bar' - * // or use `.get` - * console.log(app.get('isApp')); //=> true - * console.log(app.get('foo')); //=> 'bar' - * - * // values defined with the given `options` object will be on `app.options - * console.log(app.options.abc); //=> true - * ``` - * - * @param {Object} `config` If supplied, this object is passed to [cache-base][] to merge onto the the instance upon instantiation. - * @param {Object} `options` If supplied, this object is used to initialize the `base.options` object. - * @api public - */ +/** + * Returns true if the given `node` has the given `type` in `node.nodes`. + * Throws a `TypeError` if `node` is not an instance of `Node`. + * + * ```js + * var Node = require('snapdragon-node'); + * var node = new Node({ + * type: 'foo', + * nodes: [ + * new Node({type: 'bar'}), + * new Node({type: 'baz'}) + * ] + * }); + * console.log(utils.hasType(node, 'xyz')); // false + * console.log(utils.hasType(node, 'baz')); // true + * ``` + * @param {Object} `node` Instance of [snapdragon-node][] + * @param {String} `type` + * @return {Boolean} + * @api public + */ - function Base(config, options) { - if (!(this instanceof Base)) { - return new Base(config, options); +utils.hasType = function(node, type) { + assert(utils.isNode(node), 'expected node to be an instance of Node'); + if (!Array.isArray(node.nodes)) return false; + for (var i = 0; i < node.nodes.length; i++) { + if (utils.isType(node.nodes[i], type)) { + return true; } - Cache.call(this, config); - this.is('base'); - this.initBase(config, options); } + return false; +}; - /** - * Inherit cache-base - */ +/** + * Returns the first node from `node.nodes` of the given `type` + * + * ```js + * var node = new Node({ + * type: 'foo', + * nodes: [ + * new Node({type: 'text', val: 'abc'}), + * new Node({type: 'text', val: 'xyz'}) + * ] + * }); + * + * var textNode = utils.firstOfType(node.nodes, 'text'); + * console.log(textNode.val); + * //=> 'abc' + * ``` + * @param {Array} `nodes` + * @param {String} `type` + * @return {Object|undefined} Returns the first matching node or undefined. + * @api public + */ - util.inherits(Base, Cache); +utils.firstOfType = function(nodes, type) { + for (var i = 0; i < nodes.length; i++) { + var node = nodes[i]; + if (utils.isType(node, type)) { + return node; + } + } +}; - /** - * Add static emitter methods - */ +/** + * Returns the node at the specified index, or the first node of the + * given `type` from `node.nodes`. + * + * ```js + * var node = new Node({ + * type: 'foo', + * nodes: [ + * new Node({type: 'text', val: 'abc'}), + * new Node({type: 'text', val: 'xyz'}) + * ] + * }); + * + * var nodeOne = utils.findNode(node.nodes, 'text'); + * console.log(nodeOne.val); + * //=> 'abc' + * + * var nodeTwo = utils.findNode(node.nodes, 1); + * console.log(nodeTwo.val); + * //=> 'xyz' + * ``` + * + * @param {Array} `nodes` + * @param {String|Number} `type` Node type or index. + * @return {Object} Returns a node or undefined. + * @api public + */ - Emitter(Base); +utils.findNode = function(nodes, type) { + if (!Array.isArray(nodes)) { + return null; + } + if (typeof type === 'number') { + return nodes[type]; + } + return utils.firstOfType(nodes, type); +}; - /** - * Initialize `Base` defaults with the given `config` object - */ +/** + * Returns true if the given node is an "*.open" node. + * + * ```js + * var Node = require('snapdragon-node'); + * var brace = new Node({type: 'brace'}); + * var open = new Node({type: 'brace.open'}); + * var close = new Node({type: 'brace.close'}); + * + * console.log(utils.isOpen(brace)); // false + * console.log(utils.isOpen(open)); // true + * console.log(utils.isOpen(close)); // false + * ``` + * @param {Object} `node` Instance of [snapdragon-node][] + * @return {Boolean} + * @api public + */ - Base.prototype.initBase = function(config, options) { - this.options = merge({}, this.options, options); - this.cache = this.cache || {}; - this.define('registered', {}); - if (name) this[name] = {}; - - // make `app._callbacks` non-enumerable - this.define('_callbacks', this._callbacks); - if (isObject(config)) { - this.visit('set', config); - } - Base.run(this, 'use', fns); - }; - - /** - * Set the given `name` on `app._name` and `app.is*` properties. Used for doing - * lookups in plugins. - * - * ```js - * app.is('foo'); - * console.log(app._name); - * //=> 'foo' - * console.log(app.isFoo); - * //=> true - * app.is('bar'); - * console.log(app.isFoo); - * //=> true - * console.log(app.isBar); - * //=> true - * console.log(app._name); - * //=> 'bar' - * ``` - * @name .is - * @param {String} `name` - * @return {Boolean} - * @api public - */ - - Base.prototype.is = function(name) { - if (typeof name !== 'string') { - throw new TypeError('expected name to be a string'); - } - this.define('is' + pascal(name), true); - this.define('_name', name); - this.define('_appname', name); - return this; - }; - - /** - * Returns true if a plugin has already been registered on an instance. - * - * Plugin implementors are encouraged to use this first thing in a plugin - * to prevent the plugin from being called more than once on the same - * instance. - * - * ```js - * var base = new Base(); - * base.use(function(app) { - * if (app.isRegistered('myPlugin')) return; - * // do stuff to `app` - * }); - * - * // to also record the plugin as being registered - * base.use(function(app) { - * if (app.isRegistered('myPlugin', true)) return; - * // do stuff to `app` - * }); - * ``` - * @name .isRegistered - * @emits `plugin` Emits the name of the plugin being registered. Useful for unit tests, to ensure plugins are only registered once. - * @param {String} `name` The plugin name. - * @param {Boolean} `register` If the plugin if not already registered, to record it as being registered pass `true` as the second argument. - * @return {Boolean} Returns true if a plugin is already registered. - * @api public - */ - - Base.prototype.isRegistered = function(name, register) { - if (this.registered.hasOwnProperty(name)) { - return true; - } - if (register !== false) { - this.registered[name] = true; - this.emit('plugin', name); - } - return false; - }; - - /** - * Define a plugin function to be called immediately upon init. Plugins are chainable - * and expose the following arguments to the plugin function: - * - * - `app`: the current instance of `Base` - * - `base`: the [first ancestor instance](#base) of `Base` - * - * ```js - * var app = new Base() - * .use(foo) - * .use(bar) - * .use(baz) - * ``` - * @name .use - * @param {Function} `fn` plugin function to call - * @return {Object} Returns the item instance for chaining. - * @api public - */ - - Base.prototype.use = function(fn) { - fn.call(this, this); - return this; - }; - - /** - * The `.define` method is used for adding non-enumerable property on the instance. - * Dot-notation is **not supported** with `define`. - * - * ```js - * // arbitrary `render` function using lodash `template` - * app.define('render', function(str, locals) { - * return _.template(str)(locals); - * }); - * ``` - * @name .define - * @param {String} `key` The name of the property to define. - * @param {any} `value` - * @return {Object} Returns the instance for chaining. - * @api public - */ - - Base.prototype.define = function(key, val) { - if (isObject(key)) { - return this.visit('define', key); - } - define(this, key, val); - return this; - }; - - /** - * Mix property `key` onto the Base prototype. If base is inherited using - * `Base.extend` this method will be overridden by a new `mixin` method that will - * only add properties to the prototype of the inheriting application. - * - * ```js - * app.mixin('foo', function() { - * // do stuff - * }); - * ``` - * @name .mixin - * @param {String} `key` - * @param {Object|Array} `val` - * @return {Object} Returns the `base` instance for chaining. - * @api public - */ - - Base.prototype.mixin = function(key, val) { - Base.prototype[key] = val; - return this; - }; - - /** - * Non-enumberable mixin array, used by the static [Base.mixin]() method. - */ - - Base.prototype.mixins = Base.prototype.mixins || []; - - /** - * Getter/setter used when creating nested instances of `Base`, for storing a reference - * to the first ancestor instance. This works by setting an instance of `Base` on the `parent` - * property of a "child" instance. The `base` property defaults to the current instance if - * no `parent` property is defined. - * - * ```js - * // create an instance of `Base`, this is our first ("base") instance - * var first = new Base(); - * first.foo = 'bar'; // arbitrary property, to make it easier to see what's happening later - * - * // create another instance - * var second = new Base(); - * // create a reference to the first instance (`first`) - * second.parent = first; - * - * // create another instance - * var third = new Base(); - * // create a reference to the previous instance (`second`) - * // repeat this pattern every time a "child" instance is created - * third.parent = second; - * - * // we can always access the first instance using the `base` property - * console.log(first.base.foo); - * //=> 'bar' - * console.log(second.base.foo); - * //=> 'bar' - * console.log(third.base.foo); - * //=> 'bar' - * // and now you know how to get to third base ;) - * ``` - * @name .base - * @api public - */ - - Object.defineProperty(Base.prototype, 'base', { - configurable: true, - get: function() { - return this.parent ? this.parent.base : this; - } - }); - - /** - * Static method for adding global plugin functions that will - * be added to an instance when created. - * - * ```js - * Base.use(function(app) { - * app.foo = 'bar'; - * }); - * var app = new Base(); - * console.log(app.foo); - * //=> 'bar' - * ``` - * @name #use - * @param {Function} `fn` Plugin function to use on each instance. - * @return {Object} Returns the `Base` constructor for chaining - * @api public - */ - - define(Base, 'use', function(fn) { - fns.push(fn); - return Base; - }); - - /** - * Run an array of functions by passing each function - * to a method on the given object specified by the given property. - * - * @param {Object} `obj` Object containing method to use. - * @param {String} `prop` Name of the method on the object to use. - * @param {Array} `arr` Array of functions to pass to the method. - */ - - define(Base, 'run', function(obj, prop, arr) { - var len = arr.length, i = 0; - while (len--) { - obj[prop](arr[i++]); - } - return Base; - }); - - /** - * Static method for inheriting the prototype and static methods of the `Base` class. - * This method greatly simplifies the process of creating inheritance-based applications. - * See [static-extend][] for more details. - * - * ```js - * var extend = cu.extend(Parent); - * Parent.extend(Child); - * - * // optional methods - * Parent.extend(Child, { - * foo: function() {}, - * bar: function() {} - * }); - * ``` - * @name #extend - * @param {Function} `Ctor` constructor to extend - * @param {Object} `methods` Optional prototype properties to mix in. - * @return {Object} Returns the `Base` constructor for chaining - * @api public - */ - - define(Base, 'extend', cu.extend(Base, function(Ctor, Parent) { - Ctor.prototype.mixins = Ctor.prototype.mixins || []; - - define(Ctor, 'mixin', function(fn) { - var mixin = fn(Ctor.prototype, Ctor); - if (typeof mixin === 'function') { - Ctor.prototype.mixins.push(mixin); - } - return Ctor; - }); - - define(Ctor, 'mixins', function(Child) { - Base.run(Child, 'mixin', Ctor.prototype.mixins); - return Ctor; - }); - - Ctor.prototype.mixin = function(key, value) { - Ctor.prototype[key] = value; - return this; - }; - return Base; - })); - - /** - * Used for adding methods to the `Base` prototype, and/or to the prototype of child instances. - * When a mixin function returns a function, the returned function is pushed onto the `.mixins` - * array, making it available to be used on inheriting classes whenever `Base.mixins()` is - * called (e.g. `Base.mixins(Child)`). - * - * ```js - * Base.mixin(function(proto) { - * proto.foo = function(msg) { - * return 'foo ' + msg; - * }; - * }); - * ``` - * @name #mixin - * @param {Function} `fn` Function to call - * @return {Object} Returns the `Base` constructor for chaining - * @api public - */ - - define(Base, 'mixin', function(fn) { - var mixin = fn(Base.prototype, Base); - if (typeof mixin === 'function') { - Base.prototype.mixins.push(mixin); - } - return Base; - }); - - /** - * Static method for running global mixin functions against a child constructor. - * Mixins must be registered before calling this method. - * - * ```js - * Base.extend(Child); - * Base.mixins(Child); - * ``` - * @name #mixins - * @param {Function} `Child` Constructor function of a child class - * @return {Object} Returns the `Base` constructor for chaining - * @api public - */ - - define(Base, 'mixins', function(Child) { - Base.run(Child, 'mixin', Base.prototype.mixins); - return Base; - }); - - /** - * Similar to `util.inherit`, but copies all static properties, prototype properties, and - * getters/setters from `Provider` to `Receiver`. See [class-utils][]{#inherit} for more details. - * - * ```js - * Base.inherit(Foo, Bar); - * ``` - * @name #inherit - * @param {Function} `Receiver` Receiving (child) constructor - * @param {Function} `Provider` Providing (parent) constructor - * @return {Object} Returns the `Base` constructor for chaining - * @api public - */ - - define(Base, 'inherit', cu.inherit); - define(Base, 'bubble', cu.bubble); - return Base; -} - -/** - * Expose `Base` with default settings - */ - -module.exports = namespace(); - -/** - * Allow users to define a namespace - */ - -module.exports.namespace = namespace; - - -/***/ }), -/* 426 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var isObject = __webpack_require__(411); -var Emitter = __webpack_require__(427); -var visit = __webpack_require__(428); -var toPath = __webpack_require__(431); -var union = __webpack_require__(432); -var del = __webpack_require__(436); -var get = __webpack_require__(434); -var has = __webpack_require__(441); -var set = __webpack_require__(444); - -/** - * Create a `Cache` constructor that when instantiated will - * store values on the given `prop`. - * - * ```js - * var Cache = require('cache-base').namespace('data'); - * var cache = new Cache(); - * - * cache.set('foo', 'bar'); - * //=> {data: {foo: 'bar'}} - * ``` - * @param {String} `prop` The property name to use for storing values. - * @return {Function} Returns a custom `Cache` constructor - * @api public - */ - -function namespace(prop) { - - /** - * Create a new `Cache`. Internally the `Cache` constructor is created using - * the `namespace` function, with `cache` defined as the storage object. - * - * ```js - * var app = new Cache(); - * ``` - * @param {Object} `cache` Optionally pass an object to initialize with. - * @constructor - * @api public - */ - - function Cache(cache) { - if (prop) { - this[prop] = {}; - } - if (cache) { - this.set(cache); - } - } - - /** - * Inherit Emitter - */ - - Emitter(Cache.prototype); - - /** - * Assign `value` to `key`. Also emits `set` with - * the key and value. - * - * ```js - * app.on('set', function(key, val) { - * // do something when `set` is emitted - * }); - * - * app.set(key, value); - * - * // also takes an object or array - * app.set({name: 'Halle'}); - * app.set([{foo: 'bar'}, {baz: 'quux'}]); - * console.log(app); - * //=> {name: 'Halle', foo: 'bar', baz: 'quux'} - * ``` - * - * @name .set - * @emits `set` with `key` and `value` as arguments. - * @param {String} `key` - * @param {any} `value` - * @return {Object} Returns the instance for chaining. - * @api public - */ - - Cache.prototype.set = function(key, val) { - if (Array.isArray(key) && arguments.length === 2) { - key = toPath(key); - } - if (isObject(key) || Array.isArray(key)) { - this.visit('set', key); - } else { - set(prop ? this[prop] : this, key, val); - this.emit('set', key, val); - } - return this; - }; - - /** - * Union `array` to `key`. Also emits `set` with - * the key and value. - * - * ```js - * app.union('a.b', ['foo']); - * app.union('a.b', ['bar']); - * console.log(app.get('a')); - * //=> {b: ['foo', 'bar']} - * ``` - * @name .union - * @param {String} `key` - * @param {any} `value` - * @return {Object} Returns the instance for chaining. - * @api public - */ - - Cache.prototype.union = function(key, val) { - if (Array.isArray(key) && arguments.length === 2) { - key = toPath(key); - } - var ctx = prop ? this[prop] : this; - union(ctx, key, arrayify(val)); - this.emit('union', val); - return this; - }; - - /** - * Return the value of `key`. Dot notation may be used - * to get [nested property values][get-value]. - * - * ```js - * app.set('a.b.c', 'd'); - * app.get('a.b'); - * //=> {c: 'd'} - * - * app.get(['a', 'b']); - * //=> {c: 'd'} - * ``` - * - * @name .get - * @emits `get` with `key` and `value` as arguments. - * @param {String} `key` The name of the property to get. Dot-notation may be used. - * @return {any} Returns the value of `key` - * @api public - */ - - Cache.prototype.get = function(key) { - key = toPath(arguments); - - var ctx = prop ? this[prop] : this; - var val = get(ctx, key); - - this.emit('get', key, val); - return val; - }; - - /** - * Return true if app has a stored value for `key`, - * false only if value is `undefined`. - * - * ```js - * app.set('foo', 'bar'); - * app.has('foo'); - * //=> true - * ``` - * - * @name .has - * @emits `has` with `key` and true or false as arguments. - * @param {String} `key` - * @return {Boolean} - * @api public - */ - - Cache.prototype.has = function(key) { - key = toPath(arguments); - - var ctx = prop ? this[prop] : this; - var val = get(ctx, key); - - var has = typeof val !== 'undefined'; - this.emit('has', key, has); - return has; - }; - - /** - * Delete one or more properties from the instance. - * - * ```js - * app.del(); // delete all - * // or - * app.del('foo'); - * // or - * app.del(['foo', 'bar']); - * ``` - * @name .del - * @emits `del` with the `key` as the only argument. - * @param {String|Array} `key` Property name or array of property names. - * @return {Object} Returns the instance for chaining. - * @api public - */ - - Cache.prototype.del = function(key) { - if (Array.isArray(key)) { - this.visit('del', key); - } else { - del(prop ? this[prop] : this, key); - this.emit('del', key); - } - return this; - }; - - /** - * Reset the entire cache to an empty object. - * - * ```js - * app.clear(); - * ``` - * @api public - */ - - Cache.prototype.clear = function() { - if (prop) { - this[prop] = {}; - } - }; - - /** - * Visit `method` over the properties in the given object, or map - * visit over the object-elements in an array. - * - * @name .visit - * @param {String} `method` The name of the `base` method to call. - * @param {Object|Array} `val` The object or array to iterate over. - * @return {Object} Returns the instance for chaining. - * @api public - */ - - Cache.prototype.visit = function(method, val) { - visit(this, method, val); - return this; - }; - - return Cache; -} - -/** - * Cast val to an array - */ - -function arrayify(val) { - return val ? (Array.isArray(val) ? val : [val]) : []; -} - -/** - * Expose `Cache` - */ - -module.exports = namespace(); - -/** - * Expose `Cache.namespace` - */ - -module.exports.namespace = namespace; - - -/***/ }), -/* 427 */ -/***/ (function(module, exports, __webpack_require__) { - - -/** - * Expose `Emitter`. - */ - -if (true) { - module.exports = Emitter; -} - -/** - * Initialize a new `Emitter`. - * - * @api public - */ - -function Emitter(obj) { - if (obj) return mixin(obj); -}; - -/** - * Mixin the emitter properties. - * - * @param {Object} obj - * @return {Object} - * @api private - */ - -function mixin(obj) { - for (var key in Emitter.prototype) { - obj[key] = Emitter.prototype[key]; - } - return obj; -} - -/** - * Listen on the given `event` with `fn`. - * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public - */ - -Emitter.prototype.on = -Emitter.prototype.addEventListener = function(event, fn){ - this._callbacks = this._callbacks || {}; - (this._callbacks['$' + event] = this._callbacks['$' + event] || []) - .push(fn); - return this; -}; - -/** - * Adds an `event` listener that will be invoked a single - * time then automatically removed. - * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public - */ - -Emitter.prototype.once = function(event, fn){ - function on() { - this.off(event, on); - fn.apply(this, arguments); - } - - on.fn = fn; - this.on(event, on); - return this; -}; - -/** - * Remove the given callback for `event` or all - * registered callbacks. - * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public - */ - -Emitter.prototype.off = -Emitter.prototype.removeListener = -Emitter.prototype.removeAllListeners = -Emitter.prototype.removeEventListener = function(event, fn){ - this._callbacks = this._callbacks || {}; - - // all - if (0 == arguments.length) { - this._callbacks = {}; - return this; - } - - // specific event - var callbacks = this._callbacks['$' + event]; - if (!callbacks) return this; - - // remove all handlers - if (1 == arguments.length) { - delete this._callbacks['$' + event]; - return this; - } - - // remove specific handler - var cb; - for (var i = 0; i < callbacks.length; i++) { - cb = callbacks[i]; - if (cb === fn || cb.fn === fn) { - callbacks.splice(i, 1); - break; - } - } - return this; -}; - -/** - * Emit `event` with the given args. - * - * @param {String} event - * @param {Mixed} ... - * @return {Emitter} - */ - -Emitter.prototype.emit = function(event){ - this._callbacks = this._callbacks || {}; - var args = [].slice.call(arguments, 1) - , callbacks = this._callbacks['$' + event]; - - if (callbacks) { - callbacks = callbacks.slice(0); - for (var i = 0, len = callbacks.length; i < len; ++i) { - callbacks[i].apply(this, args); - } - } - - return this; -}; - -/** - * Return array of callbacks for `event`. - * - * @param {String} event - * @return {Array} - * @api public - */ - -Emitter.prototype.listeners = function(event){ - this._callbacks = this._callbacks || {}; - return this._callbacks['$' + event] || []; -}; - -/** - * Check if this emitter has `event` handlers. - * - * @param {String} event - * @return {Boolean} - * @api public - */ - -Emitter.prototype.hasListeners = function(event){ - return !! this.listeners(event).length; -}; - - -/***/ }), -/* 428 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * collection-visit - * - * Copyright (c) 2015, 2017, Jon Schlinkert. - * Released under the MIT License. - */ - - - -var visit = __webpack_require__(429); -var mapVisit = __webpack_require__(430); - -module.exports = function(collection, method, val) { - var result; - - if (typeof val === 'string' && (method in collection)) { - var args = [].slice.call(arguments, 2); - result = collection[method].apply(collection, args); - } else if (Array.isArray(val)) { - result = mapVisit.apply(null, arguments); - } else { - result = visit.apply(null, arguments); - } - - if (typeof result !== 'undefined') { - return result; - } - - return collection; -}; - - -/***/ }), -/* 429 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * object-visit - * - * Copyright (c) 2015, 2017, Jon Schlinkert. - * Released under the MIT License. - */ - - - -var isObject = __webpack_require__(411); - -module.exports = function visit(thisArg, method, target, val) { - if (!isObject(thisArg) && typeof thisArg !== 'function') { - throw new Error('object-visit expects `thisArg` to be an object.'); - } - - if (typeof method !== 'string') { - throw new Error('object-visit expects `method` name to be a string'); - } - - if (typeof thisArg[method] !== 'function') { - return thisArg; - } - - var args = [].slice.call(arguments, 3); - target = target || {}; - - for (var key in target) { - var arr = [key, target[key]].concat(args); - thisArg[method].apply(thisArg, arr); - } - return thisArg; -}; - - -/***/ }), -/* 430 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var util = __webpack_require__(29); -var visit = __webpack_require__(429); - -/** - * Map `visit` over an array of objects. - * - * @param {Object} `collection` The context in which to invoke `method` - * @param {String} `method` Name of the method to call on `collection` - * @param {Object} `arr` Array of objects. - */ - -module.exports = function mapVisit(collection, method, val) { - if (isObject(val)) { - return visit.apply(null, arguments); - } - - if (!Array.isArray(val)) { - throw new TypeError('expected an array: ' + util.inspect(val)); - } - - var args = [].slice.call(arguments, 3); - - for (var i = 0; i < val.length; i++) { - var ele = val[i]; - if (isObject(ele)) { - visit.apply(null, [collection, method, ele].concat(args)); - } else { - collection[method].apply(collection, [ele].concat(args)); - } - } -}; - -function isObject(val) { - return val && (typeof val === 'function' || (!Array.isArray(val) && typeof val === 'object')); -} - - -/***/ }), -/* 431 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * to-object-path - * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. - */ - - - -var typeOf = __webpack_require__(416); - -module.exports = function toPath(args) { - if (typeOf(args) !== 'arguments') { - args = arguments; - } - return filter(args).join('.'); -}; - -function filter(arr) { - var len = arr.length; - var idx = -1; - var res = []; - - while (++idx < len) { - var ele = arr[idx]; - if (typeOf(ele) === 'arguments' || Array.isArray(ele)) { - res.push.apply(res, filter(ele)); - } else if (typeof ele === 'string') { - res.push(ele); - } - } - return res; -} - - -/***/ }), -/* 432 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var isObject = __webpack_require__(395); -var union = __webpack_require__(433); -var get = __webpack_require__(434); -var set = __webpack_require__(435); - -module.exports = function unionValue(obj, prop, value) { - if (!isObject(obj)) { - throw new TypeError('union-value expects the first argument to be an object.'); - } - - if (typeof prop !== 'string') { - throw new TypeError('union-value expects `prop` to be a string.'); - } - - var arr = arrayify(get(obj, prop)); - set(obj, prop, union(arr, arrayify(value))); - return obj; -}; - -function arrayify(val) { - if (val === null || typeof val === 'undefined') { - return []; - } - if (Array.isArray(val)) { - return val; - } - return [val]; -} - - -/***/ }), -/* 433 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = function union(init) { - if (!Array.isArray(init)) { - throw new TypeError('arr-union expects the first argument to be an array.'); - } - - var len = arguments.length; - var i = 0; - - while (++i < len) { - var arg = arguments[i]; - if (!arg) continue; - - if (!Array.isArray(arg)) { - arg = [arg]; - } - - for (var j = 0; j < arg.length; j++) { - var ele = arg[j]; - - if (init.indexOf(ele) >= 0) { - continue; - } - init.push(ele); - } - } - return init; -}; - - -/***/ }), -/* 434 */ -/***/ (function(module, exports) { - -/*! - * get-value - * - * Copyright (c) 2014-2015, Jon Schlinkert. - * Licensed under the MIT License. - */ - -module.exports = function(obj, prop, a, b, c) { - if (!isObject(obj) || !prop) { - return obj; - } - - prop = toString(prop); - - // allowing for multiple properties to be passed as - // a string or array, but much faster (3-4x) than doing - // `[].slice.call(arguments)` - if (a) prop += '.' + toString(a); - if (b) prop += '.' + toString(b); - if (c) prop += '.' + toString(c); - - if (prop in obj) { - return obj[prop]; - } - - var segs = prop.split('.'); - var len = segs.length; - var i = -1; - - while (obj && (++i < len)) { - var key = segs[i]; - while (key[key.length - 1] === '\\') { - key = key.slice(0, -1) + '.' + segs[++i]; - } - obj = obj[key]; - } - return obj; -}; - -function isObject(val) { - return val !== null && (typeof val === 'object' || typeof val === 'function'); -} - -function toString(val) { - if (!val) return ''; - if (Array.isArray(val)) { - return val.join('.'); - } - return val; -} - - -/***/ }), -/* 435 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * set-value - * - * Copyright (c) 2014-2015, 2017, Jon Schlinkert. - * Released under the MIT License. - */ - - - -var toPath = __webpack_require__(431); -var extend = __webpack_require__(394); -var isPlainObject = __webpack_require__(410); -var isObject = __webpack_require__(395); - -module.exports = function(obj, path, val) { - if (!isObject(obj)) { - return obj; - } - - if (Array.isArray(path)) { - path = toPath(path); - } - - if (typeof path !== 'string') { - return obj; - } - - var segs = path.split('.'); - var len = segs.length, i = -1; - var res = obj; - var last; - - while (++i < len) { - var key = segs[i]; - - while (key[key.length - 1] === '\\') { - key = key.slice(0, -1) + '.' + segs[++i]; - } - - if (i === len - 1) { - last = key; - break; - } - - if (!isObject(obj[key])) { - obj[key] = {}; - } - obj = obj[key]; - } - - if (obj.hasOwnProperty(last) && isObject(obj[last])) { - if (isPlainObject(val)) { - extend(obj[last], val); - } else { - obj[last] = val; - } - - } else { - obj[last] = val; - } - return res; -}; - - - -/***/ }), -/* 436 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * unset-value - * - * Copyright (c) 2015, 2017, Jon Schlinkert. - * Released under the MIT License. - */ - - - -var isObject = __webpack_require__(411); -var has = __webpack_require__(437); - -module.exports = function unset(obj, prop) { - if (!isObject(obj)) { - throw new TypeError('expected an object.'); - } - if (obj.hasOwnProperty(prop)) { - delete obj[prop]; - return true; - } - - if (has(obj, prop)) { - var segs = prop.split('.'); - var last = segs.pop(); - while (segs.length && segs[segs.length - 1].slice(-1) === '\\') { - last = segs.pop().slice(0, -1) + '.' + last; - } - while (segs.length) obj = obj[prop = segs.shift()]; - return (delete obj[last]); - } - return true; -}; - - -/***/ }), -/* 437 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * has-value - * - * Copyright (c) 2014-2016, Jon Schlinkert. - * Licensed under the MIT License. - */ - - - -var isObject = __webpack_require__(438); -var hasValues = __webpack_require__(440); -var get = __webpack_require__(434); - -module.exports = function(obj, prop, noZero) { - if (isObject(obj)) { - return hasValues(get(obj, prop), noZero); - } - return hasValues(obj, prop); -}; - - -/***/ }), -/* 438 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * isobject - * - * Copyright (c) 2014-2015, Jon Schlinkert. - * Licensed under the MIT License. - */ - - - -var isArray = __webpack_require__(439); - -module.exports = function isObject(val) { - return val != null && typeof val === 'object' && isArray(val) === false; -}; - - -/***/ }), -/* 439 */ -/***/ (function(module, exports) { - -var toString = {}.toString; - -module.exports = Array.isArray || function (arr) { - return toString.call(arr) == '[object Array]'; -}; - - -/***/ }), -/* 440 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * has-values - * - * Copyright (c) 2014-2015, Jon Schlinkert. - * Licensed under the MIT License. - */ - - - -module.exports = function hasValue(o, noZero) { - if (o === null || o === undefined) { - return false; - } - - if (typeof o === 'boolean') { - return true; - } - - if (typeof o === 'number') { - if (o === 0 && noZero === true) { - return false; - } - return true; - } - - if (o.length !== undefined) { - return o.length !== 0; - } - - for (var key in o) { - if (o.hasOwnProperty(key)) { - return true; - } - } - return false; -}; - - -/***/ }), -/* 441 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * has-value - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Licensed under the MIT License. - */ - - - -var isObject = __webpack_require__(411); -var hasValues = __webpack_require__(442); -var get = __webpack_require__(434); - -module.exports = function(val, prop) { - return hasValues(isObject(val) && prop ? get(val, prop) : val); -}; - - -/***/ }), -/* 442 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * has-values - * - * Copyright (c) 2014-2015, 2017, Jon Schlinkert. - * Released under the MIT License. - */ - - - -var typeOf = __webpack_require__(443); -var isNumber = __webpack_require__(415); - -module.exports = function hasValue(val) { - // is-number checks for NaN and other edge cases - if (isNumber(val)) { - return true; - } - - switch (typeOf(val)) { - case 'null': - case 'boolean': - case 'function': - return true; - case 'string': - case 'arguments': - return val.length !== 0; - case 'error': - return val.message !== ''; - case 'array': - var len = val.length; - if (len === 0) { - return false; - } - for (var i = 0; i < len; i++) { - if (hasValue(val[i])) { - return true; - } - } - return false; - case 'file': - case 'map': - case 'set': - return val.size !== 0; - case 'object': - var keys = Object.keys(val); - if (keys.length === 0) { - return false; - } - for (var i = 0; i < keys.length; i++) { - var key = keys[i]; - if (hasValue(val[key])) { - return true; - } - } - return false; - default: { - return false; - } - } -}; - - -/***/ }), -/* 443 */ -/***/ (function(module, exports, __webpack_require__) { - -var isBuffer = __webpack_require__(391); -var toString = Object.prototype.toString; - -/** - * Get the native `typeof` a value. - * - * @param {*} `val` - * @return {*} Native javascript type - */ - -module.exports = function kindOf(val) { - // primitivies - if (typeof val === 'undefined') { - return 'undefined'; - } - if (val === null) { - return 'null'; - } - if (val === true || val === false || val instanceof Boolean) { - return 'boolean'; - } - if (typeof val === 'string' || val instanceof String) { - return 'string'; - } - if (typeof val === 'number' || val instanceof Number) { - return 'number'; - } - - // functions - if (typeof val === 'function' || val instanceof Function) { - return 'function'; - } - - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; - } - - // check for instances of RegExp and Date before calling `toString` - if (val instanceof RegExp) { - return 'regexp'; - } - if (val instanceof Date) { - return 'date'; - } - - // other objects - var type = toString.call(val); - - if (type === '[object RegExp]') { - return 'regexp'; - } - if (type === '[object Date]') { - return 'date'; - } - if (type === '[object Arguments]') { - return 'arguments'; - } - if (type === '[object Error]') { - return 'error'; - } - if (type === '[object Promise]') { - return 'promise'; - } - - // buffer - if (isBuffer(val)) { - return 'buffer'; - } - - // es6: Map, WeakMap, Set, WeakSet - if (type === '[object Set]') { - return 'set'; - } - if (type === '[object WeakSet]') { - return 'weakset'; - } - if (type === '[object Map]') { - return 'map'; - } - if (type === '[object WeakMap]') { - return 'weakmap'; - } - if (type === '[object Symbol]') { - return 'symbol'; - } - - // typed arrays - if (type === '[object Int8Array]') { - return 'int8array'; - } - if (type === '[object Uint8Array]') { - return 'uint8array'; - } - if (type === '[object Uint8ClampedArray]') { - return 'uint8clampedarray'; - } - if (type === '[object Int16Array]') { - return 'int16array'; - } - if (type === '[object Uint16Array]') { - return 'uint16array'; - } - if (type === '[object Int32Array]') { - return 'int32array'; - } - if (type === '[object Uint32Array]') { - return 'uint32array'; - } - if (type === '[object Float32Array]') { - return 'float32array'; - } - if (type === '[object Float64Array]') { - return 'float64array'; - } - - // must be a plain object - return 'object'; -}; - - -/***/ }), -/* 444 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * set-value - * - * Copyright (c) 2014-2015, 2017, Jon Schlinkert. - * Released under the MIT License. - */ - - - -var split = __webpack_require__(407); -var extend = __webpack_require__(394); -var isPlainObject = __webpack_require__(410); -var isObject = __webpack_require__(395); - -module.exports = function(obj, prop, val) { - if (!isObject(obj)) { - return obj; - } - - if (Array.isArray(prop)) { - prop = [].concat.apply([], prop).join('.'); - } - - if (typeof prop !== 'string') { - return obj; - } - - var keys = split(prop, {sep: '.', brackets: true}); - var len = keys.length; - var idx = -1; - var current = obj; - - while (++idx < len) { - var key = keys[idx]; - if (idx !== len - 1) { - if (!isObject(current[key])) { - current[key] = {}; - } - current = current[key]; - continue; - } - - if (isPlainObject(current[key]) && isPlainObject(val)) { - current[key] = extend({}, current[key], val); - } else { - current[key] = val; - } - } - - return obj; -}; - - -/***/ }), -/* 445 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var isExtendable = __webpack_require__(446); -var forIn = __webpack_require__(447); - -function mixinDeep(target, objects) { - var len = arguments.length, i = 0; - while (++i < len) { - var obj = arguments[i]; - if (isObject(obj)) { - forIn(obj, copy, target); - } - } - return target; -} +utils.isOpen = function(node) { + assert(utils.isNode(node), 'expected node to be an instance of Node'); + return node.type.slice(-5) === '.open'; +}; /** - * Copy properties from the source object to the - * target object. + * Returns true if the given node is a "*.close" node. * - * @param {*} `val` - * @param {String} `key` - */ - -function copy(val, key) { - var obj = this[key]; - if (isObject(val) && isObject(obj)) { - mixinDeep(obj, val); - } else { - this[key] = val; - } -} - -/** - * Returns true if `val` is an object or function. + * ```js + * var Node = require('snapdragon-node'); + * var brace = new Node({type: 'brace'}); + * var open = new Node({type: 'brace.open'}); + * var close = new Node({type: 'brace.close'}); * - * @param {any} val + * console.log(utils.isClose(brace)); // false + * console.log(utils.isClose(open)); // false + * console.log(utils.isClose(close)); // true + * ``` + * @param {Object} `node` Instance of [snapdragon-node][] * @return {Boolean} + * @api public */ -function isObject(val) { - return isExtendable(val) && !Array.isArray(val); -} +utils.isClose = function(node) { + assert(utils.isNode(node), 'expected node to be an instance of Node'); + return node.type.slice(-6) === '.close'; +}; /** - * Expose `mixinDeep` - */ - -module.exports = mixinDeep; - - -/***/ }), -/* 446 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * is-extendable + * Returns true if `node.nodes` **has** an `.open` node * - * Copyright (c) 2015-2017, Jon Schlinkert. - * Released under the MIT License. - */ - - - -var isPlainObject = __webpack_require__(410); - -module.exports = function isExtendable(val) { - return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); -}; - - -/***/ }), -/* 447 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * for-in + * ```js + * var Node = require('snapdragon-node'); + * var brace = new Node({ + * type: 'brace', + * nodes: [] + * }); * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ - - - -module.exports = function forIn(obj, fn, thisArg) { - for (var key in obj) { - if (fn.call(thisArg, obj[key], key, obj) === false) { - break; - } - } -}; - - -/***/ }), -/* 448 */ -/***/ (function(module, exports) { - -/*! - * pascalcase + * var open = new Node({type: 'brace.open'}); + * console.log(utils.hasOpen(brace)); // false * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. + * brace.pushNode(open); + * console.log(utils.hasOpen(brace)); // true + * ``` + * @param {Object} `node` Instance of [snapdragon-node][] + * @return {Boolean} + * @api public */ -function pascalcase(str) { - if (typeof str !== 'string') { - throw new TypeError('expected a string.'); +utils.hasOpen = function(node) { + assert(utils.isNode(node), 'expected node to be an instance of Node'); + var first = node.first || node.nodes ? node.nodes[0] : null; + if (utils.isNode(first)) { + return first.type === node.type + '.open'; } - str = str.replace(/([A-Z])/g, ' $1'); - if (str.length === 1) { return str.toUpperCase(); } - str = str.replace(/^[\W_]+|[\W_]+$/g, '').toLowerCase(); - str = str.charAt(0).toUpperCase() + str.slice(1); - return str.replace(/[\W_]+(\w|$)/g, function (_, ch) { - return ch.toUpperCase(); - }); -} - -module.exports = pascalcase; - - -/***/ }), -/* 449 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var util = __webpack_require__(29); -var utils = __webpack_require__(450); - -/** - * Expose class utils - */ - -var cu = module.exports; - -/** - * Expose class utils: `cu` - */ - -cu.isObject = function isObject(val) { - return utils.isObj(val) || typeof val === 'function'; + return false; }; /** - * Returns true if an array has any of the given elements, or an - * object has any of the give keys. + * Returns true if `node.nodes` **has** a `.close` node * * ```js - * cu.has(['a', 'b', 'c'], 'c'); - * //=> true + * var Node = require('snapdragon-node'); + * var brace = new Node({ + * type: 'brace', + * nodes: [] + * }); * - * cu.has(['a', 'b', 'c'], ['c', 'z']); - * //=> true + * var close = new Node({type: 'brace.close'}); + * console.log(utils.hasClose(brace)); // false * - * cu.has({a: 'b', c: 'd'}, ['c', 'z']); - * //=> true + * brace.pushNode(close); + * console.log(utils.hasClose(brace)); // true * ``` - * @param {Object} `obj` - * @param {String|Array} `val` + * @param {Object} `node` Instance of [snapdragon-node][] * @return {Boolean} * @api public */ -cu.has = function has(obj, val) { - val = cu.arrayify(val); - var len = val.length; - - if (cu.isObject(obj)) { - for (var key in obj) { - if (val.indexOf(key) > -1) { - return true; - } - } - - var keys = cu.nativeKeys(obj); - return cu.has(keys, val); - } - - if (Array.isArray(obj)) { - var arr = obj; - while (len--) { - if (arr.indexOf(val[len]) > -1) { - return true; - } - } - return false; +utils.hasClose = function(node) { + assert(utils.isNode(node), 'expected node to be an instance of Node'); + var last = node.last || node.nodes ? node.nodes[node.nodes.length - 1] : null; + if (utils.isNode(last)) { + return last.type === node.type + '.close'; } - - throw new TypeError('expected an array or object.'); + return false; }; /** - * Returns true if an array or object has all of the given values. + * Returns true if `node.nodes` has both `.open` and `.close` nodes * * ```js - * cu.hasAll(['a', 'b', 'c'], 'c'); - * //=> true + * var Node = require('snapdragon-node'); + * var brace = new Node({ + * type: 'brace', + * nodes: [] + * }); * - * cu.hasAll(['a', 'b', 'c'], ['c', 'z']); - * //=> false + * var open = new Node({type: 'brace.open'}); + * var close = new Node({type: 'brace.close'}); + * console.log(utils.hasOpen(brace)); // false + * console.log(utils.hasClose(brace)); // false * - * cu.hasAll({a: 'b', c: 'd'}, ['c', 'z']); - * //=> false + * brace.pushNode(open); + * brace.pushNode(close); + * console.log(utils.hasOpen(brace)); // true + * console.log(utils.hasClose(brace)); // true * ``` - * @param {Object|Array} `val` - * @param {String|Array} `values` + * @param {Object} `node` Instance of [snapdragon-node][] * @return {Boolean} * @api public */ -cu.hasAll = function hasAll(val, values) { - values = cu.arrayify(values); - var len = values.length; - while (len--) { - if (!cu.has(val, values[len])) { - return false; - } - } - return true; +utils.hasOpenAndClose = function(node) { + return utils.hasOpen(node) && utils.hasClose(node); }; /** - * Cast the given value to an array. + * Push the given `node` onto the `state.inside` array for the + * given type. This array is used as a specialized "stack" for + * only the given `node.type`. * * ```js - * cu.arrayify('foo'); - * //=> ['foo'] - * - * cu.arrayify(['foo']); - * //=> ['foo'] + * var state = { inside: {}}; + * var node = new Node({type: 'brace'}); + * utils.addType(state, node); + * console.log(state.inside); + * //=> { brace: [{type: 'brace'}] } * ``` - * - * @param {String|Array} `val` - * @return {Array} + * @param {Object} `state` The `compiler.state` object or custom state object. + * @param {Object} `node` Instance of [snapdragon-node][] + * @return {Array} Returns the `state.inside` stack for the given type. * @api public */ -cu.arrayify = function arrayify(val) { - return val ? (Array.isArray(val) ? val : [val]) : []; -}; - -/** - * Noop - */ +utils.addType = function(state, node) { + assert(utils.isNode(node), 'expected node to be an instance of Node'); + assert(isObject(state), 'expected state to be an object'); -cu.noop = function noop() { - return; -}; + var type = node.parent + ? node.parent.type + : node.type.replace(/\.open$/, ''); -/** - * Returns the first argument passed to the function. - */ + if (!state.hasOwnProperty('inside')) { + state.inside = {}; + } + if (!state.inside.hasOwnProperty(type)) { + state.inside[type] = []; + } -cu.identity = function identity(val) { - return val; + var arr = state.inside[type]; + arr.push(node); + return arr; }; /** - * Returns true if a value has a `contructor` + * Remove the given `node` from the `state.inside` array for the + * given type. This array is used as a specialized "stack" for + * only the given `node.type`. * * ```js - * cu.hasConstructor({}); - * //=> true - * - * cu.hasConstructor(Object.create(null)); - * //=> false + * var state = { inside: {}}; + * var node = new Node({type: 'brace'}); + * utils.addType(state, node); + * console.log(state.inside); + * //=> { brace: [{type: 'brace'}] } + * utils.removeType(state, node); + * //=> { brace: [] } * ``` - * @param {Object} `value` - * @return {Boolean} + * @param {Object} `state` The `compiler.state` object or custom state object. + * @param {Object} `node` Instance of [snapdragon-node][] + * @return {Array} Returns the `state.inside` stack for the given type. * @api public */ -cu.hasConstructor = function hasConstructor(val) { - return cu.isObject(val) && typeof val.constructor !== 'undefined'; -}; +utils.removeType = function(state, node) { + assert(utils.isNode(node), 'expected node to be an instance of Node'); + assert(isObject(state), 'expected state to be an object'); -/** - * Get the native `ownPropertyNames` from the constructor of the - * given `object`. An empty array is returned if the object does - * not have a constructor. - * - * ```js - * cu.nativeKeys({a: 'b', b: 'c', c: 'd'}) - * //=> ['a', 'b', 'c'] - * - * cu.nativeKeys(function(){}) - * //=> ['length', 'caller'] - * ``` - * - * @param {Object} `obj` Object that has a `constructor`. - * @return {Array} Array of keys. - * @api public - */ + var type = node.parent + ? node.parent.type + : node.type.replace(/\.close$/, ''); -cu.nativeKeys = function nativeKeys(val) { - if (!cu.hasConstructor(val)) return []; - return Object.getOwnPropertyNames(val); + if (state.inside.hasOwnProperty(type)) { + return state.inside[type].pop(); + } }; /** - * Returns property descriptor `key` if it's an "own" property - * of the given object. + * Returns true if `node.val` is an empty string, or `node.nodes` does + * not contain any non-empty text nodes. * * ```js - * function App() {} - * Object.defineProperty(App.prototype, 'count', { - * get: function() { - * return Object.keys(this).length; - * } - * }); - * cu.getDescriptor(App.prototype, 'count'); - * // returns: - * // { - * // get: [Function], - * // set: undefined, - * // enumerable: false, - * // configurable: false - * // } + * var node = new Node({type: 'text'}); + * utils.isEmpty(node); //=> true + * node.val = 'foo'; + * utils.isEmpty(node); //=> false * ``` - * - * @param {Object} `obj` - * @param {String} `key` - * @return {Object} Returns descriptor `key` + * @param {Object} `node` Instance of [snapdragon-node][] + * @param {Function} `fn` + * @return {Boolean} * @api public */ -cu.getDescriptor = function getDescriptor(obj, key) { - if (!cu.isObject(obj)) { - throw new TypeError('expected an object.'); +utils.isEmpty = function(node, fn) { + assert(utils.isNode(node), 'expected node to be an instance of Node'); + + if (!Array.isArray(node.nodes)) { + if (node.type !== 'text') { + return true; + } + if (typeof fn === 'function') { + return fn(node, node.parent); + } + return !utils.trim(node.val); } - if (typeof key !== 'string') { - throw new TypeError('expected key to be a string.'); + + for (var i = 0; i < node.nodes.length; i++) { + var child = node.nodes[i]; + if (utils.isOpen(child) || utils.isClose(child)) { + continue; + } + if (!utils.isEmpty(child, fn)) { + return false; + } } - return Object.getOwnPropertyDescriptor(obj, key); + + return true; }; /** - * Copy a descriptor from one object to another. + * Returns true if the `state.inside` stack for the given type exists + * and has one or more nodes on it. * * ```js - * function App() {} - * Object.defineProperty(App.prototype, 'count', { - * get: function() { - * return Object.keys(this).length; - * } - * }); - * var obj = {}; - * cu.copyDescriptor(obj, App.prototype, 'count'); + * var state = { inside: {}}; + * var node = new Node({type: 'brace'}); + * console.log(utils.isInsideType(state, 'brace')); //=> false + * utils.addType(state, node); + * console.log(utils.isInsideType(state, 'brace')); //=> true + * utils.removeType(state, node); + * console.log(utils.isInsideType(state, 'brace')); //=> false * ``` - * @param {Object} `receiver` - * @param {Object} `provider` - * @param {String} `name` - * @return {Object} + * @param {Object} `state` + * @param {String} `type` + * @return {Boolean} * @api public */ -cu.copyDescriptor = function copyDescriptor(receiver, provider, name) { - if (!cu.isObject(receiver)) { - throw new TypeError('expected receiving object to be an object.'); - } - if (!cu.isObject(provider)) { - throw new TypeError('expected providing object to be an object.'); +utils.isInsideType = function(state, type) { + assert(isObject(state), 'expected state to be an object'); + assert(isString(type), 'expected type to be a string'); + + if (!state.hasOwnProperty('inside')) { + return false; } - if (typeof name !== 'string') { - throw new TypeError('expected name to be a string.'); + + if (!state.inside.hasOwnProperty(type)) { + return false; } - var val = cu.getDescriptor(provider, name); - if (val) Object.defineProperty(receiver, name, val); + return state.inside[type].length > 0; }; /** - * Copy static properties, prototype properties, and descriptors - * from one object to another. + * Returns true if `node` is either a child or grand-child of the given `type`, + * or `state.inside[type]` is a non-empty array. * - * @param {Object} `receiver` - * @param {Object} `provider` - * @param {String|Array} `omit` One or more properties to omit - * @return {Object} + * ```js + * var state = { inside: {}}; + * var node = new Node({type: 'brace'}); + * var open = new Node({type: 'brace.open'}); + * console.log(utils.isInside(state, open, 'brace')); //=> false + * utils.pushNode(node, open); + * console.log(utils.isInside(state, open, 'brace')); //=> true + * ``` + * @param {Object} `state` Either the `compiler.state` object, if it exists, or a user-supplied state object. + * @param {Object} `node` Instance of [snapdragon-node][] + * @param {String} `type` The `node.type` to check for. + * @return {Boolean} * @api public */ -cu.copy = function copy(receiver, provider, omit) { - if (!cu.isObject(receiver)) { - throw new TypeError('expected receiving object to be an object.'); +utils.isInside = function(state, node, type) { + assert(utils.isNode(node), 'expected node to be an instance of Node'); + assert(isObject(state), 'expected state to be an object'); + + if (Array.isArray(type)) { + for (var i = 0; i < type.length; i++) { + if (utils.isInside(state, node, type[i])) { + return true; + } + } + return false; } - if (!cu.isObject(provider)) { - throw new TypeError('expected providing object to be an object.'); + + var parent = node.parent; + if (typeof type === 'string') { + return (parent && parent.type === type) || utils.isInsideType(state, type); } - var props = Object.getOwnPropertyNames(provider); - var keys = Object.keys(provider); - var len = props.length, - key; - omit = cu.arrayify(omit); - while (len--) { - key = props[len]; + if (typeOf(type) === 'regexp') { + if (parent && parent.type && type.test(parent.type)) { + return true; + } - if (cu.has(keys, key)) { - utils.define(receiver, key, provider[key]); - } else if (!(key in receiver) && !cu.has(omit, key)) { - cu.copyDescriptor(receiver, provider, key); + var keys = Object.keys(state.inside); + var len = keys.length; + var idx = -1; + while (++idx < len) { + var key = keys[idx]; + var val = state.inside[key]; + + if (Array.isArray(val) && val.length !== 0 && type.test(key)) { + return true; + } } } + return false; }; /** - * Inherit the static properties, prototype properties, and descriptors - * from of an object. + * Get the last `n` element from the given `array`. Used for getting + * a node from `node.nodes.` * - * @param {Object} `receiver` - * @param {Object} `provider` - * @param {String|Array} `omit` One or more properties to omit - * @return {Object} + * @param {Array} `array` + * @param {Number} `n` + * @return {undefined} * @api public */ -cu.inherit = function inherit(receiver, provider, omit) { - if (!cu.isObject(receiver)) { - throw new TypeError('expected receiving object to be an object.'); - } - if (!cu.isObject(provider)) { - throw new TypeError('expected providing object to be an object.'); - } - - var keys = []; - for (var key in provider) { - keys.push(key); - receiver[key] = provider[key]; - } - - keys = keys.concat(cu.arrayify(omit)); - - var a = provider.prototype || provider; - var b = receiver.prototype || receiver; - cu.copy(b, a, keys); +utils.last = function(arr, n) { + return arr[arr.length - (n || 1)]; }; /** - * Returns a function for extending the static properties, - * prototype properties, and descriptors from the `Parent` - * constructor onto `Child` constructors. + * Cast the given `val` to an array. * * ```js - * var extend = cu.extend(Parent); - * Parent.extend(Child); - * - * // optional methods - * Parent.extend(Child, { - * foo: function() {}, - * bar: function() {} - * }); + * console.log(utils.arrayify('')); + * //=> [] + * console.log(utils.arrayify('foo')); + * //=> ['foo'] + * console.log(utils.arrayify(['foo'])); + * //=> ['foo'] * ``` - * @param {Function} `Parent` Parent ctor - * @param {Function} `extend` Optional extend function to handle custom extensions. Useful when updating methods that require a specific prototype. - * @param {Function} `Child` Child ctor - * @param {Object} `proto` Optionally pass additional prototype properties to inherit. - * @return {Object} + * @param {any} `val` + * @return {Array} * @api public */ -cu.extend = function() { - // keep it lazy, instead of assigning to `cu.extend` - return utils.staticExtend.apply(null, arguments); +utils.arrayify = function(val) { + if (typeof val === 'string' && val !== '') { + return [val]; + } + if (!Array.isArray(val)) { + return []; + } + return val; }; /** - * Bubble up events emitted from static methods on the Parent ctor. + * Convert the given `val` to a string by joining with `,`. Useful + * for creating a cheerio/CSS/DOM-style selector from a list of strings. * - * @param {Object} `Parent` - * @param {Array} `events` Event names to bubble up + * @param {any} `val` + * @return {Array} * @api public */ -cu.bubble = function(Parent, events) { - events = events || []; - Parent.bubble = function(Child, arr) { - if (Array.isArray(arr)) { - events = utils.union([], events, arr); - } - var len = events.length; - var idx = -1; - while (++idx < len) { - var name = events[idx]; - Parent.on(name, Child.emit.bind(Child, name)); - } - cu.bubble(Child, events); - }; +utils.stringify = function(val) { + return utils.arrayify(val).join(','); }; +/** + * Ensure that the given value is a string and call `.trim()` on it, + * or return an empty string. + * + * @param {String} `str` + * @return {String} + * @api public + */ -/***/ }), -/* 450 */ -/***/ (function(module, exports, __webpack_require__) { +utils.trim = function(str) { + return typeof str === 'string' ? str.trim() : ''; +}; -"use strict"; +/** + * Return true if val is an object + */ +function isObject(val) { + return typeOf(val) === 'object'; +} -var utils = {}; +/** + * Return true if val is a string + */ + +function isString(val) { + return typeof val === 'string'; +} +/** + * Return true if val is a function + */ +function isFunction(val) { + return typeof val === 'function'; +} /** - * Lazily required module dependencies + * Return true if val is an array */ -utils.union = __webpack_require__(433); -utils.define = __webpack_require__(451); -utils.isObj = __webpack_require__(411); -utils.staticExtend = __webpack_require__(458); +function isArray(val) { + return Array.isArray(val); +} + +/** + * Shim to ensure the `.append` methods work with any version of snapdragon + */ +function append(compiler, val, node) { + if (typeof compiler.append !== 'function') { + return compiler.emit(val, node); + } + return compiler.append(val, node); +} /** - * Expose `utils` + * Simplified assertion. Throws an error is `val` is falsey. */ -module.exports = utils; +function assert(val, message) { + if (!val) throw new Error(message); +} /***/ }), -/* 451 */ +/* 423 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/*! - * define-property - * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. + + +var extend = __webpack_require__(394); +var Snapdragon = __webpack_require__(424); +var compilers = __webpack_require__(398); +var parsers = __webpack_require__(413); +var utils = __webpack_require__(399); + +/** + * Customize Snapdragon parser and renderer */ +function Braces(options) { + this.options = extend({}, options); +} + +/** + * Initialize braces + */ + +Braces.prototype.init = function(options) { + if (this.isInitialized) return; + this.isInitialized = true; + var opts = utils.createOptions({}, this.options, options); + this.snapdragon = this.options.snapdragon || new Snapdragon(opts); + this.compiler = this.snapdragon.compiler; + this.parser = this.snapdragon.parser; + compilers(this.snapdragon, opts); + parsers(this.snapdragon, opts); -var isDescriptor = __webpack_require__(452); + /** + * Call Snapdragon `.parse` method. When AST is returned, we check to + * see if any unclosed braces are left on the stack and, if so, we iterate + * over the stack and correct the AST so that compilers are called in the correct + * order and unbalance braces are properly escaped. + */ -module.exports = function defineProperty(obj, prop, val) { - if (typeof obj !== 'object' && typeof obj !== 'function') { - throw new TypeError('expected an object or function.'); - } + utils.define(this.snapdragon, 'parse', function(pattern, options) { + var parsed = Snapdragon.prototype.parse.apply(this, arguments); + this.parser.ast.input = pattern; - if (typeof prop !== 'string') { - throw new TypeError('expected `prop` to be a string.'); - } + var stack = this.parser.stack; + while (stack.length) { + addParent({type: 'brace.close', val: ''}, stack.pop()); + } - if (isDescriptor(val) && ('set' in val || 'get' in val)) { - return Object.defineProperty(obj, prop, val); - } + function addParent(node, parent) { + utils.define(node, 'parent', parent); + parent.nodes.push(node); + } - return Object.defineProperty(obj, prop, { - configurable: true, - enumerable: false, - writable: true, - value: val + // add non-enumerable parser reference + utils.define(parsed, 'parser', this.parser); + return parsed; }); }; +/** + * Decorate `.parse` method + */ -/***/ }), -/* 452 */ -/***/ (function(module, exports, __webpack_require__) { +Braces.prototype.parse = function(ast, options) { + if (ast && typeof ast === 'object' && ast.nodes) return ast; + this.init(options); + return this.snapdragon.parse(ast, options); +}; -"use strict"; -/*! - * is-descriptor - * - * Copyright (c) 2015-2017, Jon Schlinkert. - * Released under the MIT License. +/** + * Decorate `.compile` method */ +Braces.prototype.compile = function(ast, options) { + if (typeof ast === 'string') { + ast = this.parse(ast, options); + } else { + this.init(options); + } + return this.snapdragon.compile(ast, options); +}; + +/** + * Expand + */ +Braces.prototype.expand = function(pattern) { + var ast = this.parse(pattern, {expand: true}); + return this.compile(ast, {expand: true}); +}; -var typeOf = __webpack_require__(453); -var isAccessor = __webpack_require__(454); -var isData = __webpack_require__(456); +/** + * Optimize + */ -module.exports = function isDescriptor(obj, key) { - if (typeOf(obj) !== 'object') { - return false; - } - if ('get' in obj) { - return isAccessor(obj, key); - } - return isData(obj, key); +Braces.prototype.optimize = function(pattern) { + var ast = this.parse(pattern, {optimize: true}); + return this.compile(ast, {optimize: true}); }; +/** + * Expose `Braces` + */ + +module.exports = Braces; + /***/ }), -/* 453 */ -/***/ (function(module, exports) { +/* 424 */ +/***/ (function(module, exports, __webpack_require__) { -var toString = Object.prototype.toString; +"use strict"; + + +var Base = __webpack_require__(425); +var define = __webpack_require__(386); +var Compiler = __webpack_require__(455); +var Parser = __webpack_require__(485); +var utils = __webpack_require__(465); +var regexCache = {}; +var cache = {}; /** - * Get the native `typeof` a value. + * Create a new instance of `Snapdragon` with the given `options`. * - * @param {*} `val` - * @return {*} Native javascript type + * ```js + * var snapdragon = new Snapdragon(); + * ``` + * + * @param {Object} `options` + * @api public */ -module.exports = function kindOf(val) { - var type = typeof val; - - // primitivies - if (type === 'undefined') { - return 'undefined'; - } - if (val === null) { - return 'null'; - } - if (val === true || val === false || val instanceof Boolean) { - return 'boolean'; - } - if (type === 'string' || val instanceof String) { - return 'string'; - } - if (type === 'number' || val instanceof Number) { - return 'number'; - } +function Snapdragon(options) { + Base.call(this, null, options); + this.options = utils.extend({source: 'string'}, this.options); + this.compiler = new Compiler(this.options); + this.parser = new Parser(this.options); - // functions - if (type === 'function' || val instanceof Function) { - if (typeof val.constructor.name !== 'undefined' && val.constructor.name.slice(0, 9) === 'Generator') { - return 'generatorfunction'; + Object.defineProperty(this, 'compilers', { + get: function() { + return this.compiler.compilers; } - return 'function'; - } - - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; - } + }); - // check for instances of RegExp and Date before calling `toString` - if (val instanceof RegExp) { - return 'regexp'; - } - if (val instanceof Date) { - return 'date'; - } + Object.defineProperty(this, 'parsers', { + get: function() { + return this.parser.parsers; + } + }); - // other objects - type = toString.call(val); + Object.defineProperty(this, 'regex', { + get: function() { + return this.parser.regex; + } + }); +} - if (type === '[object RegExp]') { - return 'regexp'; - } - if (type === '[object Date]') { - return 'date'; - } - if (type === '[object Arguments]') { - return 'arguments'; - } - if (type === '[object Error]') { - return 'error'; - } - if (type === '[object Promise]') { - return 'promise'; - } +/** + * Inherit Base + */ - // buffer - if (isBuffer(val)) { - return 'buffer'; - } +Base.extend(Snapdragon); - // es6: Map, WeakMap, Set, WeakSet - if (type === '[object Set]') { - return 'set'; - } - if (type === '[object WeakSet]') { - return 'weakset'; - } - if (type === '[object Map]') { - return 'map'; - } - if (type === '[object WeakMap]') { - return 'weakmap'; - } - if (type === '[object Symbol]') { - return 'symbol'; - } - - if (type === '[object Map Iterator]') { - return 'mapiterator'; - } - if (type === '[object Set Iterator]') { - return 'setiterator'; - } - if (type === '[object String Iterator]') { - return 'stringiterator'; - } - if (type === '[object Array Iterator]') { - return 'arrayiterator'; - } - - // typed arrays - if (type === '[object Int8Array]') { - return 'int8array'; - } - if (type === '[object Uint8Array]') { - return 'uint8array'; - } - if (type === '[object Uint8ClampedArray]') { - return 'uint8clampedarray'; - } - if (type === '[object Int16Array]') { - return 'int16array'; - } - if (type === '[object Uint16Array]') { - return 'uint16array'; - } - if (type === '[object Int32Array]') { - return 'int32array'; - } - if (type === '[object Uint32Array]') { - return 'uint32array'; - } - if (type === '[object Float32Array]') { - return 'float32array'; - } - if (type === '[object Float64Array]') { - return 'float64array'; - } +/** + * Add a parser to `snapdragon.parsers` for capturing the given `type` using + * the specified regex or parser function. A function is useful if you need + * to customize how the token is created and/or have access to the parser + * instance to check options, etc. + * + * ```js + * snapdragon + * .capture('slash', /^\//) + * .capture('dot', function() { + * var pos = this.position(); + * var m = this.match(/^\./); + * if (!m) return; + * return pos({ + * type: 'dot', + * val: m[0] + * }); + * }); + * ``` + * @param {String} `type` + * @param {RegExp|Function} `regex` + * @return {Object} Returns the parser instance for chaining + * @api public + */ - // must be a plain object - return 'object'; +Snapdragon.prototype.capture = function() { + return this.parser.capture.apply(this.parser, arguments); }; /** - * If you need to support Safari 5-7 (8-10 yr-old browser), - * take a look at https://github.com/feross/is-buffer + * Register a plugin `fn`. + * + * ```js + * var snapdragon = new Snapdgragon([options]); + * snapdragon.use(function() { + * console.log(this); //<= snapdragon instance + * console.log(this.parser); //<= parser instance + * console.log(this.compiler); //<= compiler instance + * }); + * ``` + * @param {Object} `fn` + * @api public */ -function isBuffer(val) { - return val.constructor - && typeof val.constructor.isBuffer === 'function' - && val.constructor.isBuffer(val); -} +Snapdragon.prototype.use = function(fn) { + fn.call(this, this); + return this; +}; + +/** + * Parse the given `str`. + * + * ```js + * var snapdragon = new Snapdgragon([options]); + * // register parsers + * snapdragon.parser.use(function() {}); + * + * // parse + * var ast = snapdragon.parse('foo/bar'); + * console.log(ast); + * ``` + * @param {String} `str` + * @param {Object} `options` Set `options.sourcemap` to true to enable source maps. + * @return {Object} Returns an AST. + * @api public + */ +Snapdragon.prototype.parse = function(str, options) { + this.options = utils.extend({}, this.options, options); + var parsed = this.parser.parse(str, this.options); -/***/ }), -/* 454 */ -/***/ (function(module, exports, __webpack_require__) { + // add non-enumerable parser reference + define(parsed, 'parser', this.parser); + return parsed; +}; -"use strict"; -/*! - * is-accessor-descriptor +/** + * Compile the given `AST`. * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. + * ```js + * var snapdragon = new Snapdgragon([options]); + * // register plugins + * snapdragon.use(function() {}); + * // register parser plugins + * snapdragon.parser.use(function() {}); + * // register compiler plugins + * snapdragon.compiler.use(function() {}); + * + * // parse + * var ast = snapdragon.parse('foo/bar'); + * + * // compile + * var res = snapdragon.compile(ast); + * console.log(res.output); + * ``` + * @param {Object} `ast` + * @param {Object} `options` + * @return {Object} Returns an object with an `output` property with the rendered string. + * @api public */ +Snapdragon.prototype.compile = function(ast, options) { + this.options = utils.extend({}, this.options, options); + var compiled = this.compiler.compile(ast, this.options); + // add non-enumerable compiler reference + define(compiled, 'compiler', this.compiler); + return compiled; +}; -var typeOf = __webpack_require__(455); +/** + * Expose `Snapdragon` + */ -// accessor descriptor properties -var accessor = { - get: 'function', - set: 'function', - configurable: 'boolean', - enumerable: 'boolean' -}; +module.exports = Snapdragon; -function isAccessorDescriptor(obj, prop) { - if (typeof prop === 'string') { - var val = Object.getOwnPropertyDescriptor(obj, prop); - return typeof val !== 'undefined'; - } +/** + * Expose `Parser` and `Compiler` + */ - if (typeOf(obj) !== 'object') { - return false; - } +module.exports.Compiler = Compiler; +module.exports.Parser = Parser; - if (has(obj, 'value') || has(obj, 'writable')) { - return false; - } - if (!has(obj, 'get') || typeof obj.get !== 'function') { - return false; - } +/***/ }), +/* 425 */ +/***/ (function(module, exports, __webpack_require__) { - // tldr: it's valid to have "set" be undefined - // "set" might be undefined if `Object.getOwnPropertyDescriptor` - // was used to get the value, and only `get` was defined by the user - if (has(obj, 'set') && typeof obj[key] !== 'function' && typeof obj[key] !== 'undefined') { - return false; - } +"use strict"; - for (var key in obj) { - if (!accessor.hasOwnProperty(key)) { - continue; - } - if (typeOf(obj[key]) === accessor[key]) { - continue; - } +var util = __webpack_require__(29); +var define = __webpack_require__(426); +var CacheBase = __webpack_require__(427); +var Emitter = __webpack_require__(428); +var isObject = __webpack_require__(404); +var merge = __webpack_require__(446); +var pascal = __webpack_require__(449); +var cu = __webpack_require__(450); - if (typeof obj[key] !== 'undefined') { - return false; +/** + * Optionally define a custom `cache` namespace to use. + */ + +function namespace(name) { + var Cache = name ? CacheBase.namespace(name) : CacheBase; + var fns = []; + + /** + * Create an instance of `Base` with the given `config` and `options`. + * + * ```js + * // initialize with `config` and `options` + * var app = new Base({isApp: true}, {abc: true}); + * app.set('foo', 'bar'); + * + * // values defined with the given `config` object will be on the root of the instance + * console.log(app.baz); //=> undefined + * console.log(app.foo); //=> 'bar' + * // or use `.get` + * console.log(app.get('isApp')); //=> true + * console.log(app.get('foo')); //=> 'bar' + * + * // values defined with the given `options` object will be on `app.options + * console.log(app.options.abc); //=> true + * ``` + * + * @param {Object} `config` If supplied, this object is passed to [cache-base][] to merge onto the the instance upon instantiation. + * @param {Object} `options` If supplied, this object is used to initialize the `base.options` object. + * @api public + */ + + function Base(config, options) { + if (!(this instanceof Base)) { + return new Base(config, options); } + Cache.call(this, config); + this.is('base'); + this.initBase(config, options); } - return true; -} -function has(obj, key) { - return {}.hasOwnProperty.call(obj, key); -} + /** + * Inherit cache-base + */ -/** - * Expose `isAccessorDescriptor` - */ + util.inherits(Base, Cache); -module.exports = isAccessorDescriptor; + /** + * Add static emitter methods + */ + Emitter(Base); -/***/ }), -/* 455 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Initialize `Base` defaults with the given `config` object + */ -var isBuffer = __webpack_require__(391); -var toString = Object.prototype.toString; + Base.prototype.initBase = function(config, options) { + this.options = merge({}, this.options, options); + this.cache = this.cache || {}; + this.define('registered', {}); + if (name) this[name] = {}; -/** - * Get the native `typeof` a value. - * - * @param {*} `val` - * @return {*} Native javascript type - */ + // make `app._callbacks` non-enumerable + this.define('_callbacks', this._callbacks); + if (isObject(config)) { + this.visit('set', config); + } + Base.run(this, 'use', fns); + }; -module.exports = function kindOf(val) { - // primitivies - if (typeof val === 'undefined') { - return 'undefined'; - } - if (val === null) { - return 'null'; - } - if (val === true || val === false || val instanceof Boolean) { - return 'boolean'; - } - if (typeof val === 'string' || val instanceof String) { - return 'string'; - } - if (typeof val === 'number' || val instanceof Number) { - return 'number'; - } + /** + * Set the given `name` on `app._name` and `app.is*` properties. Used for doing + * lookups in plugins. + * + * ```js + * app.is('foo'); + * console.log(app._name); + * //=> 'foo' + * console.log(app.isFoo); + * //=> true + * app.is('bar'); + * console.log(app.isFoo); + * //=> true + * console.log(app.isBar); + * //=> true + * console.log(app._name); + * //=> 'bar' + * ``` + * @name .is + * @param {String} `name` + * @return {Boolean} + * @api public + */ - // functions - if (typeof val === 'function' || val instanceof Function) { - return 'function'; - } + Base.prototype.is = function(name) { + if (typeof name !== 'string') { + throw new TypeError('expected name to be a string'); + } + this.define('is' + pascal(name), true); + this.define('_name', name); + this.define('_appname', name); + return this; + }; - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; - } + /** + * Returns true if a plugin has already been registered on an instance. + * + * Plugin implementors are encouraged to use this first thing in a plugin + * to prevent the plugin from being called more than once on the same + * instance. + * + * ```js + * var base = new Base(); + * base.use(function(app) { + * if (app.isRegistered('myPlugin')) return; + * // do stuff to `app` + * }); + * + * // to also record the plugin as being registered + * base.use(function(app) { + * if (app.isRegistered('myPlugin', true)) return; + * // do stuff to `app` + * }); + * ``` + * @name .isRegistered + * @emits `plugin` Emits the name of the plugin being registered. Useful for unit tests, to ensure plugins are only registered once. + * @param {String} `name` The plugin name. + * @param {Boolean} `register` If the plugin if not already registered, to record it as being registered pass `true` as the second argument. + * @return {Boolean} Returns true if a plugin is already registered. + * @api public + */ - // check for instances of RegExp and Date before calling `toString` - if (val instanceof RegExp) { - return 'regexp'; - } - if (val instanceof Date) { - return 'date'; - } + Base.prototype.isRegistered = function(name, register) { + if (this.registered.hasOwnProperty(name)) { + return true; + } + if (register !== false) { + this.registered[name] = true; + this.emit('plugin', name); + } + return false; + }; - // other objects - var type = toString.call(val); + /** + * Define a plugin function to be called immediately upon init. Plugins are chainable + * and expose the following arguments to the plugin function: + * + * - `app`: the current instance of `Base` + * - `base`: the [first ancestor instance](#base) of `Base` + * + * ```js + * var app = new Base() + * .use(foo) + * .use(bar) + * .use(baz) + * ``` + * @name .use + * @param {Function} `fn` plugin function to call + * @return {Object} Returns the item instance for chaining. + * @api public + */ - if (type === '[object RegExp]') { - return 'regexp'; - } - if (type === '[object Date]') { - return 'date'; - } - if (type === '[object Arguments]') { - return 'arguments'; - } - if (type === '[object Error]') { - return 'error'; - } + Base.prototype.use = function(fn) { + fn.call(this, this); + return this; + }; - // buffer - if (isBuffer(val)) { - return 'buffer'; - } + /** + * The `.define` method is used for adding non-enumerable property on the instance. + * Dot-notation is **not supported** with `define`. + * + * ```js + * // arbitrary `render` function using lodash `template` + * app.define('render', function(str, locals) { + * return _.template(str)(locals); + * }); + * ``` + * @name .define + * @param {String} `key` The name of the property to define. + * @param {any} `value` + * @return {Object} Returns the instance for chaining. + * @api public + */ - // es6: Map, WeakMap, Set, WeakSet - if (type === '[object Set]') { - return 'set'; - } - if (type === '[object WeakSet]') { - return 'weakset'; - } - if (type === '[object Map]') { - return 'map'; - } - if (type === '[object WeakMap]') { - return 'weakmap'; - } - if (type === '[object Symbol]') { - return 'symbol'; - } + Base.prototype.define = function(key, val) { + if (isObject(key)) { + return this.visit('define', key); + } + define(this, key, val); + return this; + }; - // typed arrays - if (type === '[object Int8Array]') { - return 'int8array'; - } - if (type === '[object Uint8Array]') { - return 'uint8array'; - } - if (type === '[object Uint8ClampedArray]') { - return 'uint8clampedarray'; - } - if (type === '[object Int16Array]') { - return 'int16array'; - } - if (type === '[object Uint16Array]') { - return 'uint16array'; - } - if (type === '[object Int32Array]') { - return 'int32array'; - } - if (type === '[object Uint32Array]') { - return 'uint32array'; - } - if (type === '[object Float32Array]') { - return 'float32array'; - } - if (type === '[object Float64Array]') { - return 'float64array'; - } + /** + * Mix property `key` onto the Base prototype. If base is inherited using + * `Base.extend` this method will be overridden by a new `mixin` method that will + * only add properties to the prototype of the inheriting application. + * + * ```js + * app.mixin('foo', function() { + * // do stuff + * }); + * ``` + * @name .mixin + * @param {String} `key` + * @param {Object|Array} `val` + * @return {Object} Returns the `base` instance for chaining. + * @api public + */ - // must be a plain object - return 'object'; -}; + Base.prototype.mixin = function(key, val) { + Base.prototype[key] = val; + return this; + }; + + /** + * Non-enumberable mixin array, used by the static [Base.mixin]() method. + */ + + Base.prototype.mixins = Base.prototype.mixins || []; + + /** + * Getter/setter used when creating nested instances of `Base`, for storing a reference + * to the first ancestor instance. This works by setting an instance of `Base` on the `parent` + * property of a "child" instance. The `base` property defaults to the current instance if + * no `parent` property is defined. + * + * ```js + * // create an instance of `Base`, this is our first ("base") instance + * var first = new Base(); + * first.foo = 'bar'; // arbitrary property, to make it easier to see what's happening later + * + * // create another instance + * var second = new Base(); + * // create a reference to the first instance (`first`) + * second.parent = first; + * + * // create another instance + * var third = new Base(); + * // create a reference to the previous instance (`second`) + * // repeat this pattern every time a "child" instance is created + * third.parent = second; + * + * // we can always access the first instance using the `base` property + * console.log(first.base.foo); + * //=> 'bar' + * console.log(second.base.foo); + * //=> 'bar' + * console.log(third.base.foo); + * //=> 'bar' + * // and now you know how to get to third base ;) + * ``` + * @name .base + * @api public + */ + Object.defineProperty(Base.prototype, 'base', { + configurable: true, + get: function() { + return this.parent ? this.parent.base : this; + } + }); -/***/ }), -/* 456 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Static method for adding global plugin functions that will + * be added to an instance when created. + * + * ```js + * Base.use(function(app) { + * app.foo = 'bar'; + * }); + * var app = new Base(); + * console.log(app.foo); + * //=> 'bar' + * ``` + * @name #use + * @param {Function} `fn` Plugin function to use on each instance. + * @return {Object} Returns the `Base` constructor for chaining + * @api public + */ -"use strict"; -/*! - * is-data-descriptor - * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. - */ + define(Base, 'use', function(fn) { + fns.push(fn); + return Base; + }); + /** + * Run an array of functions by passing each function + * to a method on the given object specified by the given property. + * + * @param {Object} `obj` Object containing method to use. + * @param {String} `prop` Name of the method on the object to use. + * @param {Array} `arr` Array of functions to pass to the method. + */ + define(Base, 'run', function(obj, prop, arr) { + var len = arr.length, i = 0; + while (len--) { + obj[prop](arr[i++]); + } + return Base; + }); -var typeOf = __webpack_require__(457); + /** + * Static method for inheriting the prototype and static methods of the `Base` class. + * This method greatly simplifies the process of creating inheritance-based applications. + * See [static-extend][] for more details. + * + * ```js + * var extend = cu.extend(Parent); + * Parent.extend(Child); + * + * // optional methods + * Parent.extend(Child, { + * foo: function() {}, + * bar: function() {} + * }); + * ``` + * @name #extend + * @param {Function} `Ctor` constructor to extend + * @param {Object} `methods` Optional prototype properties to mix in. + * @return {Object} Returns the `Base` constructor for chaining + * @api public + */ -// data descriptor properties -var data = { - configurable: 'boolean', - enumerable: 'boolean', - writable: 'boolean' -}; + define(Base, 'extend', cu.extend(Base, function(Ctor, Parent) { + Ctor.prototype.mixins = Ctor.prototype.mixins || []; -function isDataDescriptor(obj, prop) { - if (typeOf(obj) !== 'object') { - return false; - } + define(Ctor, 'mixin', function(fn) { + var mixin = fn(Ctor.prototype, Ctor); + if (typeof mixin === 'function') { + Ctor.prototype.mixins.push(mixin); + } + return Ctor; + }); - if (typeof prop === 'string') { - var val = Object.getOwnPropertyDescriptor(obj, prop); - return typeof val !== 'undefined'; - } + define(Ctor, 'mixins', function(Child) { + Base.run(Child, 'mixin', Ctor.prototype.mixins); + return Ctor; + }); - if (!('value' in obj) && !('writable' in obj)) { - return false; - } + Ctor.prototype.mixin = function(key, value) { + Ctor.prototype[key] = value; + return this; + }; + return Base; + })); - for (var key in obj) { - if (key === 'value') continue; + /** + * Used for adding methods to the `Base` prototype, and/or to the prototype of child instances. + * When a mixin function returns a function, the returned function is pushed onto the `.mixins` + * array, making it available to be used on inheriting classes whenever `Base.mixins()` is + * called (e.g. `Base.mixins(Child)`). + * + * ```js + * Base.mixin(function(proto) { + * proto.foo = function(msg) { + * return 'foo ' + msg; + * }; + * }); + * ``` + * @name #mixin + * @param {Function} `fn` Function to call + * @return {Object} Returns the `Base` constructor for chaining + * @api public + */ - if (!data.hasOwnProperty(key)) { - continue; + define(Base, 'mixin', function(fn) { + var mixin = fn(Base.prototype, Base); + if (typeof mixin === 'function') { + Base.prototype.mixins.push(mixin); } + return Base; + }); - if (typeOf(obj[key]) === data[key]) { - continue; - } + /** + * Static method for running global mixin functions against a child constructor. + * Mixins must be registered before calling this method. + * + * ```js + * Base.extend(Child); + * Base.mixins(Child); + * ``` + * @name #mixins + * @param {Function} `Child` Constructor function of a child class + * @return {Object} Returns the `Base` constructor for chaining + * @api public + */ - if (typeof obj[key] !== 'undefined') { - return false; - } - } - return true; + define(Base, 'mixins', function(Child) { + Base.run(Child, 'mixin', Base.prototype.mixins); + return Base; + }); + + /** + * Similar to `util.inherit`, but copies all static properties, prototype properties, and + * getters/setters from `Provider` to `Receiver`. See [class-utils][]{#inherit} for more details. + * + * ```js + * Base.inherit(Foo, Bar); + * ``` + * @name #inherit + * @param {Function} `Receiver` Receiving (child) constructor + * @param {Function} `Provider` Providing (parent) constructor + * @return {Object} Returns the `Base` constructor for chaining + * @api public + */ + + define(Base, 'inherit', cu.inherit); + define(Base, 'bubble', cu.bubble); + return Base; } /** - * Expose `isDataDescriptor` + * Expose `Base` with default settings */ -module.exports = isDataDescriptor; +module.exports = namespace(); + +/** + * Allow users to define a namespace + */ + +module.exports.namespace = namespace; /***/ }), -/* 457 */ +/* 426 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(391); -var toString = Object.prototype.toString; - -/** - * Get the native `typeof` a value. +"use strict"; +/*! + * define-property * - * @param {*} `val` - * @return {*} Native javascript type + * Copyright (c) 2015, 2017, Jon Schlinkert. + * Released under the MIT License. */ -module.exports = function kindOf(val) { - // primitivies - if (typeof val === 'undefined') { - return 'undefined'; - } - if (val === null) { - return 'null'; - } - if (val === true || val === false || val instanceof Boolean) { - return 'boolean'; - } - if (typeof val === 'string' || val instanceof String) { - return 'string'; - } - if (typeof val === 'number' || val instanceof Number) { - return 'number'; - } - - // functions - if (typeof val === 'function' || val instanceof Function) { - return 'function'; - } - - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; - } - - // check for instances of RegExp and Date before calling `toString` - if (val instanceof RegExp) { - return 'regexp'; - } - if (val instanceof Date) { - return 'date'; - } - // other objects - var type = toString.call(val); - if (type === '[object RegExp]') { - return 'regexp'; - } - if (type === '[object Date]') { - return 'date'; - } - if (type === '[object Arguments]') { - return 'arguments'; - } - if (type === '[object Error]') { - return 'error'; - } +var isDescriptor = __webpack_require__(416); - // buffer - if (isBuffer(val)) { - return 'buffer'; +module.exports = function defineProperty(obj, prop, val) { + if (typeof obj !== 'object' && typeof obj !== 'function') { + throw new TypeError('expected an object or function.'); } - // es6: Map, WeakMap, Set, WeakSet - if (type === '[object Set]') { - return 'set'; - } - if (type === '[object WeakSet]') { - return 'weakset'; - } - if (type === '[object Map]') { - return 'map'; - } - if (type === '[object WeakMap]') { - return 'weakmap'; - } - if (type === '[object Symbol]') { - return 'symbol'; + if (typeof prop !== 'string') { + throw new TypeError('expected `prop` to be a string.'); } - // typed arrays - if (type === '[object Int8Array]') { - return 'int8array'; - } - if (type === '[object Uint8Array]') { - return 'uint8array'; - } - if (type === '[object Uint8ClampedArray]') { - return 'uint8clampedarray'; - } - if (type === '[object Int16Array]') { - return 'int16array'; - } - if (type === '[object Uint16Array]') { - return 'uint16array'; - } - if (type === '[object Int32Array]') { - return 'int32array'; - } - if (type === '[object Uint32Array]') { - return 'uint32array'; - } - if (type === '[object Float32Array]') { - return 'float32array'; - } - if (type === '[object Float64Array]') { - return 'float64array'; + if (isDescriptor(val) && ('set' in val || 'get' in val)) { + return Object.defineProperty(obj, prop, val); } - // must be a plain object - return 'object'; + return Object.defineProperty(obj, prop, { + configurable: true, + enumerable: false, + writable: true, + value: val + }); }; /***/ }), -/* 458 */ +/* 427 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/*! - * static-extend - * - * Copyright (c) 2016, Jon Schlinkert. - * Licensed under the MIT License. - */ - -var copy = __webpack_require__(459); -var define = __webpack_require__(466); -var util = __webpack_require__(29); +var isObject = __webpack_require__(404); +var Emitter = __webpack_require__(428); +var visit = __webpack_require__(429); +var toPath = __webpack_require__(432); +var union = __webpack_require__(433); +var del = __webpack_require__(437); +var get = __webpack_require__(435); +var has = __webpack_require__(442); +var set = __webpack_require__(445); /** - * Returns a function for extending the static properties, - * prototype properties, and descriptors from the `Parent` - * constructor onto `Child` constructors. + * Create a `Cache` constructor that when instantiated will + * store values on the given `prop`. * * ```js - * var extend = require('static-extend'); - * Parent.extend = extend(Parent); - * - * // optionally pass a custom merge function as the second arg - * Parent.extend = extend(Parent, function(Child) { - * Child.prototype.mixin = function(key, val) { - * Child.prototype[key] = val; - * }; - * }); - * - * // extend "child" constructors - * Parent.extend(Child); + * var Cache = require('cache-base').namespace('data'); + * var cache = new Cache(); * - * // optionally define prototype methods as the second arg - * Parent.extend(Child, { - * foo: function() {}, - * bar: function() {} - * }); + * cache.set('foo', 'bar'); + * //=> {data: {foo: 'bar'}} * ``` - * @param {Function} `Parent` Parent ctor - * @param {Function} `extendFn` Optional extend function for handling any necessary custom merging. Useful when updating methods that require a specific prototype. - * @param {Function} `Child` Child ctor - * @param {Object} `proto` Optionally pass additional prototype properties to inherit. - * @return {Object} + * @param {String} `prop` The property name to use for storing values. + * @return {Function} Returns a custom `Cache` constructor * @api public */ -function extend(Parent, extendFn) { - if (typeof Parent !== 'function') { - throw new TypeError('expected Parent to be a function.'); +function namespace(prop) { + + /** + * Create a new `Cache`. Internally the `Cache` constructor is created using + * the `namespace` function, with `cache` defined as the storage object. + * + * ```js + * var app = new Cache(); + * ``` + * @param {Object} `cache` Optionally pass an object to initialize with. + * @constructor + * @api public + */ + + function Cache(cache) { + if (prop) { + this[prop] = {}; + } + if (cache) { + this.set(cache); + } } - return function(Ctor, proto) { - if (typeof Ctor !== 'function') { - throw new TypeError('expected Ctor to be a function.'); + /** + * Inherit Emitter + */ + + Emitter(Cache.prototype); + + /** + * Assign `value` to `key`. Also emits `set` with + * the key and value. + * + * ```js + * app.on('set', function(key, val) { + * // do something when `set` is emitted + * }); + * + * app.set(key, value); + * + * // also takes an object or array + * app.set({name: 'Halle'}); + * app.set([{foo: 'bar'}, {baz: 'quux'}]); + * console.log(app); + * //=> {name: 'Halle', foo: 'bar', baz: 'quux'} + * ``` + * + * @name .set + * @emits `set` with `key` and `value` as arguments. + * @param {String} `key` + * @param {any} `value` + * @return {Object} Returns the instance for chaining. + * @api public + */ + + Cache.prototype.set = function(key, val) { + if (Array.isArray(key) && arguments.length === 2) { + key = toPath(key); + } + if (isObject(key) || Array.isArray(key)) { + this.visit('set', key); + } else { + set(prop ? this[prop] : this, key, val); + this.emit('set', key, val); } + return this; + }; - util.inherits(Ctor, Parent); - copy(Ctor, Parent); + /** + * Union `array` to `key`. Also emits `set` with + * the key and value. + * + * ```js + * app.union('a.b', ['foo']); + * app.union('a.b', ['bar']); + * console.log(app.get('a')); + * //=> {b: ['foo', 'bar']} + * ``` + * @name .union + * @param {String} `key` + * @param {any} `value` + * @return {Object} Returns the instance for chaining. + * @api public + */ + + Cache.prototype.union = function(key, val) { + if (Array.isArray(key) && arguments.length === 2) { + key = toPath(key); + } + var ctx = prop ? this[prop] : this; + union(ctx, key, arrayify(val)); + this.emit('union', val); + return this; + }; + + /** + * Return the value of `key`. Dot notation may be used + * to get [nested property values][get-value]. + * + * ```js + * app.set('a.b.c', 'd'); + * app.get('a.b'); + * //=> {c: 'd'} + * + * app.get(['a', 'b']); + * //=> {c: 'd'} + * ``` + * + * @name .get + * @emits `get` with `key` and `value` as arguments. + * @param {String} `key` The name of the property to get. Dot-notation may be used. + * @return {any} Returns the value of `key` + * @api public + */ + + Cache.prototype.get = function(key) { + key = toPath(arguments); + + var ctx = prop ? this[prop] : this; + var val = get(ctx, key); + + this.emit('get', key, val); + return val; + }; + + /** + * Return true if app has a stored value for `key`, + * false only if value is `undefined`. + * + * ```js + * app.set('foo', 'bar'); + * app.has('foo'); + * //=> true + * ``` + * + * @name .has + * @emits `has` with `key` and true or false as arguments. + * @param {String} `key` + * @return {Boolean} + * @api public + */ + + Cache.prototype.has = function(key) { + key = toPath(arguments); + + var ctx = prop ? this[prop] : this; + var val = get(ctx, key); - // proto can be null or a plain object - if (typeof proto === 'object') { - var obj = Object.create(proto); + var has = typeof val !== 'undefined'; + this.emit('has', key, has); + return has; + }; - for (var k in obj) { - Ctor.prototype[k] = obj[k]; - } + /** + * Delete one or more properties from the instance. + * + * ```js + * app.del(); // delete all + * // or + * app.del('foo'); + * // or + * app.del(['foo', 'bar']); + * ``` + * @name .del + * @emits `del` with the `key` as the only argument. + * @param {String|Array} `key` Property name or array of property names. + * @return {Object} Returns the instance for chaining. + * @api public + */ + + Cache.prototype.del = function(key) { + if (Array.isArray(key)) { + this.visit('del', key); + } else { + del(prop ? this[prop] : this, key); + this.emit('del', key); } + return this; + }; - // keep a reference to the parent prototype - define(Ctor.prototype, '_parent_', { - configurable: true, - set: function() {}, - get: function() { - return Parent.prototype; - } - }); + /** + * Reset the entire cache to an empty object. + * + * ```js + * app.clear(); + * ``` + * @api public + */ - if (typeof extendFn === 'function') { - extendFn(Ctor, Parent); + Cache.prototype.clear = function() { + if (prop) { + this[prop] = {}; } - - Ctor.extend = extend(Ctor, extendFn); }; -}; -/** - * Expose `extend` - */ + /** + * Visit `method` over the properties in the given object, or map + * visit over the object-elements in an array. + * + * @name .visit + * @param {String} `method` The name of the `base` method to call. + * @param {Object|Array} `val` The object or array to iterate over. + * @return {Object} Returns the instance for chaining. + * @api public + */ -module.exports = extend; + Cache.prototype.visit = function(method, val) { + visit(this, method, val); + return this; + }; + return Cache; +} -/***/ }), -/* 459 */ -/***/ (function(module, exports, __webpack_require__) { +/** + * Cast val to an array + */ -"use strict"; +function arrayify(val) { + return val ? (Array.isArray(val) ? val : [val]) : []; +} +/** + * Expose `Cache` + */ -var typeOf = __webpack_require__(416); -var copyDescriptor = __webpack_require__(460); -var define = __webpack_require__(461); +module.exports = namespace(); /** - * Copy static properties, prototype properties, and descriptors from one object to another. - * - * ```js - * function App() {} - * var proto = App.prototype; - * App.prototype.set = function() {}; - * App.prototype.get = function() {}; - * - * var obj = {}; - * copy(obj, proto); - * ``` - * @param {Object} `receiver` - * @param {Object} `provider` - * @param {String|Array} `omit` One or more properties to omit - * @return {Object} - * @api public + * Expose `Cache.namespace` */ -function copy(receiver, provider, omit) { - if (!isObject(receiver)) { - throw new TypeError('expected receiving object to be an object.'); - } - if (!isObject(provider)) { - throw new TypeError('expected providing object to be an object.'); - } +module.exports.namespace = namespace; - var props = nativeKeys(provider); - var keys = Object.keys(provider); - var len = props.length; - omit = arrayify(omit); - while (len--) { - var key = props[len]; +/***/ }), +/* 428 */ +/***/ (function(module, exports, __webpack_require__) { - if (has(keys, key)) { - define(receiver, key, provider[key]); - } else if (!(key in receiver) && !has(omit, key)) { - copyDescriptor(receiver, provider, key); - } - } -}; + +/** + * Expose `Emitter`. + */ + +if (true) { + module.exports = Emitter; +} + +/** + * Initialize a new `Emitter`. + * + * @api public + */ + +function Emitter(obj) { + if (obj) return mixin(obj); +}; + +/** + * Mixin the emitter properties. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +function mixin(obj) { + for (var key in Emitter.prototype) { + obj[key] = Emitter.prototype[key]; + } + return obj; +} + +/** + * Listen on the given `event` with `fn`. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.on = +Emitter.prototype.addEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + (this._callbacks['$' + event] = this._callbacks['$' + event] || []) + .push(fn); + return this; +}; + +/** + * Adds an `event` listener that will be invoked a single + * time then automatically removed. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.once = function(event, fn){ + function on() { + this.off(event, on); + fn.apply(this, arguments); + } + + on.fn = fn; + this.on(event, on); + return this; +}; + +/** + * Remove the given callback for `event` or all + * registered callbacks. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.off = +Emitter.prototype.removeListener = +Emitter.prototype.removeAllListeners = +Emitter.prototype.removeEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + + // all + if (0 == arguments.length) { + this._callbacks = {}; + return this; + } + + // specific event + var callbacks = this._callbacks['$' + event]; + if (!callbacks) return this; + + // remove all handlers + if (1 == arguments.length) { + delete this._callbacks['$' + event]; + return this; + } + + // remove specific handler + var cb; + for (var i = 0; i < callbacks.length; i++) { + cb = callbacks[i]; + if (cb === fn || cb.fn === fn) { + callbacks.splice(i, 1); + break; + } + } + return this; +}; + +/** + * Emit `event` with the given args. + * + * @param {String} event + * @param {Mixed} ... + * @return {Emitter} + */ + +Emitter.prototype.emit = function(event){ + this._callbacks = this._callbacks || {}; + var args = [].slice.call(arguments, 1) + , callbacks = this._callbacks['$' + event]; + + if (callbacks) { + callbacks = callbacks.slice(0); + for (var i = 0, len = callbacks.length; i < len; ++i) { + callbacks[i].apply(this, args); + } + } + + return this; +}; + +/** + * Return array of callbacks for `event`. + * + * @param {String} event + * @return {Array} + * @api public + */ + +Emitter.prototype.listeners = function(event){ + this._callbacks = this._callbacks || {}; + return this._callbacks['$' + event] || []; +}; + +/** + * Check if this emitter has `event` handlers. + * + * @param {String} event + * @return {Boolean} + * @api public + */ + +Emitter.prototype.hasListeners = function(event){ + return !! this.listeners(event).length; +}; -/** - * Return true if the given value is an object or function - */ -function isObject(val) { - return typeOf(val) === 'object' || typeof val === 'function'; -} +/***/ }), +/* 429 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Returns true if an array has any of the given elements, or an - * object has any of the give keys. - * - * ```js - * has(['a', 'b', 'c'], 'c'); - * //=> true - * - * has(['a', 'b', 'c'], ['c', 'z']); - * //=> true +"use strict"; +/*! + * collection-visit * - * has({a: 'b', c: 'd'}, ['c', 'z']); - * //=> true - * ``` - * @param {Object} `obj` - * @param {String|Array} `val` - * @return {Boolean} + * Copyright (c) 2015, 2017, Jon Schlinkert. + * Released under the MIT License. */ -function has(obj, val) { - val = arrayify(val); - var len = val.length; - if (isObject(obj)) { - for (var key in obj) { - if (val.indexOf(key) > -1) { - return true; - } - } - var keys = nativeKeys(obj); - return has(keys, val); +var visit = __webpack_require__(430); +var mapVisit = __webpack_require__(431); + +module.exports = function(collection, method, val) { + var result; + + if (typeof val === 'string' && (method in collection)) { + var args = [].slice.call(arguments, 2); + result = collection[method].apply(collection, args); + } else if (Array.isArray(val)) { + result = mapVisit.apply(null, arguments); + } else { + result = visit.apply(null, arguments); } - if (Array.isArray(obj)) { - var arr = obj; - while (len--) { - if (arr.indexOf(val[len]) > -1) { - return true; - } - } - return false; + if (typeof result !== 'undefined') { + return result; } - throw new TypeError('expected an array or object.'); -} + return collection; +}; -/** - * Cast the given value to an array. - * - * ```js - * arrayify('foo'); - * //=> ['foo'] - * - * arrayify(['foo']); - * //=> ['foo'] - * ``` - * - * @param {String|Array} `val` - * @return {Array} - */ -function arrayify(val) { - return val ? (Array.isArray(val) ? val : [val]) : []; -} +/***/ }), +/* 430 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Returns true if a value has a `contructor` - * - * ```js - * hasConstructor({}); - * //=> true +"use strict"; +/*! + * object-visit * - * hasConstructor(Object.create(null)); - * //=> false - * ``` - * @param {Object} `value` - * @return {Boolean} + * Copyright (c) 2015, 2017, Jon Schlinkert. + * Released under the MIT License. */ -function hasConstructor(val) { - return isObject(val) && typeof val.constructor !== 'undefined'; -} -/** - * Get the native `ownPropertyNames` from the constructor of the - * given `object`. An empty array is returned if the object does - * not have a constructor. - * - * ```js - * nativeKeys({a: 'b', b: 'c', c: 'd'}) - * //=> ['a', 'b', 'c'] - * - * nativeKeys(function(){}) - * //=> ['length', 'caller'] - * ``` - * - * @param {Object} `obj` Object that has a `constructor`. - * @return {Array} Array of keys. - */ -function nativeKeys(val) { - if (!hasConstructor(val)) return []; - return Object.getOwnPropertyNames(val); -} +var isObject = __webpack_require__(404); -/** - * Expose `copy` - */ +module.exports = function visit(thisArg, method, target, val) { + if (!isObject(thisArg) && typeof thisArg !== 'function') { + throw new Error('object-visit expects `thisArg` to be an object.'); + } -module.exports = copy; + if (typeof method !== 'string') { + throw new Error('object-visit expects `method` name to be a string'); + } -/** - * Expose `copy.has` for tests - */ + if (typeof thisArg[method] !== 'function') { + return thisArg; + } -module.exports.has = has; + var args = [].slice.call(arguments, 3); + target = target || {}; + + for (var key in target) { + var arr = [key, target[key]].concat(args); + thisArg[method].apply(thisArg, arr); + } + return thisArg; +}; /***/ }), -/* 460 */ +/* 431 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/*! - * copy-descriptor - * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. - */ +var util = __webpack_require__(29); +var visit = __webpack_require__(430); /** - * Copy a descriptor from one object to another. - * - * ```js - * function App() { - * this.cache = {}; - * } - * App.prototype.set = function(key, val) { - * this.cache[key] = val; - * return this; - * }; - * Object.defineProperty(App.prototype, 'count', { - * get: function() { - * return Object.keys(this.cache).length; - * } - * }); - * - * copy(App.prototype, 'count', 'len'); - * - * // create an instance - * var app = new App(); - * - * app.set('a', true); - * app.set('b', true); - * app.set('c', true); + * Map `visit` over an array of objects. * - * console.log(app.count); - * //=> 3 - * console.log(app.len); - * //=> 3 - * ``` - * @name copy - * @param {Object} `receiver` The target object - * @param {Object} `provider` The provider object - * @param {String} `from` The key to copy on provider. - * @param {String} `to` Optionally specify a new key name to use. - * @return {Object} - * @api public - */ - -module.exports = function copyDescriptor(receiver, provider, from, to) { - if (!isObject(provider) && typeof provider !== 'function') { - to = from; - from = provider; - provider = receiver; - } - if (!isObject(receiver) && typeof receiver !== 'function') { - throw new TypeError('expected the first argument to be an object'); - } - if (!isObject(provider) && typeof provider !== 'function') { - throw new TypeError('expected provider to be an object'); - } + * @param {Object} `collection` The context in which to invoke `method` + * @param {String} `method` Name of the method to call on `collection` + * @param {Object} `arr` Array of objects. + */ - if (typeof to !== 'string') { - to = from; - } - if (typeof from !== 'string') { - throw new TypeError('expected key to be a string'); +module.exports = function mapVisit(collection, method, val) { + if (isObject(val)) { + return visit.apply(null, arguments); } - if (!(from in provider)) { - throw new Error('property "' + from + '" does not exist'); + if (!Array.isArray(val)) { + throw new TypeError('expected an array: ' + util.inspect(val)); } - var val = Object.getOwnPropertyDescriptor(provider, from); - if (val) Object.defineProperty(receiver, to, val); + var args = [].slice.call(arguments, 3); + + for (var i = 0; i < val.length; i++) { + var ele = val[i]; + if (isObject(ele)) { + visit.apply(null, [collection, method, ele].concat(args)); + } else { + collection[method].apply(collection, [ele].concat(args)); + } + } }; function isObject(val) { - return {}.toString.call(val) === '[object Object]'; + return val && (typeof val === 'function' || (!Array.isArray(val) && typeof val === 'object')); } - /***/ }), -/* 461 */ +/* 432 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! - * define-property + * to-object-path * * Copyright (c) 2015, Jon Schlinkert. * Licensed under the MIT License. @@ -42864,421 +40622,466 @@ function isObject(val) { -var isDescriptor = __webpack_require__(462); +var typeOf = __webpack_require__(409); -module.exports = function defineProperty(obj, prop, val) { - if (typeof obj !== 'object' && typeof obj !== 'function') { - throw new TypeError('expected an object or function.'); +module.exports = function toPath(args) { + if (typeOf(args) !== 'arguments') { + args = arguments; } + return filter(args).join('.'); +}; - if (typeof prop !== 'string') { - throw new TypeError('expected `prop` to be a string.'); - } +function filter(arr) { + var len = arr.length; + var idx = -1; + var res = []; - if (isDescriptor(val) && ('set' in val || 'get' in val)) { - return Object.defineProperty(obj, prop, val); + while (++idx < len) { + var ele = arr[idx]; + if (typeOf(ele) === 'arguments' || Array.isArray(ele)) { + res.push.apply(res, filter(ele)); + } else if (typeof ele === 'string') { + res.push(ele); + } } - - return Object.defineProperty(obj, prop, { - configurable: true, - enumerable: false, - writable: true, - value: val - }); -}; + return res; +} /***/ }), -/* 462 */ +/* 433 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/*! - * is-descriptor - * - * Copyright (c) 2015-2017, Jon Schlinkert. - * Released under the MIT License. - */ +var isObject = __webpack_require__(395); +var union = __webpack_require__(434); +var get = __webpack_require__(435); +var set = __webpack_require__(436); -var typeOf = __webpack_require__(463); -var isAccessor = __webpack_require__(464); -var isData = __webpack_require__(465); - -module.exports = function isDescriptor(obj, key) { - if (typeOf(obj) !== 'object') { - return false; +module.exports = function unionValue(obj, prop, value) { + if (!isObject(obj)) { + throw new TypeError('union-value expects the first argument to be an object.'); } - if ('get' in obj) { - return isAccessor(obj, key); + + if (typeof prop !== 'string') { + throw new TypeError('union-value expects `prop` to be a string.'); } - return isData(obj, key); + + var arr = arrayify(get(obj, prop)); + set(obj, prop, union(arr, arrayify(value))); + return obj; }; +function arrayify(val) { + if (val === null || typeof val === 'undefined') { + return []; + } + if (Array.isArray(val)) { + return val; + } + return [val]; +} + /***/ }), -/* 463 */ -/***/ (function(module, exports) { - -var toString = Object.prototype.toString; +/* 434 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Get the native `typeof` a value. - * - * @param {*} `val` - * @return {*} Native javascript type - */ +"use strict"; -module.exports = function kindOf(val) { - var type = typeof val; - // primitivies - if (type === 'undefined') { - return 'undefined'; - } - if (val === null) { - return 'null'; - } - if (val === true || val === false || val instanceof Boolean) { - return 'boolean'; - } - if (type === 'string' || val instanceof String) { - return 'string'; - } - if (type === 'number' || val instanceof Number) { - return 'number'; +module.exports = function union(init) { + if (!Array.isArray(init)) { + throw new TypeError('arr-union expects the first argument to be an array.'); } - // functions - if (type === 'function' || val instanceof Function) { - if (typeof val.constructor.name !== 'undefined' && val.constructor.name.slice(0, 9) === 'Generator') { - return 'generatorfunction'; + var len = arguments.length; + var i = 0; + + while (++i < len) { + var arg = arguments[i]; + if (!arg) continue; + + if (!Array.isArray(arg)) { + arg = [arg]; } - return 'function'; - } - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; - } + for (var j = 0; j < arg.length; j++) { + var ele = arg[j]; - // check for instances of RegExp and Date before calling `toString` - if (val instanceof RegExp) { - return 'regexp'; - } - if (val instanceof Date) { - return 'date'; + if (init.indexOf(ele) >= 0) { + continue; + } + init.push(ele); + } } + return init; +}; - // other objects - type = toString.call(val); - if (type === '[object RegExp]') { - return 'regexp'; - } - if (type === '[object Date]') { - return 'date'; - } - if (type === '[object Arguments]') { - return 'arguments'; - } - if (type === '[object Error]') { - return 'error'; - } - if (type === '[object Promise]') { - return 'promise'; - } +/***/ }), +/* 435 */ +/***/ (function(module, exports) { - // buffer - if (isBuffer(val)) { - return 'buffer'; - } +/*! + * get-value + * + * Copyright (c) 2014-2015, Jon Schlinkert. + * Licensed under the MIT License. + */ - // es6: Map, WeakMap, Set, WeakSet - if (type === '[object Set]') { - return 'set'; - } - if (type === '[object WeakSet]') { - return 'weakset'; - } - if (type === '[object Map]') { - return 'map'; - } - if (type === '[object WeakMap]') { - return 'weakmap'; - } - if (type === '[object Symbol]') { - return 'symbol'; - } - - if (type === '[object Map Iterator]') { - return 'mapiterator'; - } - if (type === '[object Set Iterator]') { - return 'setiterator'; - } - if (type === '[object String Iterator]') { - return 'stringiterator'; - } - if (type === '[object Array Iterator]') { - return 'arrayiterator'; - } - - // typed arrays - if (type === '[object Int8Array]') { - return 'int8array'; - } - if (type === '[object Uint8Array]') { - return 'uint8array'; - } - if (type === '[object Uint8ClampedArray]') { - return 'uint8clampedarray'; - } - if (type === '[object Int16Array]') { - return 'int16array'; - } - if (type === '[object Uint16Array]') { - return 'uint16array'; - } - if (type === '[object Int32Array]') { - return 'int32array'; - } - if (type === '[object Uint32Array]') { - return 'uint32array'; - } - if (type === '[object Float32Array]') { - return 'float32array'; +module.exports = function(obj, prop, a, b, c) { + if (!isObject(obj) || !prop) { + return obj; } - if (type === '[object Float64Array]') { - return 'float64array'; + + prop = toString(prop); + + // allowing for multiple properties to be passed as + // a string or array, but much faster (3-4x) than doing + // `[].slice.call(arguments)` + if (a) prop += '.' + toString(a); + if (b) prop += '.' + toString(b); + if (c) prop += '.' + toString(c); + + if (prop in obj) { + return obj[prop]; } - // must be a plain object - return 'object'; + var segs = prop.split('.'); + var len = segs.length; + var i = -1; + + while (obj && (++i < len)) { + var key = segs[i]; + while (key[key.length - 1] === '\\') { + key = key.slice(0, -1) + '.' + segs[++i]; + } + obj = obj[key]; + } + return obj; }; -/** - * If you need to support Safari 5-7 (8-10 yr-old browser), - * take a look at https://github.com/feross/is-buffer - */ +function isObject(val) { + return val !== null && (typeof val === 'object' || typeof val === 'function'); +} -function isBuffer(val) { - return val.constructor - && typeof val.constructor.isBuffer === 'function' - && val.constructor.isBuffer(val); +function toString(val) { + if (!val) return ''; + if (Array.isArray(val)) { + return val.join('.'); + } + return val; } /***/ }), -/* 464 */ +/* 436 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! - * is-accessor-descriptor + * set-value * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. + * Copyright (c) 2014-2015, 2017, Jon Schlinkert. + * Released under the MIT License. */ -var typeOf = __webpack_require__(416); - -// accessor descriptor properties -var accessor = { - get: 'function', - set: 'function', - configurable: 'boolean', - enumerable: 'boolean' -}; +var toPath = __webpack_require__(432); +var extend = __webpack_require__(394); +var isPlainObject = __webpack_require__(403); +var isObject = __webpack_require__(395); -function isAccessorDescriptor(obj, prop) { - if (typeof prop === 'string') { - var val = Object.getOwnPropertyDescriptor(obj, prop); - return typeof val !== 'undefined'; +module.exports = function(obj, path, val) { + if (!isObject(obj)) { + return obj; } - if (typeOf(obj) !== 'object') { - return false; + if (Array.isArray(path)) { + path = toPath(path); } - if (has(obj, 'value') || has(obj, 'writable')) { - return false; + if (typeof path !== 'string') { + return obj; } - if (!has(obj, 'get') || typeof obj.get !== 'function') { - return false; - } + var segs = path.split('.'); + var len = segs.length, i = -1; + var res = obj; + var last; - // tldr: it's valid to have "set" be undefined - // "set" might be undefined if `Object.getOwnPropertyDescriptor` - // was used to get the value, and only `get` was defined by the user - if (has(obj, 'set') && typeof obj[key] !== 'function' && typeof obj[key] !== 'undefined') { - return false; - } + while (++i < len) { + var key = segs[i]; - for (var key in obj) { - if (!accessor.hasOwnProperty(key)) { - continue; + while (key[key.length - 1] === '\\') { + key = key.slice(0, -1) + '.' + segs[++i]; } - if (typeOf(obj[key]) === accessor[key]) { - continue; + if (i === len - 1) { + last = key; + break; } - if (typeof obj[key] !== 'undefined') { - return false; + if (!isObject(obj[key])) { + obj[key] = {}; + } + obj = obj[key]; + } + + if (obj.hasOwnProperty(last) && isObject(obj[last])) { + if (isPlainObject(val)) { + extend(obj[last], val); + } else { + obj[last] = val; + } + + } else { + obj[last] = val; + } + return res; +}; + + + +/***/ }), +/* 437 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/*! + * unset-value + * + * Copyright (c) 2015, 2017, Jon Schlinkert. + * Released under the MIT License. + */ + + + +var isObject = __webpack_require__(404); +var has = __webpack_require__(438); + +module.exports = function unset(obj, prop) { + if (!isObject(obj)) { + throw new TypeError('expected an object.'); + } + if (obj.hasOwnProperty(prop)) { + delete obj[prop]; + return true; + } + + if (has(obj, prop)) { + var segs = prop.split('.'); + var last = segs.pop(); + while (segs.length && segs[segs.length - 1].slice(-1) === '\\') { + last = segs.pop().slice(0, -1) + '.' + last; } + while (segs.length) obj = obj[prop = segs.shift()]; + return (delete obj[last]); } return true; -} +}; -function has(obj, key) { - return {}.hasOwnProperty.call(obj, key); -} -/** - * Expose `isAccessorDescriptor` +/***/ }), +/* 438 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/*! + * has-value + * + * Copyright (c) 2014-2016, Jon Schlinkert. + * Licensed under the MIT License. */ -module.exports = isAccessorDescriptor; + + +var isObject = __webpack_require__(439); +var hasValues = __webpack_require__(441); +var get = __webpack_require__(435); + +module.exports = function(obj, prop, noZero) { + if (isObject(obj)) { + return hasValues(get(obj, prop), noZero); + } + return hasValues(obj, prop); +}; /***/ }), -/* 465 */ +/* 439 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! - * is-data-descriptor + * isobject * - * Copyright (c) 2015, Jon Schlinkert. + * Copyright (c) 2014-2015, Jon Schlinkert. * Licensed under the MIT License. */ -var typeOf = __webpack_require__(416); +var isArray = __webpack_require__(440); -// data descriptor properties -var data = { - configurable: 'boolean', - enumerable: 'boolean', - writable: 'boolean' +module.exports = function isObject(val) { + return val != null && typeof val === 'object' && isArray(val) === false; }; -function isDataDescriptor(obj, prop) { - if (typeOf(obj) !== 'object') { - return false; - } - if (typeof prop === 'string') { - var val = Object.getOwnPropertyDescriptor(obj, prop); - return typeof val !== 'undefined'; - } +/***/ }), +/* 440 */ +/***/ (function(module, exports) { - if (!('value' in obj) && !('writable' in obj)) { - return false; - } +var toString = {}.toString; - for (var key in obj) { - if (key === 'value') continue; +module.exports = Array.isArray || function (arr) { + return toString.call(arr) == '[object Array]'; +}; - if (!data.hasOwnProperty(key)) { - continue; - } - if (typeOf(obj[key]) === data[key]) { - continue; - } +/***/ }), +/* 441 */ +/***/ (function(module, exports, __webpack_require__) { - if (typeof obj[key] !== 'undefined') { +"use strict"; +/*! + * has-values + * + * Copyright (c) 2014-2015, Jon Schlinkert. + * Licensed under the MIT License. + */ + + + +module.exports = function hasValue(o, noZero) { + if (o === null || o === undefined) { + return false; + } + + if (typeof o === 'boolean') { + return true; + } + + if (typeof o === 'number') { + if (o === 0 && noZero === true) { return false; } + return true; } - return true; -} -/** - * Expose `isDataDescriptor` - */ + if (o.length !== undefined) { + return o.length !== 0; + } -module.exports = isDataDescriptor; + for (var key in o) { + if (o.hasOwnProperty(key)) { + return true; + } + } + return false; +}; /***/ }), -/* 466 */ +/* 442 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! - * define-property + * has-value * - * Copyright (c) 2015, Jon Schlinkert. + * Copyright (c) 2014-2017, Jon Schlinkert. * Licensed under the MIT License. */ -var isDescriptor = __webpack_require__(467); - -module.exports = function defineProperty(obj, prop, val) { - if (typeof obj !== 'object' && typeof obj !== 'function') { - throw new TypeError('expected an object or function.'); - } - - if (typeof prop !== 'string') { - throw new TypeError('expected `prop` to be a string.'); - } +var isObject = __webpack_require__(404); +var hasValues = __webpack_require__(443); +var get = __webpack_require__(435); - if (isDescriptor(val) && ('set' in val || 'get' in val)) { - return Object.defineProperty(obj, prop, val); - } - - return Object.defineProperty(obj, prop, { - configurable: true, - enumerable: false, - writable: true, - value: val - }); +module.exports = function(val, prop) { + return hasValues(isObject(val) && prop ? get(val, prop) : val); }; /***/ }), -/* 467 */ +/* 443 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! - * is-descriptor + * has-values * - * Copyright (c) 2015-2017, Jon Schlinkert. + * Copyright (c) 2014-2015, 2017, Jon Schlinkert. * Released under the MIT License. */ -var typeOf = __webpack_require__(468); -var isAccessor = __webpack_require__(469); -var isData = __webpack_require__(471); +var typeOf = __webpack_require__(444); +var isNumber = __webpack_require__(408); -module.exports = function isDescriptor(obj, key) { - if (typeOf(obj) !== 'object') { - return false; +module.exports = function hasValue(val) { + // is-number checks for NaN and other edge cases + if (isNumber(val)) { + return true; } - if ('get' in obj) { - return isAccessor(obj, key); + + switch (typeOf(val)) { + case 'null': + case 'boolean': + case 'function': + return true; + case 'string': + case 'arguments': + return val.length !== 0; + case 'error': + return val.message !== ''; + case 'array': + var len = val.length; + if (len === 0) { + return false; + } + for (var i = 0; i < len; i++) { + if (hasValue(val[i])) { + return true; + } + } + return false; + case 'file': + case 'map': + case 'set': + return val.size !== 0; + case 'object': + var keys = Object.keys(val); + if (keys.length === 0) { + return false; + } + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + if (hasValue(val[key])) { + return true; + } + } + return false; + default: { + return false; + } } - return isData(obj, key); }; /***/ }), -/* 468 */ -/***/ (function(module, exports) { +/* 444 */ +/***/ (function(module, exports, __webpack_require__) { +var isBuffer = __webpack_require__(391); var toString = Object.prototype.toString; /** @@ -43289,10 +41092,8 @@ var toString = Object.prototype.toString; */ module.exports = function kindOf(val) { - var type = typeof val; - // primitivies - if (type === 'undefined') { + if (typeof val === 'undefined') { return 'undefined'; } if (val === null) { @@ -43301,18 +41102,15 @@ module.exports = function kindOf(val) { if (val === true || val === false || val instanceof Boolean) { return 'boolean'; } - if (type === 'string' || val instanceof String) { + if (typeof val === 'string' || val instanceof String) { return 'string'; } - if (type === 'number' || val instanceof Number) { + if (typeof val === 'number' || val instanceof Number) { return 'number'; } // functions - if (type === 'function' || val instanceof Function) { - if (typeof val.constructor.name !== 'undefined' && val.constructor.name.slice(0, 9) === 'Generator') { - return 'generatorfunction'; - } + if (typeof val === 'function' || val instanceof Function) { return 'function'; } @@ -43330,7 +41128,7 @@ module.exports = function kindOf(val) { } // other objects - type = toString.call(val); + var type = toString.call(val); if (type === '[object RegExp]') { return 'regexp'; @@ -43369,20 +41167,7 @@ module.exports = function kindOf(val) { if (type === '[object Symbol]') { return 'symbol'; } - - if (type === '[object Map Iterator]') { - return 'mapiterator'; - } - if (type === '[object Set Iterator]') { - return 'setiterator'; - } - if (type === '[object String Iterator]') { - return 'stringiterator'; - } - if (type === '[object Array Iterator]') { - return 'arrayiterator'; - } - + // typed arrays if (type === '[object Int8Array]') { return 'int8array'; @@ -43416,1013 +41201,969 @@ module.exports = function kindOf(val) { return 'object'; }; -/** - * If you need to support Safari 5-7 (8-10 yr-old browser), - * take a look at https://github.com/feross/is-buffer - */ - -function isBuffer(val) { - return val.constructor - && typeof val.constructor.isBuffer === 'function' - && val.constructor.isBuffer(val); -} - /***/ }), -/* 469 */ +/* 445 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! - * is-accessor-descriptor + * set-value * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. + * Copyright (c) 2014-2015, 2017, Jon Schlinkert. + * Released under the MIT License. */ -var typeOf = __webpack_require__(470); - -// accessor descriptor properties -var accessor = { - get: 'function', - set: 'function', - configurable: 'boolean', - enumerable: 'boolean' -}; - -function isAccessorDescriptor(obj, prop) { - if (typeof prop === 'string') { - var val = Object.getOwnPropertyDescriptor(obj, prop); - return typeof val !== 'undefined'; - } +var split = __webpack_require__(400); +var extend = __webpack_require__(394); +var isPlainObject = __webpack_require__(403); +var isObject = __webpack_require__(395); - if (typeOf(obj) !== 'object') { - return false; +module.exports = function(obj, prop, val) { + if (!isObject(obj)) { + return obj; } - if (has(obj, 'value') || has(obj, 'writable')) { - return false; + if (Array.isArray(prop)) { + prop = [].concat.apply([], prop).join('.'); } - if (!has(obj, 'get') || typeof obj.get !== 'function') { - return false; + if (typeof prop !== 'string') { + return obj; } - // tldr: it's valid to have "set" be undefined - // "set" might be undefined if `Object.getOwnPropertyDescriptor` - // was used to get the value, and only `get` was defined by the user - if (has(obj, 'set') && typeof obj[key] !== 'function' && typeof obj[key] !== 'undefined') { - return false; - } + var keys = split(prop, {sep: '.', brackets: true}); + var len = keys.length; + var idx = -1; + var current = obj; - for (var key in obj) { - if (!accessor.hasOwnProperty(key)) { + while (++idx < len) { + var key = keys[idx]; + if (idx !== len - 1) { + if (!isObject(current[key])) { + current[key] = {}; + } + current = current[key]; continue; } - if (typeOf(obj[key]) === accessor[key]) { - continue; + if (isPlainObject(current[key]) && isPlainObject(val)) { + current[key] = extend({}, current[key], val); + } else { + current[key] = val; } + } - if (typeof obj[key] !== 'undefined') { - return false; + return obj; +}; + + +/***/ }), +/* 446 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var isExtendable = __webpack_require__(447); +var forIn = __webpack_require__(448); + +function mixinDeep(target, objects) { + var len = arguments.length, i = 0; + while (++i < len) { + var obj = arguments[i]; + if (isObject(obj)) { + forIn(obj, copy, target); } } - return true; + return target; } -function has(obj, key) { - return {}.hasOwnProperty.call(obj, key); +/** + * Copy properties from the source object to the + * target object. + * + * @param {*} `val` + * @param {String} `key` + */ + +function copy(val, key) { + var obj = this[key]; + if (isObject(val) && isObject(obj)) { + mixinDeep(obj, val); + } else { + this[key] = val; + } } /** - * Expose `isAccessorDescriptor` + * Returns true if `val` is an object or function. + * + * @param {any} val + * @return {Boolean} */ -module.exports = isAccessorDescriptor; +function isObject(val) { + return isExtendable(val) && !Array.isArray(val); +} + +/** + * Expose `mixinDeep` + */ + +module.exports = mixinDeep; /***/ }), -/* 470 */ +/* 447 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(391); -var toString = Object.prototype.toString; - -/** - * Get the native `typeof` a value. +"use strict"; +/*! + * is-extendable * - * @param {*} `val` - * @return {*} Native javascript type + * Copyright (c) 2015-2017, Jon Schlinkert. + * Released under the MIT License. */ -module.exports = function kindOf(val) { - // primitivies - if (typeof val === 'undefined') { - return 'undefined'; - } - if (val === null) { - return 'null'; - } - if (val === true || val === false || val instanceof Boolean) { - return 'boolean'; - } - if (typeof val === 'string' || val instanceof String) { - return 'string'; - } - if (typeof val === 'number' || val instanceof Number) { - return 'number'; - } - // functions - if (typeof val === 'function' || val instanceof Function) { - return 'function'; - } - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; - } +var isPlainObject = __webpack_require__(403); - // check for instances of RegExp and Date before calling `toString` - if (val instanceof RegExp) { - return 'regexp'; - } - if (val instanceof Date) { - return 'date'; - } +module.exports = function isExtendable(val) { + return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); +}; - // other objects - var type = toString.call(val); - if (type === '[object RegExp]') { - return 'regexp'; - } - if (type === '[object Date]') { - return 'date'; - } - if (type === '[object Arguments]') { - return 'arguments'; - } - if (type === '[object Error]') { - return 'error'; - } +/***/ }), +/* 448 */ +/***/ (function(module, exports, __webpack_require__) { - // buffer - if (isBuffer(val)) { - return 'buffer'; - } +"use strict"; +/*! + * for-in + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */ - // es6: Map, WeakMap, Set, WeakSet - if (type === '[object Set]') { - return 'set'; - } - if (type === '[object WeakSet]') { - return 'weakset'; - } - if (type === '[object Map]') { - return 'map'; - } - if (type === '[object WeakMap]') { - return 'weakmap'; - } - if (type === '[object Symbol]') { - return 'symbol'; - } - // typed arrays - if (type === '[object Int8Array]') { - return 'int8array'; - } - if (type === '[object Uint8Array]') { - return 'uint8array'; - } - if (type === '[object Uint8ClampedArray]') { - return 'uint8clampedarray'; - } - if (type === '[object Int16Array]') { - return 'int16array'; - } - if (type === '[object Uint16Array]') { - return 'uint16array'; - } - if (type === '[object Int32Array]') { - return 'int32array'; - } - if (type === '[object Uint32Array]') { - return 'uint32array'; - } - if (type === '[object Float32Array]') { - return 'float32array'; - } - if (type === '[object Float64Array]') { - return 'float64array'; - } - // must be a plain object - return 'object'; +module.exports = function forIn(obj, fn, thisArg) { + for (var key in obj) { + if (fn.call(thisArg, obj[key], key, obj) === false) { + break; + } + } }; /***/ }), -/* 471 */ -/***/ (function(module, exports, __webpack_require__) { +/* 449 */ +/***/ (function(module, exports) { -"use strict"; /*! - * is-data-descriptor + * pascalcase * * Copyright (c) 2015, Jon Schlinkert. * Licensed under the MIT License. */ +function pascalcase(str) { + if (typeof str !== 'string') { + throw new TypeError('expected a string.'); + } + str = str.replace(/([A-Z])/g, ' $1'); + if (str.length === 1) { return str.toUpperCase(); } + str = str.replace(/^[\W_]+|[\W_]+$/g, '').toLowerCase(); + str = str.charAt(0).toUpperCase() + str.slice(1); + return str.replace(/[\W_]+(\w|$)/g, function (_, ch) { + return ch.toUpperCase(); + }); +} + +module.exports = pascalcase; + +/***/ }), +/* 450 */ +/***/ (function(module, exports, __webpack_require__) { -var typeOf = __webpack_require__(472); +"use strict"; -// data descriptor properties -var data = { - configurable: 'boolean', - enumerable: 'boolean', - writable: 'boolean' + +var util = __webpack_require__(29); +var utils = __webpack_require__(451); + +/** + * Expose class utils + */ + +var cu = module.exports; + +/** + * Expose class utils: `cu` + */ + +cu.isObject = function isObject(val) { + return utils.isObj(val) || typeof val === 'function'; }; -function isDataDescriptor(obj, prop) { - if (typeOf(obj) !== 'object') { - return false; - } +/** + * Returns true if an array has any of the given elements, or an + * object has any of the give keys. + * + * ```js + * cu.has(['a', 'b', 'c'], 'c'); + * //=> true + * + * cu.has(['a', 'b', 'c'], ['c', 'z']); + * //=> true + * + * cu.has({a: 'b', c: 'd'}, ['c', 'z']); + * //=> true + * ``` + * @param {Object} `obj` + * @param {String|Array} `val` + * @return {Boolean} + * @api public + */ - if (typeof prop === 'string') { - var val = Object.getOwnPropertyDescriptor(obj, prop); - return typeof val !== 'undefined'; +cu.has = function has(obj, val) { + val = cu.arrayify(val); + var len = val.length; + + if (cu.isObject(obj)) { + for (var key in obj) { + if (val.indexOf(key) > -1) { + return true; + } + } + + var keys = cu.nativeKeys(obj); + return cu.has(keys, val); } - if (!('value' in obj) && !('writable' in obj)) { + if (Array.isArray(obj)) { + var arr = obj; + while (len--) { + if (arr.indexOf(val[len]) > -1) { + return true; + } + } return false; } - for (var key in obj) { - if (key === 'value') continue; - - if (!data.hasOwnProperty(key)) { - continue; - } + throw new TypeError('expected an array or object.'); +}; - if (typeOf(obj[key]) === data[key]) { - continue; - } +/** + * Returns true if an array or object has all of the given values. + * + * ```js + * cu.hasAll(['a', 'b', 'c'], 'c'); + * //=> true + * + * cu.hasAll(['a', 'b', 'c'], ['c', 'z']); + * //=> false + * + * cu.hasAll({a: 'b', c: 'd'}, ['c', 'z']); + * //=> false + * ``` + * @param {Object|Array} `val` + * @param {String|Array} `values` + * @return {Boolean} + * @api public + */ - if (typeof obj[key] !== 'undefined') { +cu.hasAll = function hasAll(val, values) { + values = cu.arrayify(values); + var len = values.length; + while (len--) { + if (!cu.has(val, values[len])) { return false; } } return true; -} +}; /** - * Expose `isDataDescriptor` + * Cast the given value to an array. + * + * ```js + * cu.arrayify('foo'); + * //=> ['foo'] + * + * cu.arrayify(['foo']); + * //=> ['foo'] + * ``` + * + * @param {String|Array} `val` + * @return {Array} + * @api public */ -module.exports = isDataDescriptor; +cu.arrayify = function arrayify(val) { + return val ? (Array.isArray(val) ? val : [val]) : []; +}; +/** + * Noop + */ -/***/ }), -/* 472 */ -/***/ (function(module, exports, __webpack_require__) { +cu.noop = function noop() { + return; +}; -var isBuffer = __webpack_require__(391); -var toString = Object.prototype.toString; +/** + * Returns the first argument passed to the function. + */ + +cu.identity = function identity(val) { + return val; +}; /** - * Get the native `typeof` a value. + * Returns true if a value has a `contructor` * - * @param {*} `val` - * @return {*} Native javascript type + * ```js + * cu.hasConstructor({}); + * //=> true + * + * cu.hasConstructor(Object.create(null)); + * //=> false + * ``` + * @param {Object} `value` + * @return {Boolean} + * @api public */ -module.exports = function kindOf(val) { - // primitivies - if (typeof val === 'undefined') { - return 'undefined'; - } - if (val === null) { - return 'null'; - } - if (val === true || val === false || val instanceof Boolean) { - return 'boolean'; - } - if (typeof val === 'string' || val instanceof String) { - return 'string'; - } - if (typeof val === 'number' || val instanceof Number) { - return 'number'; - } - - // functions - if (typeof val === 'function' || val instanceof Function) { - return 'function'; - } +cu.hasConstructor = function hasConstructor(val) { + return cu.isObject(val) && typeof val.constructor !== 'undefined'; +}; - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; - } +/** + * Get the native `ownPropertyNames` from the constructor of the + * given `object`. An empty array is returned if the object does + * not have a constructor. + * + * ```js + * cu.nativeKeys({a: 'b', b: 'c', c: 'd'}) + * //=> ['a', 'b', 'c'] + * + * cu.nativeKeys(function(){}) + * //=> ['length', 'caller'] + * ``` + * + * @param {Object} `obj` Object that has a `constructor`. + * @return {Array} Array of keys. + * @api public + */ - // check for instances of RegExp and Date before calling `toString` - if (val instanceof RegExp) { - return 'regexp'; - } - if (val instanceof Date) { - return 'date'; - } +cu.nativeKeys = function nativeKeys(val) { + if (!cu.hasConstructor(val)) return []; + return Object.getOwnPropertyNames(val); +}; - // other objects - var type = toString.call(val); +/** + * Returns property descriptor `key` if it's an "own" property + * of the given object. + * + * ```js + * function App() {} + * Object.defineProperty(App.prototype, 'count', { + * get: function() { + * return Object.keys(this).length; + * } + * }); + * cu.getDescriptor(App.prototype, 'count'); + * // returns: + * // { + * // get: [Function], + * // set: undefined, + * // enumerable: false, + * // configurable: false + * // } + * ``` + * + * @param {Object} `obj` + * @param {String} `key` + * @return {Object} Returns descriptor `key` + * @api public + */ - if (type === '[object RegExp]') { - return 'regexp'; - } - if (type === '[object Date]') { - return 'date'; - } - if (type === '[object Arguments]') { - return 'arguments'; - } - if (type === '[object Error]') { - return 'error'; +cu.getDescriptor = function getDescriptor(obj, key) { + if (!cu.isObject(obj)) { + throw new TypeError('expected an object.'); } - - // buffer - if (isBuffer(val)) { - return 'buffer'; + if (typeof key !== 'string') { + throw new TypeError('expected key to be a string.'); } + return Object.getOwnPropertyDescriptor(obj, key); +}; - // es6: Map, WeakMap, Set, WeakSet - if (type === '[object Set]') { - return 'set'; - } - if (type === '[object WeakSet]') { - return 'weakset'; - } - if (type === '[object Map]') { - return 'map'; - } - if (type === '[object WeakMap]') { - return 'weakmap'; - } - if (type === '[object Symbol]') { - return 'symbol'; - } +/** + * Copy a descriptor from one object to another. + * + * ```js + * function App() {} + * Object.defineProperty(App.prototype, 'count', { + * get: function() { + * return Object.keys(this).length; + * } + * }); + * var obj = {}; + * cu.copyDescriptor(obj, App.prototype, 'count'); + * ``` + * @param {Object} `receiver` + * @param {Object} `provider` + * @param {String} `name` + * @return {Object} + * @api public + */ - // typed arrays - if (type === '[object Int8Array]') { - return 'int8array'; - } - if (type === '[object Uint8Array]') { - return 'uint8array'; - } - if (type === '[object Uint8ClampedArray]') { - return 'uint8clampedarray'; - } - if (type === '[object Int16Array]') { - return 'int16array'; - } - if (type === '[object Uint16Array]') { - return 'uint16array'; - } - if (type === '[object Int32Array]') { - return 'int32array'; - } - if (type === '[object Uint32Array]') { - return 'uint32array'; +cu.copyDescriptor = function copyDescriptor(receiver, provider, name) { + if (!cu.isObject(receiver)) { + throw new TypeError('expected receiving object to be an object.'); } - if (type === '[object Float32Array]') { - return 'float32array'; + if (!cu.isObject(provider)) { + throw new TypeError('expected providing object to be an object.'); } - if (type === '[object Float64Array]') { - return 'float64array'; + if (typeof name !== 'string') { + throw new TypeError('expected name to be a string.'); } - // must be a plain object - return 'object'; + var val = cu.getDescriptor(provider, name); + if (val) Object.defineProperty(receiver, name, val); }; - -/***/ }), -/* 473 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * define-property +/** + * Copy static properties, prototype properties, and descriptors + * from one object to another. * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. + * @param {Object} `receiver` + * @param {Object} `provider` + * @param {String|Array} `omit` One or more properties to omit + * @return {Object} + * @api public */ - - -var isDescriptor = __webpack_require__(474); - -module.exports = function defineProperty(obj, prop, val) { - if (typeof obj !== 'object' && typeof obj !== 'function') { - throw new TypeError('expected an object or function.'); +cu.copy = function copy(receiver, provider, omit) { + if (!cu.isObject(receiver)) { + throw new TypeError('expected receiving object to be an object.'); } - - if (typeof prop !== 'string') { - throw new TypeError('expected `prop` to be a string.'); + if (!cu.isObject(provider)) { + throw new TypeError('expected providing object to be an object.'); } + var props = Object.getOwnPropertyNames(provider); + var keys = Object.keys(provider); + var len = props.length, + key; + omit = cu.arrayify(omit); - if (isDescriptor(val) && ('set' in val || 'get' in val)) { - return Object.defineProperty(obj, prop, val); - } + while (len--) { + key = props[len]; - return Object.defineProperty(obj, prop, { - configurable: true, - enumerable: false, - writable: true, - value: val - }); + if (cu.has(keys, key)) { + utils.define(receiver, key, provider[key]); + } else if (!(key in receiver) && !cu.has(omit, key)) { + cu.copyDescriptor(receiver, provider, key); + } + } }; - -/***/ }), -/* 474 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * is-descriptor +/** + * Inherit the static properties, prototype properties, and descriptors + * from of an object. * - * Copyright (c) 2015-2017, Jon Schlinkert. - * Released under the MIT License. + * @param {Object} `receiver` + * @param {Object} `provider` + * @param {String|Array} `omit` One or more properties to omit + * @return {Object} + * @api public */ - - -var typeOf = __webpack_require__(475); -var isAccessor = __webpack_require__(476); -var isData = __webpack_require__(478); - -module.exports = function isDescriptor(obj, key) { - if (typeOf(obj) !== 'object') { - return false; +cu.inherit = function inherit(receiver, provider, omit) { + if (!cu.isObject(receiver)) { + throw new TypeError('expected receiving object to be an object.'); } - if ('get' in obj) { - return isAccessor(obj, key); + if (!cu.isObject(provider)) { + throw new TypeError('expected providing object to be an object.'); } - return isData(obj, key); -}; + var keys = []; + for (var key in provider) { + keys.push(key); + receiver[key] = provider[key]; + } -/***/ }), -/* 475 */ -/***/ (function(module, exports) { + keys = keys.concat(cu.arrayify(omit)); -var toString = Object.prototype.toString; + var a = provider.prototype || provider; + var b = receiver.prototype || receiver; + cu.copy(b, a, keys); +}; /** - * Get the native `typeof` a value. + * Returns a function for extending the static properties, + * prototype properties, and descriptors from the `Parent` + * constructor onto `Child` constructors. * - * @param {*} `val` - * @return {*} Native javascript type + * ```js + * var extend = cu.extend(Parent); + * Parent.extend(Child); + * + * // optional methods + * Parent.extend(Child, { + * foo: function() {}, + * bar: function() {} + * }); + * ``` + * @param {Function} `Parent` Parent ctor + * @param {Function} `extend` Optional extend function to handle custom extensions. Useful when updating methods that require a specific prototype. + * @param {Function} `Child` Child ctor + * @param {Object} `proto` Optionally pass additional prototype properties to inherit. + * @return {Object} + * @api public */ -module.exports = function kindOf(val) { - var type = typeof val; +cu.extend = function() { + // keep it lazy, instead of assigning to `cu.extend` + return utils.staticExtend.apply(null, arguments); +}; - // primitivies - if (type === 'undefined') { - return 'undefined'; - } - if (val === null) { - return 'null'; - } - if (val === true || val === false || val instanceof Boolean) { - return 'boolean'; - } - if (type === 'string' || val instanceof String) { - return 'string'; - } - if (type === 'number' || val instanceof Number) { - return 'number'; - } +/** + * Bubble up events emitted from static methods on the Parent ctor. + * + * @param {Object} `Parent` + * @param {Array} `events` Event names to bubble up + * @api public + */ - // functions - if (type === 'function' || val instanceof Function) { - if (typeof val.constructor.name !== 'undefined' && val.constructor.name.slice(0, 9) === 'Generator') { - return 'generatorfunction'; +cu.bubble = function(Parent, events) { + events = events || []; + Parent.bubble = function(Child, arr) { + if (Array.isArray(arr)) { + events = utils.union([], events, arr); } - return 'function'; - } + var len = events.length; + var idx = -1; + while (++idx < len) { + var name = events[idx]; + Parent.on(name, Child.emit.bind(Child, name)); + } + cu.bubble(Child, events); + }; +}; - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; - } - // check for instances of RegExp and Date before calling `toString` - if (val instanceof RegExp) { - return 'regexp'; - } - if (val instanceof Date) { - return 'date'; - } +/***/ }), +/* 451 */ +/***/ (function(module, exports, __webpack_require__) { - // other objects - type = toString.call(val); +"use strict"; - if (type === '[object RegExp]') { - return 'regexp'; - } - if (type === '[object Date]') { - return 'date'; - } - if (type === '[object Arguments]') { - return 'arguments'; - } - if (type === '[object Error]') { - return 'error'; - } - if (type === '[object Promise]') { - return 'promise'; - } - // buffer - if (isBuffer(val)) { - return 'buffer'; - } +var utils = {}; - // es6: Map, WeakMap, Set, WeakSet - if (type === '[object Set]') { - return 'set'; - } - if (type === '[object WeakSet]') { - return 'weakset'; - } - if (type === '[object Map]') { - return 'map'; - } - if (type === '[object WeakMap]') { - return 'weakmap'; - } - if (type === '[object Symbol]') { - return 'symbol'; - } - - if (type === '[object Map Iterator]') { - return 'mapiterator'; - } - if (type === '[object Set Iterator]') { - return 'setiterator'; - } - if (type === '[object String Iterator]') { - return 'stringiterator'; - } - if (type === '[object Array Iterator]') { - return 'arrayiterator'; - } - - // typed arrays - if (type === '[object Int8Array]') { - return 'int8array'; - } - if (type === '[object Uint8Array]') { - return 'uint8array'; - } - if (type === '[object Uint8ClampedArray]') { - return 'uint8clampedarray'; - } - if (type === '[object Int16Array]') { - return 'int16array'; - } - if (type === '[object Uint16Array]') { - return 'uint16array'; - } - if (type === '[object Int32Array]') { - return 'int32array'; - } - if (type === '[object Uint32Array]') { - return 'uint32array'; - } - if (type === '[object Float32Array]') { - return 'float32array'; - } - if (type === '[object Float64Array]') { - return 'float64array'; - } - // must be a plain object - return 'object'; -}; /** - * If you need to support Safari 5-7 (8-10 yr-old browser), - * take a look at https://github.com/feross/is-buffer + * Lazily required module dependencies */ -function isBuffer(val) { - return val.constructor - && typeof val.constructor.isBuffer === 'function' - && val.constructor.isBuffer(val); -} +utils.union = __webpack_require__(434); +utils.define = __webpack_require__(386); +utils.isObj = __webpack_require__(404); +utils.staticExtend = __webpack_require__(452); + + +/** + * Expose `utils` + */ + +module.exports = utils; /***/ }), -/* 476 */ +/* 452 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! - * is-accessor-descriptor + * static-extend * - * Copyright (c) 2015, Jon Schlinkert. + * Copyright (c) 2016, Jon Schlinkert. * Licensed under the MIT License. */ -var typeOf = __webpack_require__(477); - -// accessor descriptor properties -var accessor = { - get: 'function', - set: 'function', - configurable: 'boolean', - enumerable: 'boolean' -}; +var copy = __webpack_require__(453); +var define = __webpack_require__(386); +var util = __webpack_require__(29); -function isAccessorDescriptor(obj, prop) { - if (typeof prop === 'string') { - var val = Object.getOwnPropertyDescriptor(obj, prop); - return typeof val !== 'undefined'; - } +/** + * Returns a function for extending the static properties, + * prototype properties, and descriptors from the `Parent` + * constructor onto `Child` constructors. + * + * ```js + * var extend = require('static-extend'); + * Parent.extend = extend(Parent); + * + * // optionally pass a custom merge function as the second arg + * Parent.extend = extend(Parent, function(Child) { + * Child.prototype.mixin = function(key, val) { + * Child.prototype[key] = val; + * }; + * }); + * + * // extend "child" constructors + * Parent.extend(Child); + * + * // optionally define prototype methods as the second arg + * Parent.extend(Child, { + * foo: function() {}, + * bar: function() {} + * }); + * ``` + * @param {Function} `Parent` Parent ctor + * @param {Function} `extendFn` Optional extend function for handling any necessary custom merging. Useful when updating methods that require a specific prototype. + * @param {Function} `Child` Child ctor + * @param {Object} `proto` Optionally pass additional prototype properties to inherit. + * @return {Object} + * @api public + */ - if (typeOf(obj) !== 'object') { - return false; +function extend(Parent, extendFn) { + if (typeof Parent !== 'function') { + throw new TypeError('expected Parent to be a function.'); } - if (has(obj, 'value') || has(obj, 'writable')) { - return false; - } + return function(Ctor, proto) { + if (typeof Ctor !== 'function') { + throw new TypeError('expected Ctor to be a function.'); + } - if (!has(obj, 'get') || typeof obj.get !== 'function') { - return false; - } + util.inherits(Ctor, Parent); + copy(Ctor, Parent); - // tldr: it's valid to have "set" be undefined - // "set" might be undefined if `Object.getOwnPropertyDescriptor` - // was used to get the value, and only `get` was defined by the user - if (has(obj, 'set') && typeof obj[key] !== 'function' && typeof obj[key] !== 'undefined') { - return false; - } + // proto can be null or a plain object + if (typeof proto === 'object') { + var obj = Object.create(proto); - for (var key in obj) { - if (!accessor.hasOwnProperty(key)) { - continue; + for (var k in obj) { + Ctor.prototype[k] = obj[k]; + } } - if (typeOf(obj[key]) === accessor[key]) { - continue; - } + // keep a reference to the parent prototype + define(Ctor.prototype, '_parent_', { + configurable: true, + set: function() {}, + get: function() { + return Parent.prototype; + } + }); - if (typeof obj[key] !== 'undefined') { - return false; + if (typeof extendFn === 'function') { + extendFn(Ctor, Parent); } - } - return true; -} -function has(obj, key) { - return {}.hasOwnProperty.call(obj, key); -} + Ctor.extend = extend(Ctor, extendFn); + }; +}; /** - * Expose `isAccessorDescriptor` + * Expose `extend` */ -module.exports = isAccessorDescriptor; +module.exports = extend; /***/ }), -/* 477 */ +/* 453 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(391); -var toString = Object.prototype.toString; +"use strict"; + + +var typeOf = __webpack_require__(409); +var copyDescriptor = __webpack_require__(454); +var define = __webpack_require__(386); /** - * Get the native `typeof` a value. + * Copy static properties, prototype properties, and descriptors from one object to another. * - * @param {*} `val` - * @return {*} Native javascript type + * ```js + * function App() {} + * var proto = App.prototype; + * App.prototype.set = function() {}; + * App.prototype.get = function() {}; + * + * var obj = {}; + * copy(obj, proto); + * ``` + * @param {Object} `receiver` + * @param {Object} `provider` + * @param {String|Array} `omit` One or more properties to omit + * @return {Object} + * @api public */ -module.exports = function kindOf(val) { - // primitivies - if (typeof val === 'undefined') { - return 'undefined'; - } - if (val === null) { - return 'null'; - } - if (val === true || val === false || val instanceof Boolean) { - return 'boolean'; - } - if (typeof val === 'string' || val instanceof String) { - return 'string'; - } - if (typeof val === 'number' || val instanceof Number) { - return 'number'; - } - - // functions - if (typeof val === 'function' || val instanceof Function) { - return 'function'; - } - - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; - } - - // check for instances of RegExp and Date before calling `toString` - if (val instanceof RegExp) { - return 'regexp'; - } - if (val instanceof Date) { - return 'date'; - } - - // other objects - var type = toString.call(val); - - if (type === '[object RegExp]') { - return 'regexp'; - } - if (type === '[object Date]') { - return 'date'; - } - if (type === '[object Arguments]') { - return 'arguments'; +function copy(receiver, provider, omit) { + if (!isObject(receiver)) { + throw new TypeError('expected receiving object to be an object.'); } - if (type === '[object Error]') { - return 'error'; + if (!isObject(provider)) { + throw new TypeError('expected providing object to be an object.'); } - // buffer - if (isBuffer(val)) { - return 'buffer'; - } + var props = nativeKeys(provider); + var keys = Object.keys(provider); + var len = props.length; + omit = arrayify(omit); - // es6: Map, WeakMap, Set, WeakSet - if (type === '[object Set]') { - return 'set'; - } - if (type === '[object WeakSet]') { - return 'weakset'; - } - if (type === '[object Map]') { - return 'map'; - } - if (type === '[object WeakMap]') { - return 'weakmap'; - } - if (type === '[object Symbol]') { - return 'symbol'; - } + while (len--) { + var key = props[len]; - // typed arrays - if (type === '[object Int8Array]') { - return 'int8array'; - } - if (type === '[object Uint8Array]') { - return 'uint8array'; - } - if (type === '[object Uint8ClampedArray]') { - return 'uint8clampedarray'; - } - if (type === '[object Int16Array]') { - return 'int16array'; - } - if (type === '[object Uint16Array]') { - return 'uint16array'; - } - if (type === '[object Int32Array]') { - return 'int32array'; - } - if (type === '[object Uint32Array]') { - return 'uint32array'; - } - if (type === '[object Float32Array]') { - return 'float32array'; - } - if (type === '[object Float64Array]') { - return 'float64array'; + if (has(keys, key)) { + define(receiver, key, provider[key]); + } else if (!(key in receiver) && !has(omit, key)) { + copyDescriptor(receiver, provider, key); + } } - - // must be a plain object - return 'object'; }; +/** + * Return true if the given value is an object or function + */ -/***/ }), -/* 478 */ -/***/ (function(module, exports, __webpack_require__) { +function isObject(val) { + return typeOf(val) === 'object' || typeof val === 'function'; +} -"use strict"; -/*! - * is-data-descriptor +/** + * Returns true if an array has any of the given elements, or an + * object has any of the give keys. * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. + * ```js + * has(['a', 'b', 'c'], 'c'); + * //=> true + * + * has(['a', 'b', 'c'], ['c', 'z']); + * //=> true + * + * has({a: 'b', c: 'd'}, ['c', 'z']); + * //=> true + * ``` + * @param {Object} `obj` + * @param {String|Array} `val` + * @return {Boolean} */ +function has(obj, val) { + val = arrayify(val); + var len = val.length; + if (isObject(obj)) { + for (var key in obj) { + if (val.indexOf(key) > -1) { + return true; + } + } -var typeOf = __webpack_require__(479); - -// data descriptor properties -var data = { - configurable: 'boolean', - enumerable: 'boolean', - writable: 'boolean' -}; - -function isDataDescriptor(obj, prop) { - if (typeOf(obj) !== 'object') { - return false; - } - - if (typeof prop === 'string') { - var val = Object.getOwnPropertyDescriptor(obj, prop); - return typeof val !== 'undefined'; + var keys = nativeKeys(obj); + return has(keys, val); } - if (!('value' in obj) && !('writable' in obj)) { + if (Array.isArray(obj)) { + var arr = obj; + while (len--) { + if (arr.indexOf(val[len]) > -1) { + return true; + } + } return false; } - for (var key in obj) { - if (key === 'value') continue; - - if (!data.hasOwnProperty(key)) { - continue; - } + throw new TypeError('expected an array or object.'); +} - if (typeOf(obj[key]) === data[key]) { - continue; - } +/** + * Cast the given value to an array. + * + * ```js + * arrayify('foo'); + * //=> ['foo'] + * + * arrayify(['foo']); + * //=> ['foo'] + * ``` + * + * @param {String|Array} `val` + * @return {Array} + */ - if (typeof obj[key] !== 'undefined') { - return false; - } - } - return true; +function arrayify(val) { + return val ? (Array.isArray(val) ? val : [val]) : []; } /** - * Expose `isDataDescriptor` + * Returns true if a value has a `contructor` + * + * ```js + * hasConstructor({}); + * //=> true + * + * hasConstructor(Object.create(null)); + * //=> false + * ``` + * @param {Object} `value` + * @return {Boolean} */ -module.exports = isDataDescriptor; - +function hasConstructor(val) { + return isObject(val) && typeof val.constructor !== 'undefined'; +} -/***/ }), -/* 479 */ -/***/ (function(module, exports, __webpack_require__) { +/** + * Get the native `ownPropertyNames` from the constructor of the + * given `object`. An empty array is returned if the object does + * not have a constructor. + * + * ```js + * nativeKeys({a: 'b', b: 'c', c: 'd'}) + * //=> ['a', 'b', 'c'] + * + * nativeKeys(function(){}) + * //=> ['length', 'caller'] + * ``` + * + * @param {Object} `obj` Object that has a `constructor`. + * @return {Array} Array of keys. + */ -var isBuffer = __webpack_require__(391); -var toString = Object.prototype.toString; +function nativeKeys(val) { + if (!hasConstructor(val)) return []; + return Object.getOwnPropertyNames(val); +} /** - * Get the native `typeof` a value. - * - * @param {*} `val` - * @return {*} Native javascript type + * Expose `copy` */ -module.exports = function kindOf(val) { - // primitivies - if (typeof val === 'undefined') { - return 'undefined'; - } - if (val === null) { - return 'null'; - } - if (val === true || val === false || val instanceof Boolean) { - return 'boolean'; - } - if (typeof val === 'string' || val instanceof String) { - return 'string'; - } - if (typeof val === 'number' || val instanceof Number) { - return 'number'; - } +module.exports = copy; - // functions - if (typeof val === 'function' || val instanceof Function) { - return 'function'; - } +/** + * Expose `copy.has` for tests + */ - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; - } +module.exports.has = has; - // check for instances of RegExp and Date before calling `toString` - if (val instanceof RegExp) { - return 'regexp'; - } - if (val instanceof Date) { - return 'date'; - } - // other objects - var type = toString.call(val); +/***/ }), +/* 454 */ +/***/ (function(module, exports, __webpack_require__) { - if (type === '[object RegExp]') { - return 'regexp'; - } - if (type === '[object Date]') { - return 'date'; - } - if (type === '[object Arguments]') { - return 'arguments'; - } - if (type === '[object Error]') { - return 'error'; - } +"use strict"; +/*! + * copy-descriptor + * + * Copyright (c) 2015, Jon Schlinkert. + * Licensed under the MIT License. + */ - // buffer - if (isBuffer(val)) { - return 'buffer'; - } - // es6: Map, WeakMap, Set, WeakSet - if (type === '[object Set]') { - return 'set'; - } - if (type === '[object WeakSet]') { - return 'weakset'; - } - if (type === '[object Map]') { - return 'map'; - } - if (type === '[object WeakMap]') { - return 'weakmap'; - } - if (type === '[object Symbol]') { - return 'symbol'; - } - // typed arrays - if (type === '[object Int8Array]') { - return 'int8array'; - } - if (type === '[object Uint8Array]') { - return 'uint8array'; - } - if (type === '[object Uint8ClampedArray]') { - return 'uint8clampedarray'; - } - if (type === '[object Int16Array]') { - return 'int16array'; +/** + * Copy a descriptor from one object to another. + * + * ```js + * function App() { + * this.cache = {}; + * } + * App.prototype.set = function(key, val) { + * this.cache[key] = val; + * return this; + * }; + * Object.defineProperty(App.prototype, 'count', { + * get: function() { + * return Object.keys(this.cache).length; + * } + * }); + * + * copy(App.prototype, 'count', 'len'); + * + * // create an instance + * var app = new App(); + * + * app.set('a', true); + * app.set('b', true); + * app.set('c', true); + * + * console.log(app.count); + * //=> 3 + * console.log(app.len); + * //=> 3 + * ``` + * @name copy + * @param {Object} `receiver` The target object + * @param {Object} `provider` The provider object + * @param {String} `from` The key to copy on provider. + * @param {String} `to` Optionally specify a new key name to use. + * @return {Object} + * @api public + */ + +module.exports = function copyDescriptor(receiver, provider, from, to) { + if (!isObject(provider) && typeof provider !== 'function') { + to = from; + from = provider; + provider = receiver; } - if (type === '[object Uint16Array]') { - return 'uint16array'; + if (!isObject(receiver) && typeof receiver !== 'function') { + throw new TypeError('expected the first argument to be an object'); } - if (type === '[object Int32Array]') { - return 'int32array'; + if (!isObject(provider) && typeof provider !== 'function') { + throw new TypeError('expected provider to be an object'); } - if (type === '[object Uint32Array]') { - return 'uint32array'; + + if (typeof to !== 'string') { + to = from; } - if (type === '[object Float32Array]') { - return 'float32array'; + if (typeof from !== 'string') { + throw new TypeError('expected key to be a string'); } - if (type === '[object Float64Array]') { - return 'float64array'; + + if (!(from in provider)) { + throw new Error('property "' + from + '" does not exist'); } - // must be a plain object - return 'object'; + var val = Object.getOwnPropertyDescriptor(provider, from); + if (val) Object.defineProperty(receiver, to, val); }; +function isObject(val) { + return {}.toString.call(val) === '[object Object]'; +} + + /***/ }), -/* 480 */ +/* 455 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var use = __webpack_require__(481); -var define = __webpack_require__(473); -var debug = __webpack_require__(490)('snapdragon:compiler'); -var utils = __webpack_require__(497); +var use = __webpack_require__(456); +var define = __webpack_require__(386); +var debug = __webpack_require__(458)('snapdragon:compiler'); +var utils = __webpack_require__(465); /** * Create a new `Compiler` with the given `options`. @@ -44572,792 +42313,190 @@ Compiler.prototype = { var opts = utils.extend({}, this.options, options); this.ast = ast; this.parsingErrors = this.ast.errors; - this.output = ''; - - // source map support - if (opts.sourcemap) { - var sourcemaps = __webpack_require__(516); - sourcemaps(this); - this.mapVisit(this.ast.nodes); - this.applySourceMaps(); - this.map = opts.sourcemap === 'generator' ? this.map : this.map.toJSON(); - return this; - } - - this.mapVisit(this.ast.nodes); - return this; - } -}; - -/** - * Expose `Compiler` - */ - -module.exports = Compiler; - - -/***/ }), -/* 481 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * use - * - * Copyright (c) 2015, 2017, Jon Schlinkert. - * Released under the MIT License. - */ - - - -var utils = __webpack_require__(482); - -module.exports = function base(app, opts) { - if (!utils.isObject(app) && typeof app !== 'function') { - throw new TypeError('use: expect `app` be an object or function'); - } - - if (!utils.isObject(opts)) { - opts = {}; - } - - var prop = utils.isString(opts.prop) ? opts.prop : 'fns'; - if (!Array.isArray(app[prop])) { - utils.define(app, prop, []); - } - - /** - * Define a plugin function to be passed to use. The only - * parameter exposed to the plugin is `app`, the object or function. - * passed to `use(app)`. `app` is also exposed as `this` in plugins. - * - * Additionally, **if a plugin returns a function, the function will - * be pushed onto the `fns` array**, allowing the plugin to be - * called at a later point by the `run` method. - * - * ```js - * var use = require('use'); - * - * // define a plugin - * function foo(app) { - * // do stuff - * } - * - * var app = function(){}; - * use(app); - * - * // register plugins - * app.use(foo); - * app.use(bar); - * app.use(baz); - * ``` - * @name .use - * @param {Function} `fn` plugin function to call - * @api public - */ - - utils.define(app, 'use', use); - - /** - * Run all plugins on `fns`. Any plugin that returns a function - * when called by `use` is pushed onto the `fns` array. - * - * ```js - * var config = {}; - * app.run(config); - * ``` - * @name .run - * @param {Object} `value` Object to be modified by plugins. - * @return {Object} Returns the object passed to `run` - * @api public - */ - - utils.define(app, 'run', function(val) { - if (!utils.isObject(val)) return; - decorate(val); - - var self = this || app; - var fns = self[prop]; - var len = fns.length; - var idx = -1; - - while (++idx < len) { - val.use(fns[idx]); - } - return val; - }); - - /** - * Call plugin `fn`. If a function is returned push it into the - * `fns` array to be called by the `run` method. - */ - - function use(fn, options) { - if (typeof fn !== 'function') { - throw new TypeError('.use expects `fn` be a function'); - } - - var self = this || app; - if (typeof opts.fn === 'function') { - opts.fn.call(self, self, options); - } - - var plugin = fn.call(self, self); - if (typeof plugin === 'function') { - var fns = self[prop]; - fns.push(plugin); - } - return self; - } - - /** - * Ensure the `.use` method exists on `val` - */ - - function decorate(val) { - if (!val.use || !val.run) { - base(val); - } - } - - return app; -}; - - -/***/ }), -/* 482 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var utils = {}; - - - -/** - * Lazily required module dependencies - */ - -utils.define = __webpack_require__(483); -utils.isObject = __webpack_require__(411); - - -utils.isString = function(val) { - return val && typeof val === 'string'; -}; - -/** - * Expose `utils` modules - */ - -module.exports = utils; - - -/***/ }), -/* 483 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * define-property - * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. - */ - - - -var isDescriptor = __webpack_require__(484); - -module.exports = function defineProperty(obj, prop, val) { - if (typeof obj !== 'object' && typeof obj !== 'function') { - throw new TypeError('expected an object or function.'); - } - - if (typeof prop !== 'string') { - throw new TypeError('expected `prop` to be a string.'); - } - - if (isDescriptor(val) && ('set' in val || 'get' in val)) { - return Object.defineProperty(obj, prop, val); - } - - return Object.defineProperty(obj, prop, { - configurable: true, - enumerable: false, - writable: true, - value: val - }); -}; - - -/***/ }), -/* 484 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * is-descriptor - * - * Copyright (c) 2015-2017, Jon Schlinkert. - * Released under the MIT License. - */ - - - -var typeOf = __webpack_require__(485); -var isAccessor = __webpack_require__(486); -var isData = __webpack_require__(488); - -module.exports = function isDescriptor(obj, key) { - if (typeOf(obj) !== 'object') { - return false; - } - if ('get' in obj) { - return isAccessor(obj, key); - } - return isData(obj, key); -}; - - -/***/ }), -/* 485 */ -/***/ (function(module, exports) { - -var toString = Object.prototype.toString; - -/** - * Get the native `typeof` a value. - * - * @param {*} `val` - * @return {*} Native javascript type - */ - -module.exports = function kindOf(val) { - var type = typeof val; - - // primitivies - if (type === 'undefined') { - return 'undefined'; - } - if (val === null) { - return 'null'; - } - if (val === true || val === false || val instanceof Boolean) { - return 'boolean'; - } - if (type === 'string' || val instanceof String) { - return 'string'; - } - if (type === 'number' || val instanceof Number) { - return 'number'; - } - - // functions - if (type === 'function' || val instanceof Function) { - if (typeof val.constructor.name !== 'undefined' && val.constructor.name.slice(0, 9) === 'Generator') { - return 'generatorfunction'; - } - return 'function'; - } - - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; - } - - // check for instances of RegExp and Date before calling `toString` - if (val instanceof RegExp) { - return 'regexp'; - } - if (val instanceof Date) { - return 'date'; - } - - // other objects - type = toString.call(val); - - if (type === '[object RegExp]') { - return 'regexp'; - } - if (type === '[object Date]') { - return 'date'; - } - if (type === '[object Arguments]') { - return 'arguments'; - } - if (type === '[object Error]') { - return 'error'; - } - if (type === '[object Promise]') { - return 'promise'; - } - - // buffer - if (isBuffer(val)) { - return 'buffer'; - } - - // es6: Map, WeakMap, Set, WeakSet - if (type === '[object Set]') { - return 'set'; - } - if (type === '[object WeakSet]') { - return 'weakset'; - } - if (type === '[object Map]') { - return 'map'; - } - if (type === '[object WeakMap]') { - return 'weakmap'; - } - if (type === '[object Symbol]') { - return 'symbol'; - } - - if (type === '[object Map Iterator]') { - return 'mapiterator'; - } - if (type === '[object Set Iterator]') { - return 'setiterator'; - } - if (type === '[object String Iterator]') { - return 'stringiterator'; - } - if (type === '[object Array Iterator]') { - return 'arrayiterator'; - } - - // typed arrays - if (type === '[object Int8Array]') { - return 'int8array'; - } - if (type === '[object Uint8Array]') { - return 'uint8array'; - } - if (type === '[object Uint8ClampedArray]') { - return 'uint8clampedarray'; - } - if (type === '[object Int16Array]') { - return 'int16array'; - } - if (type === '[object Uint16Array]') { - return 'uint16array'; - } - if (type === '[object Int32Array]') { - return 'int32array'; - } - if (type === '[object Uint32Array]') { - return 'uint32array'; - } - if (type === '[object Float32Array]') { - return 'float32array'; - } - if (type === '[object Float64Array]') { - return 'float64array'; - } - - // must be a plain object - return 'object'; -}; - -/** - * If you need to support Safari 5-7 (8-10 yr-old browser), - * take a look at https://github.com/feross/is-buffer - */ - -function isBuffer(val) { - return val.constructor - && typeof val.constructor.isBuffer === 'function' - && val.constructor.isBuffer(val); -} - - -/***/ }), -/* 486 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * is-accessor-descriptor - * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. - */ - - - -var typeOf = __webpack_require__(487); - -// accessor descriptor properties -var accessor = { - get: 'function', - set: 'function', - configurable: 'boolean', - enumerable: 'boolean' -}; - -function isAccessorDescriptor(obj, prop) { - if (typeof prop === 'string') { - var val = Object.getOwnPropertyDescriptor(obj, prop); - return typeof val !== 'undefined'; - } - - if (typeOf(obj) !== 'object') { - return false; - } - - if (has(obj, 'value') || has(obj, 'writable')) { - return false; - } - - if (!has(obj, 'get') || typeof obj.get !== 'function') { - return false; - } - - // tldr: it's valid to have "set" be undefined - // "set" might be undefined if `Object.getOwnPropertyDescriptor` - // was used to get the value, and only `get` was defined by the user - if (has(obj, 'set') && typeof obj[key] !== 'function' && typeof obj[key] !== 'undefined') { - return false; - } - - for (var key in obj) { - if (!accessor.hasOwnProperty(key)) { - continue; - } - - if (typeOf(obj[key]) === accessor[key]) { - continue; - } + this.output = ''; - if (typeof obj[key] !== 'undefined') { - return false; + // source map support + if (opts.sourcemap) { + var sourcemaps = __webpack_require__(484); + sourcemaps(this); + this.mapVisit(this.ast.nodes); + this.applySourceMaps(); + this.map = opts.sourcemap === 'generator' ? this.map : this.map.toJSON(); + return this; } - } - return true; -} -function has(obj, key) { - return {}.hasOwnProperty.call(obj, key); -} + this.mapVisit(this.ast.nodes); + return this; + } +}; /** - * Expose `isAccessorDescriptor` + * Expose `Compiler` */ -module.exports = isAccessorDescriptor; +module.exports = Compiler; /***/ }), -/* 487 */ +/* 456 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(391); -var toString = Object.prototype.toString; - -/** - * Get the native `typeof` a value. +"use strict"; +/*! + * use * - * @param {*} `val` - * @return {*} Native javascript type + * Copyright (c) 2015, 2017, Jon Schlinkert. + * Released under the MIT License. */ -module.exports = function kindOf(val) { - // primitivies - if (typeof val === 'undefined') { - return 'undefined'; - } - if (val === null) { - return 'null'; - } - if (val === true || val === false || val instanceof Boolean) { - return 'boolean'; - } - if (typeof val === 'string' || val instanceof String) { - return 'string'; - } - if (typeof val === 'number' || val instanceof Number) { - return 'number'; - } - - // functions - if (typeof val === 'function' || val instanceof Function) { - return 'function'; - } - - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; - } - - // check for instances of RegExp and Date before calling `toString` - if (val instanceof RegExp) { - return 'regexp'; - } - if (val instanceof Date) { - return 'date'; - } - // other objects - var type = toString.call(val); - if (type === '[object RegExp]') { - return 'regexp'; - } - if (type === '[object Date]') { - return 'date'; - } - if (type === '[object Arguments]') { - return 'arguments'; - } - if (type === '[object Error]') { - return 'error'; - } +var utils = __webpack_require__(457); - // buffer - if (isBuffer(val)) { - return 'buffer'; +module.exports = function base(app, opts) { + if (!utils.isObject(app) && typeof app !== 'function') { + throw new TypeError('use: expect `app` be an object or function'); } - // es6: Map, WeakMap, Set, WeakSet - if (type === '[object Set]') { - return 'set'; - } - if (type === '[object WeakSet]') { - return 'weakset'; - } - if (type === '[object Map]') { - return 'map'; - } - if (type === '[object WeakMap]') { - return 'weakmap'; - } - if (type === '[object Symbol]') { - return 'symbol'; + if (!utils.isObject(opts)) { + opts = {}; } - // typed arrays - if (type === '[object Int8Array]') { - return 'int8array'; - } - if (type === '[object Uint8Array]') { - return 'uint8array'; - } - if (type === '[object Uint8ClampedArray]') { - return 'uint8clampedarray'; - } - if (type === '[object Int16Array]') { - return 'int16array'; - } - if (type === '[object Uint16Array]') { - return 'uint16array'; - } - if (type === '[object Int32Array]') { - return 'int32array'; - } - if (type === '[object Uint32Array]') { - return 'uint32array'; - } - if (type === '[object Float32Array]') { - return 'float32array'; - } - if (type === '[object Float64Array]') { - return 'float64array'; + var prop = utils.isString(opts.prop) ? opts.prop : 'fns'; + if (!Array.isArray(app[prop])) { + utils.define(app, prop, []); } - // must be a plain object - return 'object'; -}; - - -/***/ }), -/* 488 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * is-data-descriptor - * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. - */ - - + /** + * Define a plugin function to be passed to use. The only + * parameter exposed to the plugin is `app`, the object or function. + * passed to `use(app)`. `app` is also exposed as `this` in plugins. + * + * Additionally, **if a plugin returns a function, the function will + * be pushed onto the `fns` array**, allowing the plugin to be + * called at a later point by the `run` method. + * + * ```js + * var use = require('use'); + * + * // define a plugin + * function foo(app) { + * // do stuff + * } + * + * var app = function(){}; + * use(app); + * + * // register plugins + * app.use(foo); + * app.use(bar); + * app.use(baz); + * ``` + * @name .use + * @param {Function} `fn` plugin function to call + * @api public + */ -var typeOf = __webpack_require__(489); + utils.define(app, 'use', use); -// data descriptor properties -var data = { - configurable: 'boolean', - enumerable: 'boolean', - writable: 'boolean' -}; + /** + * Run all plugins on `fns`. Any plugin that returns a function + * when called by `use` is pushed onto the `fns` array. + * + * ```js + * var config = {}; + * app.run(config); + * ``` + * @name .run + * @param {Object} `value` Object to be modified by plugins. + * @return {Object} Returns the object passed to `run` + * @api public + */ -function isDataDescriptor(obj, prop) { - if (typeOf(obj) !== 'object') { - return false; - } + utils.define(app, 'run', function(val) { + if (!utils.isObject(val)) return; + decorate(val); - if (typeof prop === 'string') { - var val = Object.getOwnPropertyDescriptor(obj, prop); - return typeof val !== 'undefined'; - } + var self = this || app; + var fns = self[prop]; + var len = fns.length; + var idx = -1; - if (!('value' in obj) && !('writable' in obj)) { - return false; - } + while (++idx < len) { + val.use(fns[idx]); + } + return val; + }); - for (var key in obj) { - if (key === 'value') continue; + /** + * Call plugin `fn`. If a function is returned push it into the + * `fns` array to be called by the `run` method. + */ - if (!data.hasOwnProperty(key)) { - continue; + function use(fn, options) { + if (typeof fn !== 'function') { + throw new TypeError('.use expects `fn` be a function'); } - if (typeOf(obj[key]) === data[key]) { - continue; + var self = this || app; + if (typeof opts.fn === 'function') { + opts.fn.call(self, self, options); } - if (typeof obj[key] !== 'undefined') { - return false; + var plugin = fn.call(self, self); + if (typeof plugin === 'function') { + var fns = self[prop]; + fns.push(plugin); } + return self; } - return true; -} -/** - * Expose `isDataDescriptor` - */ + /** + * Ensure the `.use` method exists on `val` + */ -module.exports = isDataDescriptor; + function decorate(val) { + if (!val.use || !val.run) { + base(val); + } + } + + return app; +}; /***/ }), -/* 489 */ +/* 457 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(391); -var toString = Object.prototype.toString; - -/** - * Get the native `typeof` a value. - * - * @param {*} `val` - * @return {*} Native javascript type - */ +"use strict"; -module.exports = function kindOf(val) { - // primitivies - if (typeof val === 'undefined') { - return 'undefined'; - } - if (val === null) { - return 'null'; - } - if (val === true || val === false || val instanceof Boolean) { - return 'boolean'; - } - if (typeof val === 'string' || val instanceof String) { - return 'string'; - } - if (typeof val === 'number' || val instanceof Number) { - return 'number'; - } - // functions - if (typeof val === 'function' || val instanceof Function) { - return 'function'; - } +var utils = {}; - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; - } - // check for instances of RegExp and Date before calling `toString` - if (val instanceof RegExp) { - return 'regexp'; - } - if (val instanceof Date) { - return 'date'; - } - // other objects - var type = toString.call(val); +/** + * Lazily required module dependencies + */ - if (type === '[object RegExp]') { - return 'regexp'; - } - if (type === '[object Date]') { - return 'date'; - } - if (type === '[object Arguments]') { - return 'arguments'; - } - if (type === '[object Error]') { - return 'error'; - } +utils.define = __webpack_require__(386); +utils.isObject = __webpack_require__(404); - // buffer - if (isBuffer(val)) { - return 'buffer'; - } - // es6: Map, WeakMap, Set, WeakSet - if (type === '[object Set]') { - return 'set'; - } - if (type === '[object WeakSet]') { - return 'weakset'; - } - if (type === '[object Map]') { - return 'map'; - } - if (type === '[object WeakMap]') { - return 'weakmap'; - } - if (type === '[object Symbol]') { - return 'symbol'; - } +utils.isString = function(val) { + return val && typeof val === 'string'; +}; - // typed arrays - if (type === '[object Int8Array]') { - return 'int8array'; - } - if (type === '[object Uint8Array]') { - return 'uint8array'; - } - if (type === '[object Uint8ClampedArray]') { - return 'uint8clampedarray'; - } - if (type === '[object Int16Array]') { - return 'int16array'; - } - if (type === '[object Uint16Array]') { - return 'uint16array'; - } - if (type === '[object Int32Array]') { - return 'int32array'; - } - if (type === '[object Uint32Array]') { - return 'uint32array'; - } - if (type === '[object Float32Array]') { - return 'float32array'; - } - if (type === '[object Float64Array]') { - return 'float64array'; - } +/** + * Expose `utils` modules + */ - // must be a plain object - return 'object'; -}; +module.exports = utils; /***/ }), -/* 490 */ +/* 458 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -45366,14 +42505,14 @@ module.exports = function kindOf(val) { */ if (typeof process !== 'undefined' && process.type === 'renderer') { - module.exports = __webpack_require__(491); + module.exports = __webpack_require__(459); } else { - module.exports = __webpack_require__(494); + module.exports = __webpack_require__(462); } /***/ }), -/* 491 */ +/* 459 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -45382,7 +42521,7 @@ if (typeof process !== 'undefined' && process.type === 'renderer') { * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(492); +exports = module.exports = __webpack_require__(460); exports.log = log; exports.formatArgs = formatArgs; exports.save = save; @@ -45564,7 +42703,7 @@ function localstorage() { /***/ }), -/* 492 */ +/* 460 */ /***/ (function(module, exports, __webpack_require__) { @@ -45580,7 +42719,7 @@ exports.coerce = coerce; exports.disable = disable; exports.enable = enable; exports.enabled = enabled; -exports.humanize = __webpack_require__(493); +exports.humanize = __webpack_require__(461); /** * The currently active debug mode names, and names to skip. @@ -45772,7 +42911,7 @@ function coerce(val) { /***/ }), -/* 493 */ +/* 461 */ /***/ (function(module, exports) { /** @@ -45930,14 +43069,14 @@ function plural(ms, n, name) { /***/ }), -/* 494 */ +/* 462 */ /***/ (function(module, exports, __webpack_require__) { /** * Module dependencies. */ -var tty = __webpack_require__(495); +var tty = __webpack_require__(463); var util = __webpack_require__(29); /** @@ -45946,7 +43085,7 @@ var util = __webpack_require__(29); * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(492); +exports = module.exports = __webpack_require__(460); exports.init = init; exports.log = log; exports.formatArgs = formatArgs; @@ -46125,7 +43264,7 @@ function createWritableStdioStream (fd) { case 'PIPE': case 'TCP': - var net = __webpack_require__(496); + var net = __webpack_require__(464); stream = new net.Socket({ fd: fd, readable: false, @@ -46184,19 +43323,19 @@ exports.enable(load()); /***/ }), -/* 495 */ +/* 463 */ /***/ (function(module, exports) { module.exports = require("tty"); /***/ }), -/* 496 */ +/* 464 */ /***/ (function(module, exports) { module.exports = require("net"); /***/ }), -/* 497 */ +/* 465 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -46207,8 +43346,8 @@ module.exports = require("net"); */ exports.extend = __webpack_require__(394); -exports.SourceMap = __webpack_require__(498); -exports.sourceMapResolve = __webpack_require__(509); +exports.SourceMap = __webpack_require__(466); +exports.sourceMapResolve = __webpack_require__(477); /** * Convert backslash in the given string to forward slashes @@ -46251,7 +43390,7 @@ exports.last = function(arr, n) { /***/ }), -/* 498 */ +/* 466 */ /***/ (function(module, exports, __webpack_require__) { /* @@ -46259,13 +43398,13 @@ exports.last = function(arr, n) { * Licensed under the New BSD license. See LICENSE.txt or: * http://opensource.org/licenses/BSD-3-Clause */ -exports.SourceMapGenerator = __webpack_require__(499).SourceMapGenerator; -exports.SourceMapConsumer = __webpack_require__(505).SourceMapConsumer; -exports.SourceNode = __webpack_require__(508).SourceNode; +exports.SourceMapGenerator = __webpack_require__(467).SourceMapGenerator; +exports.SourceMapConsumer = __webpack_require__(473).SourceMapConsumer; +exports.SourceNode = __webpack_require__(476).SourceNode; /***/ }), -/* 499 */ +/* 467 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -46275,10 +43414,10 @@ exports.SourceNode = __webpack_require__(508).SourceNode; * http://opensource.org/licenses/BSD-3-Clause */ -var base64VLQ = __webpack_require__(500); -var util = __webpack_require__(502); -var ArraySet = __webpack_require__(503).ArraySet; -var MappingList = __webpack_require__(504).MappingList; +var base64VLQ = __webpack_require__(468); +var util = __webpack_require__(470); +var ArraySet = __webpack_require__(471).ArraySet; +var MappingList = __webpack_require__(472).MappingList; /** * An instance of the SourceMapGenerator represents a source map which is @@ -46687,7 +43826,7 @@ exports.SourceMapGenerator = SourceMapGenerator; /***/ }), -/* 500 */ +/* 468 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -46727,7 +43866,7 @@ exports.SourceMapGenerator = SourceMapGenerator; * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -var base64 = __webpack_require__(501); +var base64 = __webpack_require__(469); // A single base 64 digit can contain 6 bits of data. For the base 64 variable // length quantities we use in the source map spec, the first bit is the sign, @@ -46833,7 +43972,7 @@ exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) { /***/ }), -/* 501 */ +/* 469 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -46906,7 +44045,7 @@ exports.decode = function (charCode) { /***/ }), -/* 502 */ +/* 470 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -47329,7 +44468,7 @@ exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflate /***/ }), -/* 503 */ +/* 471 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -47339,7 +44478,7 @@ exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflate * http://opensource.org/licenses/BSD-3-Clause */ -var util = __webpack_require__(502); +var util = __webpack_require__(470); var has = Object.prototype.hasOwnProperty; var hasNativeMap = typeof Map !== "undefined"; @@ -47456,7 +44595,7 @@ exports.ArraySet = ArraySet; /***/ }), -/* 504 */ +/* 472 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -47466,7 +44605,7 @@ exports.ArraySet = ArraySet; * http://opensource.org/licenses/BSD-3-Clause */ -var util = __webpack_require__(502); +var util = __webpack_require__(470); /** * Determine whether mappingB is after mappingA with respect to generated @@ -47541,7 +44680,7 @@ exports.MappingList = MappingList; /***/ }), -/* 505 */ +/* 473 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -47551,11 +44690,11 @@ exports.MappingList = MappingList; * http://opensource.org/licenses/BSD-3-Clause */ -var util = __webpack_require__(502); -var binarySearch = __webpack_require__(506); -var ArraySet = __webpack_require__(503).ArraySet; -var base64VLQ = __webpack_require__(500); -var quickSort = __webpack_require__(507).quickSort; +var util = __webpack_require__(470); +var binarySearch = __webpack_require__(474); +var ArraySet = __webpack_require__(471).ArraySet; +var base64VLQ = __webpack_require__(468); +var quickSort = __webpack_require__(475).quickSort; function SourceMapConsumer(aSourceMap) { var sourceMap = aSourceMap; @@ -48629,7 +45768,7 @@ exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer; /***/ }), -/* 506 */ +/* 474 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -48746,7 +45885,7 @@ exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { /***/ }), -/* 507 */ +/* 475 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -48866,7 +46005,7 @@ exports.quickSort = function (ary, comparator) { /***/ }), -/* 508 */ +/* 476 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -48876,8 +46015,8 @@ exports.quickSort = function (ary, comparator) { * http://opensource.org/licenses/BSD-3-Clause */ -var SourceMapGenerator = __webpack_require__(499).SourceMapGenerator; -var util = __webpack_require__(502); +var SourceMapGenerator = __webpack_require__(467).SourceMapGenerator; +var util = __webpack_require__(470); // Matches a Windows-style `\r\n` newline or a `\n` newline used by all other // operating systems these days (capturing the result). @@ -49285,17 +46424,17 @@ exports.SourceNode = SourceNode; /***/ }), -/* 509 */ +/* 477 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2014, 2015, 2016, 2017 Simon Lydell // X11 (“MIT”) Licensed. (See LICENSE.) -var sourceMappingURL = __webpack_require__(510) -var resolveUrl = __webpack_require__(511) -var decodeUriComponent = __webpack_require__(512) -var urix = __webpack_require__(514) -var atob = __webpack_require__(515) +var sourceMappingURL = __webpack_require__(478) +var resolveUrl = __webpack_require__(479) +var decodeUriComponent = __webpack_require__(480) +var urix = __webpack_require__(482) +var atob = __webpack_require__(483) @@ -49593,7 +46732,7 @@ module.exports = { /***/ }), -/* 510 */ +/* 478 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;// Copyright 2014 Simon Lydell @@ -49656,7 +46795,7 @@ void (function(root, factory) { /***/ }), -/* 511 */ +/* 479 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2014 Simon Lydell @@ -49674,13 +46813,13 @@ module.exports = resolveUrl /***/ }), -/* 512 */ +/* 480 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2017 Simon Lydell // X11 (“MIT”) Licensed. (See LICENSE.) -var decodeUriComponent = __webpack_require__(513) +var decodeUriComponent = __webpack_require__(481) function customDecodeUriComponent(string) { // `decodeUriComponent` turns `+` into ` `, but that's not wanted. @@ -49691,7 +46830,7 @@ module.exports = customDecodeUriComponent /***/ }), -/* 513 */ +/* 481 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -49792,7 +46931,7 @@ module.exports = function (encodedURI) { /***/ }), -/* 514 */ +/* 482 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2014 Simon Lydell @@ -49815,7 +46954,7 @@ module.exports = urix /***/ }), -/* 515 */ +/* 483 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -49829,7 +46968,7 @@ module.exports = atob.atob = atob; /***/ }), -/* 516 */ +/* 484 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -49837,8 +46976,8 @@ module.exports = atob.atob = atob; var fs = __webpack_require__(23); var path = __webpack_require__(16); -var define = __webpack_require__(473); -var utils = __webpack_require__(497); +var define = __webpack_require__(386); +var utils = __webpack_require__(465); /** * Expose `mixin()`. @@ -49981,19 +47120,19 @@ exports.comment = function(node) { /***/ }), -/* 517 */ +/* 485 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var use = __webpack_require__(481); +var use = __webpack_require__(456); var util = __webpack_require__(29); -var Cache = __webpack_require__(518); -var define = __webpack_require__(473); -var debug = __webpack_require__(490)('snapdragon:parser'); -var Position = __webpack_require__(519); -var utils = __webpack_require__(497); +var Cache = __webpack_require__(486); +var define = __webpack_require__(386); +var debug = __webpack_require__(458)('snapdragon:parser'); +var Position = __webpack_require__(487); +var utils = __webpack_require__(465); /** * Create a new `Parser` with the given `input` and `options`. @@ -50521,7 +47660,7 @@ module.exports = Parser; /***/ }), -/* 518 */ +/* 486 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -50628,13 +47767,13 @@ MapCache.prototype.del = function mapDelete(key) { /***/ }), -/* 519 */ +/* 487 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var define = __webpack_require__(473); +var define = __webpack_require__(386); /** * Store position for a node @@ -50649,14 +47788,14 @@ module.exports = function Position(start, parser) { /***/ }), -/* 520 */ +/* 488 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var nanomatch = __webpack_require__(521); -var extglob = __webpack_require__(531); +var nanomatch = __webpack_require__(489); +var extglob = __webpack_require__(500); module.exports = function(snapdragon) { var compilers = snapdragon.compiler.compilers; @@ -50733,7 +47872,7 @@ function escapeExtglobs(compiler) { /***/ }), -/* 521 */ +/* 489 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -50751,10 +47890,10 @@ var extend = __webpack_require__(394); * Local dependencies */ -var compilers = __webpack_require__(522); -var parsers = __webpack_require__(523); -var cache = __webpack_require__(525); -var utils = __webpack_require__(527); +var compilers = __webpack_require__(490); +var parsers = __webpack_require__(491); +var cache = __webpack_require__(493); +var utils = __webpack_require__(495); var MAX_LENGTH = 1024 * 64; /** @@ -51583,7 +48722,7 @@ module.exports = nanomatch; /***/ }), -/* 522 */ +/* 490 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -51909,7 +49048,7 @@ module.exports = function(nanomatch, options) { /***/ }), -/* 523 */ +/* 491 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -51917,7 +49056,7 @@ module.exports = function(nanomatch, options) { var regexNot = __webpack_require__(396); var toRegex = __webpack_require__(385); -var isOdd = __webpack_require__(524); +var isOdd = __webpack_require__(492); /** * Characters to use in negation regex (we want to "not" match @@ -52304,7 +49443,7 @@ module.exports.not = NOT_REGEX; /***/ }), -/* 524 */ +/* 492 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -52317,7 +49456,7 @@ module.exports.not = NOT_REGEX; -var isNumber = __webpack_require__(415); +var isNumber = __webpack_require__(408); module.exports = function isOdd(i) { if (!isNumber(i)) { @@ -52331,14 +49470,14 @@ module.exports = function isOdd(i) { /***/ }), -/* 525 */ +/* 493 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = new (__webpack_require__(526))(); +module.exports = new (__webpack_require__(494))(); /***/ }), -/* 526 */ +/* 494 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -52351,7 +49490,7 @@ module.exports = new (__webpack_require__(526))(); -var MapCache = __webpack_require__(518); +var MapCache = __webpack_require__(486); /** * Create a new `FragmentCache` with an optional object to use for `caches`. @@ -52473,7 +49612,7 @@ exports = module.exports = FragmentCache; /***/ }), -/* 527 */ +/* 495 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -52487,11 +49626,11 @@ var path = __webpack_require__(16); */ var Snapdragon = __webpack_require__(424); -utils.define = __webpack_require__(398); -utils.diff = __webpack_require__(528); +utils.define = __webpack_require__(496); +utils.diff = __webpack_require__(497); utils.extend = __webpack_require__(394); -utils.pick = __webpack_require__(529); -utils.typeOf = __webpack_require__(530); +utils.pick = __webpack_require__(498); +utils.typeOf = __webpack_require__(499); utils.unique = __webpack_require__(397); /** @@ -52858,7 +49997,45 @@ utils.unixify = function(options) { /***/ }), -/* 528 */ +/* 496 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/*! + * define-property + * + * Copyright (c) 2015, 2017, Jon Schlinkert. + * Released under the MIT License. + */ + + + +var isDescriptor = __webpack_require__(416); + +module.exports = function defineProperty(obj, prop, val) { + if (typeof obj !== 'object' && typeof obj !== 'function') { + throw new TypeError('expected an object or function.'); + } + + if (typeof prop !== 'string') { + throw new TypeError('expected `prop` to be a string.'); + } + + if (isDescriptor(val) && ('set' in val || 'get' in val)) { + return Object.defineProperty(obj, prop, val); + } + + return Object.defineProperty(obj, prop, { + configurable: true, + enumerable: false, + writable: true, + value: val + }); +}; + + +/***/ }), +/* 497 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -52912,7 +50089,7 @@ function diffArray(one, two) { /***/ }), -/* 529 */ +/* 498 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -52925,7 +50102,7 @@ function diffArray(one, two) { -var isObject = __webpack_require__(411); +var isObject = __webpack_require__(404); module.exports = function pick(obj, keys) { if (!isObject(obj) && typeof obj !== 'function') { @@ -52954,7 +50131,7 @@ module.exports = function pick(obj, keys) { /***/ }), -/* 530 */ +/* 499 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -53107,7 +50284,7 @@ function isBuffer(val) { /***/ }), -/* 531 */ +/* 500 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -53125,10 +50302,10 @@ var toRegex = __webpack_require__(385); * Local dependencies */ -var compilers = __webpack_require__(532); -var parsers = __webpack_require__(545); -var Extglob = __webpack_require__(547); -var utils = __webpack_require__(546); +var compilers = __webpack_require__(501); +var parsers = __webpack_require__(507); +var Extglob = __webpack_require__(509); +var utils = __webpack_require__(508); var MAX_LENGTH = 1024 * 64; /** @@ -53445,13 +50622,13 @@ module.exports = extglob; /***/ }), -/* 532 */ +/* 501 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var brackets = __webpack_require__(533); +var brackets = __webpack_require__(502); /** * Extglob compilers @@ -53621,7 +50798,7 @@ module.exports = function(extglob) { /***/ }), -/* 533 */ +/* 502 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -53631,14 +50808,14 @@ module.exports = function(extglob) { * Local dependencies */ -var compilers = __webpack_require__(534); -var parsers = __webpack_require__(536); +var compilers = __webpack_require__(503); +var parsers = __webpack_require__(505); /** * Module dependencies */ -var debug = __webpack_require__(490)('expand-brackets'); +var debug = __webpack_require__(458)('expand-brackets'); var extend = __webpack_require__(394); var Snapdragon = __webpack_require__(424); var toRegex = __webpack_require__(385); @@ -53839,13 +51016,13 @@ module.exports = brackets; /***/ }), -/* 534 */ +/* 503 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var posix = __webpack_require__(535); +var posix = __webpack_require__(504); module.exports = function(brackets) { brackets.compiler @@ -53933,7 +51110,7 @@ module.exports = function(brackets) { /***/ }), -/* 535 */ +/* 504 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -53962,14 +51139,14 @@ module.exports = { /***/ }), -/* 536 */ +/* 505 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var utils = __webpack_require__(537); -var define = __webpack_require__(538); +var utils = __webpack_require__(506); +var define = __webpack_require__(386); /** * Text regex @@ -54017,829 +51194,227 @@ function parsers(brackets) { /** * POSIX character classes: "[[:alpha:][:digits:]]" - */ - - .capture('posix', function() { - var pos = this.position(); - var m = this.match(/^\[:(.*?):\](?=.*\])/); - if (!m) return; - - var inside = this.isInside('bracket'); - if (inside) { - brackets.posix++; - } - - return pos({ - type: 'posix', - insideBracket: inside, - inner: m[1], - val: m[0] - }); - }) - - /** - * Bracket (noop) - */ - - .capture('bracket', function() {}) - - /** - * Open: '[' - */ - - .capture('bracket.open', function() { - var parsed = this.parsed; - var pos = this.position(); - var m = this.match(/^\[(?=.*\])/); - if (!m) return; - - var prev = this.prev(); - var last = utils.last(prev.nodes); - - if (parsed.slice(-1) === '\\' && !this.isInside('bracket')) { - last.val = last.val.slice(0, last.val.length - 1); - return pos({ - type: 'escape', - val: m[0] - }); - } - - var open = pos({ - type: 'bracket.open', - val: m[0] - }); - - if (last.type === 'bracket.open' || this.isInside('bracket')) { - open.val = '\\' + open.val; - open.type = 'bracket.inner'; - open.escaped = true; - return open; - } - - var node = pos({ - type: 'bracket', - nodes: [open] - }); - - define(node, 'parent', prev); - define(open, 'parent', node); - this.push('bracket', node); - prev.nodes.push(node); - }) - - /** - * Bracket text - */ - - .capture('bracket.inner', function() { - if (!this.isInside('bracket')) return; - var pos = this.position(); - var m = this.match(not); - if (!m || !m[0]) return; - - var next = this.input.charAt(0); - var val = m[0]; - - var node = pos({ - type: 'bracket.inner', - val: val - }); - - if (val === '\\\\') { - return node; - } - - var first = val.charAt(0); - var last = val.slice(-1); - - if (first === '!') { - val = '^' + val.slice(1); - } - - if (last === '\\' || (val === '^' && next === ']')) { - val += this.input[0]; - this.consume(1); - } - - node.val = val; - return node; - }) - - /** - * Close: ']' - */ - - .capture('bracket.close', function() { - var parsed = this.parsed; - var pos = this.position(); - var m = this.match(/^\]/); - if (!m) return; - - var prev = this.prev(); - var last = utils.last(prev.nodes); - - if (parsed.slice(-1) === '\\' && !this.isInside('bracket')) { - last.val = last.val.slice(0, last.val.length - 1); - - return pos({ - type: 'escape', - val: m[0] - }); - } - - var node = pos({ - type: 'bracket.close', - rest: this.input, - val: m[0] - }); - - if (last.type === 'bracket.open') { - node.type = 'bracket.inner'; - node.escaped = true; - return node; - } - - var bracket = this.pop('bracket'); - if (!this.isType(bracket, 'bracket')) { - if (this.options.strict) { - throw new Error('missing opening "["'); - } - node.type = 'bracket.inner'; - node.escaped = true; - return node; - } - - bracket.nodes.push(node); - define(node, 'parent', bracket); - }); -} - -/** - * Brackets parsers - */ - -module.exports = parsers; - -/** - * Expose text regex - */ - -module.exports.TEXT_REGEX = TEXT_REGEX; - - -/***/ }), -/* 537 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var toRegex = __webpack_require__(385); -var regexNot = __webpack_require__(396); -var cached; - -/** - * Get the last element from `array` - * @param {Array} `array` - * @return {*} - */ - -exports.last = function(arr) { - return arr[arr.length - 1]; -}; - -/** - * Create and cache regex to use for text nodes - */ - -exports.createRegex = function(pattern, include) { - if (cached) return cached; - var opts = {contains: true, strictClose: false}; - var not = regexNot.create(pattern, opts); - var re; - - if (typeof include === 'string') { - re = toRegex('^(?:' + include + '|' + not + ')', opts); - } else { - re = toRegex(not, opts); - } - - return (cached = re); -}; - - -/***/ }), -/* 538 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * define-property - * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. - */ - - - -var isDescriptor = __webpack_require__(539); - -module.exports = function defineProperty(obj, prop, val) { - if (typeof obj !== 'object' && typeof obj !== 'function') { - throw new TypeError('expected an object or function.'); - } - - if (typeof prop !== 'string') { - throw new TypeError('expected `prop` to be a string.'); - } - - if (isDescriptor(val) && ('set' in val || 'get' in val)) { - return Object.defineProperty(obj, prop, val); - } - - return Object.defineProperty(obj, prop, { - configurable: true, - enumerable: false, - writable: true, - value: val - }); -}; - - -/***/ }), -/* 539 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * is-descriptor - * - * Copyright (c) 2015-2017, Jon Schlinkert. - * Released under the MIT License. - */ - - - -var typeOf = __webpack_require__(540); -var isAccessor = __webpack_require__(541); -var isData = __webpack_require__(543); - -module.exports = function isDescriptor(obj, key) { - if (typeOf(obj) !== 'object') { - return false; - } - if ('get' in obj) { - return isAccessor(obj, key); - } - return isData(obj, key); -}; - - -/***/ }), -/* 540 */ -/***/ (function(module, exports) { - -var toString = Object.prototype.toString; - -/** - * Get the native `typeof` a value. - * - * @param {*} `val` - * @return {*} Native javascript type - */ - -module.exports = function kindOf(val) { - var type = typeof val; - - // primitivies - if (type === 'undefined') { - return 'undefined'; - } - if (val === null) { - return 'null'; - } - if (val === true || val === false || val instanceof Boolean) { - return 'boolean'; - } - if (type === 'string' || val instanceof String) { - return 'string'; - } - if (type === 'number' || val instanceof Number) { - return 'number'; - } - - // functions - if (type === 'function' || val instanceof Function) { - if (typeof val.constructor.name !== 'undefined' && val.constructor.name.slice(0, 9) === 'Generator') { - return 'generatorfunction'; - } - return 'function'; - } - - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; - } - - // check for instances of RegExp and Date before calling `toString` - if (val instanceof RegExp) { - return 'regexp'; - } - if (val instanceof Date) { - return 'date'; - } - - // other objects - type = toString.call(val); - - if (type === '[object RegExp]') { - return 'regexp'; - } - if (type === '[object Date]') { - return 'date'; - } - if (type === '[object Arguments]') { - return 'arguments'; - } - if (type === '[object Error]') { - return 'error'; - } - if (type === '[object Promise]') { - return 'promise'; - } - - // buffer - if (isBuffer(val)) { - return 'buffer'; - } - - // es6: Map, WeakMap, Set, WeakSet - if (type === '[object Set]') { - return 'set'; - } - if (type === '[object WeakSet]') { - return 'weakset'; - } - if (type === '[object Map]') { - return 'map'; - } - if (type === '[object WeakMap]') { - return 'weakmap'; - } - if (type === '[object Symbol]') { - return 'symbol'; - } - - if (type === '[object Map Iterator]') { - return 'mapiterator'; - } - if (type === '[object Set Iterator]') { - return 'setiterator'; - } - if (type === '[object String Iterator]') { - return 'stringiterator'; - } - if (type === '[object Array Iterator]') { - return 'arrayiterator'; - } - - // typed arrays - if (type === '[object Int8Array]') { - return 'int8array'; - } - if (type === '[object Uint8Array]') { - return 'uint8array'; - } - if (type === '[object Uint8ClampedArray]') { - return 'uint8clampedarray'; - } - if (type === '[object Int16Array]') { - return 'int16array'; - } - if (type === '[object Uint16Array]') { - return 'uint16array'; - } - if (type === '[object Int32Array]') { - return 'int32array'; - } - if (type === '[object Uint32Array]') { - return 'uint32array'; - } - if (type === '[object Float32Array]') { - return 'float32array'; - } - if (type === '[object Float64Array]') { - return 'float64array'; - } - - // must be a plain object - return 'object'; -}; - -/** - * If you need to support Safari 5-7 (8-10 yr-old browser), - * take a look at https://github.com/feross/is-buffer - */ - -function isBuffer(val) { - return val.constructor - && typeof val.constructor.isBuffer === 'function' - && val.constructor.isBuffer(val); -} - - -/***/ }), -/* 541 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * is-accessor-descriptor - * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. - */ - - - -var typeOf = __webpack_require__(542); - -// accessor descriptor properties -var accessor = { - get: 'function', - set: 'function', - configurable: 'boolean', - enumerable: 'boolean' -}; - -function isAccessorDescriptor(obj, prop) { - if (typeof prop === 'string') { - var val = Object.getOwnPropertyDescriptor(obj, prop); - return typeof val !== 'undefined'; - } - - if (typeOf(obj) !== 'object') { - return false; - } - - if (has(obj, 'value') || has(obj, 'writable')) { - return false; - } - - if (!has(obj, 'get') || typeof obj.get !== 'function') { - return false; - } - - // tldr: it's valid to have "set" be undefined - // "set" might be undefined if `Object.getOwnPropertyDescriptor` - // was used to get the value, and only `get` was defined by the user - if (has(obj, 'set') && typeof obj[key] !== 'function' && typeof obj[key] !== 'undefined') { - return false; - } - - for (var key in obj) { - if (!accessor.hasOwnProperty(key)) { - continue; - } - - if (typeOf(obj[key]) === accessor[key]) { - continue; - } - - if (typeof obj[key] !== 'undefined') { - return false; - } - } - return true; -} + */ -function has(obj, key) { - return {}.hasOwnProperty.call(obj, key); -} + .capture('posix', function() { + var pos = this.position(); + var m = this.match(/^\[:(.*?):\](?=.*\])/); + if (!m) return; -/** - * Expose `isAccessorDescriptor` - */ + var inside = this.isInside('bracket'); + if (inside) { + brackets.posix++; + } -module.exports = isAccessorDescriptor; + return pos({ + type: 'posix', + insideBracket: inside, + inner: m[1], + val: m[0] + }); + }) + /** + * Bracket (noop) + */ -/***/ }), -/* 542 */ -/***/ (function(module, exports, __webpack_require__) { + .capture('bracket', function() {}) -var isBuffer = __webpack_require__(391); -var toString = Object.prototype.toString; + /** + * Open: '[' + */ -/** - * Get the native `typeof` a value. - * - * @param {*} `val` - * @return {*} Native javascript type - */ + .capture('bracket.open', function() { + var parsed = this.parsed; + var pos = this.position(); + var m = this.match(/^\[(?=.*\])/); + if (!m) return; -module.exports = function kindOf(val) { - // primitivies - if (typeof val === 'undefined') { - return 'undefined'; - } - if (val === null) { - return 'null'; - } - if (val === true || val === false || val instanceof Boolean) { - return 'boolean'; - } - if (typeof val === 'string' || val instanceof String) { - return 'string'; - } - if (typeof val === 'number' || val instanceof Number) { - return 'number'; - } + var prev = this.prev(); + var last = utils.last(prev.nodes); - // functions - if (typeof val === 'function' || val instanceof Function) { - return 'function'; - } + if (parsed.slice(-1) === '\\' && !this.isInside('bracket')) { + last.val = last.val.slice(0, last.val.length - 1); + return pos({ + type: 'escape', + val: m[0] + }); + } - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; - } + var open = pos({ + type: 'bracket.open', + val: m[0] + }); - // check for instances of RegExp and Date before calling `toString` - if (val instanceof RegExp) { - return 'regexp'; - } - if (val instanceof Date) { - return 'date'; - } + if (last.type === 'bracket.open' || this.isInside('bracket')) { + open.val = '\\' + open.val; + open.type = 'bracket.inner'; + open.escaped = true; + return open; + } - // other objects - var type = toString.call(val); + var node = pos({ + type: 'bracket', + nodes: [open] + }); - if (type === '[object RegExp]') { - return 'regexp'; - } - if (type === '[object Date]') { - return 'date'; - } - if (type === '[object Arguments]') { - return 'arguments'; - } - if (type === '[object Error]') { - return 'error'; - } + define(node, 'parent', prev); + define(open, 'parent', node); + this.push('bracket', node); + prev.nodes.push(node); + }) - // buffer - if (isBuffer(val)) { - return 'buffer'; - } + /** + * Bracket text + */ - // es6: Map, WeakMap, Set, WeakSet - if (type === '[object Set]') { - return 'set'; - } - if (type === '[object WeakSet]') { - return 'weakset'; - } - if (type === '[object Map]') { - return 'map'; - } - if (type === '[object WeakMap]') { - return 'weakmap'; - } - if (type === '[object Symbol]') { - return 'symbol'; - } + .capture('bracket.inner', function() { + if (!this.isInside('bracket')) return; + var pos = this.position(); + var m = this.match(not); + if (!m || !m[0]) return; - // typed arrays - if (type === '[object Int8Array]') { - return 'int8array'; - } - if (type === '[object Uint8Array]') { - return 'uint8array'; - } - if (type === '[object Uint8ClampedArray]') { - return 'uint8clampedarray'; - } - if (type === '[object Int16Array]') { - return 'int16array'; - } - if (type === '[object Uint16Array]') { - return 'uint16array'; - } - if (type === '[object Int32Array]') { - return 'int32array'; - } - if (type === '[object Uint32Array]') { - return 'uint32array'; - } - if (type === '[object Float32Array]') { - return 'float32array'; - } - if (type === '[object Float64Array]') { - return 'float64array'; - } + var next = this.input.charAt(0); + var val = m[0]; - // must be a plain object - return 'object'; -}; + var node = pos({ + type: 'bracket.inner', + val: val + }); + if (val === '\\\\') { + return node; + } -/***/ }), -/* 543 */ -/***/ (function(module, exports, __webpack_require__) { + var first = val.charAt(0); + var last = val.slice(-1); -"use strict"; -/*! - * is-data-descriptor - * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. - */ + if (first === '!') { + val = '^' + val.slice(1); + } + if (last === '\\' || (val === '^' && next === ']')) { + val += this.input[0]; + this.consume(1); + } + node.val = val; + return node; + }) -var typeOf = __webpack_require__(544); + /** + * Close: ']' + */ -// data descriptor properties -var data = { - configurable: 'boolean', - enumerable: 'boolean', - writable: 'boolean' -}; + .capture('bracket.close', function() { + var parsed = this.parsed; + var pos = this.position(); + var m = this.match(/^\]/); + if (!m) return; -function isDataDescriptor(obj, prop) { - if (typeOf(obj) !== 'object') { - return false; - } + var prev = this.prev(); + var last = utils.last(prev.nodes); - if (typeof prop === 'string') { - var val = Object.getOwnPropertyDescriptor(obj, prop); - return typeof val !== 'undefined'; - } + if (parsed.slice(-1) === '\\' && !this.isInside('bracket')) { + last.val = last.val.slice(0, last.val.length - 1); - if (!('value' in obj) && !('writable' in obj)) { - return false; - } + return pos({ + type: 'escape', + val: m[0] + }); + } - for (var key in obj) { - if (key === 'value') continue; + var node = pos({ + type: 'bracket.close', + rest: this.input, + val: m[0] + }); - if (!data.hasOwnProperty(key)) { - continue; - } + if (last.type === 'bracket.open') { + node.type = 'bracket.inner'; + node.escaped = true; + return node; + } - if (typeOf(obj[key]) === data[key]) { - continue; - } + var bracket = this.pop('bracket'); + if (!this.isType(bracket, 'bracket')) { + if (this.options.strict) { + throw new Error('missing opening "["'); + } + node.type = 'bracket.inner'; + node.escaped = true; + return node; + } - if (typeof obj[key] !== 'undefined') { - return false; - } - } - return true; + bracket.nodes.push(node); + define(node, 'parent', bracket); + }); } /** - * Expose `isDataDescriptor` + * Brackets parsers */ -module.exports = isDataDescriptor; - - -/***/ }), -/* 544 */ -/***/ (function(module, exports, __webpack_require__) { - -var isBuffer = __webpack_require__(391); -var toString = Object.prototype.toString; +module.exports = parsers; /** - * Get the native `typeof` a value. - * - * @param {*} `val` - * @return {*} Native javascript type + * Expose text regex */ -module.exports = function kindOf(val) { - // primitivies - if (typeof val === 'undefined') { - return 'undefined'; - } - if (val === null) { - return 'null'; - } - if (val === true || val === false || val instanceof Boolean) { - return 'boolean'; - } - if (typeof val === 'string' || val instanceof String) { - return 'string'; - } - if (typeof val === 'number' || val instanceof Number) { - return 'number'; - } +module.exports.TEXT_REGEX = TEXT_REGEX; - // functions - if (typeof val === 'function' || val instanceof Function) { - return 'function'; - } - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; - } +/***/ }), +/* 506 */ +/***/ (function(module, exports, __webpack_require__) { - // check for instances of RegExp and Date before calling `toString` - if (val instanceof RegExp) { - return 'regexp'; - } - if (val instanceof Date) { - return 'date'; - } +"use strict"; - // other objects - var type = toString.call(val); - if (type === '[object RegExp]') { - return 'regexp'; - } - if (type === '[object Date]') { - return 'date'; - } - if (type === '[object Arguments]') { - return 'arguments'; - } - if (type === '[object Error]') { - return 'error'; - } +var toRegex = __webpack_require__(385); +var regexNot = __webpack_require__(396); +var cached; - // buffer - if (isBuffer(val)) { - return 'buffer'; - } +/** + * Get the last element from `array` + * @param {Array} `array` + * @return {*} + */ - // es6: Map, WeakMap, Set, WeakSet - if (type === '[object Set]') { - return 'set'; - } - if (type === '[object WeakSet]') { - return 'weakset'; - } - if (type === '[object Map]') { - return 'map'; - } - if (type === '[object WeakMap]') { - return 'weakmap'; - } - if (type === '[object Symbol]') { - return 'symbol'; - } +exports.last = function(arr) { + return arr[arr.length - 1]; +}; - // typed arrays - if (type === '[object Int8Array]') { - return 'int8array'; - } - if (type === '[object Uint8Array]') { - return 'uint8array'; - } - if (type === '[object Uint8ClampedArray]') { - return 'uint8clampedarray'; - } - if (type === '[object Int16Array]') { - return 'int16array'; - } - if (type === '[object Uint16Array]') { - return 'uint16array'; - } - if (type === '[object Int32Array]') { - return 'int32array'; - } - if (type === '[object Uint32Array]') { - return 'uint32array'; - } - if (type === '[object Float32Array]') { - return 'float32array'; - } - if (type === '[object Float64Array]') { - return 'float64array'; +/** + * Create and cache regex to use for text nodes + */ + +exports.createRegex = function(pattern, include) { + if (cached) return cached; + var opts = {contains: true, strictClose: false}; + var not = regexNot.create(pattern, opts); + var re; + + if (typeof include === 'string') { + re = toRegex('^(?:' + include + '|' + not + ')', opts); + } else { + re = toRegex(not, opts); } - // must be a plain object - return 'object'; + return (cached = re); }; /***/ }), -/* 545 */ +/* 507 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var brackets = __webpack_require__(533); -var define = __webpack_require__(398); -var utils = __webpack_require__(546); +var brackets = __webpack_require__(502); +var define = __webpack_require__(496); +var utils = __webpack_require__(508); /** * Characters to use in text regex (we want to "not" match @@ -54994,14 +51569,14 @@ module.exports = parsers; /***/ }), -/* 546 */ +/* 508 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var regex = __webpack_require__(396); -var Cache = __webpack_require__(526); +var Cache = __webpack_require__(494); /** * Utils @@ -55070,7 +51645,7 @@ utils.createRegex = function(str) { /***/ }), -/* 547 */ +/* 509 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -55081,15 +51656,15 @@ utils.createRegex = function(str) { */ var Snapdragon = __webpack_require__(424); -var define = __webpack_require__(398); +var define = __webpack_require__(496); var extend = __webpack_require__(394); /** * Local dependencies */ -var compilers = __webpack_require__(532); -var parsers = __webpack_require__(545); +var compilers = __webpack_require__(501); +var parsers = __webpack_require__(507); /** * Customize Snapdragon parser and renderer @@ -55155,14 +51730,14 @@ module.exports = Extglob; /***/ }), -/* 548 */ +/* 510 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extglob = __webpack_require__(531); -var nanomatch = __webpack_require__(521); +var extglob = __webpack_require__(500); +var nanomatch = __webpack_require__(489); var regexNot = __webpack_require__(396); var toRegex = __webpack_require__(385); var not; @@ -55245,14 +51820,14 @@ function textRegex(pattern) { /***/ }), -/* 549 */ +/* 511 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = new (__webpack_require__(526))(); +module.exports = new (__webpack_require__(494))(); /***/ }), -/* 550 */ +/* 512 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -55266,11 +51841,11 @@ var path = __webpack_require__(16); */ var Snapdragon = __webpack_require__(424); -utils.define = __webpack_require__(398); -utils.diff = __webpack_require__(528); +utils.define = __webpack_require__(496); +utils.diff = __webpack_require__(497); utils.extend = __webpack_require__(394); -utils.pick = __webpack_require__(529); -utils.typeOf = __webpack_require__(551); +utils.pick = __webpack_require__(498); +utils.typeOf = __webpack_require__(513); utils.unique = __webpack_require__(397); /** @@ -55568,7 +52143,7 @@ utils.unixify = function(options) { /***/ }), -/* 551 */ +/* 513 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -55703,7 +52278,7 @@ function isBuffer(val) { /***/ }), -/* 552 */ +/* 514 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -55719,8 +52294,8 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var readdir = __webpack_require__(553); -var reader_1 = __webpack_require__(566); +var readdir = __webpack_require__(515); +var reader_1 = __webpack_require__(528); var ReaderAsync = /** @class */ (function (_super) { __extends(ReaderAsync, _super); function ReaderAsync() { @@ -55756,15 +52331,15 @@ exports.default = ReaderAsync; /***/ }), -/* 553 */ +/* 515 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const readdirSync = __webpack_require__(554); -const readdirAsync = __webpack_require__(562); -const readdirStream = __webpack_require__(565); +const readdirSync = __webpack_require__(516); +const readdirAsync = __webpack_require__(524); +const readdirStream = __webpack_require__(527); module.exports = exports = readdirAsyncPath; exports.readdir = exports.readdirAsync = exports.async = readdirAsyncPath; @@ -55848,7 +52423,7 @@ function readdirStreamStat (dir, options) { /***/ }), -/* 554 */ +/* 516 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -55856,11 +52431,11 @@ function readdirStreamStat (dir, options) { module.exports = readdirSync; -const DirectoryReader = __webpack_require__(555); +const DirectoryReader = __webpack_require__(517); let syncFacade = { - fs: __webpack_require__(560), - forEach: __webpack_require__(561), + fs: __webpack_require__(522), + forEach: __webpack_require__(523), sync: true }; @@ -55889,7 +52464,7 @@ function readdirSync (dir, options, internalOptions) { /***/ }), -/* 555 */ +/* 517 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -55898,9 +52473,9 @@ function readdirSync (dir, options, internalOptions) { const Readable = __webpack_require__(28).Readable; const EventEmitter = __webpack_require__(45).EventEmitter; const path = __webpack_require__(16); -const normalizeOptions = __webpack_require__(556); -const stat = __webpack_require__(558); -const call = __webpack_require__(559); +const normalizeOptions = __webpack_require__(518); +const stat = __webpack_require__(520); +const call = __webpack_require__(521); /** * Asynchronously reads the contents of a directory and streams the results @@ -56276,14 +52851,14 @@ module.exports = DirectoryReader; /***/ }), -/* 556 */ +/* 518 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(16); -const globToRegExp = __webpack_require__(557); +const globToRegExp = __webpack_require__(519); module.exports = normalizeOptions; @@ -56460,7 +53035,7 @@ function normalizeOptions (options, internalOptions) { /***/ }), -/* 557 */ +/* 519 */ /***/ (function(module, exports) { module.exports = function (glob, opts) { @@ -56597,13 +53172,13 @@ module.exports = function (glob, opts) { /***/ }), -/* 558 */ +/* 520 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const call = __webpack_require__(559); +const call = __webpack_require__(521); module.exports = stat; @@ -56678,7 +53253,7 @@ function symlinkStat (fs, path, lstats, callback) { /***/ }), -/* 559 */ +/* 521 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -56739,14 +53314,14 @@ function callOnce (fn) { /***/ }), -/* 560 */ +/* 522 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const fs = __webpack_require__(23); -const call = __webpack_require__(559); +const call = __webpack_require__(521); /** * A facade around {@link fs.readdirSync} that allows it to be called @@ -56810,7 +53385,7 @@ exports.lstat = function (path, callback) { /***/ }), -/* 561 */ +/* 523 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -56839,7 +53414,7 @@ function syncForEach (array, iterator, done) { /***/ }), -/* 562 */ +/* 524 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -56847,12 +53422,12 @@ function syncForEach (array, iterator, done) { module.exports = readdirAsync; -const maybe = __webpack_require__(563); -const DirectoryReader = __webpack_require__(555); +const maybe = __webpack_require__(525); +const DirectoryReader = __webpack_require__(517); let asyncFacade = { fs: __webpack_require__(23), - forEach: __webpack_require__(564), + forEach: __webpack_require__(526), async: true }; @@ -56894,7 +53469,7 @@ function readdirAsync (dir, options, callback, internalOptions) { /***/ }), -/* 563 */ +/* 525 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -56921,7 +53496,7 @@ module.exports = function maybe (cb, promise) { /***/ }), -/* 564 */ +/* 526 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -56957,7 +53532,7 @@ function asyncForEach (array, iterator, done) { /***/ }), -/* 565 */ +/* 527 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -56965,11 +53540,11 @@ function asyncForEach (array, iterator, done) { module.exports = readdirStream; -const DirectoryReader = __webpack_require__(555); +const DirectoryReader = __webpack_require__(517); let streamFacade = { fs: __webpack_require__(23), - forEach: __webpack_require__(564), + forEach: __webpack_require__(526), async: true }; @@ -56989,15 +53564,15 @@ function readdirStream (dir, options, internalOptions) { /***/ }), -/* 566 */ +/* 528 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var path = __webpack_require__(16); -var deep_1 = __webpack_require__(567); -var entry_1 = __webpack_require__(570); +var deep_1 = __webpack_require__(529); +var entry_1 = __webpack_require__(532); var Reader = /** @class */ (function () { function Reader(options) { this.options = options; @@ -57063,14 +53638,14 @@ exports.default = Reader; /***/ }), -/* 567 */ +/* 529 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var arrayUtils = __webpack_require__(568); -var pathUtils = __webpack_require__(569); +var arrayUtils = __webpack_require__(530); +var pathUtils = __webpack_require__(531); var patternUtils = __webpack_require__(378); var DeepFilter = /** @class */ (function () { function DeepFilter(options, micromatchOptions) { @@ -57146,7 +53721,7 @@ exports.default = DeepFilter; /***/ }), -/* 568 */ +/* 530 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57169,7 +53744,7 @@ exports.max = max; /***/ }), -/* 569 */ +/* 531 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57187,7 +53762,7 @@ exports.isDotDirectory = isDotDirectory; /***/ }), -/* 570 */ +/* 532 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57265,7 +53840,7 @@ exports.default = DeepFilter; /***/ }), -/* 571 */ +/* 533 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57282,8 +53857,8 @@ var __extends = (this && this.__extends) || (function () { })(); Object.defineProperty(exports, "__esModule", { value: true }); var stream = __webpack_require__(28); -var readdir = __webpack_require__(553); -var reader_1 = __webpack_require__(566); +var readdir = __webpack_require__(515); +var reader_1 = __webpack_require__(528); var TransformStream = /** @class */ (function (_super) { __extends(TransformStream, _super); function TransformStream(reader) { @@ -57326,7 +53901,7 @@ exports.default = ReaderStream; /***/ }), -/* 572 */ +/* 534 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57342,8 +53917,8 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var readdir = __webpack_require__(553); -var reader_1 = __webpack_require__(566); +var readdir = __webpack_require__(515); +var reader_1 = __webpack_require__(528); var ReaderSync = /** @class */ (function (_super) { __extends(ReaderSync, _super); function ReaderSync() { @@ -57378,7 +53953,7 @@ exports.default = ReaderSync; /***/ }), -/* 573 */ +/* 535 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57433,7 +54008,7 @@ module.exports.sync = (input, opts) => { /***/ }), -/* 574 */ +/* 536 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57441,9 +54016,9 @@ module.exports.sync = (input, opts) => { const fs = __webpack_require__(23); const path = __webpack_require__(16); const fastGlob = __webpack_require__(372); -const gitIgnore = __webpack_require__(575); +const gitIgnore = __webpack_require__(537); const pify = __webpack_require__(62); -const slash = __webpack_require__(576); +const slash = __webpack_require__(538); const DEFAULT_IGNORE = [ '**/node_modules/**', @@ -57535,7 +54110,7 @@ module.exports.sync = o => { /***/ }), -/* 575 */ +/* 537 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57967,7 +54542,7 @@ typeof process !== 'undefined' && (process.env && process.env.IGNORE_TEST_WIN32 /***/ }), -/* 576 */ +/* 538 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57985,17 +54560,17 @@ module.exports = function (str) { /***/ }), -/* 577 */ +/* 539 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(16); const fsConstants = __webpack_require__(23).constants; -const {Buffer} = __webpack_require__(578); -const CpFileError = __webpack_require__(580); -const fs = __webpack_require__(582); -const ProgressEmitter = __webpack_require__(583); +const {Buffer} = __webpack_require__(540); +const CpFileError = __webpack_require__(542); +const fs = __webpack_require__(544); +const ProgressEmitter = __webpack_require__(545); module.exports = (src, dest, opts) => { if (!src || !dest) { @@ -58145,11 +54720,11 @@ module.exports.sync = (src, dest, opts) => { /***/ }), -/* 578 */ +/* 540 */ /***/ (function(module, exports, __webpack_require__) { /* eslint-disable node/no-deprecated-api */ -var buffer = __webpack_require__(579) +var buffer = __webpack_require__(541) var Buffer = buffer.Buffer // alternative to using Object.keys for old browsers @@ -58213,18 +54788,18 @@ SafeBuffer.allocUnsafeSlow = function (size) { /***/ }), -/* 579 */ +/* 541 */ /***/ (function(module, exports) { module.exports = require("buffer"); /***/ }), -/* 580 */ +/* 542 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const NestedError = __webpack_require__(581); +const NestedError = __webpack_require__(543); class CpFileError extends NestedError { constructor(message, nested) { @@ -58238,7 +54813,7 @@ module.exports = CpFileError; /***/ }), -/* 581 */ +/* 543 */ /***/ (function(module, exports, __webpack_require__) { var inherits = __webpack_require__(43); @@ -58292,7 +54867,7 @@ module.exports = NestedError; /***/ }), -/* 582 */ +/* 544 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -58300,7 +54875,7 @@ module.exports = NestedError; const fs = __webpack_require__(22); const makeDir = __webpack_require__(90); const pify = __webpack_require__(62); -const CpFileError = __webpack_require__(580); +const CpFileError = __webpack_require__(542); const fsP = pify(fs); @@ -58445,7 +55020,7 @@ if (fs.copyFileSync) { /***/ }), -/* 583 */ +/* 545 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -58486,12 +55061,12 @@ module.exports = ProgressEmitter; /***/ }), -/* 584 */ +/* 546 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const NestedError = __webpack_require__(581); +const NestedError = __webpack_require__(543); class CpyError extends NestedError { constructor(message, nested) { @@ -58505,76 +55080,68 @@ module.exports = CpyError; /***/ }), -/* 585 */ -/***/ (function(module, exports, __webpack_require__) { +/* 547 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "prepareExternalProjectDependencies", function() { return prepareExternalProjectDependencies; }); +/* harmony import */ var _utils_package_json__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(54); +/* harmony import */ var _utils_project__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(53); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.prepareExternalProjectDependencies = undefined; +/** + * All external projects are located within `./plugins/{plugin}` relative + * to the Kibana root directory or `../kibana-extra/{plugin}` relative + * to Kibana itself. + */ +const isKibanaDep = depVersion => depVersion.includes('../../kibana/'); /** * This prepares the dependencies for an _external_ project. */ -let prepareExternalProjectDependencies = exports.prepareExternalProjectDependencies = (() => { - var _ref = _asyncToGenerator(function* (projectPath) { - const project = yield _project.Project.fromPath(projectPath); - if (!project.hasDependencies()) { - return; - } - const deps = project.allDependencies; - for (const depName of Object.keys(deps)) { - const depVersion = deps[depName]; - // Kibana currently only supports `link:` dependencies on Kibana's own - // packages, as these are packaged into the `node_modules` folder when - // Kibana is built, so we don't need to take any action to enable - // `require(...)` to resolve for these packages. - if ((0, _package_json.isLinkDependency)(depVersion) && !isKibanaDep(depVersion)) { - // For non-Kibana packages we need to set up symlinks during the - // installation process, but this is not something we support yet. - throw new Error('This plugin is using `link:` dependencies for non-Kibana packages'); - } - } - }); - return function prepareExternalProjectDependencies(_x) { - return _ref.apply(this, arguments); - }; -})(); -var _package_json = __webpack_require__(54); +async function prepareExternalProjectDependencies(projectPath) { + const project = await _utils_project__WEBPACK_IMPORTED_MODULE_1__["Project"].fromPath(projectPath); -var _project = __webpack_require__(53); + if (!project.hasDependencies()) { + return; + } -function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } /* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ + const deps = project.allDependencies; + for (const depName of Object.keys(deps)) { + const depVersion = deps[depName]; // Kibana currently only supports `link:` dependencies on Kibana's own + // packages, as these are packaged into the `node_modules` folder when + // Kibana is built, so we don't need to take any action to enable + // `require(...)` to resolve for these packages. -/** - * All external projects are located within `./plugins/{plugin}` relative - * to the Kibana root directory or `../kibana-extra/{plugin}` relative - * to Kibana itself. - */ -const isKibanaDep = depVersion => depVersion.includes('../../kibana/'); + if (Object(_utils_package_json__WEBPACK_IMPORTED_MODULE_0__["isLinkDependency"])(depVersion) && !isKibanaDep(depVersion)) { + // For non-Kibana packages we need to set up symlinks during the + // installation process, but this is not something we support yet. + throw new Error('This plugin is using `link:` dependencies for non-Kibana packages'); + } + } +} /***/ }) /******/ ]); \ No newline at end of file diff --git a/packages/kbn-pm/package.json b/packages/kbn-pm/package.json index 6248e919976db..86d67c0bcfe1f 100644 --- a/packages/kbn-pm/package.json +++ b/packages/kbn-pm/package.json @@ -10,6 +10,11 @@ "prettier": "prettier --write './src/**/*.ts'" }, "devDependencies": { + "@babel/core": "^7.3.4", + "@babel/plugin-proposal-class-properties": "^7.3.4", + "@babel/plugin-proposal-object-rest-spread": "^7.3.4", + "@babel/preset-env": "^7.3.4", + "@babel/preset-typescript": "^7.3.3", "@types/cmd-shim": "^2.0.0", "@types/cpy": "^5.1.0", "@types/dedent": "^0.7.0", @@ -32,10 +37,7 @@ "@types/tempy": "^0.1.0", "@types/wrap-ansi": "^2.0.14", "@types/write-pkg": "^3.1.0", - "babel-core": "^6.26.3", - "babel-loader": "^7.1.5", - "babel-preset-env": "^1.7.0", - "babel-preset-stage-3": "^6.24.1", + "babel-loader": "^8.0.5", "chalk": "^2.4.1", "cmd-shim": "^2.0.2", "cpy": "^7.0.1", @@ -60,7 +62,6 @@ "strip-ansi": "^4.0.0", "strong-log-transformer": "^2.1.0", "tempy": "^0.2.1", - "ts-loader": "^5.2.2", "typescript": "^3.3.3333", "unlazy-loader": "^0.1.3", "webpack": "^4.23.1", diff --git a/packages/kbn-pm/src/production/integration_tests/__fixtures__/packages/bar/package.json b/packages/kbn-pm/src/production/integration_tests/__fixtures__/packages/bar/package.json index df6ad1d3d6d9b..c1269fc7c037b 100644 --- a/packages/kbn-pm/src/production/integration_tests/__fixtures__/packages/bar/package.json +++ b/packages/kbn-pm/src/production/integration_tests/__fixtures__/packages/bar/package.json @@ -4,10 +4,11 @@ "private": true, "main": "./target/index.js", "devDependencies": { - "babel-cli": "^6.26.0", - "babel-preset-env": "^1.6.1" + "@babel/cli": "^7.2.3", + "@babel/core": "^7.3.4", + "@babel/preset-env": "^7.3.4" }, "scripts": { - "build": "babel --presets env --out-dir target src" + "build": "babel --presets=@babel/preset-env --out-dir target src" } } diff --git a/packages/kbn-pm/src/production/integration_tests/__fixtures__/packages/foo/package.json b/packages/kbn-pm/src/production/integration_tests/__fixtures__/packages/foo/package.json index 385aa59bffc7a..8b8225594c5ac 100644 --- a/packages/kbn-pm/src/production/integration_tests/__fixtures__/packages/foo/package.json +++ b/packages/kbn-pm/src/production/integration_tests/__fixtures__/packages/foo/package.json @@ -7,11 +7,12 @@ "@elastic/bar": "link:../bar" }, "devDependencies": { - "babel-cli": "^6.26.0", - "babel-preset-env": "^1.6.1", + "@babel/core": "^7.3.4", + "@babel/cli": "^7.2.3", + "@babel/preset-env": "^7.3.4", "moment": "2.20.1" }, "scripts": { - "build": "babel --presets env --out-dir target src" + "build": "babel --presets=@babel/preset-env --out-dir target src" } } diff --git a/packages/kbn-pm/src/production/integration_tests/__snapshots__/build_production_projects.test.ts.snap b/packages/kbn-pm/src/production/integration_tests/__snapshots__/build_production_projects.test.ts.snap index 94642340e0d9d..5049c692aae68 100644 --- a/packages/kbn-pm/src/production/integration_tests/__snapshots__/build_production_projects.test.ts.snap +++ b/packages/kbn-pm/src/production/integration_tests/__snapshots__/build_production_projects.test.ts.snap @@ -20,14 +20,15 @@ Array [ exports[`kbn-pm production builds and copies projects for production: packages/bar/package.json 1`] = ` Object { "devDependencies": Object { - "babel-cli": "^6.26.0", - "babel-preset-env": "^1.6.1", + "@babel/cli": "^7.2.3", + "@babel/core": "^7.3.4", + "@babel/preset-env": "^7.3.4", }, "main": "./target/index.js", "name": "@elastic/bar", "private": true, "scripts": Object { - "build": "babel --presets env --out-dir target src", + "build": "babel --presets=@babel/preset-env --out-dir target src", }, "version": "1.0.0", } @@ -47,15 +48,16 @@ Object { "@elastic/bar": "link:../bar", }, "devDependencies": Object { - "babel-cli": "^6.26.0", - "babel-preset-env": "^1.6.1", + "@babel/cli": "^7.2.3", + "@babel/core": "^7.3.4", + "@babel/preset-env": "^7.3.4", "moment": "2.20.1", }, "main": "./target/index.js", "name": "@elastic/foo", "private": true, "scripts": Object { - "build": "babel --presets env --out-dir target src", + "build": "babel --presets=@babel/preset-env --out-dir target src", }, "version": "1.0.0", } diff --git a/packages/kbn-pm/tsconfig.json b/packages/kbn-pm/tsconfig.json index f7c8cdab16782..2141c5502ae98 100644 --- a/packages/kbn-pm/tsconfig.json +++ b/packages/kbn-pm/tsconfig.json @@ -4,7 +4,7 @@ "dist" ], "include": [ - "./src/**/*.ts" + "./src/**/*.ts", ], "compilerOptions": { "types": [ diff --git a/packages/kbn-pm/webpack.config.js b/packages/kbn-pm/webpack.config.js index 1424850265e07..ff77d3cfb7e9c 100644 --- a/packages/kbn-pm/webpack.config.js +++ b/packages/kbn-pm/webpack.config.js @@ -44,15 +44,6 @@ module.exports = { { loader: 'babel-loader', }, - { - loader: 'ts-loader', - options: { - compilerOptions: { - // enable esnext modules so webpack can do its thing better - module: 'esnext', - }, - }, - }, ], exclude: /node_modules/, }, diff --git a/packages/kbn-system-loader/package.json b/packages/kbn-system-loader/package.json deleted file mode 100644 index 6e6c0eeaeac5c..0000000000000 --- a/packages/kbn-system-loader/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "@kbn/system-loader", - "version": "1.0.0", - "license": "Apache-2.0", - "private": true, - "main": "src/index.js", - "typings": "src/index.d.ts", - "dependencies": { - "tslib": "^1.9.3" - } -} diff --git a/packages/kbn-system-loader/src/__snapshots__/system.test.ts.snap b/packages/kbn-system-loader/src/__snapshots__/system.test.ts.snap deleted file mode 100644 index 4ac79d3a6e863..0000000000000 --- a/packages/kbn-system-loader/src/__snapshots__/system.test.ts.snap +++ /dev/null @@ -1,5 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`throws if start returns a promise 1`] = `"A promise was returned when starting [foo], but systems must start synchronously and return either return undefined or the contract they expose to other systems."`; - -exports[`throws if stop returns a promise 1`] = `"A promise was returned when stopping [foo], but systems must stop synchronously."`; diff --git a/packages/kbn-system-loader/src/__snapshots__/system_loader.test.ts.snap b/packages/kbn-system-loader/src/__snapshots__/system_loader.test.ts.snap deleted file mode 100644 index ef7fdb20c09e9..0000000000000 --- a/packages/kbn-system-loader/src/__snapshots__/system_loader.test.ts.snap +++ /dev/null @@ -1,5 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`throws if adding that has the same name as a system that's already added 1`] = `"a system named [foo] has already been added"`; - -exports[`throws if starting a system that depends on a system that's not present 1`] = `"System [foo] depends on [does-not-exist], which is not present"`; diff --git a/packages/kbn-system-loader/src/__snapshots__/topological_sort.test.ts.snap b/packages/kbn-system-loader/src/__snapshots__/topological_sort.test.ts.snap deleted file mode 100644 index a2041c4b6182f..0000000000000 --- a/packages/kbn-system-loader/src/__snapshots__/topological_sort.test.ts.snap +++ /dev/null @@ -1,3 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`throws if ordering does not succeed 1`] = `"Topological ordering did not complete, these edges could not be ordered: [[\\"a\\",[\\"b\\"]],[\\"b\\",[\\"c\\"]],[\\"c\\",[\\"a\\"]],[\\"f\\",[\\"g\\"]]]"`; diff --git a/packages/kbn-system-loader/src/sorted_systems.ts b/packages/kbn-system-loader/src/sorted_systems.ts deleted file mode 100644 index 85dcc64ed9654..0000000000000 --- a/packages/kbn-system-loader/src/sorted_systems.ts +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { System } from './system'; -import { SystemName } from './system_types'; -import { topologicalSort } from './topological_sort'; - -// We need this helper for the types to be correct when creating Map -// (otherwise it assumes an array of A|B instead of a tuple [A,B]) -const toTuple = (a: A, b: B): [A, B] => [a, b]; - -function toSortable(systems: Map>) { - const dependenciesBySystem = [...systems.entries()].map(([name, system]) => - toTuple(name, system.dependencies || []) - ); - return new Map(dependenciesBySystem); -} - -/** - * Sorts systems in topological order based on dependencies - */ -export function getSortedSystemNames(systems: Map>) { - const sorted = topologicalSort(toSortable(systems)); - return [...sorted]; -} diff --git a/packages/kbn-system-loader/src/system.test.ts b/packages/kbn-system-loader/src/system.test.ts deleted file mode 100644 index d4267f82e85ae..0000000000000 --- a/packages/kbn-system-loader/src/system.test.ts +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/* tslint:disable max-classes-per-file */ - -import { System } from './system'; -import { KibanaSystem } from './system_types'; - -test('can get exposed values after starting', () => { - interface ICoreType { - bar: string; - } - interface IDepsType { - quux: string; - } - interface IExposedType { - core: ICoreType; - deps: IDepsType; - } - - class FooSystem extends KibanaSystem { - public start() { - return { - core: this.kibana, - deps: this.deps, - }; - } - } - - const system = new System('foo', { - implementation: FooSystem, - }); - - system.start( - { - bar: 'bar', - }, - { - quux: 'quux', - } - ); - - expect(system.getExposedValues()).toEqual({ - core: { bar: 'bar' }, - deps: { quux: 'quux' }, - }); -}); - -test('throws if start returns a promise', () => { - class FooSystem extends KibanaSystem { - public async start() { - return 'foo'; - } - } - - const system = new System('foo', { - implementation: FooSystem, - }); - - expect(() => { - system.start({}, {}); - }).toThrowErrorMatchingSnapshot(); -}); - -test('throws if stop returns a promise', () => { - class FooSystem extends KibanaSystem { - public start() { - // noop - } - - public async stop() { - return 'stop'; - } - } - - const system = new System('foo', { - implementation: FooSystem, - }); - - system.start({}, {}); - - expect(() => { - system.stop(); - }).toThrowErrorMatchingSnapshot(); -}); diff --git a/packages/kbn-system-loader/src/system.ts b/packages/kbn-system-loader/src/system.ts deleted file mode 100644 index 7f42c073a97de..0000000000000 --- a/packages/kbn-system-loader/src/system.ts +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { - KibanaSystem, - KibanaSystemClassStatic, - SystemMetadata, - SystemName, - SystemsType, -} from './system_types'; - -function isPromise(obj: any) { - return obj != null && typeof obj === 'object' && typeof obj.then === 'function'; -} - -export class System { - public readonly name: SystemName; - public readonly dependencies: SystemName[]; - public readonly metadata?: M; - - private readonly systemClass: KibanaSystemClassStatic; - private systemInstance?: KibanaSystem; - private exposedValues?: E; - - constructor( - name: SystemName, - config: { - metadata?: M; - dependencies?: SystemName[]; - implementation: KibanaSystemClassStatic; - } - ) { - this.name = name; - this.dependencies = config.dependencies || []; - this.metadata = config.metadata; - this.systemClass = config.implementation; - } - - public getExposedValues(): E { - if (this.systemInstance === undefined) { - throw new Error('trying to get the exposed value of a system that is NOT running'); - } - - return this.exposedValues!; - } - - public start(kibanaValues: C, dependenciesValues: D) { - this.systemInstance = new this.systemClass(kibanaValues, dependenciesValues); - const exposedValues = this.systemInstance.start(); - - if (isPromise(exposedValues)) { - throw new Error( - `A promise was returned when starting [${ - this.name - }], but systems must start synchronously and return either return undefined or the contract they expose to other systems.` - ); - } - - this.exposedValues = exposedValues === undefined ? ({} as E) : exposedValues; - } - - public stop() { - const stoppedResponse = this.systemInstance && this.systemInstance.stop(); - - this.exposedValues = undefined; - this.systemInstance = undefined; - - if (isPromise(stoppedResponse)) { - throw new Error( - `A promise was returned when stopping [${this.name}], but systems must stop synchronously.` - ); - } - } -} diff --git a/packages/kbn-system-loader/src/system_loader.test.ts b/packages/kbn-system-loader/src/system_loader.test.ts deleted file mode 100644 index c6d2beff24f34..0000000000000 --- a/packages/kbn-system-loader/src/system_loader.test.ts +++ /dev/null @@ -1,499 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/* tslint:disable max-classes-per-file */ - -import { System } from './system'; -import { KibanaSystemApiFactory, SystemLoader } from './system_loader'; -import { KibanaSystem } from './system_types'; - -// To make types simpler in the tests -type CoreType = void; -const createCoreValues = () => { - // noop -}; - -test('starts system with core api', () => { - expect.assertions(1); - - interface IKibanaCoreApi { - fromCore: boolean; - name: string; - } - interface IMetadata { - configPath?: string; - } - - class FooSystem extends KibanaSystem { - public start() { - expect(this.kibana).toEqual({ - fromCore: true, - metadata: { - configPath: 'config.path.foo', - }, - name: 'foo', - }); - } - } - - const foo = new System('foo', { - implementation: FooSystem, - metadata: { - configPath: 'config.path.foo', - }, - }); - - const createSystemApi: KibanaSystemApiFactory = (name, metadata) => { - return { - fromCore: true, - metadata, - name, - }; - }; - - const systems = new SystemLoader(createSystemApi); - systems.addSystem(foo); - - systems.startSystems(); -}); - -test('system can expose a value', () => { - expect.assertions(1); - - interface IFoo { - foo: { - value: string; - }; - } - - class FooSystem extends KibanaSystem { - public start() { - return { - value: 'my-value', - }; - } - } - - class BarSystem extends KibanaSystem { - public start() { - expect(this.deps.foo).toEqual({ value: 'my-value' }); - } - } - - const foo = new System('foo', { - implementation: FooSystem, - }); - - const bar = new System('bar', { - dependencies: ['foo'], - implementation: BarSystem, - }); - - const systems = new SystemLoader(createCoreValues); - systems.addSystem(foo); - systems.addSystem(bar); - systems.startSystems(); -}); - -test('system can expose a function', () => { - expect.assertions(2); - - interface IFoo { - foo: { - fn: (val: string) => string; - }; - } - - class FooSystem extends KibanaSystem { - public start(): IFoo['foo'] { - return { - fn: val => `test-${val}`, - }; - } - } - - class BarSystem extends KibanaSystem { - public start() { - expect(this.deps.foo).toBeDefined(); - expect(this.deps.foo.fn('some-value')).toBe('test-some-value'); - } - } - - const foo = new System('foo', { - implementation: FooSystem, - }); - - const bar = new System('bar', { - dependencies: ['foo'], - implementation: BarSystem, - }); - - const systems = new SystemLoader(createCoreValues); - systems.addSystem(foo); - systems.addSystem(bar); - systems.startSystems(); -}); - -test('can expose value with same name across multiple systems', () => { - expect.assertions(2); - - interface IFoo { - foo: { - value: string; - }; - } - - interface IBar { - bar: { - value: string; - }; - } - - class FooSystem extends KibanaSystem { - public start(): IFoo['foo'] { - return { - value: 'value-foo', - }; - } - } - - class BarSystem extends KibanaSystem { - public start(): IBar['bar'] { - return { - value: 'value-bar', - }; - } - } - - class QuuxSystem extends KibanaSystem { - public start() { - expect(this.deps.foo).toEqual({ value: 'value-foo' }); - expect(this.deps.bar).toEqual({ value: 'value-bar' }); - } - } - - const foo = new System('foo', { - implementation: FooSystem, - }); - - const bar = new System('bar', { - implementation: BarSystem, - }); - - const quux = new System('quux', { - dependencies: ['foo', 'bar'], - implementation: QuuxSystem, - }); - - const systems = new SystemLoader(createCoreValues); - systems.addSystem(foo); - systems.addSystem(bar); - systems.addSystem(quux); - systems.startSystems(); -}); - -test('receives values from dependencies but not transitive dependencies', () => { - expect.assertions(3); - - interface IGrandchild { - grandchild: { - value: string; - }; - } - - interface IChild { - child: { - value: string; - }; - } - - class GrandchildSystem extends KibanaSystem { - public start() { - return { - value: 'grandchild', - }; - } - } - - class ChildSystem extends KibanaSystem { - public start() { - expect(this.deps.grandchild).toEqual({ value: 'grandchild' }); - - return { - value: 'child', - }; - } - } - - class ParentSystem extends KibanaSystem { - public start() { - expect(this.deps.child).toEqual({ value: 'child' }); - expect(this.deps.grandchild).toBeUndefined(); - } - } - - const grandchild = new System('grandchild', { - implementation: GrandchildSystem, - }); - - const child = new System('child', { - dependencies: ['grandchild'], - implementation: ChildSystem, - }); - - const parent = new System('parent', { - dependencies: ['child'], - implementation: ParentSystem, - }); - - const systems = new SystemLoader(createCoreValues); - systems.addSystem(grandchild); - systems.addSystem(child); - systems.addSystem(parent); - systems.startSystems(); -}); - -test('keeps reference on registered value', () => { - expect.assertions(1); - - interface IChild { - child: { - value: {}; - }; - } - - const myRef = {}; - - class ChildSystem extends KibanaSystem { - public start() { - return { - value: myRef, - }; - } - } - - class ParentSystem extends KibanaSystem { - public start() { - expect(this.deps.child.value).toBe(myRef); - } - } - - const child = new System('child', { - implementation: ChildSystem, - }); - - const parent = new System('parent', { - dependencies: ['child'], - implementation: ParentSystem, - }); - - const systems = new SystemLoader(createCoreValues); - systems.addSystem(child); - systems.addSystem(parent); - systems.startSystems(); -}); - -test('can register multiple values in single system', () => { - expect.assertions(1); - - interface IChild { - child: { - value1: number; - value2: number; - }; - } - - class ChildSystem extends KibanaSystem { - public start() { - return { - value1: 1, - value2: 2, - }; - } - } - - class ParentSystem extends KibanaSystem { - public start() { - expect(this.deps.child).toEqual({ - value1: 1, - value2: 2, - }); - } - } - - const child = new System('child', { - implementation: ChildSystem, - }); - - const parent = new System('parent', { - dependencies: ['child'], - implementation: ParentSystem, - }); - - const systems = new SystemLoader(createCoreValues); - systems.addSystem(child); - systems.addSystem(parent); - systems.startSystems(); -}); - -test("throws if starting a system that depends on a system that's not present", () => { - class FooSystem extends KibanaSystem { - public start() { - // noop - } - } - - const foo = new System('foo', { - dependencies: ['does-not-exist'], - implementation: FooSystem, - }); - - const systems = new SystemLoader(createCoreValues); - - systems.addSystem(foo); - - expect(() => { - systems.startSystems(); - }).toThrowErrorMatchingSnapshot(); -}); - -test("throws if adding that has the same name as a system that's already added", () => { - class FooSystem extends KibanaSystem { - public start() { - // noop - } - } - - const foo = new System('foo', { - implementation: FooSystem, - }); - - const systems = new SystemLoader(createCoreValues); - - systems.addSystem(foo); - expect(() => { - systems.addSystem(foo); - }).toThrowErrorMatchingSnapshot(); -}); - -test('stops systems in reverse order of their starting order', () => { - const events: string[] = []; - - class FooSystem extends KibanaSystem { - public start() { - events.push('start foo'); - } - public stop() { - events.push('stop foo'); - } - } - - class BarSystem extends KibanaSystem { - public start() { - events.push('start bar'); - } - public stop() { - events.push('stop bar'); - } - } - - const foo = new System('foo', { - implementation: FooSystem, - }); - const bar = new System('bar', { - implementation: BarSystem, - }); - - const systems = new SystemLoader(createCoreValues); - - systems.addSystem(foo); - systems.addSystem(bar); - - systems.startSystems(); - systems.stopSystems(); - - expect(events).toEqual(['start bar', 'start foo', 'stop foo', 'stop bar']); -}); - -test('can add systems before adding its dependencies', () => { - expect.assertions(1); - - interface IFoo { - foo: string; - } - - class FooSystem extends KibanaSystem { - public start() { - return 'value'; - } - } - - class BarSystem extends KibanaSystem { - public start() { - expect(this.deps.foo).toBe('value'); - } - } - - const foo = new System('foo', { - implementation: FooSystem, - }); - - const bar = new System('bar', { - dependencies: ['foo'], - implementation: BarSystem, - }); - - const systems = new SystemLoader(createCoreValues); - // `bar` depends on `foo`, but we add it first - systems.addSystem(bar); - systems.addSystem(foo); - systems.startSystems(); -}); - -test('can add multiple system specs at the same time', () => { - expect.assertions(1); - - const spy = jest.fn(); - - class FooSystem extends KibanaSystem { - public start() { - spy(); - } - } - - class BarSystem extends KibanaSystem { - public start() { - spy(); - } - } - - const foo = new System('foo', { - implementation: FooSystem, - }); - - const bar = new System('bar', { - implementation: BarSystem, - }); - - const systems = new SystemLoader(createCoreValues); - systems.addSystems([foo, bar]); - systems.startSystems(); - - expect(spy).toHaveBeenCalledTimes(2); -}); diff --git a/packages/kbn-system-loader/src/system_loader.ts b/packages/kbn-system-loader/src/system_loader.ts deleted file mode 100644 index b3f724737be15..0000000000000 --- a/packages/kbn-system-loader/src/system_loader.ts +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { getSortedSystemNames } from './sorted_systems'; -import { System } from './system'; -import { SystemMetadata, SystemName, SystemsType } from './system_types'; - -export type KibanaSystemApiFactory = (name: SystemName, metadata?: M) => C; - -export class SystemLoader { - private readonly systems = new Map>(); - private startedSystems: SystemName[] = []; - - constructor( - /** - * Creates the Kibana system api for each system. It is called with - * information about a system before it's started, and the return value will - * be injected into the system at startup. - */ - private readonly kibanaSystemApiFactory: KibanaSystemApiFactory - ) {} - - public addSystems(systemSpecs: Array>) { - systemSpecs.forEach(systemSpec => { - this.addSystem(systemSpec); - }); - } - - public addSystem(system: System) { - if (this.systems.has(system.name)) { - throw new Error(`a system named [${system.name}] has already been added`); - } - - this.systems.set(system.name, system); - } - - public startSystems() { - this._ensureAllSystemDependenciesCanBeResolved(); - - getSortedSystemNames(this.systems) - .map(systemName => this.systems.get(systemName)!) - .forEach(systemSpec => { - this.startSystem(systemSpec); - }); - } - - /** - * Stop all systems in the reverse order of when they were started - */ - public stopSystems() { - this.startedSystems - .map(systemName => this.systems.get(systemName)!) - .reverse() - .forEach(system => { - system.stop(); - this.systems.delete(system.name); - }); - - this.startedSystems = []; - } - - private _ensureAllSystemDependenciesCanBeResolved() { - for (const [systemName, system] of this.systems) { - for (const systemDependency of system.dependencies) { - if (!this.systems.has(systemDependency)) { - throw new Error( - `System [${systemName}] depends on [${systemDependency}], which is not present` - ); - } - } - } - } - - private startSystem(system: System) { - const dependenciesValues = {} as D; - - for (const dependency of system.dependencies) { - dependenciesValues[dependency] = this.systems.get(dependency)!.getExposedValues(); - } - - const kibanaSystemApi = this.kibanaSystemApiFactory(system.name, system.metadata); - - system.start(kibanaSystemApi, dependenciesValues); - this.startedSystems.push(system.name); - } -} diff --git a/packages/kbn-system-loader/src/system_types.ts b/packages/kbn-system-loader/src/system_types.ts deleted file mode 100644 index 3d42c12aac524..0000000000000 --- a/packages/kbn-system-loader/src/system_types.ts +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -export type SystemName = string; -export interface SystemMetadata { - [key: string]: any; -} - -export interface SystemsType { - [systemName: string]: any; -} - -export abstract class KibanaSystem { - constructor(readonly kibana: C, readonly deps: D) {} - - public abstract start(): E; - - public stop() { - // default implementation of stop does nothing - } -} - -/** - * Defines the "static side" of the Kibana system class. - * - * When a class implements an interface, only the instance side of the class is - * checked, so you can't include static methods there. Because of that we have - * a separate interface for the static side, which we can use to specify that we - * want a _class_ (not an instance) that matches this interface. - * - * See https://www.typescriptlang.org/docs/handbook/interfaces.html#difference-between-the-static-and-instance-sides-of-classes - */ -export interface KibanaSystemClassStatic { - new (kibana: C, deps: D): KibanaSystem; -} diff --git a/packages/kbn-system-loader/src/topological_sort.test.ts b/packages/kbn-system-loader/src/topological_sort.test.ts deleted file mode 100644 index 8dcf8d55c8714..0000000000000 --- a/packages/kbn-system-loader/src/topological_sort.test.ts +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { topologicalSort } from './topological_sort'; - -test('returns a topologically ordered sequence', () => { - const nodes = new Map([['a', []], ['b', ['a']], ['c', ['a', 'b']], ['d', ['a']]]); - - const sorted = topologicalSort(nodes); - - expect(sorted).toBeDefined(); - - expect([...sorted!]).toEqual(['a', 'd', 'b', 'c']); -}); - -test('handles multiple "roots" with no deps', () => { - const nodes = new Map([['a', []], ['b', []], ['c', ['a', 'b']], ['d', ['a']]]); - - const sorted = topologicalSort(nodes); - - expect(sorted).toBeDefined(); - - expect([...sorted!]).toEqual(['b', 'a', 'd', 'c']); -}); - -test('throws if ordering does not succeed', () => { - const nodes = new Map([ - ['a', ['b']], - ['b', ['c']], - ['c', ['a', 'd']], // cycles back to 'a' - ['d', []], - ['e', ['d']], - ['f', ['g']], // 'g' does not 'exist' - ]); - - expect(() => { - topologicalSort(nodes); - }).toThrowErrorMatchingSnapshot(); -}); diff --git a/packages/kbn-system-loader/src/topological_sort.ts b/packages/kbn-system-loader/src/topological_sort.ts deleted file mode 100644 index 673d12ec55740..0000000000000 --- a/packages/kbn-system-loader/src/topological_sort.ts +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/** - * A topological ordering is possible if and only if the graph has no directed - * cycles, that is, if it is a directed acyclic graph (DAG). If the input cannot - * be ordered an error is thrown. - * - * Uses Kahn's Algorithm to sort the graph. - * - * @param graph A directed acyclic graph with vertices as keys and outgoing - * edges as values. - */ -export function topologicalSort(graph: Map) { - const sorted = new Set(); - - // if (graph.size === 0) { - // return sorted; - // } - - // We clone the graph so we can remove handled nodes while we perform the - // topological ordering. If the cloned graph is _not_ empty at the end, we - // know we were not able to topologically order the graph. - const clonedGraph = new Map(graph.entries()); - - // First, find a list of "start nodes" which have no outgoing edges. At least - // one such node must exist in a non-empty acyclic graph. - const nodesWithNoEdges = [...clonedGraph.keys()].filter(name => { - const edges = clonedGraph.get(name) as T[]; - return edges.length === 0; - }); - - while (nodesWithNoEdges.length > 0) { - const processingNode = nodesWithNoEdges.pop() as T; - - // We know this node has no edges, so we can remove it - clonedGraph.delete(processingNode); - - sorted.add(processingNode); - - // Go through all nodes and remove all edges into `node` - [...clonedGraph.keys()].forEach(node => { - const edges = clonedGraph.get(node) as T[]; - const newEdges = edges.filter(edge => edge !== processingNode); - - clonedGraph.set(node, newEdges); - - if (newEdges.length === 0) { - nodesWithNoEdges.push(node); - } - }); - } - - if (clonedGraph.size > 0) { - const edgesLeft = JSON.stringify([...clonedGraph.entries()]); - throw new Error( - `Topological ordering did not complete, these edges could not be ordered: ${edgesLeft}` - ); - } - - return sorted; -} diff --git a/packages/kbn-system-loader/tsconfig.json b/packages/kbn-system-loader/tsconfig.json deleted file mode 100644 index c23b6635a5c19..0000000000000 --- a/packages/kbn-system-loader/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "declaration": true, - "outDir": "./target" - }, - "include": [ - "./src/**/*.ts" - ] -} diff --git a/packages/kbn-test-subj-selector/package.json b/packages/kbn-test-subj-selector/package.json index 83291dc059b94..f93245fd08848 100755 --- a/packages/kbn-test-subj-selector/package.json +++ b/packages/kbn-test-subj-selector/package.json @@ -10,7 +10,7 @@ "author": "Spencer Alger ", "license": "Apache-2.0", "devDependencies": { - "expect.js": "^0.3.1", + "@kbn/expect": "1.0.0", "mocha": "^2.3.4" } } diff --git a/packages/kbn-test-subj-selector/test/index.js b/packages/kbn-test-subj-selector/test/index.js index 1c0df4d3149f8..c5a3826d19479 100755 --- a/packages/kbn-test-subj-selector/test/index.js +++ b/packages/kbn-test-subj-selector/test/index.js @@ -18,7 +18,7 @@ */ const testSubjSelector = require('../'); -const expect = require('expect.js'); +const expect = require('@kbn/expect'); describe('testSubjSelector()', function() { it('converts subjectSelectors to cssSelectors', function() { diff --git a/packages/kbn-test/babel.config.js b/packages/kbn-test/babel.config.js index 962d7d3e05c55..ff657603f4c8d 100644 --- a/packages/kbn-test/babel.config.js +++ b/packages/kbn-test/babel.config.js @@ -18,6 +18,6 @@ */ module.exports = { - presets: ['@kbn/babel-preset/node_preset_7'], + presets: ['@kbn/babel-preset/node_preset'], ignore: ['**/*.test.js'], }; diff --git a/packages/kbn-test/package.json b/packages/kbn-test/package.json index aa57d854e14cc..56790e8cb194e 100644 --- a/packages/kbn-test/package.json +++ b/packages/kbn-test/package.json @@ -10,9 +10,9 @@ "kbn:watch": "yarn build --watch" }, "devDependencies": { + "@babel/cli": "^7.2.3", "@kbn/babel-preset": "1.0.0", - "@kbn/dev-utils": "1.0.0", - "@babel/cli": "^7.2.3" + "@kbn/dev-utils": "1.0.0" }, "dependencies": { "chalk": "^2.4.1", diff --git a/packages/kbn-test/types/README.md b/packages/kbn-test/types/README.md index 5e4b2c6da6141..1298d2a4afc0a 100644 --- a/packages/kbn-test/types/README.md +++ b/packages/kbn-test/types/README.md @@ -2,5 +2,4 @@ Shared types used by different parts of the tests - - **`expect.js.d.ts`**: This is a fork of the expect.js types that have been slightly modified to only expose a module type for `import expect from 'expect.js'` statements. The `@types/expect.js` includes types for the `expect` global, which is useful for some uses of the library but conflicts with the jest types we use. Making the type "module only" prevents them from conflicting. - **`ftr.d.ts`**: These types are generic types for using the functional test runner. They are here because we plan to move the functional test runner into the `@kbn/test` package at some point and having them here makes them a lot easier to import from all over the place like we do. \ No newline at end of file diff --git a/packages/kbn-test/types/expect.js.d.ts b/packages/kbn-test/types/expect.js.d.ts deleted file mode 100644 index fd3cbd852f967..0000000000000 --- a/packages/kbn-test/types/expect.js.d.ts +++ /dev/null @@ -1,225 +0,0 @@ -// tslint:disable - -// Type definitions for expect.js 0.3.1 -// Project: https://github.com/Automattic/expect.js -// Definitions by: Teppei Sato -// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -// License: MIT - -declare module 'expect.js' { - function expect(target?: any): Root; - - interface Assertion { - /** - * Assert typeof / instanceof. - */ - an: An; - /** - * Check if the value is truthy - */ - ok(): void; - - /** - * Creates an anonymous function which calls fn with arguments. - */ - withArgs(...args: any[]): Root; - - /** - * Assert that the function throws. - * - * @param fn callback to match error string against - */ - throwError(fn?: (exception: any) => void): void; - - /** - * Assert that the function throws. - * - * @param fn callback to match error string against - */ - throwException(fn?: (exception: any) => void): void; - - /** - * Assert that the function throws. - * - * @param regexp regexp to match error string against - */ - throwError(regexp: RegExp): void; - - /** - * Assert that the function throws. - * - * @param fn callback to match error string against - */ - throwException(regexp: RegExp): void; - - /** - * Checks if the array is empty. - */ - empty(): Assertion; - - /** - * Checks if the obj exactly equals another. - */ - equal(obj: any): Assertion; - - /** - * Checks if the obj sortof equals another. - */ - eql(obj: any): Assertion; - - /** - * Assert within start to finish (inclusive). - * - * @param start - * @param finish - */ - within(start: number, finish: number): Assertion; - - /** - * Assert typeof. - */ - a(type: string): Assertion; - - /** - * Assert instanceof. - */ - a(type: Function): Assertion; - - /** - * Assert numeric value above n. - */ - greaterThan(n: number): Assertion; - - /** - * Assert numeric value above n. - */ - above(n: number): Assertion; - - /** - * Assert numeric value below n. - */ - lessThan(n: number): Assertion; - - /** - * Assert numeric value below n. - */ - below(n: number): Assertion; - - /** - * Assert string value matches regexp. - * - * @param regexp - */ - match(regexp: RegExp): Assertion; - - /** - * Assert property "length" exists and has value of n. - * - * @param n - */ - length(n: number): Assertion; - - /** - * Assert property name exists, with optional val. - * - * @param name - * @param val - */ - property(name: string, val?: any): Assertion; - - /** - * Assert that string contains str. - */ - contain(str: string): Assertion; - string(str: string): Assertion; - - /** - * Assert that the array contains obj. - */ - contain(obj: any): Assertion; - string(obj: any): Assertion; - - /** - * Assert exact keys or inclusion of keys by using the `.own` modifier. - */ - key(keys: string[]): Assertion; - /** - * Assert exact keys or inclusion of keys by using the `.own` modifier. - */ - key(...keys: string[]): Assertion; - /** - * Assert exact keys or inclusion of keys by using the `.own` modifier. - */ - keys(keys: string[]): Assertion; - /** - * Assert exact keys or inclusion of keys by using the `.own` modifier. - */ - keys(...keys: string[]): Assertion; - - /** - * Assert a failure. - */ - fail(message?: string): Assertion; - } - - interface Root extends Assertion { - not: Not; - to: To; - only: Only; - have: Have; - be: Be; - } - - interface Be extends Assertion { - /** - * Checks if the obj exactly equals another. - */ - (obj: any): Assertion; - - an: An; - } - - interface An extends Assertion { - /** - * Assert typeof. - */ - (type: string): Assertion; - - /** - * Assert instanceof. - */ - (type: Function): Assertion; - } - - interface Not extends NotBase { - to: ToBase; - } - - interface NotBase extends Assertion { - be: Be; - have: Have; - include: Assertion; - only: Only; - } - - interface To extends ToBase { - not: NotBase; - } - - interface ToBase extends Assertion { - be: Be; - have: Have; - include: Assertion; - only: Only; - } - - interface Only extends Assertion { - have: Have; - } - - interface Have extends Assertion { - own: Assertion; - } - - export default expect; -} diff --git a/packages/kbn-ui-framework/doc_site/src/index.js b/packages/kbn-ui-framework/doc_site/src/index.js index 094437d85e6b6..f53e8a608e1a1 100644 --- a/packages/kbn-ui-framework/doc_site/src/index.js +++ b/packages/kbn-ui-framework/doc_site/src/index.js @@ -19,7 +19,7 @@ require('./main.scss'); -import 'babel-polyfill'; +import '@babel/polyfill'; import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; diff --git a/packages/kbn-ui-framework/package.json b/packages/kbn-ui-framework/package.json index 87e586e90ec2f..f2b9c2f7e7139 100644 --- a/packages/kbn-ui-framework/package.json +++ b/packages/kbn-ui-framework/package.json @@ -26,16 +26,16 @@ "uuid": "3.0.1" }, "peerDependencies": { - "enzyme": "3.2.0", - "enzyme-adapter-react-16": "^1.1.1" + "enzyme": "^3.8.0", + "enzyme-adapter-react-16": "^1.9.1" }, "devDependencies": { + "@babel/core": "^7.3.4", + "@babel/polyfill": "^7.2.5", "@elastic/eui": "0.0.23", "@kbn/babel-preset": "1.0.0", "autoprefixer": "6.5.4", - "babel-core": "^6.26.3", - "babel-loader": "^7.1.5", - "babel-polyfill": "^6.26.0", + "babel-loader": "^8.0.5", "brace": "0.10.0", "chalk": "^2.4.1", "chokidar": "1.6.0", @@ -43,7 +43,7 @@ "expose-loader": "^0.7.5", "file-loader": "^2.0.0", "grunt": "1.0.3", - "grunt-babel": "^7.0.0", + "grunt-babel": "^8.0.0", "grunt-contrib-clean": "^1.1.0", "grunt-contrib-copy": "^1.0.0", "highlight.js": "9.0.0", diff --git a/src/core/public/core_system.test.mocks.ts b/src/core/public/core_system.test.mocks.ts new file mode 100644 index 0000000000000..cb3f45361d5f7 --- /dev/null +++ b/src/core/public/core_system.test.mocks.ts @@ -0,0 +1,92 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { basePathServiceMock } from './base_path/base_path_service.mock'; +import { chromeServiceMock } from './chrome/chrome_service.mock'; +import { fatalErrorsServiceMock } from './fatal_errors/fatal_errors_service.mock'; +import { httpServiceMock } from './http/http_service.mock'; +import { i18nServiceMock } from './i18n/i18n_service.mock'; +import { injectedMetadataServiceMock } from './injected_metadata/injected_metadata_service.mock'; +import { legacyPlatformServiceMock } from './legacy/legacy_service.mock'; +import { notificationServiceMock } from './notifications/notifications_service.mock'; +import { uiSettingsServiceMock } from './ui_settings/ui_settings_service.mock'; + +export const MockLegacyPlatformService = legacyPlatformServiceMock.create(); +export const LegacyPlatformServiceConstructor = jest + .fn() + .mockImplementation(() => MockLegacyPlatformService); +jest.doMock('./legacy', () => ({ + LegacyPlatformService: LegacyPlatformServiceConstructor, +})); + +export const MockInjectedMetadataService = injectedMetadataServiceMock.create(); +export const InjectedMetadataServiceConstructor = jest + .fn() + .mockImplementation(() => MockInjectedMetadataService); +jest.doMock('./injected_metadata', () => ({ + InjectedMetadataService: InjectedMetadataServiceConstructor, +})); + +export const MockFatalErrorsService = fatalErrorsServiceMock.create(); +export const FatalErrorsServiceConstructor = jest + .fn() + .mockImplementation(() => MockFatalErrorsService); +jest.doMock('./fatal_errors', () => ({ + FatalErrorsService: FatalErrorsServiceConstructor, +})); + +export const MockI18nService = i18nServiceMock.create(); +export const I18nServiceConstructor = jest.fn().mockImplementation(() => MockI18nService); +jest.doMock('./i18n', () => ({ + I18nService: I18nServiceConstructor, +})); + +export const MockNotificationsService = notificationServiceMock.create(); +export const NotificationServiceConstructor = jest + .fn() + .mockImplementation(() => MockNotificationsService); +jest.doMock('./notifications', () => ({ + NotificationsService: NotificationServiceConstructor, +})); + +export const MockHttpService = httpServiceMock.create(); +export const HttpServiceConstructor = jest.fn().mockImplementation(() => MockHttpService); +jest.doMock('./http', () => ({ + HttpService: HttpServiceConstructor, +})); + +export const MockBasePathService = basePathServiceMock.create(); +export const BasePathServiceConstructor = jest.fn().mockImplementation(() => MockBasePathService); +jest.doMock('./base_path', () => ({ + BasePathService: BasePathServiceConstructor, +})); + +export const MockUiSettingsService = uiSettingsServiceMock.create(); +export const UiSettingsServiceConstructor = jest + .fn() + .mockImplementation(() => MockUiSettingsService); +jest.doMock('./ui_settings', () => ({ + UiSettingsService: UiSettingsServiceConstructor, +})); + +export const MockChromeService = chromeServiceMock.create(); +export const ChromeServiceConstructor = jest.fn().mockImplementation(() => MockChromeService); +jest.doMock('./chrome', () => ({ + ChromeService: ChromeServiceConstructor, +})); diff --git a/src/core/public/core_system.test.ts b/src/core/public/core_system.test.ts index 9d9620e3b0853..3a8580127f15c 100644 --- a/src/core/public/core_system.test.ts +++ b/src/core/public/core_system.test.ts @@ -17,73 +17,26 @@ * under the License. */ -import { basePathServiceMock } from './base_path/base_path_service.mock'; -import { chromeServiceMock } from './chrome/chrome_service.mock'; -import { fatalErrorsServiceMock } from './fatal_errors/fatal_errors_service.mock'; -import { httpServiceMock } from './http/http_service.mock'; -import { i18nServiceMock } from './i18n/i18n_service.mock'; -import { injectedMetadataServiceMock } from './injected_metadata/injected_metadata_service.mock'; -import { legacyPlatformServiceMock } from './legacy/legacy_service.mock'; -import { notificationServiceMock } from './notifications/notifications_service.mock'; -import { uiSettingsServiceMock } from './ui_settings/ui_settings_service.mock'; - -const MockLegacyPlatformService = legacyPlatformServiceMock.create(); -const LegacyPlatformServiceConstructor = jest - .fn() - .mockImplementation(() => MockLegacyPlatformService); -jest.mock('./legacy', () => ({ - LegacyPlatformService: LegacyPlatformServiceConstructor, -})); - -const MockInjectedMetadataService = injectedMetadataServiceMock.create(); -const InjectedMetadataServiceConstructor = jest - .fn() - .mockImplementation(() => MockInjectedMetadataService); -jest.mock('./injected_metadata', () => ({ - InjectedMetadataService: InjectedMetadataServiceConstructor, -})); - -const MockFatalErrorsService = fatalErrorsServiceMock.create(); -const FatalErrorsServiceConstructor = jest.fn().mockImplementation(() => MockFatalErrorsService); -jest.mock('./fatal_errors', () => ({ - FatalErrorsService: FatalErrorsServiceConstructor, -})); - -const MockI18nService = i18nServiceMock.create(); -const I18nServiceConstructor = jest.fn().mockImplementation(() => MockI18nService); -jest.mock('./i18n', () => ({ - I18nService: I18nServiceConstructor, -})); - -const MockNotificationsService = notificationServiceMock.create(); -const NotificationServiceConstructor = jest.fn().mockImplementation(() => MockNotificationsService); -jest.mock('./notifications', () => ({ - NotificationsService: NotificationServiceConstructor, -})); - -const MockHttpService = httpServiceMock.create(); -const HttpServiceConstructor = jest.fn().mockImplementation(() => MockHttpService); -jest.mock('./http', () => ({ - HttpService: HttpServiceConstructor, -})); - -const MockBasePathService = basePathServiceMock.create(); -const BasePathServiceConstructor = jest.fn().mockImplementation(() => MockBasePathService); -jest.mock('./base_path', () => ({ - BasePathService: BasePathServiceConstructor, -})); - -const MockUiSettingsService = uiSettingsServiceMock.create(); -const UiSettingsServiceConstructor = jest.fn().mockImplementation(() => MockUiSettingsService); -jest.mock('./ui_settings', () => ({ - UiSettingsService: UiSettingsServiceConstructor, -})); - -const MockChromeService = chromeServiceMock.create(); -const ChromeServiceConstructor = jest.fn().mockImplementation(() => MockChromeService); -jest.mock('./chrome', () => ({ - ChromeService: ChromeServiceConstructor, -})); +import { + BasePathServiceConstructor, + ChromeServiceConstructor, + FatalErrorsServiceConstructor, + HttpServiceConstructor, + I18nServiceConstructor, + InjectedMetadataServiceConstructor, + LegacyPlatformServiceConstructor, + MockBasePathService, + MockChromeService, + MockFatalErrorsService, + MockHttpService, + MockI18nService, + MockInjectedMetadataService, + MockLegacyPlatformService, + MockNotificationsService, + MockUiSettingsService, + NotificationServiceConstructor, + UiSettingsServiceConstructor, +} from './core_system.test.mocks'; import { CoreSystem } from './core_system'; jest.spyOn(CoreSystem.prototype, 'stop'); diff --git a/src/core/public/fatal_errors/__snapshots__/fatal_errors_screen.test.tsx.snap b/src/core/public/fatal_errors/__snapshots__/fatal_errors_screen.test.tsx.snap index a58d0f6fc9c37..c6912764db2af 100644 --- a/src/core/public/fatal_errors/__snapshots__/fatal_errors_screen.test.tsx.snap +++ b/src/core/public/fatal_errors/__snapshots__/fatal_errors_screen.test.tsx.snap @@ -53,8 +53,7 @@ exports[`rendering render matches snapshot 1`] = ` body={

diff --git a/packages/kbn-system-loader/src/index.ts b/src/core/public/fatal_errors/fatal_errors_service.test.mocks.ts similarity index 86% rename from packages/kbn-system-loader/src/index.ts rename to src/core/public/fatal_errors/fatal_errors_service.test.mocks.ts index d7fcc9e209e31..b998817a1bfcc 100644 --- a/packages/kbn-system-loader/src/index.ts +++ b/src/core/public/fatal_errors/fatal_errors_service.test.mocks.ts @@ -17,6 +17,9 @@ * under the License. */ -export { SystemLoader } from './system_loader'; -export { System } from './system'; -export { KibanaSystem } from './system_types'; +export const mockRender = jest.fn(); +jest.mock('react-dom', () => { + return { + render: mockRender, + }; +}); diff --git a/src/core/public/fatal_errors/fatal_errors_service.test.ts b/src/core/public/fatal_errors/fatal_errors_service.test.ts index 6f3842fc4e0e9..b1ad92c8c2f62 100644 --- a/src/core/public/fatal_errors/fatal_errors_service.test.ts +++ b/src/core/public/fatal_errors/fatal_errors_service.test.ts @@ -24,12 +24,7 @@ expect.addSnapshotSerializer({ print: () => `Rx.Observable`, }); -const mockRender = jest.fn(); -jest.mock('react-dom', () => { - return { - render: mockRender, - }; -}); +import { mockRender } from './fatal_errors_service.test.mocks'; import { FatalErrorsService } from './fatal_errors_service'; diff --git a/src/core/public/notifications/toasts/toasts_service.test.mocks.ts b/src/core/public/notifications/toasts/toasts_service.test.mocks.ts new file mode 100644 index 0000000000000..90ea76c551564 --- /dev/null +++ b/src/core/public/notifications/toasts/toasts_service.test.mocks.ts @@ -0,0 +1,25 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const mockReactDomRender = jest.fn(); +export const mockReactDomUnmount = jest.fn(); +jest.mock('react-dom', () => ({ + render: mockReactDomRender, + unmountComponentAtNode: mockReactDomUnmount, +})); diff --git a/src/core/public/notifications/toasts/toasts_service.test.tsx b/src/core/public/notifications/toasts/toasts_service.test.tsx index d380ad5b77ea6..849fdda97f939 100644 --- a/src/core/public/notifications/toasts/toasts_service.test.tsx +++ b/src/core/public/notifications/toasts/toasts_service.test.tsx @@ -17,12 +17,7 @@ * under the License. */ -const mockReactDomRender = jest.fn(); -const mockReactDomUnmount = jest.fn(); -jest.mock('react-dom', () => ({ - render: mockReactDomRender, - unmountComponentAtNode: mockReactDomUnmount, -})); +import { mockReactDomRender, mockReactDomUnmount } from './toasts_service.test.mocks'; import { ToastsService } from './toasts_service'; import { ToastsSetup } from './toasts_start'; diff --git a/src/core/public/ui_settings/ui_settings_service.test.mocks.ts b/src/core/public/ui_settings/ui_settings_service.test.mocks.ts new file mode 100644 index 0000000000000..458a9efdea469 --- /dev/null +++ b/src/core/public/ui_settings/ui_settings_service.test.mocks.ts @@ -0,0 +1,57 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +function mockClass( + module: string, + Class: { new (...args: any[]): T }, + setup: (instance: any, args: any[]) => void +) { + const MockClass = jest.fn(function(this: any, ...args: any[]) { + setup(this, args); + }); + + // define the mock name which is used in some snapshots + MockClass.mockName(`Mock${Class.name}`); + + // define the class name for the MockClass which is used in other snapshots + Object.defineProperty(MockClass, 'name', { + value: `Mock${Class.name}`, + }); + + jest.doMock(module, () => ({ + [Class.name]: MockClass, + })); + + return MockClass; +} + +// Mock the UiSettingsApi class +import { UiSettingsApi } from './ui_settings_api'; +export const MockUiSettingsApi = mockClass('./ui_settings_api', UiSettingsApi, inst => { + inst.stop = jest.fn(); + inst.getLoadingCount$ = jest.fn().mockReturnValue({ + loadingCountObservable: true, + }); +}); + +// Mock the UiSettingsClient class +import { UiSettingsClient } from './ui_settings_client'; +export const MockUiSettingsClient = mockClass('./ui_settings_client', UiSettingsClient, inst => { + inst.stop = jest.fn(); +}); diff --git a/src/core/public/ui_settings/ui_settings_service.test.ts b/src/core/public/ui_settings/ui_settings_service.test.ts index e58b517984fc5..f1bfab2981d6e 100644 --- a/src/core/public/ui_settings/ui_settings_service.test.ts +++ b/src/core/public/ui_settings/ui_settings_service.test.ts @@ -17,44 +17,7 @@ * under the License. */ -function mockClass( - module: string, - Class: { new (...args: any[]): T }, - setup: (instance: any, args: any[]) => void -) { - const MockClass = jest.fn(function(this: any, ...args: any[]) { - setup(this, args); - }); - - // define the mock name which is used in some snapshots - MockClass.mockName(`Mock${Class.name}`); - - // define the class name for the MockClass which is used in other snapshots - Object.defineProperty(MockClass, 'name', { - value: `Mock${Class.name}`, - }); - - jest.mock(module, () => ({ - [Class.name]: MockClass, - })); - - return MockClass; -} - -// Mock the UiSettingsApi class -import { UiSettingsApi } from './ui_settings_api'; -const MockUiSettingsApi = mockClass('./ui_settings_api', UiSettingsApi, inst => { - inst.stop = jest.fn(); - inst.getLoadingCount$ = jest.fn().mockReturnValue({ - loadingCountObservable: true, - }); -}); - -// Mock the UiSettingsClient class -import { UiSettingsClient } from './ui_settings_client'; -const MockUiSettingsClient = mockClass('./ui_settings_client', UiSettingsClient, inst => { - inst.stop = jest.fn(); -}); +import { MockUiSettingsApi, MockUiSettingsClient } from './ui_settings_service.test.mocks'; import { basePathServiceMock } from '../base_path/base_path_service.mock'; import { httpServiceMock } from '../http/http_service.mock'; diff --git a/src/core/server/README.md b/src/core/server/README.md deleted file mode 100644 index 53807c4f036b8..0000000000000 --- a/src/core/server/README.md +++ /dev/null @@ -1,6 +0,0 @@ -Platform Server Modules -======================= - -Http Server ------------ -TODO: explain diff --git a/src/core/server/config/config_service.mock.ts b/src/core/server/config/config_service.mock.ts index d9f460905fc43..92b0f117b1a02 100644 --- a/src/core/server/config/config_service.mock.ts +++ b/src/core/server/config/config_service.mock.ts @@ -16,6 +16,7 @@ * specific language governing permissions and limitations * under the License. */ + import { BehaviorSubject } from 'rxjs'; import { ObjectToConfigAdapter } from './object_to_config_adapter'; diff --git a/src/core/server/config/config_service.test.mocks.ts b/src/core/server/config/config_service.test.mocks.ts new file mode 100644 index 0000000000000..8fa1ec997d625 --- /dev/null +++ b/src/core/server/config/config_service.test.mocks.ts @@ -0,0 +1,21 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const mockPackage = new Proxy({ raw: {} as any }, { get: (obj, prop) => obj.raw[prop] }); +jest.mock('../../../../package.json', () => mockPackage); diff --git a/src/core/server/config/config_service.test.ts b/src/core/server/config/config_service.test.ts index 7a10d4992e2c2..a054786c80f7d 100644 --- a/src/core/server/config/config_service.test.ts +++ b/src/core/server/config/config_service.test.ts @@ -22,8 +22,7 @@ import { BehaviorSubject } from 'rxjs'; import { first } from 'rxjs/operators'; -const mockPackage = new Proxy({ raw: {} as any }, { get: (obj, prop) => obj.raw[prop] }); -jest.mock('../../../../package.json', () => mockPackage); +import { mockPackage } from './config_service.test.mocks'; import { schema, Type, TypeOf } from '@kbn/config-schema'; diff --git a/src/core/server/config/env.test.mocks.ts b/src/core/server/config/env.test.mocks.ts new file mode 100644 index 0000000000000..be65aa1727076 --- /dev/null +++ b/src/core/server/config/env.test.mocks.ts @@ -0,0 +1,33 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +jest.mock('process', () => ({ + cwd() { + return '/test/cwd'; + }, +})); + +jest.mock('path', () => ({ + resolve(...pathSegments: string[]) { + return pathSegments.join('/'); + }, +})); + +export const mockPackage = new Proxy({ raw: {} as any }, { get: (obj, prop) => obj.raw[prop] }); +jest.mock('../../../../package.json', () => mockPackage); diff --git a/src/core/server/config/env.test.ts b/src/core/server/config/env.test.ts index 3c251b7339e49..13bd05c3b1c84 100644 --- a/src/core/server/config/env.test.ts +++ b/src/core/server/config/env.test.ts @@ -17,20 +17,7 @@ * under the License. */ -jest.mock('process', () => ({ - cwd() { - return '/test/cwd'; - }, -})); - -jest.mock('path', () => ({ - resolve(...pathSegments: string[]) { - return pathSegments.join('/'); - }, -})); - -const mockPackage = new Proxy({ raw: {} as any }, { get: (obj, prop) => obj.raw[prop] }); -jest.mock('../../../../package.json', () => mockPackage); +import { mockPackage } from './env.test.mocks'; import { Env } from '.'; import { getEnvOptions } from './__mocks__/env'; diff --git a/src/core/server/config/raw_config_service.test.mocks.ts b/src/core/server/config/raw_config_service.test.mocks.ts new file mode 100644 index 0000000000000..be43b0f64e658 --- /dev/null +++ b/src/core/server/config/raw_config_service.test.mocks.ts @@ -0,0 +1,24 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const mockGetConfigFromFiles = jest.fn(); + +jest.mock('./read_config', () => ({ + getConfigFromFiles: mockGetConfigFromFiles, +})); diff --git a/src/core/server/config/raw_config_service.test.ts b/src/core/server/config/raw_config_service.test.ts index 0cd0dc45cd939..361cef0d042ea 100644 --- a/src/core/server/config/raw_config_service.test.ts +++ b/src/core/server/config/raw_config_service.test.ts @@ -17,11 +17,7 @@ * under the License. */ -const mockGetConfigFromFiles = jest.fn(); - -jest.mock('./read_config', () => ({ - getConfigFromFiles: mockGetConfigFromFiles, -})); +import { mockGetConfigFromFiles } from './raw_config_service.test.mocks'; import { first } from 'rxjs/operators'; import { RawConfigService } from '.'; diff --git a/src/core/server/elasticsearch/cluster_client.test.mocks.ts b/src/core/server/elasticsearch/cluster_client.test.mocks.ts new file mode 100644 index 0000000000000..4a8553d1d5f99 --- /dev/null +++ b/src/core/server/elasticsearch/cluster_client.test.mocks.ts @@ -0,0 +1,35 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const MockClient = jest.fn(); +jest.mock('elasticsearch', () => ({ + // Jest types don't include `requireActual` right now. + ...jest.requireActual('elasticsearch'), + Client: MockClient, +})); + +export const MockScopedClusterClient = jest.fn(); +jest.mock('./scoped_cluster_client', () => ({ + ScopedClusterClient: MockScopedClusterClient, +})); + +export const mockParseElasticsearchClientConfig = jest.fn(); +jest.mock('./elasticsearch_client_config', () => ({ + parseElasticsearchClientConfig: mockParseElasticsearchClientConfig, +})); diff --git a/src/core/server/elasticsearch/cluster_client.test.ts b/src/core/server/elasticsearch/cluster_client.test.ts index da511c282981e..30a1ac7a038ed 100644 --- a/src/core/server/elasticsearch/cluster_client.test.ts +++ b/src/core/server/elasticsearch/cluster_client.test.ts @@ -19,22 +19,11 @@ import { ElasticsearchConfig } from './elasticsearch_config'; -const MockClient = jest.fn(); -jest.mock('elasticsearch', () => ({ - // Jest types don't include `requireActual` right now. - ...(jest as any).requireActual('elasticsearch'), - Client: MockClient, -})); - -const MockScopedClusterClient = jest.fn(); -jest.mock('./scoped_cluster_client', () => ({ - ScopedClusterClient: MockScopedClusterClient, -})); - -const mockParseElasticsearchClientConfig = jest.fn(); -jest.mock('./elasticsearch_client_config', () => ({ - parseElasticsearchClientConfig: mockParseElasticsearchClientConfig, -})); +import { + MockClient, + mockParseElasticsearchClientConfig, + MockScopedClusterClient, +} from './cluster_client.test.mocks'; import { errors } from 'elasticsearch'; import { get } from 'lodash'; diff --git a/src/legacy/ui/public/autoload/directives.js b/src/core/server/elasticsearch/elasticsearch_client_config.test.mocks.ts similarity index 85% rename from src/legacy/ui/public/autoload/directives.js rename to src/core/server/elasticsearch/elasticsearch_client_config.test.mocks.ts index c31f62e8db6b4..f6c6079822cb5 100644 --- a/src/legacy/ui/public/autoload/directives.js +++ b/src/core/server/elasticsearch/elasticsearch_client_config.test.mocks.ts @@ -17,5 +17,5 @@ * under the License. */ -const context = require.context('../directives', false, /[\/\\](?!\.|_)[^\/\\]+\.js/); -context.keys().forEach(key => context(key)); +export const mockReadFileSync = jest.fn(); +jest.mock('fs', () => ({ readFileSync: mockReadFileSync })); diff --git a/src/core/server/elasticsearch/elasticsearch_client_config.test.ts b/src/core/server/elasticsearch/elasticsearch_client_config.test.ts index f2eb30f736403..64fb41cb3e4e5 100644 --- a/src/core/server/elasticsearch/elasticsearch_client_config.test.ts +++ b/src/core/server/elasticsearch/elasticsearch_client_config.test.ts @@ -17,8 +17,7 @@ * under the License. */ -const mockReadFileSync = jest.fn(); -jest.mock('fs', () => ({ readFileSync: mockReadFileSync })); +import { mockReadFileSync } from './elasticsearch_client_config.test.mocks'; import { duration } from 'moment'; import { loggingServiceMock } from '../logging/logging_service.mock'; @@ -67,7 +66,7 @@ Object { }); test('parses fully specified config', () => { - mockReadFileSync.mockImplementation(path => `content-of-${path}`); + mockReadFileSync.mockImplementation((path: string) => `content-of-${path}`); const elasticsearchConfig: ElasticsearchClientConfig = { apiVersion: 'v7.0.0', @@ -607,7 +606,7 @@ Object { }); test('#ignoreCertAndKey = true', () => { - mockReadFileSync.mockImplementation(path => `content-of-${path}`); + mockReadFileSync.mockImplementation((path: string) => `content-of-${path}`); expect( parseElasticsearchClientConfig( diff --git a/src/core/server/elasticsearch/elasticsearch_service.mock.ts b/src/core/server/elasticsearch/elasticsearch_service.mock.ts index bbd7fda86c5e4..57157adc2fac5 100644 --- a/src/core/server/elasticsearch/elasticsearch_service.mock.ts +++ b/src/core/server/elasticsearch/elasticsearch_service.mock.ts @@ -16,6 +16,7 @@ * specific language governing permissions and limitations * under the License. */ + import { BehaviorSubject } from 'rxjs'; import { ClusterClient } from './cluster_client'; import { ElasticsearchConfig } from './elasticsearch_config'; diff --git a/src/core/server/elasticsearch/elasticsearch_service.test.mocks.ts b/src/core/server/elasticsearch/elasticsearch_service.test.mocks.ts new file mode 100644 index 0000000000000..e87913a3c5e4f --- /dev/null +++ b/src/core/server/elasticsearch/elasticsearch_service.test.mocks.ts @@ -0,0 +1,21 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const MockClusterClient = jest.fn(); +jest.mock('./cluster_client', () => ({ ClusterClient: MockClusterClient })); diff --git a/src/core/server/elasticsearch/elasticsearch_service.test.ts b/src/core/server/elasticsearch/elasticsearch_service.test.ts index f880e318e7173..0697d9152f0a9 100644 --- a/src/core/server/elasticsearch/elasticsearch_service.test.ts +++ b/src/core/server/elasticsearch/elasticsearch_service.test.ts @@ -19,8 +19,7 @@ import { first } from 'rxjs/operators'; -const MockClusterClient = jest.fn(); -jest.mock('./cluster_client', () => ({ ClusterClient: MockClusterClient })); +import { MockClusterClient } from './elasticsearch_service.test.mocks'; import { BehaviorSubject, combineLatest } from 'rxjs'; import { Config, ConfigService, Env, ObjectToConfigAdapter } from '../config'; diff --git a/src/core/server/elasticsearch/index.ts b/src/core/server/elasticsearch/index.ts index aeb490b42db2f..cc35c9b75e32c 100644 --- a/src/core/server/elasticsearch/index.ts +++ b/src/core/server/elasticsearch/index.ts @@ -17,17 +17,5 @@ * under the License. */ -export { ElasticsearchServiceSetup } from './elasticsearch_service'; +export { ElasticsearchServiceSetup, ElasticsearchService } from './elasticsearch_service'; export { CallAPIOptions, ClusterClient } from './cluster_client'; - -import { CoreContext } from '../core_context'; -import { ElasticsearchService } from './elasticsearch_service'; - -/** @internal */ -export class ElasticsearchModule { - public readonly service: ElasticsearchService; - - constructor(coreContext: CoreContext) { - this.service = new ElasticsearchService(coreContext); - } -} diff --git a/src/core/server/http/http_service.mock.ts b/src/core/server/http/http_service.mock.ts index f246ff6634b31..bc9a42b26fdff 100644 --- a/src/core/server/http/http_service.mock.ts +++ b/src/core/server/http/http_service.mock.ts @@ -16,6 +16,7 @@ * specific language governing permissions and limitations * under the License. */ + import { Server, ServerOptions } from 'hapi'; import { HttpService } from './http_service'; diff --git a/src/core/server/http/http_service.test.mocks.ts b/src/core/server/http/http_service.test.mocks.ts new file mode 100644 index 0000000000000..a0d7ff5069eb0 --- /dev/null +++ b/src/core/server/http/http_service.test.mocks.ts @@ -0,0 +1,24 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const mockHttpServer = jest.fn(); + +jest.mock('./http_server', () => ({ + HttpServer: mockHttpServer, +})); diff --git a/src/core/server/http/http_service.test.ts b/src/core/server/http/http_service.test.ts index 6ed3d13221dc2..6c38162a0b7f9 100644 --- a/src/core/server/http/http_service.test.ts +++ b/src/core/server/http/http_service.test.ts @@ -17,11 +17,7 @@ * under the License. */ -const mockHttpServer = jest.fn(); - -jest.mock('./http_server', () => ({ - HttpServer: mockHttpServer, -})); +import { mockHttpServer } from './http_service.test.mocks'; import { noop } from 'lodash'; import { BehaviorSubject } from 'rxjs'; diff --git a/src/core/server/http/index.ts b/src/core/server/http/index.ts index a1385b1b7bf91..2c0dbf2488373 100644 --- a/src/core/server/http/index.ts +++ b/src/core/server/http/index.ts @@ -17,28 +17,8 @@ * under the License. */ -import { Observable } from 'rxjs'; - -import { LoggerFactory } from '../logging'; -import { HttpConfig } from './http_config'; -import { HttpService, HttpServiceSetup } from './http_service'; -import { Router } from './router'; - +export { HttpConfig } from './http_config'; +export { HttpService, HttpServiceSetup } from './http_service'; export { Router, KibanaRequest } from './router'; -export { HttpService, HttpServiceSetup }; export { HttpServerInfo } from './http_server'; export { BasePathProxyServer } from './base_path_proxy_server'; - -export { HttpConfig }; - -export class HttpModule { - public readonly service: HttpService; - - constructor(readonly config$: Observable, logger: LoggerFactory) { - this.service = new HttpService(this.config$, logger); - - const router = new Router('/core'); - router.get({ path: '/', validate: false }, async (req, res) => res.ok({ version: '0.0.1' })); - this.service.registerRouter(router); - } -} diff --git a/src/core/server/index.test.mocks.ts b/src/core/server/index.test.mocks.ts new file mode 100644 index 0000000000000..c25772ea46de4 --- /dev/null +++ b/src/core/server/index.test.mocks.ts @@ -0,0 +1,40 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { httpServiceMock } from './http/http_service.mock'; +export const httpService = httpServiceMock.create(); +jest.doMock('./http/http_service', () => ({ + HttpService: jest.fn(() => httpService), +})); + +export const mockPluginsService = { setup: jest.fn(), stop: jest.fn() }; +jest.doMock('./plugins/plugins_service', () => ({ + PluginsService: jest.fn(() => mockPluginsService), +})); + +import { elasticsearchServiceMock } from './elasticsearch/elasticsearch_service.mock'; +export const elasticsearchService = elasticsearchServiceMock.create(); +jest.doMock('./elasticsearch/elasticsearch_service', () => ({ + ElasticsearchService: jest.fn(() => elasticsearchService), +})); + +export const mockLegacyService = { setup: jest.fn(), stop: jest.fn() }; +jest.mock('./legacy/legacy_service', () => ({ + LegacyService: jest.fn(() => mockLegacyService), +})); diff --git a/src/core/server/legacy/__snapshots__/legacy_service.test.ts.snap b/src/core/server/legacy/__snapshots__/legacy_service.test.ts.snap index 050184b1f1d52..76d53b4b1cc5d 100644 --- a/src/core/server/legacy/__snapshots__/legacy_service.test.ts.snap +++ b/src/core/server/legacy/__snapshots__/legacy_service.test.ts.snap @@ -28,6 +28,7 @@ Array [ "valueInBytes": 1073741824, }, }, + "httpsAgent": undefined, "log": Object { "context": Array [ "server", @@ -52,6 +53,7 @@ Array [ "trace": [MockFunction], "warn": [MockFunction], }, + "server": undefined, }, ], ] diff --git a/src/core/server/legacy/index.ts b/src/core/server/legacy/index.ts index 429e54ef673d4..bb965c0272d14 100644 --- a/src/core/server/legacy/index.ts +++ b/src/core/server/legacy/index.ts @@ -17,19 +17,7 @@ * under the License. */ -import { CoreContext } from '../core_context'; -import { LegacyService } from './legacy_service'; - /** @internal */ export { LegacyObjectToConfigAdapter } from './config/legacy_object_to_config_adapter'; /** @internal */ export { LegacyService } from './legacy_service'; - -/** @internal */ -export class LegacyCompatModule { - public readonly service: LegacyService; - - constructor(coreContext: CoreContext) { - this.service = new LegacyService(coreContext); - } -} diff --git a/src/core/server/logging/appenders/appenders.test.mocks.ts b/src/core/server/logging/appenders/appenders.test.mocks.ts new file mode 100644 index 0000000000000..551a4ac1bedc3 --- /dev/null +++ b/src/core/server/logging/appenders/appenders.test.mocks.ts @@ -0,0 +1,29 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const mockCreateLayout = jest.fn(); +jest.mock('../layouts/layouts', () => { + const { schema } = require('@kbn/config-schema'); + return { + Layouts: { + configSchema: schema.object({ kind: schema.literal('mock') }), + create: mockCreateLayout, + }, + }; +}); diff --git a/src/core/server/logging/appenders/appenders.test.ts b/src/core/server/logging/appenders/appenders.test.ts index df528f4c58cd5..7cfd2158be338 100644 --- a/src/core/server/logging/appenders/appenders.test.ts +++ b/src/core/server/logging/appenders/appenders.test.ts @@ -17,16 +17,7 @@ * under the License. */ -const mockCreateLayout = jest.fn(); -jest.mock('../layouts/layouts', () => { - const { schema } = require('@kbn/config-schema'); - return { - Layouts: { - configSchema: schema.object({ kind: schema.literal('mock') }), - create: mockCreateLayout, - }, - }; -}); +import { mockCreateLayout } from './appenders.test.mocks'; import { LegacyAppender } from '../../legacy/logging/appenders/legacy_appender'; import { Appenders } from './appenders'; diff --git a/src/core/server/logging/appenders/file/file_appender.test.mocks.ts b/src/core/server/logging/appenders/file/file_appender.test.mocks.ts new file mode 100644 index 0000000000000..a4e4532882f52 --- /dev/null +++ b/src/core/server/logging/appenders/file/file_appender.test.mocks.ts @@ -0,0 +1,32 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +jest.mock('../../layouts/layouts', () => { + const { schema } = require('@kbn/config-schema'); + return { + Layouts: { + configSchema: schema.object({ + kind: schema.literal('mock'), + }), + }, + }; +}); + +export const mockCreateWriteStream = jest.fn(); +jest.mock('fs', () => ({ createWriteStream: mockCreateWriteStream })); diff --git a/src/core/server/logging/appenders/file/file_appender.test.ts b/src/core/server/logging/appenders/file/file_appender.test.ts index 1d9ef33995955..fccca629f7d60 100644 --- a/src/core/server/logging/appenders/file/file_appender.test.ts +++ b/src/core/server/logging/appenders/file/file_appender.test.ts @@ -17,19 +17,7 @@ * under the License. */ -jest.mock('../../layouts/layouts', () => { - const { schema } = require('@kbn/config-schema'); - return { - Layouts: { - configSchema: schema.object({ - kind: schema.literal('mock'), - }), - }, - }; -}); - -const mockCreateWriteStream = jest.fn(); -jest.mock('fs', () => ({ createWriteStream: mockCreateWriteStream })); +import { mockCreateWriteStream } from './file_appender.test.mocks'; import { LogLevel } from '../../log_level'; import { LogRecord } from '../../log_record'; diff --git a/src/core/server/plugins/discovery/plugin_discovery.test.mocks.ts b/src/core/server/plugins/discovery/plugin_discovery.test.mocks.ts new file mode 100644 index 0000000000000..d92465e4dd497 --- /dev/null +++ b/src/core/server/plugins/discovery/plugin_discovery.test.mocks.ts @@ -0,0 +1,30 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const mockReaddir = jest.fn(); +export const mockReadFile = jest.fn(); +export const mockStat = jest.fn(); +jest.mock('fs', () => ({ + readdir: mockReaddir, + readFile: mockReadFile, + stat: mockStat, +})); + +export const mockPackage = new Proxy({ raw: {} as any }, { get: (obj, prop) => obj.raw[prop] }); +jest.mock('../../../../../package.json', () => mockPackage); diff --git a/src/core/server/plugins/discovery/plugin_discovery.test.ts b/src/core/server/plugins/discovery/plugin_discovery.test.ts index 266ad1780d47f..ac02a21cbe7a7 100644 --- a/src/core/server/plugins/discovery/plugin_discovery.test.ts +++ b/src/core/server/plugins/discovery/plugin_discovery.test.ts @@ -17,17 +17,7 @@ * under the License. */ -const mockReaddir = jest.fn(); -const mockReadFile = jest.fn(); -const mockStat = jest.fn(); -jest.mock('fs', () => ({ - readdir: mockReaddir, - readFile: mockReadFile, - stat: mockStat, -})); - -const mockPackage = new Proxy({ raw: {} as any }, { get: (obj, prop) => obj.raw[prop] }); -jest.mock('../../../../../package.json', () => mockPackage); +import { mockPackage, mockReaddir, mockReadFile, mockStat } from './plugin_discovery.test.mocks'; import { resolve } from 'path'; import { BehaviorSubject } from 'rxjs'; diff --git a/src/core/server/plugins/discovery/plugin_manifest_parser.test.mocks.ts b/src/core/server/plugins/discovery/plugin_manifest_parser.test.mocks.ts new file mode 100644 index 0000000000000..eb8dc1e609582 --- /dev/null +++ b/src/core/server/plugins/discovery/plugin_manifest_parser.test.mocks.ts @@ -0,0 +1,22 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const mockReadFile = jest.fn(); +const mockStat = jest.fn(); +jest.mock('fs', () => ({ readFile: mockReadFile, stat: mockStat })); diff --git a/src/core/server/plugins/discovery/plugin_manifest_parser.test.ts b/src/core/server/plugins/discovery/plugin_manifest_parser.test.ts index d6012e4a5e2e4..082cd82e5e1f0 100644 --- a/src/core/server/plugins/discovery/plugin_manifest_parser.test.ts +++ b/src/core/server/plugins/discovery/plugin_manifest_parser.test.ts @@ -19,9 +19,7 @@ import { PluginDiscoveryErrorType } from './plugin_discovery_error'; -const mockReadFile = jest.fn(); -const mockStat = jest.fn(); -jest.mock('fs', () => ({ readFile: mockReadFile, stat: mockStat })); +import { mockReadFile } from './plugin_manifest_parser.test.mocks'; import { resolve } from 'path'; import { parseManifest } from './plugin_manifest_parser'; diff --git a/src/core/server/plugins/index.ts b/src/core/server/plugins/index.ts index 7b3c680a90018..69a0a8ae1dcdf 100644 --- a/src/core/server/plugins/index.ts +++ b/src/core/server/plugins/index.ts @@ -17,8 +17,7 @@ * under the License. */ -import { CoreContext } from '../core_context'; -import { PluginsService } from './plugins_service'; +export { PluginsService } from './plugins_service'; /** @internal */ export { isNewPlatformPlugin } from './discovery'; @@ -26,12 +25,3 @@ export { isNewPlatformPlugin } from './discovery'; export { DiscoveredPlugin, DiscoveredPluginInternal } from './plugin'; export { PluginName } from './plugin'; export { PluginInitializerContext, PluginSetupContext } from './plugin_context'; - -/** @internal */ -export class PluginsModule { - public readonly service: PluginsService; - - constructor(coreContext: CoreContext) { - this.service = new PluginsService(coreContext); - } -} diff --git a/src/core/server/plugins/plugin.test.ts b/src/core/server/plugins/plugin.test.ts index 284e9e10cb7b8..2f2a73668a59d 100644 --- a/src/core/server/plugins/plugin.test.ts +++ b/src/core/server/plugins/plugin.test.ts @@ -30,15 +30,15 @@ import { createPluginInitializerContext, createPluginSetupContext } from './plug const mockPluginInitializer = jest.fn(); const logger = loggingServiceMock.create(); -jest.mock( +jest.doMock( join('plugin-with-initializer-path', 'server'), () => ({ plugin: mockPluginInitializer }), { virtual: true } ); -jest.mock(join('plugin-without-initializer-path', 'server'), () => ({}), { +jest.doMock(join('plugin-without-initializer-path', 'server'), () => ({}), { virtual: true, }); -jest.mock(join('plugin-with-wrong-initializer-path', 'server'), () => ({ plugin: {} }), { +jest.doMock(join('plugin-with-wrong-initializer-path', 'server'), () => ({ plugin: {} }), { virtual: true, }); diff --git a/src/core/server/plugins/plugins_service.test.mocks.ts b/src/core/server/plugins/plugins_service.test.mocks.ts new file mode 100644 index 0000000000000..13b492e382d67 --- /dev/null +++ b/src/core/server/plugins/plugins_service.test.mocks.ts @@ -0,0 +1,26 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const mockPackage = new Proxy({ raw: {} as any }, { get: (obj, prop) => obj.raw[prop] }); +jest.mock('../../../legacy/utils/package_json', () => ({ pkg: mockPackage })); + +export const mockDiscover = jest.fn(); +jest.mock('./discovery/plugins_discovery', () => ({ discover: mockDiscover })); + +jest.mock('./plugins_system'); diff --git a/src/core/server/plugins/plugins_service.test.ts b/src/core/server/plugins/plugins_service.test.ts index 553cb8a031389..2a3ce3a4f88d5 100644 --- a/src/core/server/plugins/plugins_service.test.ts +++ b/src/core/server/plugins/plugins_service.test.ts @@ -17,13 +17,7 @@ * under the License. */ -const mockPackage = new Proxy({ raw: {} as any }, { get: (obj, prop) => obj.raw[prop] }); -jest.mock('../../../legacy/utils/package_json', () => ({ pkg: mockPackage })); - -const mockDiscover = jest.fn(); -jest.mock('./discovery/plugins_discovery', () => ({ discover: mockDiscover })); - -jest.mock('./plugins_system'); +import { mockDiscover, mockPackage } from './plugins_service.test.mocks'; import { resolve } from 'path'; import { BehaviorSubject, from } from 'rxjs'; diff --git a/src/core/server/plugins/plugins_system.test.mocks.ts b/src/core/server/plugins/plugins_system.test.mocks.ts new file mode 100644 index 0000000000000..9bcbba892fa2a --- /dev/null +++ b/src/core/server/plugins/plugins_system.test.mocks.ts @@ -0,0 +1,23 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const mockCreatePluginSetupContext = jest.fn(); +jest.mock('./plugin_context', () => ({ + createPluginSetupContext: mockCreatePluginSetupContext, +})); diff --git a/src/core/server/plugins/plugins_system.test.ts b/src/core/server/plugins/plugins_system.test.ts index 2df8b8301b0ef..3202a7697bd60 100644 --- a/src/core/server/plugins/plugins_system.test.ts +++ b/src/core/server/plugins/plugins_system.test.ts @@ -17,16 +17,12 @@ * under the License. */ -import { CoreContext } from '../core_context'; - -const mockCreatePluginSetupContext = jest.fn(); -jest.mock('./plugin_context', () => ({ - createPluginSetupContext: mockCreatePluginSetupContext, -})); +import { mockCreatePluginSetupContext } from './plugins_system.test.mocks'; import { BehaviorSubject } from 'rxjs'; import { Config, ConfigService, Env, ObjectToConfigAdapter } from '../config'; import { getEnvOptions } from '../config/__mocks__/env'; +import { CoreContext } from '../core_context'; import { elasticsearchServiceMock } from '../elasticsearch/elasticsearch_service.mock'; import { loggingServiceMock } from '../logging/logging_service.mock'; import { Plugin, PluginName } from './plugin'; diff --git a/src/core/server/root/index.test.mocks.ts b/src/core/server/root/index.test.mocks.ts new file mode 100644 index 0000000000000..602fa2368a766 --- /dev/null +++ b/src/core/server/root/index.test.mocks.ts @@ -0,0 +1,33 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { loggingServiceMock } from '../logging/logging_service.mock'; +export const logger = loggingServiceMock.create(); +jest.doMock('../logging', () => ({ + LoggingService: jest.fn(() => logger), +})); + +import { configServiceMock } from '../config/config_service.mock'; +export const configService = configServiceMock.create(); +jest.doMock('../config/config_service', () => ({ + ConfigService: jest.fn(() => configService), +})); + +export const mockServer = { setup: jest.fn(), stop: jest.fn() }; +jest.mock('../server', () => ({ Server: jest.fn(() => mockServer) })); diff --git a/src/core/server/root/index.test.ts b/src/core/server/root/index.test.ts index b5915debfe6a4..4eba2133dce28 100644 --- a/src/core/server/root/index.test.ts +++ b/src/core/server/root/index.test.ts @@ -17,20 +17,7 @@ * under the License. */ -import { loggingServiceMock } from '../logging/logging_service.mock'; -const logger = loggingServiceMock.create(); -jest.mock('../logging', () => ({ - LoggingService: jest.fn(() => logger), -})); - -import { configServiceMock } from '../config/config_service.mock'; -const configService = configServiceMock.create(); -jest.mock('../config/config_service', () => ({ - ConfigService: jest.fn(() => configService), -})); - -const mockServer = { setup: jest.fn(), stop: jest.fn() }; -jest.mock('../server', () => ({ Server: jest.fn(() => mockServer) })); +import { configService, logger, mockServer } from './index.test.mocks'; import { BehaviorSubject } from 'rxjs'; import { filter, first } from 'rxjs/operators'; diff --git a/src/core/server/server.test.ts b/src/core/server/server.test.ts index a3bfa8db21c44..cbfdbbc3bc00d 100644 --- a/src/core/server/server.test.ts +++ b/src/core/server/server.test.ts @@ -16,27 +16,13 @@ * specific language governing permissions and limitations * under the License. */ -import { httpServiceMock } from './http/http_service.mock'; -const httpService = httpServiceMock.create(); -jest.mock('./http/http_service', () => ({ - HttpService: jest.fn(() => httpService), -})); - -const mockPluginsService = { setup: jest.fn(), stop: jest.fn() }; -jest.mock('./plugins/plugins_service', () => ({ - PluginsService: jest.fn(() => mockPluginsService), -})); - -import { elasticsearchServiceMock } from './elasticsearch/elasticsearch_service.mock'; -const elasticsearchService = elasticsearchServiceMock.create(); -jest.mock('./elasticsearch/elasticsearch_service', () => ({ - ElasticsearchService: jest.fn(() => elasticsearchService), -})); - -const mockLegacyService = { setup: jest.fn(), stop: jest.fn() }; -jest.mock('./legacy/legacy_service', () => ({ - LegacyService: jest.fn(() => mockLegacyService), -})); + +import { + elasticsearchService, + httpService, + mockLegacyService, + mockPluginsService, +} from './index.test.mocks'; import { BehaviorSubject } from 'rxjs'; import { Env } from './config'; diff --git a/src/core/server/server.ts b/src/core/server/server.ts index 51cebd8365570..26be718bf2d65 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -19,28 +19,35 @@ import { first } from 'rxjs/operators'; import { ConfigService, Env } from './config'; -import { ElasticsearchModule } from './elasticsearch'; -import { HttpConfig, HttpModule, HttpServiceSetup } from './http'; -import { LegacyCompatModule } from './legacy'; +import { ElasticsearchService } from './elasticsearch'; +import { HttpConfig, HttpService, HttpServiceSetup, Router } from './http'; +import { LegacyService } from './legacy'; import { Logger, LoggerFactory } from './logging'; -import { PluginsModule } from './plugins'; +import { PluginsService } from './plugins'; export class Server { - private readonly elasticsearch: ElasticsearchModule; - private readonly http: HttpModule; - private readonly plugins: PluginsModule; - private readonly legacy: LegacyCompatModule; + private readonly elasticsearch: ElasticsearchService; + private readonly http: HttpService; + private readonly plugins: PluginsService; + private readonly legacy: LegacyService; private readonly log: Logger; - constructor(configService: ConfigService, logger: LoggerFactory, private readonly env: Env) { + constructor( + private readonly configService: ConfigService, + logger: LoggerFactory, + private readonly env: Env + ) { this.log = logger.get('server'); - this.http = new HttpModule(configService.atPath('server', HttpConfig), logger); + this.http = new HttpService(configService.atPath('server', HttpConfig), logger); + const router = new Router('/core'); + router.get({ path: '/', validate: false }, async (req, res) => res.ok({ version: '0.0.1' })); + this.http.registerRouter(router); const core = { env, configService, logger }; - this.plugins = new PluginsModule(core); - this.legacy = new LegacyCompatModule(core); - this.elasticsearch = new ElasticsearchModule(core); + this.plugins = new PluginsService(core); + this.legacy = new LegacyService(core); + this.elasticsearch = new ElasticsearchService(core); } public async setup() { @@ -51,18 +58,21 @@ export class Server { // 2. When the process is run as dev cluster master in which case cluster manager // will fork a dedicated process where http service will be set up instead. let httpSetup: HttpServiceSetup | undefined; - const httpConfig = await this.http.config$.pipe(first()).toPromise(); + const httpConfig = await this.configService + .atPath('server', HttpConfig) + .pipe(first()) + .toPromise(); if (!this.env.isDevClusterMaster && httpConfig.autoListen) { - httpSetup = await this.http.service.setup(); + httpSetup = await this.http.setup(); } - const elasticsearchServiceSetup = await this.elasticsearch.service.setup(); + const elasticsearchServiceSetup = await this.elasticsearch.setup(); - const pluginsSetup = await this.plugins.service.setup({ + const pluginsSetup = await this.plugins.setup({ elasticsearch: elasticsearchServiceSetup, }); - await this.legacy.service.setup({ + await this.legacy.setup({ elasticsearch: elasticsearchServiceSetup, http: httpSetup, plugins: pluginsSetup, @@ -72,9 +82,9 @@ export class Server { public async stop() { this.log.debug('stopping server'); - await this.legacy.service.stop(); - await this.plugins.service.stop(); - await this.elasticsearch.service.stop(); - await this.http.service.stop(); + await this.legacy.stop(); + await this.plugins.stop(); + await this.elasticsearch.stop(); + await this.http.stop(); } } diff --git a/src/dev/__tests__/file.js b/src/dev/__tests__/file.js index 36fe23a81bab9..0e8790f32c7c9 100644 --- a/src/dev/__tests__/file.js +++ b/src/dev/__tests__/file.js @@ -19,7 +19,7 @@ import { resolve, sep } from 'path'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { File } from '../file'; diff --git a/src/dev/__tests__/node_versions_must_match.js b/src/dev/__tests__/node_versions_must_match.js index e01d93f512844..99f2e255f47ea 100644 --- a/src/dev/__tests__/node_versions_must_match.js +++ b/src/dev/__tests__/node_versions_must_match.js @@ -21,7 +21,7 @@ import fs from 'fs'; import { engines } from '../../../package.json'; import { promisify } from 'util'; const readFile = promisify(fs.readFile); -import expect from 'expect.js'; +import expect from '@kbn/expect'; describe('All configs should use a single version of Node', () => { it('should compare .node-version and .nvmrc', async () => { diff --git a/src/dev/build/build_distributables.js b/src/dev/build/build_distributables.js index cda00064162f2..bb450dcd006bc 100644 --- a/src/dev/build/build_distributables.js +++ b/src/dev/build/build_distributables.js @@ -47,8 +47,8 @@ import { RemovePackageJsonDepsTask, RemoveWorkspacesTask, TranspileBabelTask, - TranspileTypescriptTask, TranspileScssTask, + TypecheckTypescriptTask, UpdateLicenseFileTask, VerifyEnvTask, VerifyExistingNodeBuildsTask, @@ -107,15 +107,14 @@ export async function buildDistributables(options) { * run platform-generic build tasks */ await run(CopySourceTask); + await run(TypecheckTypescriptTask); await run(CreateEmptyDirsAndFilesTask); await run(CreateReadmeTask); await run(TranspileBabelTask); - await run(TranspileTypescriptTask); await run(BuildPackagesTask); await run(CreatePackageJsonTask); await run(InstallDependenciesTask); await run(RemoveWorkspacesTask); - await run(CleanTypescriptTask); await run(CleanPackagesTask); await run(CreateNoticeFileTask); await run(UpdateLicenseFileTask); @@ -123,6 +122,7 @@ export async function buildDistributables(options) { await run(TranspileScssTask); await run(OptimizeBuildTask); await run(CleanClientModulesOnDLLTask); + await run(CleanTypescriptTask); await run(CleanExtraFilesFromModulesTask); await run(CleanEmptyFoldersTask); diff --git a/src/dev/build/lib/__tests__/build.js b/src/dev/build/lib/__tests__/build.js index 466abd67f0cd3..28a96c2108436 100644 --- a/src/dev/build/lib/__tests__/build.js +++ b/src/dev/build/lib/__tests__/build.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { createBuild } from '../build'; diff --git a/src/dev/build/lib/__tests__/config.js b/src/dev/build/lib/__tests__/config.js index 6b395ce137e63..2bb0f349715af 100644 --- a/src/dev/build/lib/__tests__/config.js +++ b/src/dev/build/lib/__tests__/config.js @@ -19,7 +19,7 @@ import { resolve } from 'path'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import pkg from '../../../../../package.json'; import { getConfig } from '../config'; diff --git a/src/dev/build/lib/__tests__/errors.js b/src/dev/build/lib/__tests__/errors.js index 7edc6244f8fe4..dc23b3e372bc6 100644 --- a/src/dev/build/lib/__tests__/errors.js +++ b/src/dev/build/lib/__tests__/errors.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { isErrorLogged, markErrorLogged } from '../errors'; diff --git a/src/dev/build/lib/__tests__/fs.js b/src/dev/build/lib/__tests__/fs.js index 3c0c515342039..a4e2a5f444751 100644 --- a/src/dev/build/lib/__tests__/fs.js +++ b/src/dev/build/lib/__tests__/fs.js @@ -21,7 +21,7 @@ import { resolve } from 'path'; import { chmodSync, statSync } from 'fs'; import del from 'del'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { mkdirp, write, read, getChildPaths, copy, copyAll, getFileHash, untar } from '../fs'; diff --git a/src/dev/build/lib/__tests__/platform.js b/src/dev/build/lib/__tests__/platform.js index 91aef80d0e836..86ef1749feca9 100644 --- a/src/dev/build/lib/__tests__/platform.js +++ b/src/dev/build/lib/__tests__/platform.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { createPlatform } from '../platform'; diff --git a/src/dev/build/lib/__tests__/runner.js b/src/dev/build/lib/__tests__/runner.js index c41d1fb6a8d2b..07d484f72f185 100644 --- a/src/dev/build/lib/__tests__/runner.js +++ b/src/dev/build/lib/__tests__/runner.js @@ -18,7 +18,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { ToolingLog } from '@kbn/dev-utils'; import { createRunner } from '../runner'; diff --git a/src/dev/build/lib/__tests__/version_info.js b/src/dev/build/lib/__tests__/version_info.js index 1ec4eb5c51747..517a6cc494cf8 100644 --- a/src/dev/build/lib/__tests__/version_info.js +++ b/src/dev/build/lib/__tests__/version_info.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import pkg from '../../../../../package.json'; import { getVersionInfo } from '../version_info'; diff --git a/src/dev/build/tasks/copy_source_task.js b/src/dev/build/tasks/copy_source_task.js index 18ca6492f08c3..01b31b51a060d 100644 --- a/src/dev/build/tasks/copy_source_task.js +++ b/src/dev/build/tasks/copy_source_task.js @@ -28,7 +28,8 @@ export const CopySourceTask = { select: [ 'yarn.lock', 'src/**', - '!src/**/*.test.{js,ts,tsx}', + '!src/**/*.{test,test.mocks,mock}.{js,ts,tsx}', + '!src/**/mocks.ts', // special file who imports .mock files '!src/**/{__tests__,__snapshots__}/**', '!src/test_utils/**', '!src/fixtures/**', diff --git a/src/dev/build/tasks/index.js b/src/dev/build/tasks/index.js index ecf86d6af23eb..acf4680fd6f42 100644 --- a/src/dev/build/tasks/index.js +++ b/src/dev/build/tasks/index.js @@ -33,7 +33,7 @@ export * from './notice_file_task'; export * from './optimize_task'; export * from './os_packages'; export * from './transpile_babel_task'; -export * from './transpile_typescript_task'; +export * from './typecheck_typescript_task'; export * from './transpile_scss_task'; export * from './verify_env_task'; export * from './write_sha_sums_task'; diff --git a/src/dev/build/tasks/nodejs/__tests__/download.js b/src/dev/build/tasks/nodejs/__tests__/download.js index a3514d3254cce..0007e9ae9df5a 100644 --- a/src/dev/build/tasks/nodejs/__tests__/download.js +++ b/src/dev/build/tasks/nodejs/__tests__/download.js @@ -23,7 +23,7 @@ import { readFileSync } from 'fs'; import del from 'del'; import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import Wreck from 'wreck'; import { ToolingLog } from '@kbn/dev-utils'; diff --git a/src/dev/build/tasks/nodejs/__tests__/download_node_builds_task.js b/src/dev/build/tasks/nodejs/__tests__/download_node_builds_task.js index 191ca47e12563..0206680b4d9fe 100644 --- a/src/dev/build/tasks/nodejs/__tests__/download_node_builds_task.js +++ b/src/dev/build/tasks/nodejs/__tests__/download_node_builds_task.js @@ -18,7 +18,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import * as NodeShasumsNS from '../node_shasums'; import * as NodeDownloadInfoNS from '../node_download_info'; diff --git a/src/dev/build/tasks/nodejs/__tests__/node_shasums.js b/src/dev/build/tasks/nodejs/__tests__/node_shasums.js index 61fd8f6400560..3e400283dbd80 100644 --- a/src/dev/build/tasks/nodejs/__tests__/node_shasums.js +++ b/src/dev/build/tasks/nodejs/__tests__/node_shasums.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getNodeShasums } from '../node_shasums'; diff --git a/src/dev/build/tasks/nodejs/__tests__/verify_existing_node_builds_task.js b/src/dev/build/tasks/nodejs/__tests__/verify_existing_node_builds_task.js index 3cf75216d286f..fa6ae4675229b 100644 --- a/src/dev/build/tasks/nodejs/__tests__/verify_existing_node_builds_task.js +++ b/src/dev/build/tasks/nodejs/__tests__/verify_existing_node_builds_task.js @@ -18,7 +18,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import * as NodeShasumsNS from '../node_shasums'; import * as NodeDownloadInfoNS from '../node_download_info'; diff --git a/src/dev/build/tasks/transpile_babel_task.js b/src/dev/build/tasks/transpile_babel_task.js index 1ea3d81583918..c6d762be9d732 100644 --- a/src/dev/build/tasks/transpile_babel_task.js +++ b/src/dev/build/tasks/transpile_babel_task.js @@ -22,31 +22,59 @@ import vfs from 'vinyl-fs'; import { createPromiseFromStreams } from '../../../legacy/utils'; +const transpileWithBabel = async (srcGlobs, build, presets) => { + const buildRoot = build.resolvePath(); + + await createPromiseFromStreams([ + vfs.src( + srcGlobs.concat([ + '!**/*.d.ts', + '!packages/**', + '!**/node_modules/**', + '!**/bower_components/**', + '!**/__tests__/**', + ]), + { + cwd: buildRoot, + } + ), + + gulpBabel({ + babelrc: false, + presets, + }), + + vfs.dest(buildRoot), + ]); +}; + export const TranspileBabelTask = { description: 'Transpiling sources with babel', async run(config, log, build) { - await createPromiseFromStreams([ - vfs.src( - [ - '**/*.js', - '!packages/**', - '!**/public/**', - '!**/node_modules/**', - '!**/bower_components/**', - '!**/__tests__/**', - ], - { - cwd: build.resolvePath(), - } - ), - - gulpBabel({ - babelrc: false, - presets: [require.resolve('@kbn/babel-preset/node_preset')], - }), - - vfs.dest(build.resolvePath()), - ]); + // Transpile server code + await transpileWithBabel( + [ + '**/*.{js,ts,tsx}', + '!**/public/**', + ], + build, + [ + require.resolve('@kbn/babel-preset/node_preset') + ] + ); + + // Transpile client code + // NOTE: For the client, as we have the optimizer, we are only + // pre-transpiling the typescript based files + await transpileWithBabel( + [ + '**/public/**/*.{ts,tsx}', + ], + build, + [ + require.resolve('@kbn/babel-preset/webpack_preset') + ] + ); }, }; diff --git a/src/dev/build/tasks/transpile_typescript_task.js b/src/dev/build/tasks/typecheck_typescript_task.js similarity index 85% rename from src/dev/build/tasks/transpile_typescript_task.js rename to src/dev/build/tasks/typecheck_typescript_task.js index 735d6c17afec5..bbdc5f69be8b4 100644 --- a/src/dev/build/tasks/transpile_typescript_task.js +++ b/src/dev/build/tasks/typecheck_typescript_task.js @@ -20,22 +20,13 @@ import { exec, write } from '../lib'; import { Project } from '../../typescript'; -export const TranspileTypescriptTask = { - description: 'Transpiling sources with typescript compiler', +export const TypecheckTypescriptTask = { + description: 'Typechecking sources with typescript compiler', async run(config, log, build) { // these projects are built in the build folder - const defaultProject = new Project(build.resolvePath('tsconfig.json')); const browserProject = new Project(build.resolvePath('tsconfig.browser.json')); - - // update the default config to exclude **/public/**/* files - await write(defaultProject.tsConfigPath, JSON.stringify({ - ...defaultProject.config, - exclude: [ - ...defaultProject.config.exclude, - 'src/**/public/**/*' - ] - })); + const defaultProject = new Project(build.resolvePath('tsconfig.json')); // update the browser config file to include **/public/**/* files await write(browserProject.tsConfigPath, JSON.stringify({ @@ -47,21 +38,28 @@ export const TranspileTypescriptTask = { ] })); + // update the default config to exclude **/public/**/* files + await write(defaultProject.tsConfigPath, JSON.stringify({ + ...defaultProject.config, + exclude: [ + ...defaultProject.config.exclude, + 'src/**/public/**/*' + ] + })); + const projects = [ - // Browser needs to be compiled before server code so that any shared code - // is compiled to the lowest common denominator (server's CommonJS format) - // which can be supported by both environments. browserProject.tsConfigPath, defaultProject.tsConfigPath, ]; // compile each typescript config file for (const tsConfigPath of projects) { - log.info(`Compiling`, tsConfigPath, 'project'); + log.info(`Typechecking`, tsConfigPath, 'project'); await exec( log, require.resolve('typescript/bin/tsc'), [ + '--noEmit', '--pretty', 'true', '--project', tsConfigPath, ], diff --git a/src/dev/ci_setup/setup.sh b/src/dev/ci_setup/setup.sh index c5ab06f40983e..179fac9aa8a74 100755 --- a/src/dev/ci_setup/setup.sh +++ b/src/dev/ci_setup/setup.sh @@ -144,3 +144,19 @@ if [ "$GIT_CHANGES" ]; then echo -e "$GIT_CHANGES\n" exit 1 fi + +### +### rebuild kbn-pm distributable to ensure it's not out of date +### +echo " -- building kbn-pm distributable" +yarn kbn run build -i @kbn/pm + +### +### verify no git modifications +### +GIT_CHANGES="$(git ls-files --modified)" +if [ "$GIT_CHANGES" ]; then + echo -e "\n${RED}ERROR: 'yarn kbn run build -i @kbn/pm' caused changes to the following files:${C_RESET}\n" + echo -e "$GIT_CHANGES\n" + exit 1 +fi diff --git a/src/dev/file.ts b/src/dev/file.ts index b4283de3dbe4d..5dc66016e1e55 100644 --- a/src/dev/file.ts +++ b/src/dev/file.ts @@ -48,6 +48,10 @@ export class File { return this.ext === '.ts' || this.ext === '.tsx'; } + public isTypescriptAmbient() { + return this.path.endsWith('.d.ts'); + } + public isSass() { return this.ext === '.sass' || this.ext === '.scss'; } diff --git a/src/dev/i18n/integrate_locale_files.test.mocks.ts b/src/dev/i18n/integrate_locale_files.test.mocks.ts new file mode 100644 index 0000000000000..e84ca068c067e --- /dev/null +++ b/src/dev/i18n/integrate_locale_files.test.mocks.ts @@ -0,0 +1,27 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const mockWriteFileAsync = jest.fn(); +export const mockMakeDirAsync = jest.fn(); +jest.mock('./utils', () => ({ + // Jest typings don't define `requireActual` for some reason. + ...(jest as any).requireActual('./utils'), + writeFileAsync: mockWriteFileAsync, + makeDirAsync: mockMakeDirAsync, +})); diff --git a/src/dev/i18n/integrate_locale_files.test.ts b/src/dev/i18n/integrate_locale_files.test.ts index 050f16f3d3344..7d7d1ba744684 100644 --- a/src/dev/i18n/integrate_locale_files.test.ts +++ b/src/dev/i18n/integrate_locale_files.test.ts @@ -17,14 +17,7 @@ * under the License. */ -const mockWriteFileAsync = jest.fn(); -const mockMakeDirAsync = jest.fn(); -jest.mock('./utils', () => ({ - // Jest typings don't define `requireActual` for some reason. - ...(jest as any).requireActual('./utils'), - writeFileAsync: mockWriteFileAsync, - makeDirAsync: mockMakeDirAsync, -})); +import { mockMakeDirAsync, mockWriteFileAsync } from './integrate_locale_files.test.mocks'; import path from 'path'; import { integrateLocaleFiles, verifyMessages } from './integrate_locale_files'; diff --git a/src/dev/jest/babel_transform.js b/src/dev/jest/babel_transform.js index 7bdba8ae7fa15..0796cf859d4ef 100644 --- a/src/dev/jest/babel_transform.js +++ b/src/dev/jest/babel_transform.js @@ -22,5 +22,5 @@ const babelJest = require('babel-jest'); module.exports = babelJest.createTransformer({ presets: [ require.resolve('@kbn/babel-preset/node_preset') - ] + ], }); diff --git a/src/dev/jest/config.integration.js b/src/dev/jest/config.integration.js index 884172f646c67..8348b7594961f 100644 --- a/src/dev/jest/config.integration.js +++ b/src/dev/jest/config.integration.js @@ -32,4 +32,7 @@ export default { 'default', ['/src/dev/jest/junit_reporter.js', { reportName: 'Jest Integration Tests' }], ], + setupFilesAfterEnv: [ + '/src/dev/jest/setup/after_env.integration.js' + ] }; diff --git a/src/dev/jest/config.js b/src/dev/jest/config.js index 1427624f0ce98..e8d78abf1210e 100644 --- a/src/dev/jest/config.js +++ b/src/dev/jest/config.js @@ -44,6 +44,7 @@ export default { '!packages/kbn-ui-framework/src/services/**/*/index.js', ], moduleNameMapper: { + '^plugins/([^\/.]*)/(.*)': '/src/legacy/core_plugins/$1/public/$2', '^ui/(.*)': '/src/legacy/ui/public/$1', '^uiExports/(.*)': '/src/dev/jest/mocks/file_mock.js', '^test_utils/(.*)': '/src/test_utils/public/$1', @@ -59,11 +60,6 @@ export default { coverageReporters: [ 'html', ], - globals: { - 'ts-jest': { - skipBabel: true, - }, - }, moduleFileExtensions: [ 'js', 'json', @@ -83,8 +79,7 @@ export default { 'integration_tests/' ], transform: { - '^.+\\.js$': '/src/dev/jest/babel_transform.js', - '^.+\\.tsx?$': '/src/dev/jest/ts_transform.js', + '^.+\\.(js|tsx?)$': '/src/dev/jest/babel_transform.js', '^.+\\.txt?$': 'jest-raw-loader', '^.+\\.html?$': 'jest-raw-loader', }, diff --git a/src/dev/jest/setup/after_env.integration.js b/src/dev/jest/setup/after_env.integration.js new file mode 100644 index 0000000000000..7a2e7b8ab31c3 --- /dev/null +++ b/src/dev/jest/setup/after_env.integration.js @@ -0,0 +1,25 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* eslint-env jest */ + +/** + * Set the default timeout for the integration test suite to 30 seconds + */ +jest.setTimeout(30 * 1000); diff --git a/src/dev/jest/setup/babel_polyfill.js b/src/dev/jest/setup/babel_polyfill.js index 38e1cfbcdd721..58325c1a67f94 100644 --- a/src/dev/jest/setup/babel_polyfill.js +++ b/src/dev/jest/setup/babel_polyfill.js @@ -18,6 +18,6 @@ */ // Note: In theory importing the polyfill should not be needed, as Babel should -// include the necessary polyfills when using `babel-preset-env`, but for some +// include the necessary polyfills when using `@babel/preset-env`, but for some // reason it did not work. See https://github.com/elastic/kibana/issues/14506 import '../../../setup_node_env/babel_register/polyfill'; diff --git a/src/dev/jest/ts_transform.ts b/src/dev/jest/ts_transform.ts deleted file mode 100644 index ed366bcd091a0..0000000000000 --- a/src/dev/jest/ts_transform.ts +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import TsJest from 'ts-jest'; - -import { getTsProjectForAbsolutePath } from '../typescript'; - -const DEFAULT_TS_CONFIG_PATH = require.resolve('../../../tsconfig.json'); -const DEFAULT_BROWSER_TS_CONFIG_PATH = require.resolve('../../../tsconfig.browser.json'); - -function extendJestConfigJSON(jestConfigJSON: string, filePath: string) { - const jestConfig = JSON.parse(jestConfigJSON) as jest.ProjectConfig; - return JSON.stringify(extendJestConfig(jestConfig, filePath)); -} - -function extendJestConfig(jestConfig: jest.ProjectConfig, filePath: string) { - let tsConfigFile = getTsProjectForAbsolutePath(filePath).tsConfigPath; - - // swap ts config file for jest tests - if (tsConfigFile === DEFAULT_BROWSER_TS_CONFIG_PATH) { - tsConfigFile = DEFAULT_TS_CONFIG_PATH; - } - - return { - ...jestConfig, - globals: { - ...(jestConfig.globals || {}), - 'ts-jest': { - skipBabel: true, - tsConfigFile, - }, - }, - }; -} - -module.exports = { - canInstrument: true, - - process( - src: string, - filePath: jest.Path, - jestConfig: jest.ProjectConfig, - transformOptions: jest.TransformOptions - ) { - const extendedConfig = extendJestConfig(jestConfig, filePath); - return TsJest.process(src, filePath, extendedConfig, transformOptions); - }, - - getCacheKey( - src: string, - filePath: string, - jestConfigJSON: string, - transformOptions: jest.TransformOptions - ) { - const extendedConfigJSON = extendJestConfigJSON(jestConfigJSON, filePath); - return TsJest.getCacheKey!(src, filePath, extendedConfigJSON, transformOptions); - }, -}; diff --git a/src/dev/license_checker/__tests__/valid.js b/src/dev/license_checker/__tests__/valid.js index bb608e33d52a0..04c9347bc74ec 100644 --- a/src/dev/license_checker/__tests__/valid.js +++ b/src/dev/license_checker/__tests__/valid.js @@ -19,7 +19,7 @@ import { resolve } from 'path'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { assertLicensesValid } from '../valid'; diff --git a/src/dev/license_checker/config.js b/src/dev/license_checker/config.js index 9c6fa7767ee1e..879c2147ccb11 100644 --- a/src/dev/license_checker/config.js +++ b/src/dev/license_checker/config.js @@ -105,5 +105,5 @@ export const LICENSE_OVERRIDES = { 'walk@2.3.9': ['MIT'], // TODO remove this once we upgrade past or equal to v1.0.2 - 'babel-plugin-mock-imports@0.0.5': ['MIT'] + 'babel-plugin-mock-imports@1.0.1': ['MIT'] }; diff --git a/src/dev/mocha/__tests__/junit_report_generation.js b/src/dev/mocha/__tests__/junit_report_generation.js index 7142a14b662e5..f7631e972ad14 100644 --- a/src/dev/mocha/__tests__/junit_report_generation.js +++ b/src/dev/mocha/__tests__/junit_report_generation.js @@ -24,7 +24,7 @@ import { fromNode as fcb } from 'bluebird'; import { parseString } from 'xml2js'; import del from 'del'; import Mocha from 'mocha'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { setupJUnitReportGeneration } from '../junit_report_generation'; diff --git a/src/dev/mocha/run_mocha_cli.js b/src/dev/mocha/run_mocha_cli.js index d24f9a06eafdd..299a910127d40 100644 --- a/src/dev/mocha/run_mocha_cli.js +++ b/src/dev/mocha/run_mocha_cli.js @@ -43,7 +43,7 @@ export function runMochaCli() { // check that we aren't leaking any globals process.argv.push('--check-leaks'); // prevent globals injected from canvas plugins from triggering leak check - process.argv.push('--globals', 'core,regeneratorRuntime,_'); + process.argv.push('--globals', '__core-js_shared__,core,_, '); // ensure that mocha requires the setup_node_env script process.argv.push('--require', require.resolve('../../setup_node_env')); diff --git a/src/dev/npm/__tests__/installed_packages.js b/src/dev/npm/__tests__/installed_packages.js index 70ccf1916c75b..24bad227cbbde 100644 --- a/src/dev/npm/__tests__/installed_packages.js +++ b/src/dev/npm/__tests__/installed_packages.js @@ -20,7 +20,7 @@ import { resolve, sep } from 'path'; import { uniq } from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getInstalledPackages } from '../installed_packages'; diff --git a/src/dev/precommit_hook/casing_check_config.js b/src/dev/precommit_hook/casing_check_config.js index 8eb404749219a..fefb205e0289c 100644 --- a/src/dev/precommit_hook/casing_check_config.js +++ b/src/dev/precommit_hook/casing_check_config.js @@ -107,7 +107,6 @@ export const IGNORE_DIRECTORY_GLOBS = [ export const TEMPORARILY_IGNORED_PATHS = [ 'src/legacy/core_plugins/console/public/src/directives/helpExample.txt', 'src/legacy/core_plugins/console/public/src/sense_editor/theme-sense-dark.js', - 'src/legacy/core_plugins/console/public/webpackShims/ui-bootstrap-custom.js', 'src/legacy/core_plugins/kibana/public/assets/play-circle.svg', 'src/legacy/core_plugins/tests_bundle/webpackShims/angular-mocks.js', 'src/legacy/core_plugins/tile_map/public/__tests__/scaledCircleMarkers.png', @@ -123,8 +122,6 @@ export const TEMPORARILY_IGNORED_PATHS = [ 'src/legacy/ui/public/angular-bootstrap/bindHtml/bindHtml.js', 'src/legacy/ui/public/angular-bootstrap/tooltip/tooltip-html-unsafe-popup.html', 'src/legacy/ui/public/angular-bootstrap/tooltip/tooltip-popup.html', - 'src/legacy/ui/public/angular-bootstrap/typeahead/typeahead-match.html', - 'src/legacy/ui/public/angular-bootstrap/typeahead/typeahead-popup.html', 'src/legacy/ui/public/assets/favicons/android-chrome-192x192.png', 'src/legacy/ui/public/assets/favicons/android-chrome-256x256.png', 'src/legacy/ui/public/assets/favicons/android-chrome-512x512.png', diff --git a/src/dev/tslint/rules/moduleMigrationRule.js b/src/dev/tslint/rules/moduleMigrationRule.js new file mode 100644 index 0000000000000..be79664e889c7 --- /dev/null +++ b/src/dev/tslint/rules/moduleMigrationRule.js @@ -0,0 +1,59 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +const Lint = require('tslint'); + +class ModuleMigrationWalker extends Lint.RuleWalker { + visitImportDeclaration(node) { + + const moduleId = node.moduleSpecifier.text; + const mapping = this.options.find( + mapping => mapping.from === moduleId || mapping.from.startsWith(moduleId + '/') + ); + + if (!mapping) { + return; + } + + const newSource = moduleId.replace(mapping.from, mapping.to); + const start = node.moduleSpecifier.getStart(); + const width = node.moduleSpecifier.getWidth(); + + this.addFailure( + this.createFailure( + start, + width, + `Imported module "${moduleId}" should be "${newSource}"`, + this.createReplacement( + start, + width, + `'${newSource}'` + ) + ) + ); + + super.visitImportDeclaration(node); + } +} + +exports.Rule = class extends Lint.Rules.AbstractRule { + apply(sourceFile) { + return this.applyWithWalker(new ModuleMigrationWalker(sourceFile, this.getOptions())); + } +}; diff --git a/src/dev/typescript/get_ts_project_for_absolute_path.ts b/src/dev/typescript/get_ts_project_for_absolute_path.ts index 409d18bed6f5e..843743fd7a3b6 100644 --- a/src/dev/typescript/get_ts_project_for_absolute_path.ts +++ b/src/dev/typescript/get_ts_project_for_absolute_path.ts @@ -17,9 +17,10 @@ * under the License. */ -import { relative } from 'path'; +import { relative, resolve } from 'path'; import { REPO_ROOT } from '../constants'; +import { File } from '../file'; import { PROJECTS } from './projects'; /** @@ -33,6 +34,7 @@ import { PROJECTS } from './projects'; */ export function getTsProjectForAbsolutePath(path: string) { const relPath = relative(REPO_ROOT, path); + const file = new File(resolve(REPO_ROOT, path)); const projects = PROJECTS.filter(p => p.isAbsolutePathSelected(path)); if (!projects.length) { @@ -41,7 +43,7 @@ export function getTsProjectForAbsolutePath(path: string) { ); } - if (projects.length !== 1) { + if (projects.length !== 1 && !file.isTypescriptAmbient()) { const configPaths = projects.map(p => `"${relative(REPO_ROOT, p.tsConfigPath)}"`); const pathsMsg = `${configPaths.slice(0, -1).join(', ')} or ${ diff --git a/src/dev/typescript/projects.ts b/src/dev/typescript/projects.ts index 540441ab6b8de..7ef3419751be5 100644 --- a/src/dev/typescript/projects.ts +++ b/src/dev/typescript/projects.ts @@ -35,6 +35,9 @@ export const PROJECTS = [ ...glob .sync('packages/*/tsconfig.json', { cwd: REPO_ROOT }) .map(path => new Project(resolve(REPO_ROOT, path))), + ...glob + .sync('test/plugin_functional/plugins/*/tsconfig.json', { cwd: REPO_ROOT }) + .map(path => new Project(resolve(REPO_ROOT, path))), ]; export function filterProjectsByFlag(projectFlag?: string) { diff --git a/src/dev/typescript/run_check_ts_projects_cli.ts b/src/dev/typescript/run_check_ts_projects_cli.ts index d9c1259882c56..d4a4b5dee5fa3 100644 --- a/src/dev/typescript/run_check_ts_projects_cli.ts +++ b/src/dev/typescript/run_check_ts_projects_cli.ts @@ -55,7 +55,7 @@ export async function runCheckTsProjectsCli() { if (projects.length === 0) { isNotInTsProject.push(file); } - if (projects.length > 1) { + if (projects.length > 1 && !file.isTypescriptAmbient()) { isInMultipleTsProjects.push(file); } } diff --git a/src/es_archiver/lib/__tests__/stats.js b/src/es_archiver/lib/__tests__/stats.js index eb7d9f09f858d..38febda53dbed 100644 --- a/src/es_archiver/lib/__tests__/stats.js +++ b/src/es_archiver/lib/__tests__/stats.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { uniq } from 'lodash'; import sinon from 'sinon'; diff --git a/src/es_archiver/lib/archives/__tests__/format.js b/src/es_archiver/lib/archives/__tests__/format.js index 53da1718c8926..d537245c44fc6 100644 --- a/src/es_archiver/lib/archives/__tests__/format.js +++ b/src/es_archiver/lib/archives/__tests__/format.js @@ -20,7 +20,7 @@ import Stream from 'stream'; import { createGunzip } from 'zlib'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { createListStream, diff --git a/src/es_archiver/lib/archives/__tests__/parse.js b/src/es_archiver/lib/archives/__tests__/parse.js index 6645df47fc60c..2a525e76d98e8 100644 --- a/src/es_archiver/lib/archives/__tests__/parse.js +++ b/src/es_archiver/lib/archives/__tests__/parse.js @@ -20,7 +20,7 @@ import Stream, { PassThrough, Transform } from 'stream'; import { createGzip } from 'zlib'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { createConcatStream, diff --git a/src/es_archiver/lib/docs/__tests__/generate_doc_records_stream.js b/src/es_archiver/lib/docs/__tests__/generate_doc_records_stream.js index d9eb99d39f87d..b4f221ea0432a 100644 --- a/src/es_archiver/lib/docs/__tests__/generate_doc_records_stream.js +++ b/src/es_archiver/lib/docs/__tests__/generate_doc_records_stream.js @@ -18,7 +18,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { delay } from 'bluebird'; import { diff --git a/src/es_archiver/lib/docs/__tests__/index_doc_records_stream.js b/src/es_archiver/lib/docs/__tests__/index_doc_records_stream.js index cdb2925e0eeaf..a0ab1430417f1 100644 --- a/src/es_archiver/lib/docs/__tests__/index_doc_records_stream.js +++ b/src/es_archiver/lib/docs/__tests__/index_doc_records_stream.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { delay } from 'bluebird'; import { diff --git a/src/es_archiver/lib/indices/__tests__/create_index_stream.js b/src/es_archiver/lib/indices/__tests__/create_index_stream.js index e705b0065427c..830512f3476ed 100644 --- a/src/es_archiver/lib/indices/__tests__/create_index_stream.js +++ b/src/es_archiver/lib/indices/__tests__/create_index_stream.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import Chance from 'chance'; diff --git a/src/es_archiver/lib/indices/__tests__/generate_index_records_stream.js b/src/es_archiver/lib/indices/__tests__/generate_index_records_stream.js index 115e7a97f0647..3ff30c0267da3 100644 --- a/src/es_archiver/lib/indices/__tests__/generate_index_records_stream.js +++ b/src/es_archiver/lib/indices/__tests__/generate_index_records_stream.js @@ -18,7 +18,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { createListStream, diff --git a/src/es_archiver/lib/records/__tests__/filter_records_stream.js b/src/es_archiver/lib/records/__tests__/filter_records_stream.js index 90a89424cfa78..48a8aaf7de721 100644 --- a/src/es_archiver/lib/records/__tests__/filter_records_stream.js +++ b/src/es_archiver/lib/records/__tests__/filter_records_stream.js @@ -18,7 +18,7 @@ */ import Chance from 'chance'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { createListStream, diff --git a/src/functional_test_runner/__tests__/fixtures/simple_project/tests.js b/src/functional_test_runner/__tests__/fixtures/simple_project/tests.js index 6ea7c84167229..02e49fefc587e 100644 --- a/src/functional_test_runner/__tests__/fixtures/simple_project/tests.js +++ b/src/functional_test_runner/__tests__/fixtures/simple_project/tests.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default () => { describe('app one', () => { diff --git a/src/functional_test_runner/__tests__/integration/basic.js b/src/functional_test_runner/__tests__/integration/basic.js index b5e4f5f24fd4c..1c3858a8cfd6d 100644 --- a/src/functional_test_runner/__tests__/integration/basic.js +++ b/src/functional_test_runner/__tests__/integration/basic.js @@ -20,7 +20,7 @@ import { spawnSync } from 'child_process'; import { resolve } from 'path'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; const SCRIPT = resolve(__dirname, '../../../../scripts/functional_test_runner.js'); const BASIC_CONFIG = resolve(__dirname, '../fixtures/simple_project/config.js'); diff --git a/src/functional_test_runner/__tests__/integration/failure_hooks.js b/src/functional_test_runner/__tests__/integration/failure_hooks.js index 1e2c2035df889..0c00e2771bb1f 100644 --- a/src/functional_test_runner/__tests__/integration/failure_hooks.js +++ b/src/functional_test_runner/__tests__/integration/failure_hooks.js @@ -21,7 +21,7 @@ import { spawnSync } from 'child_process'; import { resolve } from 'path'; import stripAnsi from 'strip-ansi'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; const SCRIPT = resolve(__dirname, '../../../../scripts/functional_test_runner.js'); const FAILURE_HOOKS_CONFIG = resolve(__dirname, '../fixtures/failure_hooks/config.js'); diff --git a/src/functional_test_runner/lib/config/__tests__/read_config_file.js b/src/functional_test_runner/lib/config/__tests__/read_config_file.js index d9da00d9b3c81..d4a08333e8143 100644 --- a/src/functional_test_runner/lib/config/__tests__/read_config_file.js +++ b/src/functional_test_runner/lib/config/__tests__/read_config_file.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { ToolingLog } from '@kbn/dev-utils'; import { readConfigFile } from '../read_config_file'; diff --git a/src/legacy/core_plugins/console/__tests__/index.js b/src/legacy/core_plugins/console/__tests__/index.js index aebb5e16bc6d2..e516898ef2fd8 100644 --- a/src/legacy/core_plugins/console/__tests__/index.js +++ b/src/legacy/core_plugins/console/__tests__/index.js @@ -18,7 +18,7 @@ */ import { Deprecations } from '../../../deprecation'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import index from '../index'; import { noop } from 'lodash'; import sinon from 'sinon'; diff --git a/src/legacy/core_plugins/console/index.js b/src/legacy/core_plugins/console/index.js index 64d3c04db242c..652696bc7bfd8 100644 --- a/src/legacy/core_plugins/console/index.js +++ b/src/legacy/core_plugins/console/index.js @@ -103,7 +103,7 @@ export default function (kibana) { } const config = server.config(); - const legacyEsConfig = await server.newPlatform.start.core.elasticsearch.legacy.config$.pipe(first()).toPromise(); + const legacyEsConfig = await server.newPlatform.setup.core.elasticsearch.legacy.config$.pipe(first()).toPromise(); const proxyConfigCollection = new ProxyConfigCollection(options.proxyConfig); const proxyPathFilters = options.proxyFilter.map(str => new RegExp(str)); diff --git a/src/legacy/core_plugins/console/public/console.js b/src/legacy/core_plugins/console/public/console.js index 461423ce4ebbb..3976e38302879 100644 --- a/src/legacy/core_plugins/console/public/console.js +++ b/src/legacy/core_plugins/console/public/console.js @@ -21,9 +21,7 @@ import uiRoutes from 'ui/routes'; import template from './index.html'; require('brace'); -require('ui-bootstrap-custom'); -require('ui/modules').get('kibana', ['sense.ui.bootstrap']); require('ui/tooltip'); require('ui/autoload/styles'); diff --git a/src/legacy/core_plugins/console/public/src/__tests__/utils.js b/src/legacy/core_plugins/console/public/src/__tests__/utils.js index 5863923c82718..fa88e42fa557f 100644 --- a/src/legacy/core_plugins/console/public/src/__tests__/utils.js +++ b/src/legacy/core_plugins/console/public/src/__tests__/utils.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import utils from '../utils'; diff --git a/src/legacy/core_plugins/console/public/src/controllers/sense_controller.js b/src/legacy/core_plugins/console/public/src/controllers/sense_controller.js index 4d3757be9a6ac..ce7e6d48aa987 100644 --- a/src/legacy/core_plugins/console/public/src/controllers/sense_controller.js +++ b/src/legacy/core_plugins/console/public/src/controllers/sense_controller.js @@ -16,8 +16,8 @@ * specific language governing permissions and limitations * under the License. */ -import 'ui/doc_title'; -import { useResizeChecker } from '../sense_editor_resize'; +import { DocTitleProvider } from 'ui/doc_title'; +import { applyResizeCheckerToEditors } from '../sense_editor_resize'; import $ from 'jquery'; import { initializeInput } from '../input'; import { initializeOutput } from '../output'; @@ -30,11 +30,12 @@ const module = require('ui/modules').get('app/sense'); module.run(function (Private, $rootScope) { module.setupResizeCheckerForRootEditors = ($el, ...editors) => { - return useResizeChecker($rootScope, $el, ...editors); + return applyResizeCheckerToEditors($rootScope, $el, ...editors); }; }); -module.controller('SenseController', function SenseController(Private, $scope, $timeout, $location, docTitle, kbnUiAceKeyboardModeService) { +module.controller('SenseController', function SenseController(Private, $scope, $timeout, $location, kbnUiAceKeyboardModeService) { + const docTitle = Private(DocTitleProvider); docTitle.change('Console'); $scope.topNavController = Private(SenseTopNavController); diff --git a/src/legacy/core_plugins/console/public/src/directives/sense_help_example.js b/src/legacy/core_plugins/console/public/src/directives/sense_help_example.js index 6a7cbff4df3d7..d4e4632a45dfb 100644 --- a/src/legacy/core_plugins/console/public/src/directives/sense_help_example.js +++ b/src/legacy/core_plugins/console/public/src/directives/sense_help_example.js @@ -19,7 +19,7 @@ const SenseEditor = require('../sense_editor/editor'); const exampleText = require('raw-loader!./helpExample.txt').trim(); -import { useResizeChecker } from '../sense_editor_resize'; +import { applyResizeCheckerToEditors } from '../sense_editor_resize'; require('ui/modules') .get('app/sense') @@ -29,7 +29,7 @@ require('ui/modules') link: function ($scope, $el) { $el.text(exampleText); $scope.editor = new SenseEditor($el); - useResizeChecker($scope, $el, $scope.editor); + applyResizeCheckerToEditors($scope, $el, $scope.editor); $scope.editor.setReadOnly(true); $scope.editor.$blockScrolling = Infinity; diff --git a/src/legacy/core_plugins/console/public/src/directives/sense_history_viewer.js b/src/legacy/core_plugins/console/public/src/directives/sense_history_viewer.js index 9502a10f0a362..d7ad736335f52 100644 --- a/src/legacy/core_plugins/console/public/src/directives/sense_history_viewer.js +++ b/src/legacy/core_plugins/console/public/src/directives/sense_history_viewer.js @@ -19,7 +19,7 @@ const SenseEditor = require('../sense_editor/editor'); -import { useResizeChecker } from '../sense_editor_resize'; +import { applyResizeCheckerToEditors } from '../sense_editor_resize'; require('ui/modules') .get('app/sense') @@ -33,7 +33,7 @@ require('ui/modules') const viewer = new SenseEditor($el); viewer.setReadOnly(true); viewer.renderer.setShowPrintMargin(false); - useResizeChecker($scope, $el, viewer); + applyResizeCheckerToEditors($scope, $el, viewer); require('../settings').applyCurrentSettings(viewer); $scope.$watch('req', function (req) { diff --git a/src/legacy/core_plugins/console/public/src/sense_editor_resize.js b/src/legacy/core_plugins/console/public/src/sense_editor_resize.js index eff840254a864..6b950a394db1b 100644 --- a/src/legacy/core_plugins/console/public/src/sense_editor_resize.js +++ b/src/legacy/core_plugins/console/public/src/sense_editor_resize.js @@ -19,7 +19,7 @@ import { ResizeChecker } from 'ui/resize_checker'; -export function useResizeChecker($scope, $el, ...editors) { +export function applyResizeCheckerToEditors($scope, $el, ...editors) { const checker = new ResizeChecker($el); checker.on('resize', () => editors.forEach(e => e.resize())); $scope.$on('$destroy', () => checker.destroy()); diff --git a/src/legacy/core_plugins/console/public/webpackShims/.eslintrc b/src/legacy/core_plugins/console/public/webpackShims/.eslintrc deleted file mode 100644 index 761851c90eea5..0000000000000 --- a/src/legacy/core_plugins/console/public/webpackShims/.eslintrc +++ /dev/null @@ -1,2 +0,0 @@ ---- -root: true diff --git a/src/legacy/core_plugins/console/public/webpackShims/ui-bootstrap-custom.js b/src/legacy/core_plugins/console/public/webpackShims/ui-bootstrap-custom.js deleted file mode 100755 index 55ebc7aba8e47..0000000000000 --- a/src/legacy/core_plugins/console/public/webpackShims/ui-bootstrap-custom.js +++ /dev/null @@ -1,729 +0,0 @@ -/* - * angular-ui-bootstrap - * http://angular-ui.github.io/bootstrap/ - - * Version: 0.14.2 - 2015-10-17 - * License: MIT - */ - -/* @notice - * This product bundles angular-ui-bootstrap@0.12.1 which is available under a - * "MIT" license. - * - * The MIT License - * - * Copyright (c) 2012-2014 the AngularUI Team, https://github.com/organizations/angular-ui/teams/291112 - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -angular.module("sense.ui.bootstrap", ["sense.ui.bootstrap.tpls","sense.ui.bootstrap.typeahead","sense.ui.bootstrap.position"]); -angular.module("sense.ui.bootstrap.tpls", ["sense/template/typeahead/typeahead-match.html","sense/template/typeahead/typeahead-popup.html"]); -angular.module('sense.ui.bootstrap.typeahead', ['sense.ui.bootstrap.position']) - -/** - * A helper service that can parse typeahead's syntax (string provided by users) - * Extracted to a separate service for ease of unit testing - */ - .factory('senseUibTypeaheadParser', ['$parse', function($parse) { - // 00000111000000000000022200000000000000003333333333333330000000000044000 - var TYPEAHEAD_REGEXP = /^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w\d]*))\s+in\s+([\s\S]+?)$/; - return { - parse: function(input) { - var match = input.match(TYPEAHEAD_REGEXP); - if (!match) { - throw new Error( - 'Expected typeahead specification in form of "_modelValue_ (as _label_)? for _item_ in _collection_"' + - ' but got "' + input + '".'); - } - - return { - itemName: match[3], - source: $parse(match[4]), - viewMapper: $parse(match[2] || match[1]), - modelMapper: $parse(match[1]) - }; - } - }; - }]) - - .controller('SenseUibTypeaheadController', ['$scope', '$element', '$attrs', '$compile', '$parse', '$q', '$timeout', '$document', '$window', '$rootScope', '$senseUibPosition', 'senseUibTypeaheadParser', - function(originalScope, element, attrs, $compile, $parse, $q, $timeout, $document, $window, $rootScope, $position, typeaheadParser) { - var HOT_KEYS = [9, 13, 27, 38, 40]; - var eventDebounceTime = 200; - var modelCtrl, ngModelOptions; - //SUPPORTED ATTRIBUTES (OPTIONS) - - //minimal no of characters that needs to be entered before typeahead kicks-in - var minLength = originalScope.$eval(attrs.typeaheadMinLength); - if (!minLength && minLength !== 0) { - minLength = 1; - } - - //minimal wait time after last character typed before typeahead kicks-in - var waitTime = originalScope.$eval(attrs.typeaheadWaitMs) || 0; - - //should it restrict model values to the ones selected from the popup only? - var isEditable = originalScope.$eval(attrs.typeaheadEditable) !== false; - - //binding to a variable that indicates if matches are being retrieved asynchronously - var isLoadingSetter = $parse(attrs.typeaheadLoading).assign || angular.noop; - - //a callback executed when a match is selected - var onSelectCallback = $parse(attrs.typeaheadOnSelect); - - //should it select highlighted popup value when losing focus? - var isSelectOnBlur = angular.isDefined(attrs.typeaheadSelectOnBlur) ? originalScope.$eval(attrs.typeaheadSelectOnBlur) : false; - - //binding to a variable that indicates if there were no results after the query is completed - var isNoResultsSetter = $parse(attrs.typeaheadNoResults).assign || angular.noop; - - var inputFormatter = attrs.typeaheadInputFormatter ? $parse(attrs.typeaheadInputFormatter) : undefined; - - var appendToBody = attrs.typeaheadAppendToBody ? originalScope.$eval(attrs.typeaheadAppendToBody) : false; - - var appendToElementId = attrs.typeaheadAppendToElementId || false; - - var focusFirst = originalScope.$eval(attrs.typeaheadFocusFirst) !== false; - - //If input matches an item of the list exactly, select it automatically - var selectOnExact = attrs.typeaheadSelectOnExact ? originalScope.$eval(attrs.typeaheadSelectOnExact) : false; - - //INTERNAL VARIABLES - - //model setter executed upon match selection - var parsedModel = $parse(attrs.ngModel); - var invokeModelSetter = $parse(attrs.ngModel + '($$$p)'); - var $setModelValue = function(scope, newValue) { - if (angular.isFunction(parsedModel(originalScope)) && - ngModelOptions && ngModelOptions.$options && ngModelOptions.$options.getterSetter) { - return invokeModelSetter(scope, {$$$p: newValue}); - } else { - return parsedModel.assign(scope, newValue); - } - }; - - //expressions used by typeahead - var parserResult = typeaheadParser.parse(attrs.senseUibTypeahead); - - var hasFocus; - - //Used to avoid bug in iOS webview where iOS keyboard does not fire - //mousedown & mouseup events - //Issue #3699 - var selected; - - //create a child scope for the typeahead directive so we are not polluting original scope - //with typeahead-specific data (matches, query etc.) - var scope = originalScope.$new(); - var offDestroy = originalScope.$on('$destroy', function() { - scope.$destroy(); - }); - scope.$on('$destroy', offDestroy); - - // WAI-ARIA - var popupId = 'typeahead-' + scope.$id + '-' + Math.floor(Math.random() * 10000); - element.attr({ - 'aria-autocomplete': 'list', - 'aria-expanded': false, - 'aria-owns': popupId - }); - - //pop-up element used to display matches - var popUpEl = angular.element('

'); - popUpEl.attr({ - id: popupId, - matches: 'matches', - active: 'activeIdx', - select: 'select(activeIdx)', - 'move-in-progress': 'moveInProgress', - query: 'query', - position: 'position' - }); - //custom item template - if (angular.isDefined(attrs.typeaheadTemplateUrl)) { - popUpEl.attr('template-url', attrs.typeaheadTemplateUrl); - } - - if (angular.isDefined(attrs.typeaheadPopupTemplateUrl)) { - popUpEl.attr('popup-template-url', attrs.typeaheadPopupTemplateUrl); - } - - var resetMatches = function() { - scope.matches = []; - scope.activeIdx = -1; - element.attr('aria-expanded', false); - }; - - var getMatchId = function(index) { - return popupId + '-option-' + index; - }; - - // Indicate that the specified match is the active (pre-selected) item in the list owned by this typeahead. - // This attribute is added or removed automatically when the `activeIdx` changes. - scope.$watch('activeIdx', function(index) { - if (index < 0) { - element.removeAttr('aria-activedescendant'); - } else { - element.attr('aria-activedescendant', getMatchId(index)); - } - }); - - var inputIsExactMatch = function(inputValue, index) { - if (scope.matches.length > index && inputValue) { - return inputValue.toUpperCase() === scope.matches[index].label.toUpperCase(); - } - - return false; - }; - - var getMatchesAsync = function(inputValue) { - var locals = {$viewValue: inputValue}; - isLoadingSetter(originalScope, true); - isNoResultsSetter(originalScope, false); - $q.when(parserResult.source(originalScope, locals)).then(function(matches) { - //it might happen that several async queries were in progress if a user were typing fast - //but we are interested only in responses that correspond to the current view value - var onCurrentRequest = (inputValue === modelCtrl.$viewValue); - if (onCurrentRequest && hasFocus) { - if (matches && matches.length > 0) { - scope.activeIdx = focusFirst ? 0 : -1; - isNoResultsSetter(originalScope, false); - scope.matches.length = 0; - - //transform labels - for (var i = 0; i < matches.length; i++) { - locals[parserResult.itemName] = matches[i]; - scope.matches.push({ - id: getMatchId(i), - label: parserResult.viewMapper(scope, locals), - model: matches[i] - }); - } - - scope.query = inputValue; - //position pop-up with matches - we need to re-calculate its position each time we are opening a window - //with matches as a pop-up might be absolute-positioned and position of an input might have changed on a page - //due to other elements being rendered - recalculatePosition(); - - element.attr('aria-expanded', true); - - //Select the single remaining option if user input matches - if (selectOnExact && scope.matches.length === 1 && inputIsExactMatch(inputValue, 0)) { - scope.select(0); - } - } else { - resetMatches(); - isNoResultsSetter(originalScope, true); - } - } - if (onCurrentRequest) { - isLoadingSetter(originalScope, false); - } - }, function() { - resetMatches(); - isLoadingSetter(originalScope, false); - isNoResultsSetter(originalScope, true); - }); - }; - - // bind events only if appendToBody params exist - performance feature - if (appendToBody) { - angular.element($window).bind('resize', fireRecalculating); - $document.find('body').bind('scroll', fireRecalculating); - } - - // Declare the timeout promise var outside the function scope so that stacked calls can be cancelled later - var timeoutEventPromise; - - // Default progress type - scope.moveInProgress = false; - - function fireRecalculating() { - if (!scope.moveInProgress) { - scope.moveInProgress = true; - scope.$digest(); - } - - // Cancel previous timeout - if (timeoutEventPromise) { - $timeout.cancel(timeoutEventPromise); - } - - // Debounced executing recalculate after events fired - timeoutEventPromise = $timeout(function() { - // if popup is visible - if (scope.matches.length) { - recalculatePosition(); - } - - scope.moveInProgress = false; - }, eventDebounceTime); - } - - // recalculate actual position and set new values to scope - // after digest loop is popup in right position - function recalculatePosition() { - scope.position = appendToBody ? $position.offset(element) : $position.position(element); - scope.position.top += element.prop('offsetHeight'); - } - - //we need to propagate user's query so we can highlight matches - scope.query = undefined; - - //Declare the timeout promise var outside the function scope so that stacked calls can be cancelled later - var timeoutPromise; - - var scheduleSearchWithTimeout = function(inputValue) { - timeoutPromise = $timeout(function() { - getMatchesAsync(inputValue); - }, waitTime); - }; - - var cancelPreviousTimeout = function() { - if (timeoutPromise) { - $timeout.cancel(timeoutPromise); - } - }; - - resetMatches(); - - scope.select = function(activeIdx) { - //called from within the $digest() cycle - var locals = {}; - var model, item; - - selected = true; - locals[parserResult.itemName] = item = scope.matches[activeIdx].model; - model = parserResult.modelMapper(originalScope, locals); - $setModelValue(originalScope, model); - modelCtrl.$setValidity('editable', true); - modelCtrl.$setValidity('parse', true); - - onSelectCallback(originalScope, { - $item: item, - $model: model, - $label: parserResult.viewMapper(originalScope, locals) - }); - - resetMatches(); - - //return focus to the input element if a match was selected via a mouse click event - // use timeout to avoid $rootScope:inprog error - if (scope.$eval(attrs.typeaheadFocusOnSelect) !== false) { - $timeout(function() { element[0].focus(); }, 0, false); - } - }; - - //bind keyboard events: arrows up(38) / down(40), enter(13) and tab(9), esc(27) - element.bind('keydown', function(evt) { - //typeahead is open and an "interesting" key was pressed - if (scope.matches.length === 0 || HOT_KEYS.indexOf(evt.which) === -1) { - return; - } - - // if there's nothing selected (i.e. focusFirst) and enter or tab is hit, clear the results - if (scope.activeIdx === -1 && (evt.which === 9 || evt.which === 13)) { - resetMatches(); - scope.$digest(); - return; - } - - evt.preventDefault(); - - if (evt.which === 40) { - scope.activeIdx = (scope.activeIdx + 1) % scope.matches.length; - scope.$digest(); - } else if (evt.which === 38) { - scope.activeIdx = (scope.activeIdx > 0 ? scope.activeIdx : scope.matches.length) - 1; - scope.$digest(); - } else if (evt.which === 13 || evt.which === 9) { - scope.$apply(function () { - scope.select(scope.activeIdx); - }); - } else if (evt.which === 27) { - evt.stopPropagation(); - - resetMatches(); - scope.$digest(); - } - }); - - element.bind('blur', function() { - if (isSelectOnBlur && scope.matches.length && scope.activeIdx !== -1 && !selected) { - selected = true; - scope.$apply(function() { - scope.select(scope.activeIdx); - }); - } - hasFocus = false; - selected = false; - }); - - // Keep reference to click handler to unbind it. - var dismissClickHandler = function(evt) { - // Issue #3973 - // Firefox treats right click as a click on document - if (element[0] !== evt.target && evt.which !== 3 && scope.matches.length !== 0) { - resetMatches(); - if (!$rootScope.$$phase) { - scope.$digest(); - } - } - }; - - $document.bind('click', dismissClickHandler); - - originalScope.$on('$destroy', function() { - $document.unbind('click', dismissClickHandler); - if (appendToBody || appendToElementId) { - $popup.remove(); - } - // Prevent jQuery cache memory leak - popUpEl.remove(); - }); - - var $popup = $compile(popUpEl)(scope); - - if (appendToBody) { - $document.find('body').append($popup); - } else if (appendToElementId !== false) { - angular.element($document[0].getElementById(appendToElementId)).append($popup); - } else { - element.after($popup); - } - - this.init = function(_modelCtrl, _ngModelOptions) { - modelCtrl = _modelCtrl; - ngModelOptions = _ngModelOptions; - - //plug into $parsers pipeline to open a typeahead on view changes initiated from DOM - //$parsers kick-in on all the changes coming from the view as well as manually triggered by $setViewValue - modelCtrl.$parsers.unshift(function(inputValue) { - hasFocus = true; - - if (minLength === 0 || inputValue && inputValue.length >= minLength) { - if (waitTime > 0) { - cancelPreviousTimeout(); - scheduleSearchWithTimeout(inputValue); - } else { - getMatchesAsync(inputValue); - } - } else { - isLoadingSetter(originalScope, false); - cancelPreviousTimeout(); - resetMatches(); - } - - if (isEditable) { - return inputValue; - } else { - if (!inputValue) { - // Reset in case user had typed something previously. - modelCtrl.$setValidity('editable', true); - return null; - } else { - modelCtrl.$setValidity('editable', false); - return undefined; - } - } - }); - - modelCtrl.$formatters.push(function(modelValue) { - var candidateViewValue, emptyViewValue; - var locals = {}; - - // The validity may be set to false via $parsers (see above) if - // the model is restricted to selected values. If the model - // is set manually it is considered to be valid. - if (!isEditable) { - modelCtrl.$setValidity('editable', true); - } - - if (inputFormatter) { - locals.$model = modelValue; - return inputFormatter(originalScope, locals); - } else { - //it might happen that we don't have enough info to properly render input value - //we need to check for this situation and simply return model value if we can't apply custom formatting - locals[parserResult.itemName] = modelValue; - candidateViewValue = parserResult.viewMapper(originalScope, locals); - locals[parserResult.itemName] = undefined; - emptyViewValue = parserResult.viewMapper(originalScope, locals); - - return candidateViewValue !== emptyViewValue ? candidateViewValue : modelValue; - } - }); - }; - }]) - - .directive('senseUibTypeahead', function() { - return { - controller: 'SenseUibTypeaheadController', - require: ['ngModel', '^?ngModelOptions', 'senseUibTypeahead'], - link: function(originalScope, element, attrs, ctrls) { - ctrls[2].init(ctrls[0], ctrls[1]); - } - }; - }) - - .directive('senseUibTypeaheadPopup', function() { - return { - scope: { - matches: '=', - query: '=', - active: '=', - position: '&', - moveInProgress: '=', - select: '&' - }, - replace: true, - templateUrl: function(element, attrs) { - return attrs.popupTemplateUrl || 'sense/template/typeahead/typeahead-popup.html'; - }, - link: function(scope, element, attrs) { - scope.templateUrl = attrs.templateUrl; - - scope.isOpen = function() { - return scope.matches.length > 0; - }; - - scope.isActive = function(matchIdx) { - return scope.active == matchIdx; - }; - - scope.selectActive = function(matchIdx) { - scope.active = matchIdx; - }; - - scope.selectMatch = function(activeIdx) { - scope.select({activeIdx:activeIdx}); - }; - } - }; - }) - - .directive('senseUibTypeaheadMatch', ['$templateCache', '$compile', '$parse', function($templateCache, $compile, $parse) { - return { - scope: { - index: '=', - match: '=', - query: '=' - }, - link:function(scope, element, attrs) { - var tplUrl = $parse(attrs.templateUrl)(scope.$parent) || 'sense/template/typeahead/typeahead-match.html'; - $compile($templateCache.get(tplUrl).trim())(scope, function(clonedElement) { - element.replaceWith(clonedElement); - }); - } - }; - }]) - - .filter('senseUibTypeaheadHighlight', ['$sce', '$injector', '$log', function($sce, $injector, $log) { - var isSanitizePresent; - isSanitizePresent = $injector.has('$sanitize'); - - function escapeRegexp(queryToEscape) { - // Regex: capture the whole query string and replace it with the string that will be used to match - // the results, for example if the capture is "a" the result will be \a - return queryToEscape.replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1'); - } - - function containsHtml(matchItem) { - return /<.*>/g.test(matchItem); - } - - return function(matchItem, query) { - if (!isSanitizePresent && containsHtml(matchItem)) { - $log.warn('Unsafe use of typeahead please use ngSanitize'); // Warn the user about the danger - } - matchItem = query? ('' + matchItem).replace(new RegExp(escapeRegexp(query), 'gi'), '$&') : matchItem; // Replaces the capture string with a the same string inside of a "strong" tag - if (!isSanitizePresent) { - matchItem = $sce.trustAsHtml(matchItem); // If $sanitize is not present we pack the string in a $sce object for the ng-bind-html directive - } - return matchItem; - }; - }]); - -angular.module('sense.ui.bootstrap.position', []) - -/** - * A set of utility methods that can be use to retrieve position of DOM elements. - * It is meant to be used where we need to absolute-position DOM elements in - * relation to other, existing elements (this is the case for tooltips, popovers, - * typeahead suggestions etc.). - */ - .factory('$senseUibPosition', ['$document', '$window', function($document, $window) { - function getStyle(el, cssprop) { - if (el.currentStyle) { //IE - return el.currentStyle[cssprop]; - } else if ($window.getComputedStyle) { - return $window.getComputedStyle(el)[cssprop]; - } - // finally try and get inline style - return el.style[cssprop]; - } - - /** - * Checks if a given element is statically positioned - * @param element - raw DOM element - */ - function isStaticPositioned(element) { - return (getStyle(element, 'position') || 'static' ) === 'static'; - } - - /** - * returns the closest, non-statically positioned parentOffset of a given element - * @param element - */ - var parentOffsetEl = function(element) { - var docDomEl = $document[0]; - var offsetParent = element.offsetParent || docDomEl; - while (offsetParent && offsetParent !== docDomEl && isStaticPositioned(offsetParent) ) { - offsetParent = offsetParent.offsetParent; - } - return offsetParent || docDomEl; - }; - - return { - /** - * Provides read-only equivalent of jQuery's position function: - * http://api.jquery.com/position/ - */ - position: function(element) { - var elBCR = this.offset(element); - var offsetParentBCR = { top: 0, left: 0 }; - var offsetParentEl = parentOffsetEl(element[0]); - if (offsetParentEl != $document[0]) { - offsetParentBCR = this.offset(angular.element(offsetParentEl)); - offsetParentBCR.top += offsetParentEl.clientTop - offsetParentEl.scrollTop; - offsetParentBCR.left += offsetParentEl.clientLeft - offsetParentEl.scrollLeft; - } - - var boundingClientRect = element[0].getBoundingClientRect(); - return { - width: boundingClientRect.width || element.prop('offsetWidth'), - height: boundingClientRect.height || element.prop('offsetHeight'), - top: elBCR.top - offsetParentBCR.top, - left: elBCR.left - offsetParentBCR.left - }; - }, - - /** - * Provides read-only equivalent of jQuery's offset function: - * http://api.jquery.com/offset/ - */ - offset: function(element) { - var boundingClientRect = element[0].getBoundingClientRect(); - return { - width: boundingClientRect.width || element.prop('offsetWidth'), - height: boundingClientRect.height || element.prop('offsetHeight'), - top: boundingClientRect.top + ($window.pageYOffset || $document[0].documentElement.scrollTop), - left: boundingClientRect.left + ($window.pageXOffset || $document[0].documentElement.scrollLeft) - }; - }, - - /** - * Provides coordinates for the targetEl in relation to hostEl - */ - positionElements: function(hostEl, targetEl, positionStr, appendToBody) { - var positionStrParts = positionStr.split('-'); - var pos0 = positionStrParts[0], pos1 = positionStrParts[1] || 'center'; - - var hostElPos, - targetElWidth, - targetElHeight, - targetElPos; - - hostElPos = appendToBody ? this.offset(hostEl) : this.position(hostEl); - - targetElWidth = targetEl.prop('offsetWidth'); - targetElHeight = targetEl.prop('offsetHeight'); - - var shiftWidth = { - center: function() { - return hostElPos.left + hostElPos.width / 2 - targetElWidth / 2; - }, - left: function() { - return hostElPos.left; - }, - right: function() { - return hostElPos.left + hostElPos.width; - } - }; - - var shiftHeight = { - center: function() { - return hostElPos.top + hostElPos.height / 2 - targetElHeight / 2; - }, - top: function() { - return hostElPos.top; - }, - bottom: function() { - return hostElPos.top + hostElPos.height; - } - }; - - switch (pos0) { - case 'right': - targetElPos = { - top: shiftHeight[pos1](), - left: shiftWidth[pos0]() - }; - break; - case 'left': - targetElPos = { - top: shiftHeight[pos1](), - left: hostElPos.left - targetElWidth - }; - break; - case 'bottom': - targetElPos = { - top: shiftHeight[pos0](), - left: shiftWidth[pos1]() - }; - break; - default: - targetElPos = { - top: hostElPos.top - targetElHeight, - left: shiftWidth[pos1]() - }; - break; - } - - return targetElPos; - } - }; - }]); - -angular.module("sense/template/typeahead/typeahead-match.html", []).run(["$templateCache", function($templateCache) { - $templateCache.put("sense/template/typeahead/typeahead-match.html", - "\n" + - ""); -}]); - -angular.module("sense/template/typeahead/typeahead-popup.html", []).run(["$templateCache", function($templateCache) { - $templateCache.put("sense/template/typeahead/typeahead-popup.html", - "
    \n" + - "
  • \n" + - "
    \n" + - "
  • \n" + - "
\n" + - ""); -}]); diff --git a/src/legacy/core_plugins/console/server/__tests__/elasticsearch_proxy_config.js b/src/legacy/core_plugins/console/server/__tests__/elasticsearch_proxy_config.js index 5d00e497ec2e6..45d8346936632 100644 --- a/src/legacy/core_plugins/console/server/__tests__/elasticsearch_proxy_config.js +++ b/src/legacy/core_plugins/console/server/__tests__/elasticsearch_proxy_config.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import moment from 'moment'; import fs from 'fs'; import { promisify } from 'bluebird'; diff --git a/src/legacy/core_plugins/console/server/__tests__/proxy_config.js b/src/legacy/core_plugins/console/server/__tests__/proxy_config.js index 79fbf444d07f1..dd6d9c4de7602 100644 --- a/src/legacy/core_plugins/console/server/__tests__/proxy_config.js +++ b/src/legacy/core_plugins/console/server/__tests__/proxy_config.js @@ -19,7 +19,7 @@ /* eslint-env mocha */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import fs from 'fs'; import https, { Agent as HttpsAgent } from 'https'; diff --git a/src/legacy/core_plugins/console/server/__tests__/proxy_config_collection.js b/src/legacy/core_plugins/console/server/__tests__/proxy_config_collection.js index 6b9878f06952e..91797f897d8ba 100644 --- a/src/legacy/core_plugins/console/server/__tests__/proxy_config_collection.js +++ b/src/legacy/core_plugins/console/server/__tests__/proxy_config_collection.js @@ -19,7 +19,7 @@ /* eslint-env mocha */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import fs from 'fs'; import { Agent as HttpsAgent } from 'https'; diff --git a/src/legacy/core_plugins/console/server/__tests__/proxy_route/body.js b/src/legacy/core_plugins/console/server/__tests__/proxy_route/body.js index 9dae2ec8047ff..5a8bcd9ef4144 100644 --- a/src/legacy/core_plugins/console/server/__tests__/proxy_route/body.js +++ b/src/legacy/core_plugins/console/server/__tests__/proxy_route/body.js @@ -19,7 +19,7 @@ import sinon from 'sinon'; import Wreck from 'wreck'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { Server } from 'hapi'; import { createProxyRoute } from '../../'; diff --git a/src/legacy/core_plugins/console/server/__tests__/proxy_route/headers.js b/src/legacy/core_plugins/console/server/__tests__/proxy_route/headers.js index 2d3ddf11e020f..a7fbd57c16d6e 100644 --- a/src/legacy/core_plugins/console/server/__tests__/proxy_route/headers.js +++ b/src/legacy/core_plugins/console/server/__tests__/proxy_route/headers.js @@ -21,7 +21,7 @@ import { request } from 'http'; import sinon from 'sinon'; import Wreck from 'wreck'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { Server } from 'hapi'; import { createProxyRoute } from '../../'; diff --git a/src/legacy/core_plugins/console/server/__tests__/proxy_route/params.js b/src/legacy/core_plugins/console/server/__tests__/proxy_route/params.js index 4ceccc8855d6a..c85b30ed7f6fe 100644 --- a/src/legacy/core_plugins/console/server/__tests__/proxy_route/params.js +++ b/src/legacy/core_plugins/console/server/__tests__/proxy_route/params.js @@ -21,7 +21,7 @@ import { Agent } from 'http'; import sinon from 'sinon'; import Wreck from 'wreck'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { Server } from 'hapi'; import { createProxyRoute } from '../../'; diff --git a/src/legacy/core_plugins/console/server/__tests__/proxy_route/query_string.js b/src/legacy/core_plugins/console/server/__tests__/proxy_route/query_string.js index c5b44cf39713d..8c3fc145181e3 100644 --- a/src/legacy/core_plugins/console/server/__tests__/proxy_route/query_string.js +++ b/src/legacy/core_plugins/console/server/__tests__/proxy_route/query_string.js @@ -19,7 +19,7 @@ import sinon from 'sinon'; import Wreck from 'wreck'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { Server } from 'hapi'; import { createProxyRoute } from '../../'; diff --git a/src/legacy/core_plugins/console/server/__tests__/set_headers.js b/src/legacy/core_plugins/console/server/__tests__/set_headers.js index 0bbfe8d443cf9..a270cca1e586e 100644 --- a/src/legacy/core_plugins/console/server/__tests__/set_headers.js +++ b/src/legacy/core_plugins/console/server/__tests__/set_headers.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { setHeaders } from '../set_headers'; describe('#set_headers', function () { diff --git a/src/legacy/core_plugins/elasticsearch/index.js b/src/legacy/core_plugins/elasticsearch/index.js index 6abeceb300a0e..8dc9c77e79d99 100644 --- a/src/legacy/core_plugins/elasticsearch/index.js +++ b/src/legacy/core_plugins/elasticsearch/index.js @@ -36,9 +36,9 @@ export default function (kibana) { // value from all observables here to be able to synchronously return and create // cluster clients afterwards. const [esConfig, adminCluster, dataCluster] = await combineLatest( - server.newPlatform.start.core.elasticsearch.legacy.config$, - server.newPlatform.start.core.elasticsearch.adminClient$, - server.newPlatform.start.core.elasticsearch.dataClient$ + server.newPlatform.setup.core.elasticsearch.legacy.config$, + server.newPlatform.setup.core.elasticsearch.adminClient$, + server.newPlatform.setup.core.elasticsearch.dataClient$ ).pipe( first(), map(([config, adminClusterClient, dataClusterClient]) => [ @@ -80,7 +80,7 @@ export default function (kibana) { // We fill all the missing properties in the `clientConfig` using the default // Elasticsearch config so that we don't depend on default values set and // controlled by underlying Elasticsearch JS client. - const cluster = new Cluster(server.newPlatform.start.core.elasticsearch.createClient(name, { + const cluster = new Cluster(server.newPlatform.setup.core.elasticsearch.createClient(name, { ...esConfig, ...clientConfig, })); diff --git a/src/legacy/core_plugins/elasticsearch/lib/__tests__/ensure_es_version.js b/src/legacy/core_plugins/elasticsearch/lib/__tests__/ensure_es_version.js index 24df2f9c5f893..c82e4418f4d85 100644 --- a/src/legacy/core_plugins/elasticsearch/lib/__tests__/ensure_es_version.js +++ b/src/legacy/core_plugins/elasticsearch/lib/__tests__/ensure_es_version.js @@ -20,7 +20,7 @@ import _ from 'lodash'; import Promise from 'bluebird'; import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { esTestConfig } from '@kbn/test'; import { ensureEsVersion } from '../ensure_es_version'; diff --git a/src/legacy/core_plugins/elasticsearch/lib/__tests__/health_check.js b/src/legacy/core_plugins/elasticsearch/lib/__tests__/health_check.js index 0c588b98e9a70..cae3734eca0de 100644 --- a/src/legacy/core_plugins/elasticsearch/lib/__tests__/health_check.js +++ b/src/legacy/core_plugins/elasticsearch/lib/__tests__/health_check.js @@ -19,7 +19,7 @@ import Promise from 'bluebird'; import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; const NoConnections = require('elasticsearch').errors.NoConnections; diff --git a/src/legacy/core_plugins/elasticsearch/lib/__tests__/is_es_compatible_with_kibana.js b/src/legacy/core_plugins/elasticsearch/lib/__tests__/is_es_compatible_with_kibana.js index 5b7cfd372b191..092c0ecf1071c 100644 --- a/src/legacy/core_plugins/elasticsearch/lib/__tests__/is_es_compatible_with_kibana.js +++ b/src/legacy/core_plugins/elasticsearch/lib/__tests__/is_es_compatible_with_kibana.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import isEsCompatibleWithKibana from '../is_es_compatible_with_kibana'; diff --git a/src/legacy/core_plugins/input_control_vis/index.js b/src/legacy/core_plugins/input_control_vis/index.js index b6e18cf0f7e31..e9864aa8c394f 100644 --- a/src/legacy/core_plugins/input_control_vis/index.js +++ b/src/legacy/core_plugins/input_control_vis/index.js @@ -25,6 +25,7 @@ export default function (kibana) { visTypes: [ 'plugins/input_control_vis/register_vis' ], + interpreter: ['plugins/input_control_vis/input_control_fn'], styleSheetPaths: resolve(__dirname, 'public/index.scss'), } }); diff --git a/src/legacy/core_plugins/interpreter/public/functions/__snapshots__/input_control.test.js.snap b/src/legacy/core_plugins/input_control_vis/public/__snapshots__/input_control_fn.test.js.snap similarity index 100% rename from src/legacy/core_plugins/interpreter/public/functions/__snapshots__/input_control.test.js.snap rename to src/legacy/core_plugins/input_control_vis/public/__snapshots__/input_control_fn.test.js.snap diff --git a/src/legacy/core_plugins/input_control_vis/public/control/control.test.js b/src/legacy/core_plugins/input_control_vis/public/control/control.test.js index 366a662e989e5..9fdd79df507a4 100644 --- a/src/legacy/core_plugins/input_control_vis/public/control/control.test.js +++ b/src/legacy/core_plugins/input_control_vis/public/control/control.test.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { Control } from './control'; function createControlParams(id, label) { diff --git a/src/legacy/core_plugins/input_control_vis/public/control/filter_manager/filter_manager.test.js b/src/legacy/core_plugins/input_control_vis/public/control/filter_manager/filter_manager.test.js index 49ac5d6700330..61d07e8fd179b 100644 --- a/src/legacy/core_plugins/input_control_vis/public/control/filter_manager/filter_manager.test.js +++ b/src/legacy/core_plugins/input_control_vis/public/control/filter_manager/filter_manager.test.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { FilterManager } from './filter_manager'; describe('FilterManager', function () { diff --git a/src/legacy/core_plugins/input_control_vis/public/control/filter_manager/phrase_filter_manager.test.js b/src/legacy/core_plugins/input_control_vis/public/control/filter_manager/phrase_filter_manager.test.js index 76519e0f58edc..28bebb59c4fed 100644 --- a/src/legacy/core_plugins/input_control_vis/public/control/filter_manager/phrase_filter_manager.test.js +++ b/src/legacy/core_plugins/input_control_vis/public/control/filter_manager/phrase_filter_manager.test.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { PhraseFilterManager } from './phrase_filter_manager'; describe('PhraseFilterManager', function () { diff --git a/src/legacy/core_plugins/input_control_vis/public/control/filter_manager/range_filter_manager.test.js b/src/legacy/core_plugins/input_control_vis/public/control/filter_manager/range_filter_manager.test.js index be700ad72ab42..b7f88f495d578 100644 --- a/src/legacy/core_plugins/input_control_vis/public/control/filter_manager/range_filter_manager.test.js +++ b/src/legacy/core_plugins/input_control_vis/public/control/filter_manager/range_filter_manager.test.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { RangeFilterManager } from './range_filter_manager'; describe('RangeFilterManager', function () { diff --git a/src/legacy/core_plugins/interpreter/public/functions/input_control.js b/src/legacy/core_plugins/input_control_vis/public/input_control_fn.js similarity index 88% rename from src/legacy/core_plugins/interpreter/public/functions/input_control.js rename to src/legacy/core_plugins/input_control_vis/public/input_control_fn.js index dce383516bae9..32769d8561f2a 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/input_control.js +++ b/src/legacy/core_plugins/input_control_vis/public/input_control_fn.js @@ -17,6 +17,7 @@ * under the License. */ +import { functionsRegistry } from 'plugins/interpreter/registries'; import { i18n } from '@kbn/i18n'; export const inputControlVis = () => ({ @@ -25,7 +26,7 @@ export const inputControlVis = () => ({ context: { types: [], }, - help: i18n.translate('interpreter.functions.input_control.help', { + help: i18n.translate('inputControl.function.help', { defaultMessage: 'Input control visualization' }), args: { @@ -46,3 +47,5 @@ export const inputControlVis = () => ({ }; } }); + +functionsRegistry.register(inputControlVis); diff --git a/src/legacy/core_plugins/interpreter/public/functions/input_control.test.js b/src/legacy/core_plugins/input_control_vis/public/input_control_fn.test.js similarity index 92% rename from src/legacy/core_plugins/interpreter/public/functions/input_control.test.js rename to src/legacy/core_plugins/input_control_vis/public/input_control_fn.test.js index 6fcc007716ff8..60d9956ec1261 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/input_control.test.js +++ b/src/legacy/core_plugins/input_control_vis/public/input_control_fn.test.js @@ -17,8 +17,8 @@ * under the License. */ -import { functionWrapper } from '../../test_helpers'; -import { inputControlVis } from './input_control'; +import { functionWrapper } from '../../interpreter/test_helpers'; +import { inputControlVis } from './input_control_fn'; describe('interpreter/functions#input_control_vis', () => { const fn = functionWrapper(inputControlVis); diff --git a/src/legacy/core_plugins/input_control_vis/public/lineage/lineage_map.test.js b/src/legacy/core_plugins/input_control_vis/public/lineage/lineage_map.test.js index b001899144b54..0031503fc025d 100644 --- a/src/legacy/core_plugins/input_control_vis/public/lineage/lineage_map.test.js +++ b/src/legacy/core_plugins/input_control_vis/public/lineage/lineage_map.test.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getLineageMap } from './lineage_map'; import { CONTROL_TYPES, diff --git a/src/legacy/core_plugins/input_control_vis/public/lineage/parent_candidates.test.js b/src/legacy/core_plugins/input_control_vis/public/lineage/parent_candidates.test.js index 8ffe819ca5942..50dea30541a9d 100644 --- a/src/legacy/core_plugins/input_control_vis/public/lineage/parent_candidates.test.js +++ b/src/legacy/core_plugins/input_control_vis/public/lineage/parent_candidates.test.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getLineageMap } from './lineage_map'; import { getParentCandidates } from './parent_candidates'; import { diff --git a/src/legacy/core_plugins/inspector_views/public/data/__snapshots__/data_view.test.js.snap b/src/legacy/core_plugins/inspector_views/public/data/__snapshots__/data_view.test.js.snap index fdd47c581b7f5..522a12b4ec84f 100644 --- a/src/legacy/core_plugins/inspector_views/public/data/__snapshots__/data_view.test.js.snap +++ b/src/legacy/core_plugins/inspector_views/public/data/__snapshots__/data_view.test.js.snap @@ -222,6 +222,8 @@ exports[`Inspector Data View component should render loading state 1`] = ` }, "_eventsCount": 1, "_maxListeners": undefined, + "tabular": undefined, + "tabularOptions": undefined, }, } } diff --git a/src/legacy/core_plugins/interpreter/common/types/register.js b/src/legacy/core_plugins/interpreter/common/types/register.js index 17b03f0229672..582843c91f83b 100644 --- a/src/legacy/core_plugins/interpreter/common/types/register.js +++ b/src/legacy/core_plugins/interpreter/common/types/register.js @@ -17,7 +17,7 @@ * under the License. */ -import 'babel-polyfill'; +import '@babel/polyfill'; import { typeSpecs } from './index'; // eslint-disable-next-line no-undef diff --git a/src/legacy/core_plugins/interpreter/public/functions/index.js b/src/legacy/core_plugins/interpreter/public/functions/index.js index 307b67f68b57c..e7d658821633f 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/index.js +++ b/src/legacy/core_plugins/interpreter/public/functions/index.js @@ -21,21 +21,8 @@ import { clog } from './clog'; import { esaggs } from './esaggs'; import { kibana } from './kibana'; import { kibanaContext } from './kibana_context'; -import { vega } from './vega'; -import { timelionVis } from './timelion_vis'; -import { tsvb } from './tsvb'; -import { kibanaMarkdown } from './markdown'; -import { inputControlVis } from './input_control'; -import { metric } from './metric'; -import { kibanaPie } from './pie'; -import { regionmap } from './regionmap'; -import { tilemap } from './tilemap'; -import { kibanaTable } from './table'; -import { tagcloud } from './tagcloud'; -import { vislib } from './vislib'; import { visualization } from './visualization'; export const functions = [ - clog, esaggs, kibana, kibanaContext, vega, timelionVis, tsvb, kibanaMarkdown, inputControlVis, - metric, kibanaPie, regionmap, tilemap, kibanaTable, tagcloud, vislib, visualization + clog, esaggs, kibana, kibanaContext, visualization ]; diff --git a/src/legacy/core_plugins/interpreter/server/lib/__tests__/create_handlers.js b/src/legacy/core_plugins/interpreter/server/lib/__tests__/create_handlers.js index 948ec7369d631..a6e0e13049e1c 100644 --- a/src/legacy/core_plugins/interpreter/server/lib/__tests__/create_handlers.js +++ b/src/legacy/core_plugins/interpreter/server/lib/__tests__/create_handlers.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { createHandlers } from '../create_handlers'; const mockRequest = { diff --git a/src/legacy/core_plugins/kbn_doc_views/public/__tests__/doc_views.js b/src/legacy/core_plugins/kbn_doc_views/public/__tests__/doc_views.js index e14974c09838f..4bd41bfa3968e 100644 --- a/src/legacy/core_plugins/kbn_doc_views/public/__tests__/doc_views.js +++ b/src/legacy/core_plugins/kbn_doc_views/public/__tests__/doc_views.js @@ -20,7 +20,7 @@ import angular from 'angular'; import _ from 'lodash'; import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import 'ui/render_directive'; import '../views/table'; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/index.js b/src/legacy/core_plugins/kbn_vislib_vis_types/index.js index f8467326ac8f0..abd8b8a3f6b5b 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/index.js +++ b/src/legacy/core_plugins/kbn_vislib_vis_types/index.js @@ -24,6 +24,10 @@ export default function (kibana) { uiExports: { visTypes: [ 'plugins/kbn_vislib_vis_types/kbn_vislib_vis_types' + ], + interpreter: [ + 'plugins/kbn_vislib_vis_types/pie_fn', + 'plugins/kbn_vislib_vis_types/vislib_fn', ] } diff --git a/src/legacy/core_plugins/interpreter/public/functions/__snapshots__/pie.test.js.snap b/src/legacy/core_plugins/kbn_vislib_vis_types/public/__snapshots__/pie_fn.test.js.snap similarity index 100% rename from src/legacy/core_plugins/interpreter/public/functions/__snapshots__/pie.test.js.snap rename to src/legacy/core_plugins/kbn_vislib_vis_types/public/__snapshots__/pie_fn.test.js.snap diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/controls/gauge_options.html b/src/legacy/core_plugins/kbn_vislib_vis_types/public/controls/gauge_options.html index d22a34cfad1ee..9d29f390ac358 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/controls/gauge_options.html +++ b/src/legacy/core_plugins/kbn_vislib_vis_types/public/controls/gauge_options.html @@ -173,7 +173,7 @@ type="number" class="form-control" name="range.from" - greater-or-equal-than="{{getGreaterThan($index)}}" + greater-or-equal-than="getGreaterThan($index)" required step="any" /> @@ -184,7 +184,7 @@ type="number" class="form-control" name="range.to" - greater-or-equal-than="{{range.from}}" + greater-or-equal-than="range.from" required step="any" /> diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/controls/gauge_options.js b/src/legacy/core_plugins/kbn_vislib_vis_types/public/controls/gauge_options.js index 7da9d16b7f74a..b036741291eb5 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/controls/gauge_options.js +++ b/src/legacy/core_plugins/kbn_vislib_vis_types/public/controls/gauge_options.js @@ -81,7 +81,7 @@ module.directive('gaugeOptions', function (i18n) { }; $scope.getGreaterThan = function (index) { - if (index === 0) return 0; + if (index === 0) return -Infinity; return $scope.editorState.params.gauge.colorsRange[index - 1].to; }; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/controls/heatmap_options.html b/src/legacy/core_plugins/kbn_vislib_vis_types/public/controls/heatmap_options.html index 7a56e2ce8f0ef..0eaa3477bbb11 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/controls/heatmap_options.html +++ b/src/legacy/core_plugins/kbn_vislib_vis_types/public/controls/heatmap_options.html @@ -161,7 +161,7 @@ type="number" class="form-control" name="range.from" - greater-or-equal-than="{{getGreaterThan($index)}}" + greater-or-equal-than="getGreaterThan($index)" step="any" /> diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/controls/heatmap_options.js b/src/legacy/core_plugins/kbn_vislib_vis_types/public/controls/heatmap_options.js index a96a27cb4b71e..6a4839abb5354 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/controls/heatmap_options.js +++ b/src/legacy/core_plugins/kbn_vislib_vis_types/public/controls/heatmap_options.js @@ -64,7 +64,7 @@ module.directive('heatmapOptions', function (i18n) { }; $scope.getGreaterThan = function (index) { - if (index === 0) return; + if (index === 0) return -Infinity; return $scope.editorState.params.colorsRange[index - 1].to; }; diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/controls/point_series/value_axes.html b/src/legacy/core_plugins/kbn_vislib_vis_types/public/controls/point_series/value_axes.html index fb62021a51c93..5fb086585a244 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/controls/point_series/value_axes.html +++ b/src/legacy/core_plugins/kbn_vislib_vis_types/public/controls/point_series/value_axes.html @@ -284,6 +284,7 @@ class="kuiInput visEditorSidebar__input" type="number" step="0.1" + greater-than="axis.scale.min" ng-model="axis.scale.max" > @@ -301,7 +302,8 @@ class="kuiInput visEditorSidebar__input" type="number" step="0.1" - greater-than="{{axis.scale.type === 'log' ? 0 : ''}}" + greater-than="axis.scale.type === 'log' ? 0 : undefined" + less-than="axis.scale.max" ng-model="axis.scale.min" > diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/controls/point_series_options.html b/src/legacy/core_plugins/kbn_vislib_vis_types/public/controls/point_series_options.html index ff4d30837c8de..b4ebf8ebbd481 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/controls/point_series_options.html +++ b/src/legacy/core_plugins/kbn_vislib_vis_types/public/controls/point_series_options.html @@ -17,7 +17,7 @@ class="form-control" type="number" step="0.1" - greater-than="{{editorState.params.yAxis.min}}" + greater-than="editorState.params.yAxis.min" ng-model="editorState.params.yAxis.max" ng-required="editorState.params.setYExtents"> @@ -30,8 +30,8 @@ class="form-control" type="number" step="0.1" - less-than="{{editorState.params.yAxis.max}}" - greater-than="{{editorState.params.scale === 'log' ? 0 : ''}}" + less-than="editorState.params.yAxis.max" + greater-than="editorState.params.scale === 'log' ? 0 : undefined" ng-model="editorState.params.yAxis.min" ng-required="editorState.params.setYExtents"> diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/editors/__tests__/point_series.js b/src/legacy/core_plugins/kbn_vislib_vis_types/public/editors/__tests__/point_series.js index be20e8952492e..0a9c304777d21 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/editors/__tests__/point_series.js +++ b/src/legacy/core_plugins/kbn_vislib_vis_types/public/editors/__tests__/point_series.js @@ -19,7 +19,7 @@ import angular from 'angular'; import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import $ from 'jquery'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; diff --git a/src/legacy/core_plugins/interpreter/public/functions/pie.js b/src/legacy/core_plugins/kbn_vislib_vis_types/public/pie_fn.js similarity index 90% rename from src/legacy/core_plugins/interpreter/public/functions/pie.js rename to src/legacy/core_plugins/kbn_vislib_vis_types/public/pie_fn.js index e005a41574aea..b47a9c4b7c569 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/pie.js +++ b/src/legacy/core_plugins/kbn_vislib_vis_types/public/pie_fn.js @@ -17,6 +17,7 @@ * under the License. */ +import { functionsRegistry } from 'plugins/interpreter/registries'; import { VislibSlicesResponseHandlerProvider as vislibSlicesResponseHandler } from 'ui/vis/response_handlers/vislib'; import { i18n } from '@kbn/i18n'; @@ -28,7 +29,7 @@ export const kibanaPie = () => ({ 'kibana_datatable' ], }, - help: i18n.translate('interpreter.functions.pie.help', { + help: i18n.translate('kbnVislibVisTypes.functions.pie.help', { defaultMessage: 'Pie visualization' }), args: { @@ -57,3 +58,5 @@ export const kibanaPie = () => ({ }; }, }); + +functionsRegistry.register(kibanaPie); diff --git a/src/legacy/core_plugins/interpreter/public/functions/pie.test.js b/src/legacy/core_plugins/kbn_vislib_vis_types/public/pie_fn.test.js similarity index 95% rename from src/legacy/core_plugins/interpreter/public/functions/pie.test.js rename to src/legacy/core_plugins/kbn_vislib_vis_types/public/pie_fn.test.js index c0356de986f24..8d9c79961919f 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/pie.test.js +++ b/src/legacy/core_plugins/kbn_vislib_vis_types/public/pie_fn.test.js @@ -17,8 +17,8 @@ * under the License. */ -import { functionWrapper } from '../../test_helpers'; -import { kibanaPie } from './pie'; +import { functionWrapper } from '../../interpreter/test_helpers'; +import { kibanaPie } from './pie_fn'; const mockResponseHandler = jest.fn().mockReturnValue(Promise.resolve({ hits: 1, diff --git a/src/legacy/core_plugins/interpreter/public/functions/vislib.js b/src/legacy/core_plugins/kbn_vislib_vis_types/public/vislib_fn.js similarity index 91% rename from src/legacy/core_plugins/interpreter/public/functions/vislib.js rename to src/legacy/core_plugins/kbn_vislib_vis_types/public/vislib_fn.js index 5ce07c0ee534f..4eac35b759e0b 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/vislib.js +++ b/src/legacy/core_plugins/kbn_vislib_vis_types/public/vislib_fn.js @@ -17,6 +17,7 @@ * under the License. */ +import { functionsRegistry } from 'plugins/interpreter/registries'; import { i18n } from '@kbn/i18n'; import { VislibSeriesResponseHandlerProvider } from 'ui/vis/response_handlers/vislib'; import chrome from 'ui/chrome'; @@ -29,7 +30,7 @@ export const vislib = () => ({ 'kibana_datatable' ], }, - help: i18n.translate('interpreter.functions.vislib.help', { + help: i18n.translate('kbnVislibVisTypes.functions.vislib.help', { defaultMessage: 'Vislib visualization' }), args: { @@ -60,3 +61,5 @@ export const vislib = () => ({ }; }, }); + +functionsRegistry.register(vislib); diff --git a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/boolean.js b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/boolean.js index a96409bbce44e..e81381462386c 100644 --- a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/boolean.js +++ b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/boolean.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { createBoolFormat } from '../boolean'; import { FieldFormat } from '../../../../../../ui/field_formats/field_format'; diff --git a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/bytes.js b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/bytes.js index f0ece59128e04..58e69c468d503 100644 --- a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/bytes.js +++ b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/bytes.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { createBytesFormat } from '../bytes'; import { FieldFormat } from '../../../../../../ui/field_formats/field_format'; diff --git a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/color.js b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/color.js index e00c4c9cb455c..52b00c303445d 100644 --- a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/color.js +++ b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/color.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { createColorFormat } from '../color'; import { FieldFormat } from '../../../../../../ui/field_formats/field_format'; diff --git a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/date.js b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/date.js index 45748d0860456..bab2358d3c182 100644 --- a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/date.js +++ b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/date.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import moment from 'moment-timezone'; import { createDateFormat } from '../date'; import { FieldFormat } from '../../../../../../ui/field_formats/field_format'; diff --git a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/duration.js b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/duration.js index 620668fa94161..1c2fcae2e9de0 100644 --- a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/duration.js +++ b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/duration.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { createDurationFormat } from '../duration'; import { FieldFormat } from '../../../../../../ui/field_formats/field_format'; diff --git a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/ip.js b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/ip.js index ff3af3b2e3018..3223c45411c31 100644 --- a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/ip.js +++ b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/ip.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { createIpFormat } from '../ip'; import { FieldFormat } from '../../../../../../ui/field_formats/field_format'; diff --git a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/number.js b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/number.js index 100f035ac7d44..e6f72946e4267 100644 --- a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/number.js +++ b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/number.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { createNumberFormat } from '../number'; import { FieldFormat } from '../../../../../../ui/field_formats/field_format'; diff --git a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/percent.js b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/percent.js index ad2ba502d6052..0b0aecc8f87a0 100644 --- a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/percent.js +++ b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/percent.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { createPercentFormat } from '../percent'; import { FieldFormat } from '../../../../../../ui/field_formats/field_format'; diff --git a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/relative_date.js b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/relative_date.js index 551da872c77ff..7cde856542488 100644 --- a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/relative_date.js +++ b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/relative_date.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import moment from 'moment-timezone'; import { createRelativeDateFormat } from '../relative_date'; import { FieldFormat } from '../../../../../../ui/field_formats/field_format'; diff --git a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/string.js b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/string.js index 74fb0e1f886b6..04c0b9a045d38 100644 --- a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/string.js +++ b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/string.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { createStringFormat } from '../string'; import { FieldFormat } from '../../../../../../ui/field_formats/field_format'; diff --git a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/truncate.js b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/truncate.js index ca52dfd01000c..ed0f1bb5fdb06 100644 --- a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/truncate.js +++ b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/truncate.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { createTruncateFormat } from '../truncate'; import { FieldFormat } from '../../../../../../ui/field_formats/field_format'; diff --git a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/url.js b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/url.js index 45fc4ed3dae12..16895d9e25a8d 100644 --- a/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/url.js +++ b/src/legacy/core_plugins/kibana/common/field_formats/types/__tests__/url.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { createUrlFormat } from '../url'; import { FieldFormat } from '../../../../../../ui/field_formats/field_format'; diff --git a/src/legacy/core_plugins/kibana/common/highlight/__tests__/highlight_html.js b/src/legacy/core_plugins/kibana/common/highlight/__tests__/highlight_html.js index 58daae53cf78f..0fdec31ec0d00 100644 --- a/src/legacy/core_plugins/kibana/common/highlight/__tests__/highlight_html.js +++ b/src/legacy/core_plugins/kibana/common/highlight/__tests__/highlight_html.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { highlightTags } from '../highlight_tags'; import { htmlTags } from '../html_tags'; import { getHighlightHtml } from '../highlight_html'; diff --git a/src/legacy/core_plugins/kibana/common/highlight/__tests__/highlight_request.js b/src/legacy/core_plugins/kibana/common/highlight/__tests__/highlight_request.js index af81979a54774..f7015ee333f6c 100644 --- a/src/legacy/core_plugins/kibana/common/highlight/__tests__/highlight_request.js +++ b/src/legacy/core_plugins/kibana/common/highlight/__tests__/highlight_request.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getHighlightRequest } from '../highlight_request'; describe('getHighlightRequest', () => { diff --git a/src/legacy/core_plugins/kibana/common/lib/__tests__/convert_pattern_and_ingest_name.js b/src/legacy/core_plugins/kibana/common/lib/__tests__/convert_pattern_and_ingest_name.js index 65a3a94935332..d130aa1809507 100644 --- a/src/legacy/core_plugins/kibana/common/lib/__tests__/convert_pattern_and_ingest_name.js +++ b/src/legacy/core_plugins/kibana/common/lib/__tests__/convert_pattern_and_ingest_name.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { patternToIngest, ingestToPattern } from '../convert_pattern_and_ingest_name'; describe('convertPatternAndTemplateName', function () { diff --git a/src/legacy/core_plugins/kibana/common/utils/__tests__/as_pretty_string.js b/src/legacy/core_plugins/kibana/common/utils/__tests__/as_pretty_string.js index 72a41b3a3f856..723b3ccf0c596 100644 --- a/src/legacy/core_plugins/kibana/common/utils/__tests__/as_pretty_string.js +++ b/src/legacy/core_plugins/kibana/common/utils/__tests__/as_pretty_string.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { asPrettyString } from '../as_pretty_string'; describe('asPrettyString', () => { diff --git a/src/legacy/core_plugins/kibana/common/utils/__tests__/shorten_dotted_string.js b/src/legacy/core_plugins/kibana/common/utils/__tests__/shorten_dotted_string.js index e2915fcc12499..e47c08800d8e6 100644 --- a/src/legacy/core_plugins/kibana/common/utils/__tests__/shorten_dotted_string.js +++ b/src/legacy/core_plugins/kibana/common/utils/__tests__/shorten_dotted_string.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { shortenDottedString } from '../shorten_dotted_string'; describe('shortenDottedString', () => { diff --git a/src/legacy/core_plugins/kibana/public/.eslintrc b/src/legacy/core_plugins/kibana/public/.eslintrc index bc1b9bbdf4949..95e3757201989 100644 --- a/src/legacy/core_plugins/kibana/public/.eslintrc +++ b/src/legacy/core_plugins/kibana/public/.eslintrc @@ -1,7 +1,3 @@ - -plugins: [ - '@elastic/eslint-plugin-kibana-custom' -] rules: no-console: 2 - '@elastic/kibana-custom/no-default-export': error + '@kbn/eslint/no-default-export': error diff --git a/src/legacy/core_plugins/kibana/public/context/api/__tests__/anchor.js b/src/legacy/core_plugins/kibana/public/context/api/__tests__/anchor.js index 598cebf4c546b..9af9d8032fb27 100644 --- a/src/legacy/core_plugins/kibana/public/context/api/__tests__/anchor.js +++ b/src/legacy/core_plugins/kibana/public/context/api/__tests__/anchor.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import sinon from 'sinon'; diff --git a/src/legacy/core_plugins/kibana/public/context/api/__tests__/predecessors.js b/src/legacy/core_plugins/kibana/public/context/api/__tests__/predecessors.js index 698053eb93b67..63bd9987bc7e6 100644 --- a/src/legacy/core_plugins/kibana/public/context/api/__tests__/predecessors.js +++ b/src/legacy/core_plugins/kibana/public/context/api/__tests__/predecessors.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import moment from 'moment'; import * as _ from 'lodash'; diff --git a/src/legacy/core_plugins/kibana/public/context/api/__tests__/successors.js b/src/legacy/core_plugins/kibana/public/context/api/__tests__/successors.js index 14330a4d38775..ba6b0071865bc 100644 --- a/src/legacy/core_plugins/kibana/public/context/api/__tests__/successors.js +++ b/src/legacy/core_plugins/kibana/public/context/api/__tests__/successors.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import moment from 'moment'; import * as _ from 'lodash'; diff --git a/src/legacy/core_plugins/kibana/public/context/api/utils/__tests__/sorting.js b/src/legacy/core_plugins/kibana/public/context/api/utils/__tests__/sorting.js index bf221c6711d1b..bfea37088c875 100644 --- a/src/legacy/core_plugins/kibana/public/context/api/utils/__tests__/sorting.js +++ b/src/legacy/core_plugins/kibana/public/context/api/utils/__tests__/sorting.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { reverseSortDirection, diff --git a/src/legacy/core_plugins/kibana/public/context/index.js b/src/legacy/core_plugins/kibana/public/context/index.js index 2de49cde48c88..d1908be4bea7d 100644 --- a/src/legacy/core_plugins/kibana/public/context/index.js +++ b/src/legacy/core_plugins/kibana/public/context/index.js @@ -20,6 +20,7 @@ import _ from 'lodash'; import { FilterBarQueryFilterProvider } from 'ui/filter_bar/query_filter'; +import 'ui/listen'; import uiRoutes from 'ui/routes'; import { i18n } from '@kbn/i18n'; diff --git a/src/legacy/core_plugins/kibana/public/context/query_parameters/__tests__/action_add_filter.js b/src/legacy/core_plugins/kibana/public/context/query_parameters/__tests__/action_add_filter.js index bfa0206fa7645..e616fab9c0c2f 100644 --- a/src/legacy/core_plugins/kibana/public/context/query_parameters/__tests__/action_add_filter.js +++ b/src/legacy/core_plugins/kibana/public/context/query_parameters/__tests__/action_add_filter.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import sinon from 'sinon'; diff --git a/src/legacy/core_plugins/kibana/public/context/query_parameters/__tests__/action_increase_predecessor_count.js b/src/legacy/core_plugins/kibana/public/context/query_parameters/__tests__/action_increase_predecessor_count.js index a89279e4d2cec..156264cd98563 100644 --- a/src/legacy/core_plugins/kibana/public/context/query_parameters/__tests__/action_increase_predecessor_count.js +++ b/src/legacy/core_plugins/kibana/public/context/query_parameters/__tests__/action_increase_predecessor_count.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { FilterManagerProvider } from 'ui/filter_manager'; diff --git a/src/legacy/core_plugins/kibana/public/context/query_parameters/__tests__/action_increase_successor_count.js b/src/legacy/core_plugins/kibana/public/context/query_parameters/__tests__/action_increase_successor_count.js index ec8799473f595..f4eb82d217c98 100644 --- a/src/legacy/core_plugins/kibana/public/context/query_parameters/__tests__/action_increase_successor_count.js +++ b/src/legacy/core_plugins/kibana/public/context/query_parameters/__tests__/action_increase_successor_count.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { FilterManagerProvider } from 'ui/filter_manager'; diff --git a/src/legacy/core_plugins/kibana/public/context/query_parameters/__tests__/action_set_predecessor_count.js b/src/legacy/core_plugins/kibana/public/context/query_parameters/__tests__/action_set_predecessor_count.js index d542adedcc4ce..0aa1f640f266d 100644 --- a/src/legacy/core_plugins/kibana/public/context/query_parameters/__tests__/action_set_predecessor_count.js +++ b/src/legacy/core_plugins/kibana/public/context/query_parameters/__tests__/action_set_predecessor_count.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { FilterManagerProvider } from 'ui/filter_manager'; diff --git a/src/legacy/core_plugins/kibana/public/context/query_parameters/__tests__/action_set_query_parameters.js b/src/legacy/core_plugins/kibana/public/context/query_parameters/__tests__/action_set_query_parameters.js index fb04b5414c7b8..6a3638bc9f554 100644 --- a/src/legacy/core_plugins/kibana/public/context/query_parameters/__tests__/action_set_query_parameters.js +++ b/src/legacy/core_plugins/kibana/public/context/query_parameters/__tests__/action_set_query_parameters.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { FilterManagerProvider } from 'ui/filter_manager'; diff --git a/src/legacy/core_plugins/kibana/public/context/query_parameters/__tests__/action_set_successor_count.js b/src/legacy/core_plugins/kibana/public/context/query_parameters/__tests__/action_set_successor_count.js index 93a388a6d6639..f4e85eefe1e6f 100644 --- a/src/legacy/core_plugins/kibana/public/context/query_parameters/__tests__/action_set_successor_count.js +++ b/src/legacy/core_plugins/kibana/public/context/query_parameters/__tests__/action_set_successor_count.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { FilterManagerProvider } from 'ui/filter_manager'; diff --git a/src/legacy/core_plugins/kibana/public/dashboard/__tests__/saved_dashboards.js b/src/legacy/core_plugins/kibana/public/dashboard/__tests__/saved_dashboards.js index 9656232031ea7..d5732a5a6cc4e 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/__tests__/saved_dashboards.js +++ b/src/legacy/core_plugins/kibana/public/dashboard/__tests__/saved_dashboards.js @@ -18,7 +18,7 @@ */ import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; describe('SavedDashboards Service', function () { let savedDashboardLoader; diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js index 5539d95c56c85..3a38a1c9c0d1d 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js +++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.js @@ -25,6 +25,7 @@ import chrome from 'ui/chrome'; import { wrapInI18nContext } from 'ui/i18n'; import { toastNotifications } from 'ui/notify'; +import 'ui/listen'; import 'ui/search_bar'; import 'ui/apply_filters'; diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_state_manager.js b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_state_manager.js index b40dfd4f08bf0..e5d43c8de94b9 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_state_manager.js +++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_state_manager.js @@ -290,7 +290,7 @@ export class DashboardStateManager { * Resets the state back to the last saved version of the dashboard. */ resetState() { - // In order to show the correct warning for the saved-object-save-as-check-box we have to store the unsaved + // In order to show the correct warning, we have to store the unsaved // title on the dashboard object. We should fix this at some point, but this is how all the other object // save panels work at the moment. this.savedDashboard.title = this.savedDashboard.lastSavedTitle; @@ -341,9 +341,6 @@ export class DashboardStateManager { setTitle(title) { this.appState.title = title; - // The saved-object-save-as-check-box shows a warning if the current object title is different then - // the existing object title. It calculates this difference by comparing this.dashboard.title to - // this.dashboard.lastSavedTitle, so we need to push the temporary, unsaved title, onto the dashboard. this.savedDashboard.title = title; this.saveState(); } diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_strings.js b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_strings.ts similarity index 92% rename from src/legacy/core_plugins/kibana/public/dashboard/dashboard_strings.js rename to src/legacy/core_plugins/kibana/public/dashboard/dashboard_strings.ts index a0d2af3e9c00a..3ea7cf593687c 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_strings.js +++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_strings.ts @@ -27,9 +27,13 @@ import { DashboardViewMode } from './dashboard_view_mode'; * end of the title. * @returns {string} A title to display to the user based on the above parameters. */ -export function getDashboardTitle(title, viewMode, isDirty) { +export function getDashboardTitle( + title: string, + viewMode: DashboardViewMode, + isDirty: boolean +): string { const isEditMode = viewMode === DashboardViewMode.EDIT; - let displayTitle; + let displayTitle: string; if (isEditMode && isDirty) { displayTitle = i18n.translate('kbn.dashboard.strings.dashboardUnsavedEditTitle', { diff --git a/src/legacy/core_plugins/kibana/public/dashboard/grid/dashboard_grid.test.js b/src/legacy/core_plugins/kibana/public/dashboard/grid/dashboard_grid.test.js index b71e83159d763..0d9b80763c136 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/grid/dashboard_grid.test.js +++ b/src/legacy/core_plugins/kibana/public/dashboard/grid/dashboard_grid.test.js @@ -88,6 +88,6 @@ test('adjusts z-index of focused panel to be higher than siblings', () => { const panelElements = component.find('Connect(InjectIntl(DashboardPanelUi))'); panelElements.first().prop('onPanelFocused')('1'); const [gridItem1, gridItem2] = component.update().findWhere(el => el.key() === '1' || el.key() === '2'); - expect(gridItem1.props.style.zIndex).toEqual('2'); + expect(gridItem1.props.style.zIndex).toEqual(2); expect(gridItem2.props.style.zIndex).toEqual('auto'); }); diff --git a/src/legacy/core_plugins/kibana/public/dashboard/grid/dashboard_grid.js b/src/legacy/core_plugins/kibana/public/dashboard/grid/dashboard_grid.tsx similarity index 67% rename from src/legacy/core_plugins/kibana/public/dashboard/grid/dashboard_grid.js rename to src/legacy/core_plugins/kibana/public/dashboard/grid/dashboard_grid.tsx index d90b597b1a0c0..bfbf3101c198e 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/grid/dashboard_grid.js +++ b/src/legacy/core_plugins/kibana/public/dashboard/grid/dashboard_grid.tsx @@ -17,27 +17,29 @@ * under the License. */ -import React from 'react'; -import PropTypes from 'prop-types'; import { injectI18n } from '@kbn/i18n/react'; -import _ from 'lodash'; -import ReactGridLayout from 'react-grid-layout'; import classNames from 'classnames'; +import _ from 'lodash'; +import React from 'react'; +import ReactGridLayout, { Layout } from 'react-grid-layout'; import 'react-grid-layout/css/styles.css'; import 'react-resizable/css/styles.css'; -import { PanelUtils } from '../panel/panel_utils'; -import { DashboardViewMode } from '../dashboard_view_mode'; -import { DashboardPanel } from '../panel'; +// @ts-ignore +import sizeMe from 'react-sizeme'; +import { EmbeddableFactory } from 'ui/embeddable'; import { toastNotifications } from 'ui/notify'; import { - DashboardConstants, DASHBOARD_GRID_COLUMN_COUNT, DASHBOARD_GRID_HEIGHT, + DashboardConstants, } from '../dashboard_constants'; -import sizeMe from 'react-sizeme'; +import { DashboardViewMode } from '../dashboard_view_mode'; +import { DashboardPanel } from '../panel'; +import { PanelUtils } from '../panel/panel_utils'; +import { PanelState, PanelStateMap, Pre61PanelState } from '../selectors/types'; +import { GridData } from '../types'; -const config = { monitorWidth: true }; let lastValidGridSize = 0; /** @@ -45,7 +47,7 @@ let lastValidGridSize = 0; * taller than the current grid. * see https://github.com/elastic/kibana/issues/14710. */ -function ensureWindowScrollsToBottom(layout, oldResizeItem, l, placeholder, event) { +function ensureWindowScrollsToBottom(event: { clientY: number; pageY: number }) { // The buffer is to handle the case where the browser is maximized and it's impossible for the mouse to move below // the screen, out of the window. see https://github.com/elastic/kibana/issues/14737 const WINDOW_BUFFER = 10; @@ -62,6 +64,14 @@ function ResponsiveGrid({ children, maximizedPanelId, useMargins, +}: { + size: { width: number }; + isViewMode: boolean; + layout: Layout[]; + onLayoutChange: () => void; + children: JSX.Element[]; + maximizedPanelId: string; + useMargins: boolean; }) { // This is to prevent a bug where view mode changes when the panel is expanded. View mode changes will trigger // the grid to re-render, but when a panel is expanded, the size will be 0. Minimizing the panel won't cause the @@ -94,8 +104,7 @@ function ResponsiveGrid({ draggableHandle={isViewMode ? '.doesnt-exist' : '.dshPanel__dragger'} layout={layout} onLayoutChange={onLayoutChange} - measureBeforeMount={false} - onResize={ensureWindowScrollsToBottom} + onResize={({}, {}, {}, {}, event) => ensureWindowScrollsToBottom(event)} > {children} @@ -104,15 +113,43 @@ function ResponsiveGrid({ // Using sizeMe sets up the grid to be re-rendered automatically not only when the window size changes, but also // when the container size changes, so it works for Full Screen mode switches. +const config = { monitorWidth: true }; const ResponsiveSizedGrid = sizeMe(config)(ResponsiveGrid); +interface Props extends ReactIntl.InjectedIntlProps { + panels: PanelStateMap; + getEmbeddableFactory: (panelType: string) => EmbeddableFactory; + dashboardViewMode: DashboardViewMode.EDIT | DashboardViewMode.VIEW; + onPanelsUpdated: (updatedPanels: PanelStateMap) => void; + maximizedPanelId?: string; + useMargins: boolean; +} -class DashboardGridUi extends React.Component { - constructor(props) { +interface State { + focusedPanelIndex?: string; + isLayoutInvalid: boolean; + layout?: GridData[]; +} + +interface PanelLayout extends Layout { + i: string; +} + +class DashboardGridUi extends React.Component { + // A mapping of panelIndexes to grid items so we can set the zIndex appropriately on the last focused + // item. + private gridItems = {} as { [key: string]: HTMLDivElement | null }; + + // A mapping of panel type to embeddable handlers. Because this function reaches out of react and into angular, + // if done in the render method, it appears to be triggering a scope.apply, which appears to be trigging a setState + // call inside TSVB visualizations. Moving the function out of render appears to fix the issue. See + // https://github.com/elastic/kibana/issues/14802 for more info. + // This is probably a better implementation anyway so the handlers are cached. + // @type {Object.} + private embeddableFactoryMap: { [s: string]: EmbeddableFactory } = {}; + + constructor(props: Props) { super(props); - // A mapping of panelIndexes to grid items so we can set the zIndex appropriately on the last focused - // item. - this.gridItems = {}; let isLayoutInvalid = false; let layout; @@ -127,41 +164,36 @@ class DashboardGridUi extends React.Component { }), text: error.message, }); - window.location = `#${DashboardConstants.LANDING_PAGE_PATH}`; + window.location.hash = DashboardConstants.LANDING_PAGE_PATH; } this.state = { focusedPanelIndex: undefined, layout, isLayoutInvalid, }; - - // A mapping of panel type to embeddable handlers. Because this function reaches out of react and into angular, - // if done in the render method, it appears to be triggering a scope.apply, which appears to be trigging a setState - // call inside TSVB visualizations. Moving the function out of render appears to fix the issue. See - // https://github.com/elastic/kibana/issues/14802 for more info. - // This is probably a better implementation anyway so the handlers are cached. - // @type {Object.} - this.embeddableFactoryMap = {}; } - buildLayoutFromPanels() { + public buildLayoutFromPanels(): GridData[] { return _.map(this.props.panels, panel => { // panel version numbers added in 6.1. Any panel without version number is assumed to be 6.0.0 - const panelVersion = panel.version ? PanelUtils.parseVersion(panel.version) : PanelUtils.parseVersion('6.0.0'); + const panelVersion = + 'version' in panel + ? PanelUtils.parseVersion(panel.version) + : PanelUtils.parseVersion('6.0.0'); if (panelVersion.major < 6 || (panelVersion.major === 6 && panelVersion.minor < 1)) { - PanelUtils.convertPanelDataPre_6_1(panel); + panel = PanelUtils.convertPanelDataPre_6_1(panel as Pre61PanelState); } if (panelVersion.major < 6 || (panelVersion.major === 6 && panelVersion.minor < 3)) { - PanelUtils.convertPanelDataPre_6_3(panel, this.props.useMargins); + PanelUtils.convertPanelDataPre_6_3(panel as PanelState, this.props.useMargins); } - return panel.gridData; + return (panel as PanelState).gridData; }); } - createEmbeddableFactoriesMap(panels) { + public createEmbeddableFactoriesMap(panels: PanelStateMap) { Object.values(panels).map(panel => { if (!this.embeddableFactoryMap[panel.type]) { this.embeddableFactoryMap[panel.type] = this.props.getEmbeddableFactory(panel.type); @@ -169,46 +201,46 @@ class DashboardGridUi extends React.Component { }); } - componentWillMount() { + public componentWillMount() { this.createEmbeddableFactoriesMap(this.props.panels); } - componentWillReceiveProps(nextProps) { + public componentWillReceiveProps(nextProps: Props) { this.createEmbeddableFactoriesMap(nextProps.panels); } - onLayoutChange = (layout) => { + public onLayoutChange = (layout: PanelLayout[]) => { const { onPanelsUpdated, panels } = this.props; - const updatedPanels = layout.reduce((updatedPanelsAcc, panelLayout) => { - updatedPanelsAcc[panelLayout.i] = { - ...panels[panelLayout.i], - panelIndex: panelLayout.i, - gridData: _.pick(panelLayout, ['x', 'y', 'w', 'h', 'i']) - }; - return updatedPanelsAcc; - }, []); + const updatedPanels = layout.reduce( + (updatedPanelsAcc, panelLayout) => { + updatedPanelsAcc[panelLayout.i] = { + ...panels[panelLayout.i], + panelIndex: panelLayout.i, + gridData: _.pick(panelLayout, ['x', 'y', 'w', 'h', 'i']), + }; + return updatedPanelsAcc; + }, + {} as PanelStateMap + ); onPanelsUpdated(updatedPanels); }; - onPanelFocused = focusedPanelIndex => { + public onPanelFocused = (focusedPanelIndex: string): void => { this.setState({ focusedPanelIndex }); }; - onPanelBlurred = blurredPanelIndex => { + public onPanelBlurred = (blurredPanelIndex: string): void => { if (this.state.focusedPanelIndex === blurredPanelIndex) { this.setState({ focusedPanelIndex: undefined }); } }; - renderDOM() { - const { - panels, - maximizedPanelId - } = this.props; + public renderDOM() { + const { panels, maximizedPanelId } = this.props; const { focusedPanelIndex } = this.state; // Part of our unofficial API - need to render in a consistent order for plugins. - const panelsInOrder = Object.keys(panels).map(key => panels[key]); + const panelsInOrder = Object.keys(panels).map((key: string) => panels[key] as PanelState); panelsInOrder.sort((panelA, panelB) => { if (panelA.gridData.y === panelB.gridData.y) { return panelA.gridData.x - panelB.gridData.x; @@ -226,10 +258,12 @@ class DashboardGridUi extends React.Component { }); return (
{ this.gridItems[panel.panelIndex] = reactGridItem; }} + ref={reactGridItem => { + this.gridItems[panel.panelIndex] = reactGridItem; + }} > ({ +interface DashboardGridContainerDispatchProps { + onPanelsUpdated(updatedPanels: PanelStateMap): void; +} + +const mapStateToProps = ({ dashboard }: any): any => ({ panels: getPanels(dashboard), dashboardViewMode: getViewMode(dashboard), useMargins: getUseMargins(dashboard), }); -const mapDispatchToProps = (dispatch) => ({ - onPanelsUpdated: updatedPanels => dispatch(updatePanels(updatedPanels)), +const mapDispatchToProps = (dispatch: Dispatch) => ({ + onPanelsUpdated: (updatedPanels: PanelStateMap) => dispatch(updatePanels(updatedPanels)), }); -export const DashboardGridContainer = connect( +export const DashboardGridContainer = connect< + DashboardGridContainerStateProps, + DashboardGridContainerDispatchProps +>( mapStateToProps, mapDispatchToProps )(DashboardGrid); - diff --git a/src/legacy/core_plugins/kibana/public/dashboard/grid/index.js b/src/legacy/core_plugins/kibana/public/dashboard/grid/index.ts similarity index 100% rename from src/legacy/core_plugins/kibana/public/dashboard/grid/index.js rename to src/legacy/core_plugins/kibana/public/dashboard/grid/index.ts diff --git a/src/legacy/core_plugins/kibana/public/dashboard/index.js b/src/legacy/core_plugins/kibana/public/dashboard/index.js index a5e6bb668a7c5..000f5e840a8dc 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/index.js +++ b/src/legacy/core_plugins/kibana/public/dashboard/index.js @@ -22,6 +22,7 @@ import './saved_dashboard/saved_dashboards'; import './dashboard_config'; import uiRoutes from 'ui/routes'; import chrome from 'ui/chrome'; +import 'ui/filter_bar'; import { wrapInI18nContext } from 'ui/i18n'; import { toastNotifications } from 'ui/notify'; diff --git a/src/legacy/core_plugins/kibana/public/dashboard/panel/__tests__/panel_state.ts b/src/legacy/core_plugins/kibana/public/dashboard/panel/__tests__/panel_state.ts index e6162184145eb..4d910feaa4119 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/panel/__tests__/panel_state.ts +++ b/src/legacy/core_plugins/kibana/public/dashboard/panel/__tests__/panel_state.ts @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { PanelState } from '../../selectors'; import { createPanelState } from '../panel_state'; diff --git a/src/legacy/core_plugins/kibana/public/dashboard/panel/dashboard_panel.tsx b/src/legacy/core_plugins/kibana/public/dashboard/panel/dashboard_panel.tsx index ceb37dee0da19..0a3cd61a627ad 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/panel/dashboard_panel.tsx +++ b/src/legacy/core_plugins/kibana/public/dashboard/panel/dashboard_panel.tsx @@ -36,8 +36,8 @@ import { PanelHeader } from './panel_header'; export interface DashboardPanelProps { viewOnlyMode: boolean; - onPanelFocused?: (panelIndex: PanelId) => {}; - onPanelBlurred?: (panelIndex: PanelId) => {}; + onPanelFocused?: (panelIndex: PanelId) => void; + onPanelBlurred?: (panelIndex: PanelId) => void; error?: string | object; destroy: () => void; containerState: ContainerState; diff --git a/src/legacy/core_plugins/kibana/public/dashboard/panel/panel_utils.ts b/src/legacy/core_plugins/kibana/public/dashboard/panel/panel_utils.ts index 52485b48ce307..c4ea15eac5374 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/panel/panel_utils.ts +++ b/src/legacy/core_plugins/kibana/public/dashboard/panel/panel_utils.ts @@ -21,7 +21,8 @@ import { i18n } from '@kbn/i18n'; import _ from 'lodash'; import chrome from 'ui/chrome'; import { DEFAULT_PANEL_HEIGHT, DEFAULT_PANEL_WIDTH } from '../dashboard_constants'; -import { GridData, PanelState } from '../selectors'; +import { PanelState } from '../selectors'; +import { GridData } from '../types'; const PANEL_HEIGHT_SCALE_FACTOR = 5; const PANEL_HEIGHT_SCALE_FACTOR_WITH_MARGINS = 4; @@ -34,15 +35,7 @@ export interface SemanticVersion { export class PanelUtils { // 6.1 switched from gridster to react grid. React grid uses different variables for tracking layout - public static convertPanelDataPre_6_1(panel: { - panelIndex: any; // earlier versions allowed panelIndex to be a number or a string - gridData: GridData; - col: number; - row: number; - size_x: number; - size_y: number; - version: string; - }): Partial { + public static convertPanelDataPre_6_1(panel: any): PanelState { ['col', 'row'].forEach(key => { if (!_.has(panel, key)) { throw new Error( @@ -78,7 +71,7 @@ export class PanelUtils { // Need to scale pre 6.3 panels so they maintain the same layout public static convertPanelDataPre_6_3( panel: { - gridData: { w: number; x: number; h: number; y: number }; + gridData: GridData; version: string; }, useMargins: boolean diff --git a/src/legacy/core_plugins/kibana/public/dashboard/reducers/panels.ts b/src/legacy/core_plugins/kibana/public/dashboard/reducers/panels.ts index 172110df340a3..f4961a61c01b8 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/reducers/panels.ts +++ b/src/legacy/core_plugins/kibana/public/dashboard/reducers/panels.ts @@ -57,7 +57,7 @@ const setPanelTitle = (panels: PanelStateMap, payload: SetPanelTitleActionPayloa }, }); -const setPanels = (panels: PanelStateMap, newPanels: PanelStateMap) => _.cloneDeep(newPanels); +const setPanels = ({}, newPanels: PanelStateMap) => _.cloneDeep(newPanels); export const panelsReducer: Reducer = (panels = {}, action): PanelStateMap => { switch ((action as PanelActions).type) { diff --git a/src/legacy/core_plugins/kibana/public/dashboard/selectors/dashboard.ts b/src/legacy/core_plugins/kibana/public/dashboard/selectors/dashboard.ts index c2a9c245838a7..39ff7e51c689c 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/selectors/dashboard.ts +++ b/src/legacy/core_plugins/kibana/public/dashboard/selectors/dashboard.ts @@ -38,10 +38,10 @@ import { PanelStateMap, } from './types'; -export const getPanels = (dashboard: DashboardState): PanelStateMap => dashboard.panels; +export const getPanels = (dashboard: DashboardState): Readonly => dashboard.panels; export const getPanel = (dashboard: DashboardState, panelId: PanelId): PanelState => - getPanels(dashboard)[panelId]; + getPanels(dashboard)[panelId] as PanelState; export const getPanelType = (dashboard: DashboardState, panelId: PanelId): string => getPanel(dashboard, panelId).type; diff --git a/src/legacy/core_plugins/kibana/public/dashboard/selectors/types.ts b/src/legacy/core_plugins/kibana/public/dashboard/selectors/types.ts index 27d75875e40a8..165f06d9037ae 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/selectors/types.ts +++ b/src/legacy/core_plugins/kibana/public/dashboard/selectors/types.ts @@ -19,7 +19,9 @@ import { EmbeddableMetadata, Filters, Query, RefreshConfig, TimeRange } from 'ui/embeddable'; import { DashboardViewMode } from '../dashboard_view_mode'; +import { GridData } from '../types'; +export type DashboardViewMode = DashboardViewMode; export interface ViewState { readonly viewMode: DashboardViewMode; readonly isFullScreenMode: boolean; @@ -33,14 +35,6 @@ export interface ViewState { readonly filters: Filters; } -export interface GridData { - readonly w: number; - readonly h: number; - readonly x: number; - readonly y: number; - readonly i: string; -} - export type PanelId = string; export type SavedObjectId = string; @@ -65,8 +59,21 @@ export interface EmbeddableReduxState { readonly lastReloadRequestTime: number; } +export interface Pre61PanelState { + size_x: number; + size_y: number; + row: number; + col: number; + panelIndex: any; // earlier versions allowed this to be number or string + id: string; + type: string; + // Embeddableconfig didn't actually exist on older panel states but `migrate_app_state.js` handles + // stuffing it on. + embeddableConfig: any; +} + export interface PanelStateMap { - readonly [panelId: string]: PanelState; + [panelId: string]: PanelState | Pre61PanelState; } export interface EmbeddablesMap { diff --git a/src/dev/jest/ts_transform.js b/src/legacy/core_plugins/kibana/public/dashboard/types.ts similarity index 89% rename from src/dev/jest/ts_transform.js rename to src/legacy/core_plugins/kibana/public/dashboard/types.ts index f097ed2f8076a..eb76d73af7a58 100644 --- a/src/dev/jest/ts_transform.js +++ b/src/legacy/core_plugins/kibana/public/dashboard/types.ts @@ -17,5 +17,10 @@ * under the License. */ -require('../../setup_node_env'); -module.exports = require('./ts_transform.ts'); +export interface GridData { + w: number; + h: number; + x: number; + y: number; + i: string; +} diff --git a/src/legacy/core_plugins/kibana/public/dashboard/viewport/dashboard_viewport.js b/src/legacy/core_plugins/kibana/public/dashboard/viewport/dashboard_viewport.tsx similarity index 79% rename from src/legacy/core_plugins/kibana/public/dashboard/viewport/dashboard_viewport.js rename to src/legacy/core_plugins/kibana/public/dashboard/viewport/dashboard_viewport.tsx index bc037ed908b9d..8e34b50a0383d 100644 --- a/src/legacy/core_plugins/kibana/public/dashboard/viewport/dashboard_viewport.js +++ b/src/legacy/core_plugins/kibana/public/dashboard/viewport/dashboard_viewport.tsx @@ -18,9 +18,9 @@ */ import React from 'react'; -import PropTypes from 'prop-types'; -import { DashboardGrid } from '../grid'; +import { EmbeddableFactory } from 'ui/embeddable'; import { ExitFullScreenButton } from 'ui/exit_full_screen'; +import { DashboardGrid } from '../grid'; export function DashboardViewport({ maximizedPanelId, @@ -31,6 +31,15 @@ export function DashboardViewport({ useMargins, isFullScreenMode, onExitFullScreenMode, +}: { + maximizedPanelId: string; + getEmbeddableFactory: (panelType: string) => EmbeddableFactory; + panelCount: number; + title: string; + description: string; + useMargins: boolean; + isFullScreenMode: boolean; + onExitFullScreenMode: () => void; }) { return (
- { isFullScreenMode && } + {isFullScreenMode && } ); } - -DashboardViewport.propTypes = { - getEmbeddableFactory: PropTypes.func, - maximizedPanelId: PropTypes.string, - panelCount: PropTypes.number, - title: PropTypes.string, - description: PropTypes.string, - useMargins: PropTypes.bool.isRequired, -}; diff --git a/src/legacy/core_plugins/kibana/public/dev_tools/directives/dev_tools_app.js b/src/legacy/core_plugins/kibana/public/dev_tools/directives/dev_tools_app.js index 1f39cdf458216..c7cb877be676b 100644 --- a/src/legacy/core_plugins/kibana/public/dev_tools/directives/dev_tools_app.js +++ b/src/legacy/core_plugins/kibana/public/dev_tools/directives/dev_tools_app.js @@ -20,7 +20,6 @@ import { uiModules } from 'ui/modules'; import { DevToolsRegistryProvider } from 'ui/registry/dev_tools'; import template from '../partials/dev_tools_app.html'; -import 'ui/kbn_top_nav'; uiModules .get('apps/dev_tools') diff --git a/src/legacy/core_plugins/kibana/public/dev_tools/hacks/__tests__/hide_empty_tools.js b/src/legacy/core_plugins/kibana/public/dev_tools/hacks/__tests__/hide_empty_tools.js index 6e0e07104fa80..bf69fa09823f2 100644 --- a/src/legacy/core_plugins/kibana/public/dev_tools/hacks/__tests__/hide_empty_tools.js +++ b/src/legacy/core_plugins/kibana/public/dev_tools/hacks/__tests__/hide_empty_tools.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import chrome from 'ui/chrome'; diff --git a/src/legacy/core_plugins/kibana/public/dev_tools/index.js b/src/legacy/core_plugins/kibana/public/dev_tools/index.js index 27e388fe10e26..3218a6b823274 100644 --- a/src/legacy/core_plugins/kibana/public/dev_tools/index.js +++ b/src/legacy/core_plugins/kibana/public/dev_tools/index.js @@ -20,6 +20,7 @@ import uiRoutes from 'ui/routes'; import { DevToolsRegistryProvider } from 'ui/registry/dev_tools'; import { FeatureCatalogueRegistryProvider, FeatureCatalogueCategory } from 'ui/registry/feature_catalogue'; +import 'ui/directives/kbn_href'; import './directives/dev_tools_app'; uiRoutes diff --git a/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/discover_field.js b/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/discover_field.js index 211773a5ae867..50e9067b48367 100644 --- a/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/discover_field.js +++ b/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/discover_field.js @@ -22,7 +22,7 @@ import angular from 'angular'; import _ from 'lodash'; import sinon from 'sinon'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import 'ui/private'; import '../../components/field_chooser/discover_field'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; diff --git a/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_calculator.js b/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_calculator.js index 46c77e26c0ac5..cce6127ed9c47 100644 --- a/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_calculator.js +++ b/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_calculator.js @@ -21,7 +21,7 @@ import _ from 'lodash'; import ngMock from 'ng_mock'; import { fieldCalculator } from '../../components/field_chooser/lib/field_calculator'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import 'ui/private'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; diff --git a/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_chooser.js b/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_chooser.js index 6920c058e1eac..f76a0ab72b212 100644 --- a/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_chooser.js +++ b/src/legacy/core_plugins/kibana/public/discover/__tests__/directives/field_chooser.js @@ -21,7 +21,7 @@ import angular from 'angular'; import ngMock from 'ng_mock'; import _ from 'lodash'; import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import $ from 'jquery'; import 'ui/private'; import '../../components/field_chooser/field_chooser'; diff --git a/src/legacy/core_plugins/kibana/public/discover/__tests__/hit_sort_fn.js b/src/legacy/core_plugins/kibana/public/discover/__tests__/hit_sort_fn.js deleted file mode 100644 index c73cd2b56f752..0000000000000 --- a/src/legacy/core_plugins/kibana/public/discover/__tests__/hit_sort_fn.js +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - - -import _ from 'lodash'; -import ngMock from 'ng_mock'; -import expect from 'expect.js'; -import PluginsKibanaDiscoverHitSortFnProvider from '../_hit_sort_fn'; - -describe('hit sort function', function () { - let createHitSortFn; - - beforeEach(ngMock.module('kibana')); - beforeEach(ngMock.inject(function (Private) { - createHitSortFn = Private(PluginsKibanaDiscoverHitSortFnProvider); - })); - - - const runSortTest = function (dir, sortOpts) { - const groupSize = _.random(10, 30); - const total = sortOpts.length * groupSize; - - sortOpts = sortOpts.map(function (opt) { - if (Array.isArray(opt)) return opt; - else return [opt]; - }); - const sortOptLength = sortOpts.length; - - const hits = _.times(total, function (i) { - return { - _source: {}, - sort: sortOpts[i % sortOptLength] - }; - }); - - hits.sort(createHitSortFn(dir)) - .forEach(function (hit, i) { - const group = Math.floor(i / groupSize); - expect(hit.sort).to.eql(sortOpts[group]); - }); - }; - - - it('sorts a list of hits in ascending order', function () { - runSortTest('asc', [200, 404, 500]); - }); - - it('sorts a list of hits in descending order', function () { - runSortTest('desc', [10, 3, 1]); - }); - - it('breaks ties in ascending order', function () { - runSortTest('asc', [ - [ 'apache', 200, 'facebook.com' ], - [ 'apache', 200, 'twitter.com' ], - [ 'apache', 301, 'facebook.com' ], - [ 'apache', 301, 'twitter.com' ], - [ 'nginx', 200, 'facebook.com' ], - [ 'nginx', 200, 'twitter.com' ], - [ 'nginx', 301, 'facebook.com' ], - [ 'nginx', 301, 'twitter.com' ] - ]); - }); - - it('breaks ties in descending order', function () { - runSortTest('desc', [ - [ 'nginx', 301, 'twitter.com' ], - [ 'nginx', 301, 'facebook.com' ], - [ 'nginx', 200, 'twitter.com' ], - [ 'nginx', 200, 'facebook.com' ], - [ 'apache', 301, 'twitter.com' ], - [ 'apache', 301, 'facebook.com' ], - [ 'apache', 200, 'twitter.com' ], - [ 'apache', 200, 'facebook.com' ] - ]); - }); -}); diff --git a/src/legacy/core_plugins/kibana/public/discover/_hit_sort_fn.js b/src/legacy/core_plugins/kibana/public/discover/_hit_sort_fn.js deleted file mode 100644 index ce5311e46d655..0000000000000 --- a/src/legacy/core_plugins/kibana/public/discover/_hit_sort_fn.js +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -// eslint-disable-next-line @elastic/kibana-custom/no-default-export -export default function HitSortFnFactory() { - /** - * Creates a sort function that will resort hits based on the value - * es used to sort them. - * - * background: - * When a hit is sorted by elasticsearch, es will write the values that it used - * to sort them into an array at the top level of the hit like so - * - * ``` - * hits: { - * total: x, - * hits: [ - * { - * _id: i, - * _source: {}, - * sort: [ - * // all values used to sort, in the order of precedence - * ] - * } - * ] - * }; - * ``` - * - * @param {[type]} field [description] - * @param {[type]} direction [description] - * @return {[type]} [description] - */ - return function createHitSortFn(direction) { - const descending = (direction === 'desc'); - - return function sortHits(hitA, hitB) { - let bBelowa = null; - - const aSorts = hitA.sort || []; - const bSorts = hitB.sort || []; - - // walk each sort value, and compare until one is different - for (let i = 0; i < bSorts.length; i++) { - const a = aSorts[i]; - const b = bSorts[i]; - - if (a == null || b > a) { - bBelowa = !descending; - break; - } - - if (b < a) { - bBelowa = descending; - break; - } - } - - if (bBelowa !== null) { - return bBelowa ? -1 : 1; - } else { - return 0; - } - - }; - }; -} diff --git a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/_field_chooser.scss b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/_field_chooser.scss index 65b26da9afa4c..fcc8de845c334 100644 --- a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/_field_chooser.scss +++ b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/_field_chooser.scss @@ -2,3 +2,10 @@ color: $euiColorMediumShade; margin-left: $euiSizeS !important; } + +/* + Fixes EUI known issue https://github.com/elastic/eui/issues/1749 +*/ +.dscProgressBarTooltip__anchor { + display: block; +} \ No newline at end of file diff --git a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field.js b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field.js index 66b8eb8ab6cd2..1f4b3103af7c1 100644 --- a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field.js +++ b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field.js @@ -22,6 +22,7 @@ import html from './discover_field.html'; import _ from 'lodash'; import 'ui/directives/css_truncate'; import 'ui/directives/field_name'; +import './string_progress_bar'; import detailsHtml from './lib/detail_views/string.html'; import { uiModules } from 'ui/modules'; const app = uiModules.get('apps/discover'); diff --git a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/lib/detail_views/string.html b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/lib/detail_views/string.html index b0eb97ea5b62e..37786c3812ec5 100644 --- a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/lib/detail_views/string.html +++ b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/lib/detail_views/string.html @@ -77,15 +77,10 @@
- - - {{bucket.percent}}% - - + diff --git a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/string_progress_bar.js b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/string_progress_bar.js new file mode 100644 index 0000000000000..ae00df6dfbbf8 --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/string_progress_bar.js @@ -0,0 +1,70 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +import { wrapInI18nContext } from 'ui/i18n'; +import { uiModules } from 'ui/modules'; + +import React from 'react'; + +import { + EuiFlexGroup, + EuiFlexItem, + EuiProgress, + EuiText, + EuiToolTip, +} from '@elastic/eui'; + +const module = uiModules.get('discover/field_chooser'); + +function StringFieldProgressBar(props) { + return ( + + + + + + + + {props.percent}% + + + + + ); +} + +module.directive('stringFieldProgressBar', function (reactDirective) { + return reactDirective(wrapInI18nContext(StringFieldProgressBar)); +}); diff --git a/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js b/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js index 3c8da5dd3ab8f..a91ec2e5b446b 100644 --- a/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js +++ b/src/legacy/core_plugins/kibana/public/discover/controllers/discover.js @@ -26,9 +26,9 @@ import * as columnActions from 'ui/doc_table/actions/columns'; import * as filterActions from 'ui/doc_table/actions/filter'; import dateMath from '@elastic/datemath'; import 'ui/doc_table'; +import 'ui/listen'; import 'ui/visualize'; import 'ui/fixed_scroll'; -import 'ui/directives/validate_json'; import 'ui/filters/moment'; import 'ui/index_patterns'; import 'ui/state_management/app_state'; @@ -39,7 +39,6 @@ import { toastNotifications } from 'ui/notify'; import { VisProvider } from 'ui/vis'; import { VislibSeriesResponseHandlerProvider } from 'ui/vis/response_handlers/vislib'; import { DocTitleProvider } from 'ui/doc_title'; -import PluginsKibanaDiscoverHitSortFnProvider from '../_hit_sort_fn'; import { FilterBarQueryFilterProvider } from 'ui/filter_bar/query_filter'; import { intervalOptions } from 'ui/agg_types/buckets/_interval_options'; import { stateMonitorFactory } from 'ui/state_management/state_monitor_factory'; @@ -67,6 +66,12 @@ import { SavedObjectSaveModal } from 'ui/saved_objects/components/saved_object_s import { getRootBreadcrumbs, getSavedSearchBreadcrumbs } from '../breadcrumbs'; import { buildVislibDimensions } from 'ui/visualize/loader/pipeline_helpers/build_pipeline'; +const fetchStatuses = { + UNINITIALIZED: 'uninitialized', + LOADING: 'loading', + COMPLETE: 'complete', +}; + const app = uiModules.get('apps/discover', [ 'kibana/notify', 'kibana/courier', @@ -170,7 +175,6 @@ function discoverController( let visualizeHandler; const Vis = Private(VisProvider); const docTitle = Private(DocTitleProvider); - const HitSortFn = Private(PluginsKibanaDiscoverHitSortFnProvider); const queryFilter = Private(FilterBarQueryFilterProvider); const responseHandler = Private(VislibSeriesResponseHandlerProvider).handler; const filterManager = Private(FilterManagerProvider); @@ -190,6 +194,7 @@ function discoverController( $scope.intervalOptions = intervalOptions; $scope.showInterval = false; $scope.minimumVisibleRows = 50; + $scope.fetchStatus = fetchStatuses.UNINITIALIZED; $scope.intervalEnabled = function (interval) { return interval.val !== 'custom'; @@ -373,18 +378,16 @@ function discoverController( const getFieldCounts = async () => { // the field counts aren't set until we have the data back, // so we wait for the fetch to be done before proceeding - if (!$scope.fetchStatus) { + if ($scope.fetchStatus === fetchStatuses.COMPLETE) { return $scope.fieldCounts; } return await new Promise(resolve => { const unwatch = $scope.$watch('fetchStatus', (newValue) => { - if (newValue) { - return; + if (newValue === fetchStatuses.COMPLETE) { + unwatch(); + resolve($scope.fieldCounts); } - - unwatch(); - resolve($scope.fieldCounts); }); }); }; @@ -567,13 +570,9 @@ function discoverController( if (rows == null && oldRows == null) return status.LOADING; const rowsEmpty = _.isEmpty(rows); - // An undefined fetchStatus means the requests are still being - // prepared to be sent. When all requests are completed, - // fetchStatus is set to null, so it's important that we - // specifically check for undefined to determine a loading status. - const preparingForFetch = _.isUndefined(fetchStatus); + const preparingForFetch = fetchStatus === fetchStatuses.UNINITIALIZED; if (preparingForFetch) return status.LOADING; - else if (rowsEmpty && fetchStatus) return status.LOADING; + else if (rowsEmpty && fetchStatus === fetchStatuses.LOADING) return status.LOADING; else if (!rowsEmpty) return status.READY; else return status.NO_RESULTS; } @@ -662,6 +661,8 @@ function discoverController( .then(setupVisualization) .then(function () { $state.save(); + $scope.fetchStatus = fetchStatuses.LOADING; + logInspectorRequest(); return courier.fetch(); }) .catch(notify.error); @@ -673,176 +674,72 @@ function discoverController( $scope.fetch(); }; - - function handleSegmentedFetch(segmented) { - function flushResponseData() { - $scope.fetchError = undefined; - $scope.hits = 0; - $scope.failures = []; - $scope.rows = []; - $scope.fieldCounts = {}; - } - - if (!$scope.rows) flushResponseData(); - - const sort = $state.sort; - const timeField = $scope.indexPattern.timeFieldName; - - /** - * Basically an emum. - * - * opts: - * "time" - sorted by the timefield - * "non-time" - explicitly sorted by a non-time field, NOT THE SAME AS `sortBy !== "time"` - * "implicit" - no sorting set, NOT THE SAME AS "non-time" - * - * @type {String} - */ - const sortBy = (function () { - if (!Array.isArray(sort)) return 'implicit'; - else if (sort[0] === '_score') return 'implicit'; - else if (sort[0] === timeField) return 'time'; - else return 'non-time'; - }()); - - let sortFn = null; - if (sortBy !== 'implicit') { - sortFn = new HitSortFn(sort[1]); - } - - $scope.updateTime(); - - if (sort[0] === '_score') { - segmented.setMaxSegments(1); - } - - segmented.setDirection(sortBy === 'time' ? (sort[1] || 'desc') : 'desc'); - segmented.setSortFn(sortFn); - segmented.setSize($scope.opts.sampleSize); - - let inspectorRequests = []; - function logResponseInInspector(resp) { - if (inspectorRequests.length > 0) { - const inspectorRequest = inspectorRequests.shift(); - inspectorRequest - .stats(getResponseInspectorStats($scope.searchSource, resp)) - .ok({ json: resp }); - } - } - - // triggered when the status updated - segmented.on('status', function (status) { - $scope.fetchStatus = status; - if (status.complete === 0) { - // starting new segmented search request - inspectorAdapters.requests.reset(); - inspectorRequests = []; - } - - if (status.remaining > 0) { - const inspectorRequest = inspectorAdapters.requests.start( - i18n('kbn.discover.inspectorRequest.segmentFetchCompleteStatusTitle', { - defaultMessage: 'Segment {fetchCompleteStatus}', - values: { - fetchCompleteStatus: $scope.fetchStatus.complete, + function onResults(resp) { + logInspectorResponse(resp); + + if ($scope.opts.timefield) { + const tabifiedData = tabifyAggResponse($scope.vis.aggs, resp); + $scope.searchSource.rawResponse = resp; + Promise + .resolve(buildVislibDimensions($scope.vis, { timeRange: $scope.timeRange, searchSource: $scope.searchSource })) + .then(resp => responseHandler(tabifiedData, resp)) + .then(resp => { + visualizeHandler.render({ + as: 'visualization', + value: { + visType: $scope.vis.type.name, + visData: resp, + visConfig: $scope.vis.params, + params: {}, } - }), - { - description: i18n('kbn.discover.inspectorRequest.segmentFetchCompleteStatusDescription', { - defaultMessage: 'This request queries Elasticsearch to fetch the data for the search.', - }), }); - inspectorRequest.stats(getRequestInspectorStats($scope.searchSource)); - $scope.searchSource.getSearchRequestBody().then(body => { - inspectorRequest.json(body); }); - inspectorRequests.push(inspectorRequest); - } - - }); + } - segmented.on('first', function () { - flushResponseData(); - }); + $scope.hits = resp.hits.total; + $scope.rows = resp.hits.hits; - segmented.on('segment', (resp) => { - logResponseInInspector(resp); - if (resp._shards.failed > 0) { - $scope.failures = _.union($scope.failures, resp._shards.failures); - $scope.failures = _.uniq($scope.failures, false, function (failure) { - return failure.index + failure.shard + failure.reason; - }); - } - }); + // if we haven't counted yet, reset the counts + const counts = $scope.fieldCounts = $scope.fieldCounts || {}; - segmented.on('emptySegment', function (resp) { - logResponseInInspector(resp); + $scope.rows.forEach(hit => { + const fields = Object.keys($scope.indexPattern.flattenHit(hit)); + fields.forEach(fieldName => { + counts[fieldName] = (counts[fieldName] || 0) + 1; + }); }); - segmented.on('mergedSegment', function (merged) { - $scope.mergedEsResp = merged; - - if ($scope.opts.timefield) { - const tabifiedData = tabifyAggResponse($scope.vis.aggs, merged); - $scope.searchSource.rawResponse = merged; - Promise - .resolve(buildVislibDimensions($scope.vis, { timeRange: $scope.timeRange, searchSource: $scope.searchSource })) - .then(resp => responseHandler(tabifiedData, resp)) - .then(resp => { - visualizeHandler.render({ - as: 'visualization', - value: { - visType: $scope.vis.type.name, - visData: resp, - visConfig: $scope.vis.params, - params: {}, - } - }); - }); - } - - $scope.hits = merged.hits.total; - - const indexPattern = $scope.searchSource.getField('index'); - - // the merge rows, use a new array to help watchers - $scope.rows = merged.hits.hits.slice(); + $scope.fetchStatus = fetchStatuses.COMPLETE; - let counts = $scope.fieldCounts; - - // if we haven't counted yet, or need a fresh count because we are sorting, reset the counts - if (!counts || sortFn) counts = $scope.fieldCounts = {}; - - $scope.rows.forEach(function (hit) { - // skip this work if we have already done it - if (hit.$$_counted) return; + return $scope.searchSource.onResults().then(onResults); + } - // when we are sorting results, we need to redo the counts each time because the - // "top 500" may change with each response, so don't mark this as counted - if (!sortFn) hit.$$_counted = true; + let inspectorRequest; - const fields = _.keys(indexPattern.flattenHit(hit)); - let n = fields.length; - let field; - while (field = fields[--n]) { - if (counts[field]) counts[field] += 1; - else counts[field] = 1; - } - }); + function logInspectorRequest() { + inspectorAdapters.requests.reset(); + const title = i18n('kbn.discover.inspectorRequestDataTitle', { + defaultMessage: 'Data', }); - - segmented.on('complete', function () { - if ($scope.fetchStatus.hitCount === 0) { - flushResponseData(); - } - - $scope.fetchStatus = null; + const description = i18n('kbn.discover.inspectorRequestDescription', { + defaultMessage: 'This request queries Elasticsearch to fetch the data for the search.', + }); + inspectorRequest = inspectorAdapters.requests.start(title, { description }); + inspectorRequest.stats(getRequestInspectorStats($scope.searchSource)); + $scope.searchSource.getSearchRequestBody().then(body => { + inspectorRequest.json(body); }); } + function logInspectorResponse(resp) { + inspectorRequest + .stats(getResponseInspectorStats($scope.searchSource, resp)) + .ok({ json: resp }); + } - function beginSegmentedFetch() { - $scope.searchSource.onBeginSegmentedFetch(handleSegmentedFetch) + function startSearching() { + return $scope.searchSource.onResults() + .then(onResults) .catch((error) => { const fetchError = getPainlessError(error); @@ -853,10 +750,11 @@ function discoverController( } // Restart. This enables auto-refresh functionality. - beginSegmentedFetch(); + startSearching(); }); } - beginSegmentedFetch(); + + startSearching(); $scope.updateTime = function () { $scope.timeRange = { diff --git a/src/legacy/core_plugins/kibana/public/discover/index.html b/src/legacy/core_plugins/kibana/public/discover/index.html index ecd6dcf5e6772..4def63c620d49 100644 --- a/src/legacy/core_plugins/kibana/public/discover/index.html +++ b/src/legacy/core_plugins/kibana/public/discover/index.html @@ -101,8 +101,6 @@

-
-
{{fetchStatus.complete}} / {{fetchStatus.total}}
diff --git a/src/legacy/core_plugins/kibana/public/doc/__tests__/doc.js b/src/legacy/core_plugins/kibana/public/doc/__tests__/doc.js index a529650ae96a4..69ca21b2cf869 100644 --- a/src/legacy/core_plugins/kibana/public/doc/__tests__/doc.js +++ b/src/legacy/core_plugins/kibana/public/doc/__tests__/doc.js @@ -19,7 +19,7 @@ // Load the kibana app dependencies. import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import '..'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; import { timefilter } from 'ui/timefilter'; diff --git a/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_boolean.js b/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_boolean.js index b02c87b1c111d..24c67c0dccbf3 100644 --- a/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_boolean.js +++ b/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_boolean.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { fieldFormats } from 'ui/registry/field_formats'; describe('Boolean Format', function () { diff --git a/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_color.js b/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_color.js index bebe202bf82d5..329624269ae1d 100644 --- a/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_color.js +++ b/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_color.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { fieldFormats } from 'ui/registry/field_formats'; describe('Color Format', function () { diff --git a/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_conformance.js b/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_conformance.js index 9e1f6015bd35f..e84d5e217cf7c 100644 --- a/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_conformance.js +++ b/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_conformance.js @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import chrome from 'ui/chrome'; import { fieldFormats } from 'ui/registry/field_formats'; import { FieldFormat } from '../../../../../ui/field_formats/field_format'; @@ -43,7 +43,7 @@ const formatIds = [ 'static_lookup' ]; -// eslint-disable-next-line @elastic/kibana-custom/no-default-export +// eslint-disable-next-line @kbn/eslint/no-default-export export default describe('conformance', function () { const getConfig = (...args) => config.get(...args); diff --git a/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_date.js b/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_date.js index ac49c93f63cb5..33b3a4d4c73cf 100644 --- a/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_date.js +++ b/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_date.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import moment from 'moment-timezone'; import { fieldFormats } from 'ui/registry/field_formats'; diff --git a/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_duration.js b/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_duration.js index d12c616bec6e2..baa45caa4bcc3 100644 --- a/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_duration.js +++ b/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_duration.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { fieldFormats } from 'ui/registry/field_formats'; describe('Duration Format', function () { diff --git a/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_ip.js b/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_ip.js index a7b920f9eda1f..529bcf772a488 100644 --- a/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_ip.js +++ b/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_ip.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { fieldFormats } from 'ui/registry/field_formats'; describe('IP Address Format', function () { diff --git a/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_source.js b/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_source.js index 4726c3993771e..e254487679574 100644 --- a/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_source.js +++ b/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_source.js @@ -19,7 +19,7 @@ import $ from 'jquery'; import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { fieldFormats } from 'ui/registry/field_formats'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; diff --git a/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_string.js b/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_string.js index c779c164b7d16..e4e11e288d1f4 100644 --- a/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_string.js +++ b/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_string.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { fieldFormats } from 'ui/registry/field_formats'; describe('String Format', function () { diff --git a/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_truncate.js b/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_truncate.js index d5c89f98182b8..0db4c844e2917 100644 --- a/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_truncate.js +++ b/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_truncate.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { fieldFormats } from 'ui/registry/field_formats'; describe('String Truncate Format', function () { diff --git a/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_url.js b/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_url.js index e00131caa84db..b62ba4b147cf2 100644 --- a/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_url.js +++ b/src/legacy/core_plugins/kibana/public/field_formats/__tests__/_url.js @@ -18,7 +18,7 @@ */ import $ from 'jquery'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { fieldFormats } from 'ui/registry/field_formats'; describe('Url Format', function () { diff --git a/src/legacy/core_plugins/kibana/public/home/components/__snapshots__/add_data.test.js.snap b/src/legacy/core_plugins/kibana/public/home/components/__snapshots__/add_data.test.js.snap index 4daa4eeebf4ab..ce99cbbf5408f 100644 --- a/src/legacy/core_plugins/kibana/public/home/components/__snapshots__/add_data.test.js.snap +++ b/src/legacy/core_plugins/kibana/public/home/components/__snapshots__/add_data.test.js.snap @@ -47,9 +47,16 @@ exports[`apmUiEnabled 1`] = ` > + APM automatically collects in-depth performance metrics and errors from inside your applications. + + } footer={ + Ingest logs from popular data sources and easily visualize in preconfigured dashboards. + + } footer={ + Collect metrics from the operating system and services running on your servers. + + } footer={ + Centralize security events for interactive investigation in ready-to-go visualizations. + + } footer={ + Ingest logs from popular data sources and easily visualize in preconfigured dashboards. + + } footer={ + Collect metrics from the operating system and services running on your servers. + + } footer={ + Centralize security events for interactive investigation in ready-to-go visualizations. + + } footer={ + APM automatically collects in-depth performance metrics and errors from inside your applications. + + } footer={ + Ingest logs from popular data sources and easily visualize in preconfigured dashboards. + + } footer={ + Collect metrics from the operating system and services running on your servers. + + } footer={ + Centralize security events for interactive investigation in ready-to-go visualizations. + + } footer={ + Ingest logs from popular data sources and easily visualize in preconfigured dashboards. + + } footer={ + Collect metrics from the operating system and services running on your servers. + + } footer={ + Centralize security events for interactive investigation in ready-to-go visualizations. + + } footer={ { const renderCards = () => { - const apmTitle = intl.formatMessage({ - id: 'kbn.home.addData.apm.nameTitle', defaultMessage: 'APM' - }); - const apmDescription = intl.formatMessage({ - id: 'kbn.home.addData.apm.nameDescription', - defaultMessage: 'APM automatically collects in-depth performance metrics and errors from inside your applications.' - }); - const loggingTitle = intl.formatMessage({ - id: 'kbn.home.addData.logging.nameTitle', defaultMessage: 'Logging' - }); - const loggingDescription = intl.formatMessage({ - id: 'kbn.home.addData.logging.nameDescription', - defaultMessage: 'Ingest logs from popular data sources and easily visualize in preconfigured dashboards.' - }); - const metricsTitle = intl.formatMessage({ - id: 'kbn.home.addData.metrics.nameTitle', defaultMessage: 'Metrics' - }); - const metricsDescription = intl.formatMessage({ - id: 'kbn.home.addData.metrics.nameDescription', - defaultMessage: 'Collect metrics from the operating system and services running on your servers.' - }); - const securityTitle = intl.formatMessage({ - id: 'kbn.home.addData.security.nameTitle', defaultMessage: 'Security analytics' - }); - const securityDescription = intl.formatMessage({ - id: 'kbn.home.addData.security.nameDescription', - defaultMessage: 'Centralize security events for interactive investigation in ready-to-go visualizations.' - }); + const ampData = { + title: intl.formatMessage({ + id: 'kbn.home.addData.apm.nameTitle', defaultMessage: 'APM' + }), + description: intl.formatMessage({ + id: 'kbn.home.addData.apm.nameDescription', + defaultMessage: 'APM automatically collects in-depth performance metrics and errors from inside your applications.' + }), + ariaDescribedby: 'aria-describedby.addAmpButtonLabel' + }; + const loggingData = { + title: intl.formatMessage({ + id: 'kbn.home.addData.logging.nameTitle', defaultMessage: 'Logging' + }), + description: intl.formatMessage({ + id: 'kbn.home.addData.logging.nameDescription', + defaultMessage: 'Ingest logs from popular data sources and easily visualize in preconfigured dashboards.' + }), + ariaDescribedby: 'aria-describedby.addLogDataButtonLabel' + }; + const metricsData = { + title: intl.formatMessage({ + id: 'kbn.home.addData.metrics.nameTitle', defaultMessage: 'Metrics' + }), + description: intl.formatMessage({ + id: 'kbn.home.addData.metrics.nameDescription', + defaultMessage: 'Collect metrics from the operating system and services running on your servers.' + }), + ariaDescribedby: 'aria-describedby.addMetricsButtonLabel' + }; + const securityData = { + title: intl.formatMessage({ + id: 'kbn.home.addData.security.nameTitle', defaultMessage: 'Security analytics' + }), + description: intl.formatMessage({ + id: 'kbn.home.addData.security.nameDescription', + defaultMessage: 'Centralize security events for interactive investigation in ready-to-go visualizations.' + }), + ariaDescribedby: 'aria-describedby.addSecurityButtonLabel' + }; const getApmCard = () => ( } - title={apmTitle} - description={apmDescription} + title={ampData.title} + description={{ampData.description}} footer={ { } - title={loggingTitle} - description={loggingDescription} + title={loggingData.title} + description={{loggingData.description}} footer={ { } - title={metricsTitle} - description={metricsDescription} + title={metricsData.title} + description={{metricsData.description}} footer={ { } - title={securityTitle} - description={securityDescription} + title={securityData.title} + description={{securityData.description}} footer={ config.get(...args); + const docTitle = Private(DocTitleProvider); const fieldFormatEditors = Private(RegistryFieldFormatEditorsProvider); const kbnUrl = Private(KbnUrlProvider); diff --git a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_index_pattern.js b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_index_pattern.js index a9184977dc802..c3cd781279bd8 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_index_pattern.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/index_patterns/edit_index_pattern/edit_index_pattern.js @@ -20,6 +20,7 @@ import _ from 'lodash'; import './index_header'; import './create_edit_field'; +import { DocTitleProvider } from 'ui/doc_title'; import { KbnUrlProvider } from 'ui/url'; import { IndicesEditSectionsProvider } from './edit_sections'; import { fatalError, toastNotifications } from 'ui/notify'; @@ -170,7 +171,7 @@ uiRoutes uiModules.get('apps/management') .controller('managementIndexPatternsEdit', function ( - $scope, $location, $route, config, indexPatterns, Private, AppState, docTitle, confirmModal) { + $scope, $location, $route, config, indexPatterns, Private, AppState, confirmModal) { const $state = $scope.state = new AppState(); const { fieldWildcardMatcher } = Private(FieldWildcardProvider); const indexPatternListProvider = Private(IndexPatternListFactory)(); @@ -182,6 +183,7 @@ uiModules.get('apps/management') $scope.indexPatternListProvider = indexPatternListProvider; $scope.indexPattern.tags = indexPatternListProvider.getIndexPatternTags($scope.indexPattern); $scope.getFieldInfo = indexPatternListProvider.getFieldInfo; + const docTitle = Private(DocTitleProvider); docTitle.change($scope.indexPattern.title); const otherPatterns = _.filter($route.current.locals.indexPatterns, pattern => { diff --git a/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/__tests__/default_category.test.js b/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/__tests__/default_category.test.js index f3b15caa92637..d12e0649ec8c5 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/__tests__/default_category.test.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/__tests__/default_category.test.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { DEFAULT_CATEGORY } from '../default_category'; describe('Settings', function () { diff --git a/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/__tests__/get_aria_name.test.js b/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/__tests__/get_aria_name.test.js index 59606b6677b40..e71cf3459a8da 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/__tests__/get_aria_name.test.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/__tests__/get_aria_name.test.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getAriaName } from '../get_aria_name'; describe('Settings', function () { diff --git a/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/__tests__/get_category_name.test.js b/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/__tests__/get_category_name.test.js index 939eca86afed2..d517e82395373 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/__tests__/get_category_name.test.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/__tests__/get_category_name.test.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getCategoryName } from '../get_category_name'; describe('Settings', function () { diff --git a/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/__tests__/get_val_type.test.js b/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/__tests__/get_val_type.test.js index 212e9c94f37e9..ac6436590fd9b 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/__tests__/get_val_type.test.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/__tests__/get_val_type.test.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getValType } from '../get_val_type'; describe('Settings', function () { diff --git a/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/__tests__/is_default_value.test.js b/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/__tests__/is_default_value.test.js index d668c6ff1dbc8..043230d5f9eab 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/__tests__/is_default_value.test.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/__tests__/is_default_value.test.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { isDefaultValue } from '../is_default_value'; describe('Settings', function () { diff --git a/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/__tests__/to_editable_config.test.js b/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/__tests__/to_editable_config.test.js index 428b9852ff842..ad1ba30ece4b1 100644 --- a/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/__tests__/to_editable_config.test.js +++ b/src/legacy/core_plugins/kibana/public/management/sections/settings/lib/__tests__/to_editable_config.test.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { toEditableConfig } from '../to_editable_config'; describe('Settings', function () { diff --git a/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js b/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js index 62e764f60eae6..a84a805b2f1b9 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js +++ b/src/legacy/core_plugins/kibana/public/visualize/editor/editor.js @@ -25,6 +25,7 @@ import 'ui/visualize'; import 'ui/collapsible_sidebar'; import 'ui/search_bar'; import 'ui/apply_filters'; +import 'ui/listen'; import chrome from 'ui/chrome'; import React from 'react'; import angular from 'angular'; diff --git a/src/legacy/core_plugins/kibana/public/visualize/index.js b/src/legacy/core_plugins/kibana/public/visualize/index.js index 14c1e48d04fe0..2d79e7f55c79d 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/index.js +++ b/src/legacy/core_plugins/kibana/public/visualize/index.js @@ -24,6 +24,7 @@ import 'ui/draggable/draggable_handle'; import './saved_visualizations/_saved_vis'; import './saved_visualizations/saved_visualizations'; import 'ui/filters/sort_prefix_first'; +import 'ui/filter_bar'; import uiRoutes from 'ui/routes'; import visualizeListingTemplate from './listing/visualize_listing.html'; import { VisualizeListingController } from './listing/visualize_listing'; diff --git a/src/legacy/core_plugins/kibana/public/visualize/listing/visualize_listing.js b/src/legacy/core_plugins/kibana/public/visualize/listing/visualize_listing.js index 35fa7761f3ba9..b904a59e690c4 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/listing/visualize_listing.js +++ b/src/legacy/core_plugins/kibana/public/visualize/listing/visualize_listing.js @@ -20,6 +20,7 @@ import { SavedObjectRegistryProvider } from 'ui/saved_objects/saved_object_registry'; import 'ui/pager_control'; import 'ui/pager'; +import 'ui/directives/kbn_href'; import { uiModules } from 'ui/modules'; import { timefilter } from 'ui/timefilter'; import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; diff --git a/src/legacy/core_plugins/kibana/public/visualize/wizard/__snapshots__/new_vis_modal.test.tsx.snap b/src/legacy/core_plugins/kibana/public/visualize/wizard/__snapshots__/new_vis_modal.test.tsx.snap index bc0bdddfdbc53..b638849ae0d62 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/wizard/__snapshots__/new_vis_modal.test.tsx.snap +++ b/src/legacy/core_plugins/kibana/public/visualize/wizard/__snapshots__/new_vis_modal.test.tsx.snap @@ -162,7 +162,9 @@ exports[`NewVisModal filter for visualization types should render as expected 1` data-focus-lock-disabled="false" > - + @@ -1593,7 +1610,9 @@ exports[`NewVisModal should render as expected 1`] = ` data-focus-lock-disabled="false" > - + diff --git a/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.test.mocks.ts b/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.test.mocks.ts new file mode 100644 index 0000000000000..04c99a1547ba9 --- /dev/null +++ b/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.test.mocks.ts @@ -0,0 +1,26 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const settingsGet = jest.fn(); + +jest.doMock('ui/chrome', () => ({ + getUiSettingsClient: () => ({ + get: settingsGet, + }), +})); diff --git a/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.test.tsx b/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.test.tsx index dd357d70f8a0a..fbb3faf7b3564 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.test.tsx +++ b/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.test.tsx @@ -20,13 +20,7 @@ import React from 'react'; import { mountWithIntl } from 'test_utils/enzyme_helpers'; -const settingsGet = jest.fn(); - -jest.mock('ui/chrome', () => ({ - getUiSettingsClient: () => ({ - get: settingsGet, - }), -})); +import { settingsGet } from './new_vis_modal.test.mocks'; import { NewVisModal } from './new_vis_modal'; diff --git a/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.tsx b/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.tsx index 99b394a3f2e5d..ae2e54dc21fdb 100644 --- a/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.tsx +++ b/src/legacy/core_plugins/kibana/public/visualize/wizard/new_vis_modal.tsx @@ -20,6 +20,7 @@ import React from 'react'; import { EuiModal, EuiOverlayMask } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; import { VisualizeConstants } from '../visualize_constants'; @@ -64,13 +65,26 @@ class NewVisModal extends React.Component ) : ( - + diff --git a/src/legacy/core_plugins/kibana/server/lib/__tests__/handle_es_error.js b/src/legacy/core_plugins/kibana/server/lib/__tests__/handle_es_error.js index a3cd660687897..c8ce291af0cae 100644 --- a/src/legacy/core_plugins/kibana/server/lib/__tests__/handle_es_error.js +++ b/src/legacy/core_plugins/kibana/server/lib/__tests__/handle_es_error.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import handleESError from '../handle_es_error'; import { errors as esErrors } from 'elasticsearch'; diff --git a/src/legacy/core_plugins/kibana/server/lib/__tests__/manage_uuid.js b/src/legacy/core_plugins/kibana/server/lib/__tests__/manage_uuid.js index 80fa79ab64f55..907b2c8e95f8a 100644 --- a/src/legacy/core_plugins/kibana/server/lib/__tests__/manage_uuid.js +++ b/src/legacy/core_plugins/kibana/server/lib/__tests__/manage_uuid.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { startTestServers } from '../../../../../../test_utils/kbn_server'; import manageUuid from '../manage_uuid'; diff --git a/src/legacy/core_plugins/kibana/server/lib/__tests__/relationships.js b/src/legacy/core_plugins/kibana/server/lib/__tests__/relationships.js index 42845b4cf0eb1..1ef1a1f19218a 100644 --- a/src/legacy/core_plugins/kibana/server/lib/__tests__/relationships.js +++ b/src/legacy/core_plugins/kibana/server/lib/__tests__/relationships.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { findRelationships } from '../management/saved_objects/relationships'; describe('findRelationships', () => { diff --git a/src/legacy/core_plugins/kibana/server/lib/__tests__/system_api.js b/src/legacy/core_plugins/kibana/server/lib/__tests__/system_api.js index c8b9cefc5aa1b..f575918777568 100644 --- a/src/legacy/core_plugins/kibana/server/lib/__tests__/system_api.js +++ b/src/legacy/core_plugins/kibana/server/lib/__tests__/system_api.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { isSystemApiRequest } from '../system_api'; describe('system_api', () => { diff --git a/src/legacy/core_plugins/kibana/server/tutorials/apm/saved_objects/get_saved_objects.test.js b/src/legacy/core_plugins/kibana/server/tutorials/apm/saved_objects/get_saved_objects.test.js index 108ed4c713300..13e5b4711f488 100644 --- a/src/legacy/core_plugins/kibana/server/tutorials/apm/saved_objects/get_saved_objects.test.js +++ b/src/legacy/core_plugins/kibana/server/tutorials/apm/saved_objects/get_saved_objects.test.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getSavedObjects } from './get_saved_objects'; const indexPatternTitle = 'dynamic index pattern title'; diff --git a/src/legacy/core_plugins/kibana/server/tutorials/apm/saved_objects/index_pattern.json b/src/legacy/core_plugins/kibana/server/tutorials/apm/saved_objects/index_pattern.json index 2fbb87fa2e19e..0f681b4c79bb7 100644 --- a/src/legacy/core_plugins/kibana/server/tutorials/apm/saved_objects/index_pattern.json +++ b/src/legacy/core_plugins/kibana/server/tutorials/apm/saved_objects/index_pattern.json @@ -1,7 +1,7 @@ { "attributes": { - "fieldFormatMap": "{\"client.bytes\":{\"id\":\"bytes\"},\"destination.bytes\":{\"id\":\"bytes\"},\"event.duration\":{\"id\":\"duration\",\"params\":{\"inputFormat\":\"nanoseconds\"}},\"file.size\":{\"id\":\"bytes\"},\"http.request.body.bytes\":{\"id\":\"bytes\"},\"http.request.bytes\":{\"id\":\"bytes\"},\"http.response.body.bytes\":{\"id\":\"bytes\"},\"http.response.bytes\":{\"id\":\"bytes\"},\"network.bytes\":{\"id\":\"bytes\"},\"server.bytes\":{\"id\":\"bytes\"},\"source.bytes\":{\"id\":\"bytes\"},\"system.cpu.total.norm.pct\":{\"id\":\"percent\"},\"system.memory.actual.free\":{\"id\":\"bytes\"},\"system.memory.total\":{\"id\":\"bytes\"},\"system.process.cpu.total.norm.pct\":{\"id\":\"percent\"},\"system.process.memory.rss.bytes\":{\"id\":\"bytes\"},\"system.process.memory.size\":{\"id\":\"bytes\"},\"view spans\":{\"id\":\"url\",\"params\":{\"labelTemplate\":\"View Spans\"}}}", - "fields": "[{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"@timestamp\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tags\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"labels\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.ephemeral_id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.address\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.ip\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.provider\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.availability_zone\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.region\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.instance.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.instance.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.machine.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.account.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.runtime\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.image.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.image.tag\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.labels\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.address\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.ip\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"ecs.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":4,\"doc_values\":true,\"indexed\":true,\"name\":\"error.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.kind\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.category\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.action\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.outcome\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.module\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.dataset\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.severity\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"event.original\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.duration\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.timezone\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.created\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.start\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.end\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.risk_score\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.risk_score_norm\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.target_path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.extension\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.device\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.inode\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.uid\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.owner\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.gid\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.group\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.mode\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.size\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.mtime\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.ctime\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.hostname\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.ip\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.architecture\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.platform\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.family\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.kernel\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.method\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.body.content\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.referrer\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.status_code\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.body.content\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.body.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.body.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.level\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"log.original\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.iana_number\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.transport\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.application\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.protocol\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.direction\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.forwarded_ip\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.community_id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.ip\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.hostname\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.vendor\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.serial_number\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.platform\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.family\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.kernel\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"organization.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.platform\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.family\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.kernel\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.pid\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.ppid\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.args\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.executable\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.title\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.thread.id\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.start\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.working_directory\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"related.ip\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.address\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.ip\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.state\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.ephemeral_id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.address\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.ip\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.original\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.scheme\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.query\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.fragment\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.username\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.password\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.full_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.email\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.original\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.device.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.platform\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.family\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.kernel\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.hostname\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"fields\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.project.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"docker.container.labels\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.pod.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.pod.uid\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.namespace\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.node.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.labels\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.annotations\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.container.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.container.image\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"processor.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"processor.event\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"timestamp.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"enabled\":false,\"indexed\":false,\"name\":\"http.request.headers\",\"scripted\":false,\"searchable\":false},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.finished\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"enabled\":false,\"indexed\":false,\"name\":\"http.response.headers\",\"scripted\":false,\"searchable\":false},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.environment\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.language.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.language.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.runtime.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.runtime.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.framework.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.framework.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.sampled\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"trace.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"parent.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.listening\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.version_major\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.original.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"experimental\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":2,\"doc_values\":true,\"indexed\":true,\"name\":\"error.culprit\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.grouping_key\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":2,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.module\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":4,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":2,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.handled\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.log.level\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.log.logger_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":2,\"doc_values\":true,\"indexed\":true,\"name\":\"error.log.message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.log.param_message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.cpu.total.norm.pct\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.memory.total\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.memory.actual.free\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.process.cpu.total.norm.pct\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.process.memory.size\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.process.memory.rss.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"sourcemap.service.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"sourcemap.service.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"sourcemap.bundle_filepath\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"view spans\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.subtype\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.action\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.start.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.duration.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.sync\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.duration.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.result\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.marks\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.marks.*.*\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.span_count.dropped\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"_id\",\"scripted\":false,\"searchable\":false,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"_type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"_index\",\"scripted\":false,\"searchable\":false,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"_score\",\"scripted\":false,\"searchable\":false,\"type\":\"number\"}]", + "fieldFormatMap": "{\"client.bytes\":{\"id\":\"bytes\"},\"destination.bytes\":{\"id\":\"bytes\"},\"event.duration\":{\"id\":\"duration\",\"params\":{\"inputFormat\":\"nanoseconds\"}},\"http.request.body.bytes\":{\"id\":\"bytes\"},\"http.request.bytes\":{\"id\":\"bytes\"},\"http.response.body.bytes\":{\"id\":\"bytes\"},\"http.response.bytes\":{\"id\":\"bytes\"},\"network.bytes\":{\"id\":\"bytes\"},\"server.bytes\":{\"id\":\"bytes\"},\"source.bytes\":{\"id\":\"bytes\"},\"system.cpu.total.norm.pct\":{\"id\":\"percent\"},\"system.memory.actual.free\":{\"id\":\"bytes\"},\"system.memory.total\":{\"id\":\"bytes\"},\"system.process.cpu.total.norm.pct\":{\"id\":\"percent\"},\"system.process.memory.rss.bytes\":{\"id\":\"bytes\"},\"system.process.memory.size\":{\"id\":\"bytes\"},\"view spans\":{\"id\":\"url\",\"params\":{\"labelTemplate\":\"View Spans\"}}}", + "fields": "[{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"@timestamp\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"labels\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tags\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.ephemeral_id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.address\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.email\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.full_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.account.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.availability_zone\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.instance.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.instance.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.machine.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.provider\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.region\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.image.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.image.tag\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.labels\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"container.runtime\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.address\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.email\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.full_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"ecs.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":4,\"doc_values\":true,\"indexed\":true,\"name\":\"error.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.action\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.category\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.created\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.dataset\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.duration\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.end\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.kind\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.module\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.original\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.outcome\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.risk_score\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.risk_score_norm\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.severity\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.start\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.timezone\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.ctime\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.device\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.extension\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.gid\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.group\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.inode\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.mode\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.mtime\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.owner\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.size\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.target_path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.uid\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.architecture\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.hostname\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.family\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.kernel\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.platform\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.email\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.full_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.body.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.body.content\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.method\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.referrer\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.body.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.body.content\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.status_code\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.level\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.original\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.application\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.community_id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.direction\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.forwarded_ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.iana_number\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.protocol\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.transport\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.hostname\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.family\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.kernel\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.platform\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.serial_number\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.vendor\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"organization.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.family\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.kernel\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.platform\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.args\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.executable\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.pid\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.ppid\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.start\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.thread.id\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.title\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.working_directory\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"related.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.address\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.email\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.full_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.ephemeral_id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.state\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.address\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.city_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.continent_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.country_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.country_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.location\",\"scripted\":false,\"searchable\":true,\"type\":\"geo_point\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.region_iso_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.geo.region_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.mac\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.packets\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.email\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.full_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.fragment\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.original\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.password\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.query\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.scheme\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.username\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.email\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.full_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.group.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.group.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.device.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.original\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.family\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.full\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.kernel\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.platform\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"agent.hostname\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"fields\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.project.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"docker.container.labels\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.containerized\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.build\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.pod.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.pod.uid\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.namespace\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.node.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.labels\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.annotations\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.replicaset.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.deployment.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.statefulset.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.container.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"kubernetes.container.image\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"processor.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"processor.event\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"timestamp.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"enabled\":false,\"indexed\":false,\"name\":\"http.request.headers\",\"scripted\":false,\"searchable\":false},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.finished\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"enabled\":false,\"indexed\":false,\"name\":\"http.response.headers\",\"scripted\":false,\"searchable\":false},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.environment\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.language.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.language.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.runtime.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.runtime.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.framework.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"service.framework.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.sampled\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"trace.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"parent.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.listening\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.version_major\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.original.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"experimental\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":2,\"doc_values\":true,\"indexed\":true,\"name\":\"error.culprit\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.grouping_key\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":2,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.module\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":4,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":2,\"doc_values\":true,\"indexed\":true,\"name\":\"error.exception.handled\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.log.level\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.log.logger_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":2,\"doc_values\":true,\"indexed\":true,\"name\":\"error.log.message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.log.param_message\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.cpu.total.norm.pct\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.memory.total\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.memory.actual.free\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.process.cpu.total.norm.pct\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.process.memory.size\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.process.memory.rss.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"sourcemap.service.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"sourcemap.service.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"sourcemap.bundle_filepath\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"view spans\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.subtype\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.action\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.start.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"span.duration.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.sync\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.duration.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.result\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.marks\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.marks.*.*\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.span_count.dropped\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"_id\",\"scripted\":false,\"searchable\":false,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"_type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"_index\",\"scripted\":false,\"searchable\":false,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":false,\"indexed\":false,\"name\":\"_score\",\"scripted\":false,\"searchable\":false,\"type\":\"number\"}]", "sourceFilters": "[{\"value\":\"sourcemap.sourcemap\"}]", "timeFieldName": "@timestamp" }, diff --git a/src/legacy/core_plugins/kibana/server/tutorials/coredns_metrics/index.js b/src/legacy/core_plugins/kibana/server/tutorials/coredns_metrics/index.js new file mode 100644 index 0000000000000..2d0f450688e02 --- /dev/null +++ b/src/legacy/core_plugins/kibana/server/tutorials/coredns_metrics/index.js @@ -0,0 +1,61 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { i18n } from '@kbn/i18n'; +import { TUTORIAL_CATEGORY } from '../../../common/tutorials/tutorial_category'; +import { onPremInstructions, cloudInstructions, onPremCloudInstructions } from '../../../common/tutorials/metricbeat_instructions'; + +export function corednsMetricsSpecProvider(server, context) { + const moduleName = 'coredns'; + return { + id: 'corednsMetrics', + name: i18n.translate('kbn.server.tutorials.corednsMetrics.nameTitle', { + defaultMessage: 'CoreDNS metrics', + }), + category: TUTORIAL_CATEGORY.METRICS, + shortDescription: i18n.translate('kbn.server.tutorials.corednsMetrics.shortDescription', { + defaultMessage: 'Fetch monitoring metrics from the CoreDNS server.', + }), + longDescription: i18n.translate('kbn.server.tutorials.corednsMetrics.longDescription', { + defaultMessage: 'The `coredns` Metricbeat module fetches monitoring metrics from CoreDNS. \ +[Learn more]({learnMoreLink}).', + values: { + learnMoreLink: '{config.docs.beats.metricbeat}/metricbeat-module-coredns.html', + }, + }), + // euiIconType: 'logoCoreDNS', + artifacts: { + application: { + label: i18n.translate('kbn.server.tutorials.corednsMetrics.artifacts.application.label', { + defaultMessage: 'Discover', + }), + path: '/app/kibana#/discover' + }, + dashboards: [], + exportedFields: { + documentationUrl: '{config.docs.beats.metricbeat}/exported-fields-coredns.html' + } + }, + completionTimeMinutes: 10, + // previewImagePath: '/plugins/kibana/home/tutorial_resources/coredns_metrics/screenshot.png', + onPrem: onPremInstructions(moduleName, null, null, null, context), + elasticCloud: cloudInstructions(moduleName), + onPremElasticCloud: onPremCloudInstructions(moduleName) + }; +} diff --git a/src/legacy/core_plugins/kibana/server/tutorials/register.js b/src/legacy/core_plugins/kibana/server/tutorials/register.js index 1f0b39fef0e59..a0db02e34498b 100644 --- a/src/legacy/core_plugins/kibana/server/tutorials/register.js +++ b/src/legacy/core_plugins/kibana/server/tutorials/register.js @@ -68,6 +68,7 @@ import { mssqlMetricsSpecProvider } from './mssql_metrics'; import { natsMetricsSpecProvider } from './nats_metrics'; import { natsLogsSpecProvider } from './nats_logs'; import { zeekLogsSpecProvider } from './zeek_logs'; +import { corednsMetricsSpecProvider } from './coredns_metrics'; export function registerTutorials(server) { server.registerTutorial(systemLogsSpecProvider); @@ -121,4 +122,5 @@ export function registerTutorials(server) { server.registerTutorial(natsMetricsSpecProvider); server.registerTutorial(natsLogsSpecProvider); server.registerTutorial(zeekLogsSpecProvider); + server.registerTutorial(corednsMetricsSpecProvider); } diff --git a/src/legacy/core_plugins/kibana/ui_setting_defaults.js b/src/legacy/core_plugins/kibana/ui_setting_defaults.js index de8fdd9dabdb5..00af1aeae26b8 100644 --- a/src/legacy/core_plugins/kibana/ui_setting_defaults.js +++ b/src/legacy/core_plugins/kibana/ui_setting_defaults.js @@ -302,19 +302,6 @@ export function getUiSettingDefaults() { }), category: ['discover'], }, - 'courier:maxSegmentCount': { - name: i18n.translate('kbn.advancedSettings.courier.maxSegmentCountTitle', { - defaultMessage: 'Maximum segment count', - }), - value: 30, - description: i18n.translate('kbn.advancedSettings.courier.maxSegmentCountText', { - defaultMessage: - 'Requests in discover are split into segments to prevent massive requests from being sent to elasticsearch. ' + - 'This setting attempts to prevent the list of segments from getting too long, ' + - 'which might cause requests to take much longer to process.', - }), - category: ['search'], - }, 'courier:ignoreFilterIfFieldNotInIndex': { name: i18n.translate('kbn.advancedSettings.courier.ignoreFilterTitle', { defaultMessage: 'Ignore filter(s)', @@ -323,8 +310,8 @@ export function getUiSettingDefaults() { description: i18n.translate('kbn.advancedSettings.courier.ignoreFilterText', { defaultMessage: 'This configuration enhances support for dashboards containing visualizations accessing dissimilar indexes. ' + - 'When set to false, all filters are applied to all visualizations. ' + - 'When set to true, filter(s) will be ignored for a visualization ' + + 'When disabled, all filters are applied to all visualizations. ' + + 'When enabled, filter(s) will be ignored for a visualization ' + `when the visualization's index does not contain the filtering field.`, }), category: ['search'], diff --git a/src/legacy/core_plugins/markdown_vis/index.js b/src/legacy/core_plugins/markdown_vis/index.js index 9ad633073bd23..7f255b628f577 100644 --- a/src/legacy/core_plugins/markdown_vis/index.js +++ b/src/legacy/core_plugins/markdown_vis/index.js @@ -27,6 +27,7 @@ export default function (kibana) { visTypes: [ 'plugins/markdown_vis/markdown_vis' ], + interpreter: ['plugins/markdown_vis/markdown_fn'], styleSheetPaths: resolve(__dirname, 'public/index.scss'), } diff --git a/src/legacy/core_plugins/interpreter/public/functions/__snapshots__/markdown.test.js.snap b/src/legacy/core_plugins/markdown_vis/public/__snapshots__/markdown_fn.test.js.snap similarity index 100% rename from src/legacy/core_plugins/interpreter/public/functions/__snapshots__/markdown.test.js.snap rename to src/legacy/core_plugins/markdown_vis/public/__snapshots__/markdown_fn.test.js.snap diff --git a/src/legacy/core_plugins/interpreter/public/functions/markdown.js b/src/legacy/core_plugins/markdown_vis/public/markdown_fn.js similarity index 88% rename from src/legacy/core_plugins/interpreter/public/functions/markdown.js rename to src/legacy/core_plugins/markdown_vis/public/markdown_fn.js index dafbfe76f9119..4cf7bd6af3cfa 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/markdown.js +++ b/src/legacy/core_plugins/markdown_vis/public/markdown_fn.js @@ -17,6 +17,7 @@ * under the License. */ +import { functionsRegistry } from 'plugins/interpreter/registries'; import { i18n } from '@kbn/i18n'; export const kibanaMarkdown = () => ({ @@ -25,7 +26,7 @@ export const kibanaMarkdown = () => ({ context: { types: [], }, - help: i18n.translate('interpreter.functions.markdown.help', { + help: i18n.translate('markdownVis.function.help', { defaultMessage: 'Markdown visualization' }), args: { @@ -48,3 +49,5 @@ export const kibanaMarkdown = () => ({ }; } }); + +functionsRegistry.register(kibanaMarkdown); diff --git a/src/legacy/core_plugins/interpreter/public/functions/markdown.test.js b/src/legacy/core_plugins/markdown_vis/public/markdown_fn.test.js similarity index 91% rename from src/legacy/core_plugins/interpreter/public/functions/markdown.test.js rename to src/legacy/core_plugins/markdown_vis/public/markdown_fn.test.js index c64c95a0c9dbc..185db7cb995f1 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/markdown.test.js +++ b/src/legacy/core_plugins/markdown_vis/public/markdown_fn.test.js @@ -17,8 +17,8 @@ * under the License. */ -import { functionWrapper } from '../../test_helpers'; -import { kibanaMarkdown } from './markdown'; +import { functionWrapper } from '../../interpreter/test_helpers'; +import { kibanaMarkdown } from './markdown_fn'; describe('interpreter/functions#markdown', () => { const fn = functionWrapper(kibanaMarkdown); diff --git a/src/legacy/core_plugins/metric_vis/index.js b/src/legacy/core_plugins/metric_vis/index.js index 58328fdee212b..3738baccb5c51 100644 --- a/src/legacy/core_plugins/metric_vis/index.js +++ b/src/legacy/core_plugins/metric_vis/index.js @@ -27,6 +27,7 @@ export default function (kibana) { visTypes: [ 'plugins/metric_vis/metric_vis' ], + interpreter: ['plugins/metric_vis/metric_vis_fn'], styleSheetPaths: resolve(__dirname, 'public/index.scss'), } diff --git a/src/legacy/core_plugins/interpreter/public/functions/__snapshots__/metric.test.js.snap b/src/legacy/core_plugins/metric_vis/public/__snapshots__/metric_vis_fn.test.js.snap similarity index 100% rename from src/legacy/core_plugins/interpreter/public/functions/__snapshots__/metric.test.js.snap rename to src/legacy/core_plugins/metric_vis/public/__snapshots__/metric_vis_fn.test.js.snap diff --git a/src/legacy/core_plugins/metric_vis/public/__tests__/metric_vis.js b/src/legacy/core_plugins/metric_vis/public/__tests__/metric_vis.js index 43def2fe543a1..a8bfec6c86203 100644 --- a/src/legacy/core_plugins/metric_vis/public/__tests__/metric_vis.js +++ b/src/legacy/core_plugins/metric_vis/public/__tests__/metric_vis.js @@ -19,7 +19,7 @@ import $ from 'jquery'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { VisProvider } from 'ui/vis'; import LogstashIndexPatternStubProvider from 'fixtures/stubbed_logstash_index_pattern'; diff --git a/src/legacy/core_plugins/metric_vis/public/__tests__/metric_vis_controller.js b/src/legacy/core_plugins/metric_vis/public/__tests__/metric_vis_controller.js index 470669f3f5688..82ef6f2de50be 100644 --- a/src/legacy/core_plugins/metric_vis/public/__tests__/metric_vis_controller.js +++ b/src/legacy/core_plugins/metric_vis/public/__tests__/metric_vis_controller.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { MetricVisComponent } from '../metric_vis_controller'; describe('metric vis controller', function () { diff --git a/src/legacy/core_plugins/interpreter/public/functions/metric.js b/src/legacy/core_plugins/metric_vis/public/metric_vis_fn.js similarity index 90% rename from src/legacy/core_plugins/interpreter/public/functions/metric.js rename to src/legacy/core_plugins/metric_vis/public/metric_vis_fn.js index 435368acfc24a..dd35865a929ad 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/metric.js +++ b/src/legacy/core_plugins/metric_vis/public/metric_vis_fn.js @@ -17,6 +17,7 @@ * under the License. */ +import { functionsRegistry } from 'plugins/interpreter/registries'; import { i18n } from '@kbn/i18n'; export const metric = () => ({ @@ -27,7 +28,7 @@ export const metric = () => ({ 'kibana_datatable' ], }, - help: i18n.translate('interpreter.functions.metric.help', { + help: i18n.translate('metricVis.function.help', { defaultMessage: 'Metric visualization' }), args: { @@ -53,3 +54,5 @@ export const metric = () => ({ }; }, }); + +functionsRegistry.register(metric); diff --git a/src/legacy/core_plugins/interpreter/public/functions/metric.test.js b/src/legacy/core_plugins/metric_vis/public/metric_vis_fn.test.js similarity index 94% rename from src/legacy/core_plugins/interpreter/public/functions/metric.test.js rename to src/legacy/core_plugins/metric_vis/public/metric_vis_fn.test.js index 2e6dba2f07f5c..9b393a33b75ff 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/metric.test.js +++ b/src/legacy/core_plugins/metric_vis/public/metric_vis_fn.test.js @@ -17,8 +17,8 @@ * under the License. */ -import { functionWrapper } from '../../test_helpers'; -import { metric } from './metric'; +import { functionWrapper } from '../../interpreter/test_helpers'; +import { metric } from './metric_vis_fn'; describe('interpreter/functions#metric', () => { const fn = functionWrapper(metric); diff --git a/src/legacy/core_plugins/metric_vis/public/metric_vis_params.html b/src/legacy/core_plugins/metric_vis/public/metric_vis_params.html index c11d0bd8b111b..6efdd60faf4ed 100644 --- a/src/legacy/core_plugins/metric_vis/public/metric_vis_params.html +++ b/src/legacy/core_plugins/metric_vis/public/metric_vis_params.html @@ -78,7 +78,7 @@ type="number" class="form-control" name="range.from" - greater-or-equal-than="{{getGreaterThan($index)}}" + greater-or-equal-than="getGreaterThan($index)" required step="any" /> @@ -89,7 +89,7 @@ type="number" class="form-control" name="range.to" - greater-or-equal-than="{{range.from}}" + greater-or-equal-than="range.from" required step="any" /> diff --git a/src/legacy/core_plugins/metric_vis/public/metric_vis_params.js b/src/legacy/core_plugins/metric_vis/public/metric_vis_params.js index 76a709f5df24f..20ad8954f9617 100644 --- a/src/legacy/core_plugins/metric_vis/public/metric_vis_params.js +++ b/src/legacy/core_plugins/metric_vis/public/metric_vis_params.js @@ -18,6 +18,7 @@ */ import { uiModules } from 'ui/modules'; +import 'ui/directives/inequality'; import metricVisParamsTemplate from './metric_vis_params.html'; import _ from 'lodash'; const module = uiModules.get('kibana'); @@ -54,7 +55,7 @@ module.directive('metricVisParams', function (i18n) { }; $scope.getGreaterThan = function (index) { - if (index === 0) return 0; + if (index === 0) return -Infinity; return $scope.editorState.params.metric.colorsRange[index - 1].to; }; diff --git a/src/legacy/core_plugins/metrics/index.js b/src/legacy/core_plugins/metrics/index.js index b0b3dbb8377e0..076d98931e328 100644 --- a/src/legacy/core_plugins/metrics/index.js +++ b/src/legacy/core_plugins/metrics/index.js @@ -31,6 +31,7 @@ export default function (kibana) { visTypes: [ 'plugins/metrics/kbn_vis_types', ], + interpreter: ['plugins/metrics/tsvb_fn'], styleSheetPaths: resolve(__dirname, 'public/index.scss'), }, diff --git a/src/legacy/core_plugins/metrics/public/components/vis_editor.js b/src/legacy/core_plugins/metrics/public/components/vis_editor.js index 5c53bddf9bd27..c1701552a8936 100644 --- a/src/legacy/core_plugins/metrics/public/components/vis_editor.js +++ b/src/legacy/core_plugins/metrics/public/components/vis_editor.js @@ -1,173 +1,169 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import * as Rx from 'rxjs'; -import { share } from 'rxjs/operators'; -import VisEditorVisualization from './vis_editor_visualization'; -import Visualization from './visualization'; -import VisPicker from './vis_picker'; -import PanelConfig from './panel_config'; -import brushHandler from '../lib/create_brush_handler'; -import { fetchIndexPatternFields } from '../lib/fetch_fields'; - -class VisEditor extends Component { - constructor(props) { - super(props); - const { vis } = props; - this.appState = vis.API.getAppState(); - this.state = { - model: props.visParams, - dirty: false, - autoApply: true, - visFields: props.visFields - }; - this.onBrush = brushHandler(props.vis.API.timeFilter); - this.visDataSubject = new Rx.Subject(); - this.visData$ = this.visDataSubject.asObservable().pipe(share()); - } - - get uiState() { - return this.props.vis.getUiState(); - } - - getConfig = (...args) => { - return this.props.config.get(...args); - }; - - handleUiState = (field, value) => { - this.props.vis.uiStateVal(field, value); - }; - - handleChange = async (partialModel) => { - const nextModel = { ...this.state.model, ...partialModel }; - this.props.vis.params = nextModel; - if (this.state.autoApply) { - this.props.vis.updateState(); - } - this.setState({ - model: nextModel, - dirty: !this.state.autoApply - }); - const { params, fields } = this.props.vis; - fetchIndexPatternFields(params, fields).then(visFields => { - this.setState({ visFields }); - }); - }; - - handleCommit = () => { - this.props.vis.updateState(); - this.setState({ dirty: false }); - }; - - handleAutoApplyToggle = (event) => { - this.setState({ autoApply: event.target.checked }); - }; - - onDataChange = ({ visData }) => { - this.visDataSubject.next(visData); - }; - - render() { - if (!this.props.isEditorMode) { - if (!this.props.visParams || !this.props.visData) { - return null; - } - return ( - - ); - } - - const { model } = this.state; - - if (model) { - return ( -
-
- -
- -
- -
-
- ); - } - - return null; - } - - componentDidMount() { - this.props.renderComplete(); - } - - componentDidUpdate() { - this.props.renderComplete(); - } -} - -VisEditor.defaultProps = { - visData: {} -}; - -VisEditor.propTypes = { - vis: PropTypes.object, - visData: PropTypes.object, - visFields: PropTypes.object, - renderComplete: PropTypes.func, - config: PropTypes.object, - isEditorMode: PropTypes.bool, - savedObj: PropTypes.object, - timeRange: PropTypes.object, -}; - -export default VisEditor; +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; +import * as Rx from 'rxjs'; +import { share } from 'rxjs/operators'; +import VisEditorVisualization from './vis_editor_visualization'; +import Visualization from './visualization'; +import VisPicker from './vis_picker'; +import PanelConfig from './panel_config'; +import brushHandler from '../lib/create_brush_handler'; +import { fetchIndexPatternFields } from '../lib/fetch_fields'; + +class VisEditor extends Component { + constructor(props) { + super(props); + const { vis } = props; + this.appState = vis.API.getAppState(); + this.state = { + model: props.visParams, + dirty: false, + autoApply: true, + visFields: props.visFields + }; + this.onBrush = brushHandler(props.vis.API.timeFilter); + this.visDataSubject = new Rx.Subject(); + this.visData$ = this.visDataSubject.asObservable().pipe(share()); + } + + get uiState() { + return this.props.vis.getUiState(); + } + + getConfig = (...args) => { + return this.props.config.get(...args); + }; + + handleUiState = (field, value) => { + this.props.vis.uiStateVal(field, value); + }; + + handleChange = async (partialModel) => { + const nextModel = { ...this.state.model, ...partialModel }; + this.props.vis.params = nextModel; + if (this.state.autoApply) { + this.props.vis.updateState(); + } + this.setState({ + model: nextModel, + dirty: !this.state.autoApply + }); + const { params, fields } = this.props.vis; + fetchIndexPatternFields(params, fields).then(visFields => { + this.setState({ visFields }); + }); + }; + + handleCommit = () => { + this.props.vis.updateState(); + this.setState({ dirty: false }); + }; + + handleAutoApplyToggle = (event) => { + this.setState({ autoApply: event.target.checked }); + }; + + onDataChange = ({ visData }) => { + this.visDataSubject.next(visData); + }; + + render() { + if (!this.props.isEditorMode) { + if (!this.props.visParams || !this.props.visData) { + return null; + } + return ( + + ); + } + + const { model } = this.state; + + if (model) { + return ( +
+
+ +
+ +
+ +
+
+ ); + } + + return null; + } + + componentDidMount() { + this.props.renderComplete(); + } + + componentDidUpdate() { + this.props.renderComplete(); + } +} + +VisEditor.defaultProps = { + visData: {} +}; + +VisEditor.propTypes = { + vis: PropTypes.object, + visData: PropTypes.object, + visFields: PropTypes.object, + renderComplete: PropTypes.func, + config: PropTypes.object, + isEditorMode: PropTypes.bool, + savedObj: PropTypes.object, + timeRange: PropTypes.object, +}; + +export default VisEditor; diff --git a/src/legacy/core_plugins/metrics/public/components/vis_editor_visualization.js b/src/legacy/core_plugins/metrics/public/components/vis_editor_visualization.js index c6ba52f34841f..daf2b87e44e15 100644 --- a/src/legacy/core_plugins/metrics/public/components/vis_editor_visualization.js +++ b/src/legacy/core_plugins/metrics/public/components/vis_editor_visualization.js @@ -18,7 +18,7 @@ */ import PropTypes from 'prop-types'; import React, { Component } from 'react'; -import { get } from 'lodash'; +import { get, isEqual } from 'lodash'; import { keyCodes, EuiFlexGroup, EuiFlexItem, EuiButton, EuiText, EuiSwitch } from '@elastic/eui'; import { getVisualizeLoader } from 'ui/visualize/loader/visualize_loader'; import { FormattedMessage, injectI18n } from '@kbn/i18n/react'; @@ -35,74 +35,54 @@ class VisEditorVisualization extends Component { panelInterval: 0, }; - this.handleMouseUp = this.handleMouseUp.bind(this); - this.handleMouseDown = this.handleMouseDown.bind(this); - this.onSizeHandleKeyDown = this.onSizeHandleKeyDown.bind(this); - this._visEl = React.createRef(); this._subscription = null; } - handleMouseDown() { + handleMouseDown = () => { + window.addEventListener('mouseup', this.handleMouseUp); this.setState({ dragging: true }); - } + }; - handleMouseUp() { + handleMouseUp = () => { + window.removeEventListener('mouseup', this.handleMouseUp); this.setState({ dragging: false }); - } - - componentWillMount() { - this.handleMouseMove = (event) => { - if (this.state.dragging) { - this.setState((prevState) => ({ - height: Math.max(MIN_CHART_HEIGHT, prevState.height + event.movementY), - })); - } - }; - window.addEventListener('mousemove', this.handleMouseMove); - window.addEventListener('mouseup', this.handleMouseUp); - } + }; - componentWillUnmount() { - window.removeEventListener('mousemove', this.handleMouseMove); - window.removeEventListener('mouseup', this.handleMouseUp); - if (this._handler) { - this._handler.destroy(); - } - if (this._subscription) { - this._subscription.unsubscribe(); + handleMouseMove = (event) => { + if (this.state.dragging) { + this.setState((prevState) => ({ + height: Math.max(MIN_CHART_HEIGHT, prevState.height + event.movementY), + })); } - } - - onUpdate = () => { - this._handler.update({ - timeRange: this.props.timeRange, - }); }; - _loadVisualization() { - getVisualizeLoader().then(loader => { - if (!this._visEl.current) { - // In case the visualize loader isn't done before the component is unmounted. - return; - } + async _loadVisualization() { + const loader = await getVisualizeLoader(); - this._loader = loader; - this._handler = this._loader.embedVisualizationWithSavedObject(this._visEl.current, this.props.savedObj, { - uiState: this.props.uiState, - listenOnChange: false, - timeRange: this.props.timeRange, - appState: this.props.appState, - }); + if (!this._visEl.current) { + // In case the visualize loader isn't done before the component is unmounted. + return; + } - this._subscription = this._handler.data$.subscribe((data) => { - this.setPanelInterval(data.visData); - this.props.onDataChange(data); - }); + const { + uiState, + timeRange, + appState, + savedObj, + onDataChange + } = this.props; + + this._handler = loader.embedVisualizationWithSavedObject(this._visEl.current, savedObj, { + listenOnChange: false, + uiState, + timeRange, + appState, + }); - if (this._handlerUpdateHasAlreadyBeenTriggered) { - this.onUpdate(); - } + this._subscription = this._handler.data$.subscribe((data) => { + this.setPanelInterval(data.visData); + onDataChange(data); }); } @@ -114,26 +94,13 @@ class VisEditorVisualization extends Component { } } - componentDidUpdate() { - if (!this._handler) { - this._handlerUpdateHasAlreadyBeenTriggered = true; - return; - } - - this.onUpdate(); - } - - componentDidMount() { - this._loadVisualization(); - } - /** * Resize the chart height when pressing up/down while the drag handle * for resizing has the focus. * We use 15px steps to do the scaling and make sure the chart has at least its * defined minimum width (MIN_CHART_HEIGHT). */ - onSizeHandleKeyDown(ev) { + onSizeHandleKeyDown = (ev) => { const { keyCode } = ev; if (keyCode === keyCodes.UP || keyCode === keyCodes.DOWN) { ev.preventDefault(); @@ -174,9 +141,41 @@ class VisEditorVisualization extends Component { } } + componentWillUnmount() { + window.removeEventListener('mousemove', this.handleMouseMove); + window.removeEventListener('mouseup', this.handleMouseUp); + if (this._handler) { + this._handler.destroy(); + } + if (this._subscription) { + this._subscription.unsubscribe(); + } + } + + componentDidMount() { + window.addEventListener('mousemove', this.handleMouseMove); + this._loadVisualization(); + } + + componentDidUpdate(prevProps) { + if (this._handler && !isEqual(this.props.timeRange, prevProps.timeRange)) { + this._handler.update({ + timeRange: this.props.timeRange, + }); + } + } + render() { - const { dirty, autoApply } = this.props; + const { + dirty, + autoApply, + title, + description, + onToggleAutoApply, + onCommit + } = this.props; const style = { height: this.state.height }; + if (this.state.dragging) { style.userSelect = 'none'; } @@ -209,7 +208,7 @@ class VisEditorVisualization extends Component { defaultMessage="Auto apply" />)} checked={autoApply} - onChange={this.props.onToggleAutoApply} + onChange={onToggleAutoApply} /> @@ -220,9 +219,7 @@ class VisEditorVisualization extends Component {

@@ -239,7 +236,7 @@ class VisEditorVisualization extends Component { {!autoApply && - + @@ -284,17 +281,13 @@ class VisEditorVisualization extends Component { VisEditorVisualization.propTypes = { model: PropTypes.object, - onBrush: PropTypes.func, - onChange: PropTypes.func, onCommit: PropTypes.func, - onUiState: PropTypes.func, uiState: PropTypes.object, onToggleAutoApply: PropTypes.func, savedObj: PropTypes.object, timeRange: PropTypes.object, dirty: PropTypes.bool, autoApply: PropTypes.bool, - dateFormat: PropTypes.string, appState: PropTypes.object, }; diff --git a/src/legacy/core_plugins/metrics/public/components/vis_editor_visualization.test.js b/src/legacy/core_plugins/metrics/public/components/vis_editor_visualization.test.js index 146afeb07605d..b16f9e2ea22e0 100644 --- a/src/legacy/core_plugins/metrics/public/components/vis_editor_visualization.test.js +++ b/src/legacy/core_plugins/metrics/public/components/vis_editor_visualization.test.js @@ -35,13 +35,9 @@ describe('getVisualizeLoader', () => { } }; const loaderMock = { - embedVisualizationWithSavedObject: () => { - return handlerMock; - } - }; - require('ui/visualize/loader/visualize_loader').getVisualizeLoader = async () => { - return loaderMock; + embedVisualizationWithSavedObject: () => handlerMock, }; + require('ui/visualize/loader/visualize_loader').getVisualizeLoader = async () => loaderMock; }); it('should not call _handler.update until getVisualizeLoader returns _handler', async () => { @@ -50,12 +46,25 @@ describe('getVisualizeLoader', () => { ); // Set prop to force DOM change and componentDidUpdate to be triggered - wrapper.setProps({ dirty: true }); + wrapper.setProps({ + timeRange: { + from: '2019-03-20T20:35:37.637Z', + to: '2019-03-23T18:40:16.486Z' + } + }); + + expect(updateStub).not.toHaveBeenCalled(); // Ensure all promises resolve await new Promise(resolve => process.nextTick(resolve)); - // Ensure the state changes are reflected - wrapper.update(); + + // Set prop to force DOM change and componentDidUpdate to be triggered + wrapper.setProps({ + timeRange: { + from: 'now/d', + to: 'now/d' + } + }); expect(updateStub).toHaveBeenCalled(); }); diff --git a/src/legacy/core_plugins/interpreter/public/functions/tsvb.js b/src/legacy/core_plugins/metrics/public/tsvb_fn.js similarity index 90% rename from src/legacy/core_plugins/interpreter/public/functions/tsvb.js rename to src/legacy/core_plugins/metrics/public/tsvb_fn.js index bc6c2c60088dc..2cb84e5d3ff34 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/tsvb.js +++ b/src/legacy/core_plugins/metrics/public/tsvb_fn.js @@ -17,9 +17,10 @@ * under the License. */ +import { functionsRegistry } from 'plugins/interpreter/registries'; import { get } from 'lodash'; import { i18n } from '@kbn/i18n'; -import { MetricsRequestHandlerProvider } from 'plugins/metrics/kbn_vis_types/request_handler'; +import { MetricsRequestHandlerProvider } from './kbn_vis_types/request_handler'; import { PersistedState } from 'ui/persisted_state'; import chrome from 'ui/chrome'; @@ -34,7 +35,7 @@ export const tsvb = () => ({ 'null', ], }, - help: i18n.translate('interpreter.functions.tsvb.help', { + help: i18n.translate('tsvb.function.help', { defaultMessage: 'TSVB visualization' }), args: { @@ -78,3 +79,5 @@ export const tsvb = () => ({ }; }, }); + +functionsRegistry.register(tsvb); diff --git a/src/legacy/core_plugins/metrics/server/lib/vis_data/__tests__/helpers/get_es_shard_timeout.js b/src/legacy/core_plugins/metrics/server/lib/vis_data/__tests__/helpers/get_es_shard_timeout.js index a3174d0b2c6cf..123922ea6a563 100644 --- a/src/legacy/core_plugins/metrics/server/lib/vis_data/__tests__/helpers/get_es_shard_timeout.js +++ b/src/legacy/core_plugins/metrics/server/lib/vis_data/__tests__/helpers/get_es_shard_timeout.js @@ -27,7 +27,7 @@ describe('getEsShardTimeout', () => { const req = { server: { newPlatform: { - start: { + setup: { core: { elasticsearch: { legacy: { config$: of({ shardTimeout: moment.duration(12345) }) } } } diff --git a/src/legacy/core_plugins/metrics/server/lib/vis_data/helpers/get_es_shard_timeout.js b/src/legacy/core_plugins/metrics/server/lib/vis_data/helpers/get_es_shard_timeout.js index 7f3b8c157cda2..a49cc7a6de7c4 100644 --- a/src/legacy/core_plugins/metrics/server/lib/vis_data/helpers/get_es_shard_timeout.js +++ b/src/legacy/core_plugins/metrics/server/lib/vis_data/helpers/get_es_shard_timeout.js @@ -19,7 +19,7 @@ import { first, map } from 'rxjs/operators'; export async function getEsShardTimeout(req) { - return await req.server.newPlatform.start.core.elasticsearch.legacy.config$.pipe( + return await req.server.newPlatform.setup.core.elasticsearch.legacy.config$.pipe( first(), map(config => config.shardTimeout.asMilliseconds()) ).toPromise(); diff --git a/src/legacy/core_plugins/region_map/index.js b/src/legacy/core_plugins/region_map/index.js index bb0815d3f73e1..9f2f3904f75d3 100644 --- a/src/legacy/core_plugins/region_map/index.js +++ b/src/legacy/core_plugins/region_map/index.js @@ -24,6 +24,7 @@ export default function (kibana) { return new kibana.Plugin({ uiExports: { visTypes: ['plugins/region_map/region_map_vis'], + interpreter: ['plugins/region_map/region_map_fn'], styleSheetPaths: resolve(__dirname, 'public/index.scss'), } }); diff --git a/src/legacy/core_plugins/interpreter/public/functions/__snapshots__/regionmap.test.js.snap b/src/legacy/core_plugins/region_map/public/__snapshots__/region_map_fn.test.js.snap similarity index 100% rename from src/legacy/core_plugins/interpreter/public/functions/__snapshots__/regionmap.test.js.snap rename to src/legacy/core_plugins/region_map/public/__snapshots__/region_map_fn.test.js.snap diff --git a/src/legacy/core_plugins/region_map/public/__tests__/region_map_visualization.js b/src/legacy/core_plugins/region_map/public/__tests__/region_map_visualization.js index 54a2e018983ab..c223660f869ba 100644 --- a/src/legacy/core_plugins/region_map/public/__tests__/region_map_visualization.js +++ b/src/legacy/core_plugins/region_map/public/__tests__/region_map_visualization.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import _ from 'lodash'; import { RegionMapsVisualizationProvider } from '../region_map_visualization'; diff --git a/src/legacy/core_plugins/interpreter/public/functions/regionmap.js b/src/legacy/core_plugins/region_map/public/region_map_fn.js similarity index 89% rename from src/legacy/core_plugins/interpreter/public/functions/regionmap.js rename to src/legacy/core_plugins/region_map/public/region_map_fn.js index a383ba34af265..37d3580860494 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/regionmap.js +++ b/src/legacy/core_plugins/region_map/public/region_map_fn.js @@ -17,6 +17,7 @@ * under the License. */ +import { functionsRegistry } from 'plugins/interpreter/registries'; import { i18n } from '@kbn/i18n'; export const regionmap = () => ({ @@ -27,7 +28,7 @@ export const regionmap = () => ({ 'kibana_datatable' ], }, - help: i18n.translate('interpreter.functions.regionmap.help', { + help: i18n.translate('regionMap.function.help', { defaultMessage: 'Regionmap visualization' }), args: { @@ -53,3 +54,5 @@ export const regionmap = () => ({ }; }, }); + +functionsRegistry.register(regionmap); diff --git a/src/legacy/core_plugins/interpreter/public/functions/regionmap.test.js b/src/legacy/core_plugins/region_map/public/region_map_fn.test.js similarity index 94% rename from src/legacy/core_plugins/interpreter/public/functions/regionmap.test.js rename to src/legacy/core_plugins/region_map/public/region_map_fn.test.js index 5cce7ff154068..0239dc22b6c48 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/regionmap.test.js +++ b/src/legacy/core_plugins/region_map/public/region_map_fn.test.js @@ -17,8 +17,8 @@ * under the License. */ -import { functionWrapper } from '../../test_helpers'; -import { regionmap } from './regionmap'; +import { functionWrapper } from '../../interpreter/test_helpers'; +import { regionmap } from './region_map_fn'; describe('interpreter/functions#regionmap', () => { const fn = functionWrapper(regionmap); diff --git a/src/legacy/core_plugins/table_vis/index.js b/src/legacy/core_plugins/table_vis/index.js index 7f07e4be88568..affdcae73df70 100644 --- a/src/legacy/core_plugins/table_vis/index.js +++ b/src/legacy/core_plugins/table_vis/index.js @@ -26,6 +26,7 @@ export default function (kibana) { visTypes: [ 'plugins/table_vis/table_vis' ], + interpreter: ['plugins/table_vis/table_vis_fn'], styleSheetPaths: resolve(__dirname, 'public/index.scss'), }, }); diff --git a/src/legacy/core_plugins/interpreter/public/functions/__snapshots__/table.test.js.snap b/src/legacy/core_plugins/table_vis/public/__snapshots__/table_vis_fn.test.js.snap similarity index 100% rename from src/legacy/core_plugins/interpreter/public/functions/__snapshots__/table.test.js.snap rename to src/legacy/core_plugins/table_vis/public/__snapshots__/table_vis_fn.test.js.snap diff --git a/src/legacy/core_plugins/table_vis/public/__tests__/_table_vis_controller.js b/src/legacy/core_plugins/table_vis/public/__tests__/_table_vis_controller.js index 41028de007833..ac46ec373f9f0 100644 --- a/src/legacy/core_plugins/table_vis/public/__tests__/_table_vis_controller.js +++ b/src/legacy/core_plugins/table_vis/public/__tests__/_table_vis_controller.js @@ -18,7 +18,7 @@ */ import $ from 'jquery'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { LegacyResponseHandlerProvider } from 'ui/vis/response_handlers/legacy'; import { VisProvider } from 'ui/vis'; diff --git a/src/legacy/core_plugins/interpreter/public/functions/table.js b/src/legacy/core_plugins/table_vis/public/table_vis_fn.js similarity index 91% rename from src/legacy/core_plugins/interpreter/public/functions/table.js rename to src/legacy/core_plugins/table_vis/public/table_vis_fn.js index 1db86688ee48d..9498d8ce6549c 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/table.js +++ b/src/legacy/core_plugins/table_vis/public/table_vis_fn.js @@ -17,6 +17,7 @@ * under the License. */ +import { functionsRegistry } from 'plugins/interpreter/registries'; import { LegacyResponseHandlerProvider as legacyResponseHandlerProvider } from 'ui/vis/response_handlers/legacy'; import { i18n } from '@kbn/i18n'; @@ -28,7 +29,7 @@ export const kibanaTable = () => ({ 'kibana_datatable' ], }, - help: i18n.translate('interpreter.functions.table.help', { + help: i18n.translate('tableVis.function.help', { defaultMessage: 'Table visualization' }), args: { @@ -57,3 +58,5 @@ export const kibanaTable = () => ({ }; }, }); + +functionsRegistry.register(kibanaTable); diff --git a/src/legacy/core_plugins/interpreter/public/functions/table.test.js b/src/legacy/core_plugins/table_vis/public/table_vis_fn.test.js similarity index 95% rename from src/legacy/core_plugins/interpreter/public/functions/table.test.js rename to src/legacy/core_plugins/table_vis/public/table_vis_fn.test.js index 401a1ec9ca800..dc6da69800b29 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/table.test.js +++ b/src/legacy/core_plugins/table_vis/public/table_vis_fn.test.js @@ -17,8 +17,8 @@ * under the License. */ -import { functionWrapper } from '../../test_helpers'; -import { kibanaTable } from './table'; +import { functionWrapper } from '../../interpreter/test_helpers'; +import { kibanaTable } from './table_vis_fn'; const mockResponseHandler = jest.fn().mockReturnValue(Promise.resolve({ tables: [{ columns: [], rows: [] }], diff --git a/src/legacy/core_plugins/tagcloud/index.js b/src/legacy/core_plugins/tagcloud/index.js index 1cc8052fdcdb4..6ae53f745f82a 100644 --- a/src/legacy/core_plugins/tagcloud/index.js +++ b/src/legacy/core_plugins/tagcloud/index.js @@ -24,6 +24,7 @@ export default function (kibana) { return new kibana.Plugin({ uiExports: { visTypes: ['plugins/tagcloud/tag_cloud_vis'], + interpreter: ['plugins/tagcloud/tag_cloud_fn'], styleSheetPaths: resolve(__dirname, 'public/index.scss'), } }); diff --git a/src/legacy/core_plugins/interpreter/public/functions/__snapshots__/tagcloud.test.js.snap b/src/legacy/core_plugins/tagcloud/public/__snapshots__/tag_cloud_fn.test.js.snap similarity index 100% rename from src/legacy/core_plugins/interpreter/public/functions/__snapshots__/tagcloud.test.js.snap rename to src/legacy/core_plugins/tagcloud/public/__snapshots__/tag_cloud_fn.test.js.snap diff --git a/src/legacy/core_plugins/tagcloud/public/__tests__/tag_cloud.js b/src/legacy/core_plugins/tagcloud/public/__tests__/tag_cloud.js index 441d2bb002cb9..f6736b5d3d116 100644 --- a/src/legacy/core_plugins/tagcloud/public/__tests__/tag_cloud.js +++ b/src/legacy/core_plugins/tagcloud/public/__tests__/tag_cloud.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import _ from 'lodash'; import TagCloud from '../tag_cloud'; import d3 from 'd3'; diff --git a/src/legacy/core_plugins/tagcloud/public/__tests__/tag_cloud_visualization.js b/src/legacy/core_plugins/tagcloud/public/__tests__/tag_cloud_visualization.js index 9a0e904ccc715..69d08d8cb3f74 100644 --- a/src/legacy/core_plugins/tagcloud/public/__tests__/tag_cloud_visualization.js +++ b/src/legacy/core_plugins/tagcloud/public/__tests__/tag_cloud_visualization.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import LogstashIndexPatternStubProvider from 'fixtures/stubbed_logstash_index_pattern'; import * as visModule from 'ui/vis'; diff --git a/src/legacy/core_plugins/interpreter/public/functions/tagcloud.js b/src/legacy/core_plugins/tagcloud/public/tag_cloud_fn.js similarity index 90% rename from src/legacy/core_plugins/interpreter/public/functions/tagcloud.js rename to src/legacy/core_plugins/tagcloud/public/tag_cloud_fn.js index 874725b1820e7..59360af6adeb3 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/tagcloud.js +++ b/src/legacy/core_plugins/tagcloud/public/tag_cloud_fn.js @@ -17,6 +17,7 @@ * under the License. */ +import { functionsRegistry } from 'plugins/interpreter/registries'; import { i18n } from '@kbn/i18n'; export const tagcloud = () => ({ @@ -27,7 +28,7 @@ export const tagcloud = () => ({ 'kibana_datatable' ], }, - help: i18n.translate('interpreter.functions.tagcloud.help', { + help: i18n.translate('tagCloud.function.help', { defaultMessage: 'Tagcloud visualization' }), args: { @@ -53,3 +54,5 @@ export const tagcloud = () => ({ }; }, }); + +functionsRegistry.register(tagcloud); diff --git a/src/legacy/core_plugins/interpreter/public/functions/tagcloud.test.js b/src/legacy/core_plugins/tagcloud/public/tag_cloud_fn.test.js similarity index 93% rename from src/legacy/core_plugins/interpreter/public/functions/tagcloud.test.js rename to src/legacy/core_plugins/tagcloud/public/tag_cloud_fn.test.js index 9fe00084573af..d0098d7905ced 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/tagcloud.test.js +++ b/src/legacy/core_plugins/tagcloud/public/tag_cloud_fn.test.js @@ -17,8 +17,8 @@ * under the License. */ -import { functionWrapper } from '../../test_helpers'; -import { tagcloud } from './tagcloud'; +import { functionWrapper } from '../../interpreter/test_helpers'; +import { tagcloud } from './tag_cloud_fn'; describe('interpreter/functions#tagcloud', () => { const fn = functionWrapper(tagcloud); diff --git a/src/legacy/core_plugins/tests_bundle/tests_entry_template.js b/src/legacy/core_plugins/tests_bundle/tests_entry_template.js index 99238fcd1c9cc..bed96987ac2b1 100644 --- a/src/legacy/core_plugins/tests_bundle/tests_entry_template.js +++ b/src/legacy/core_plugins/tests_bundle/tests_entry_template.js @@ -30,7 +30,7 @@ export const createTestEntryTemplate = (defaultUiSettings) => (bundle) => ` */ // import global polyfills before everything else -import 'babel-polyfill'; +import '@babel/polyfill'; import 'custom-event-polyfill'; import 'whatwg-fetch'; import 'abortcontroller-polyfill'; diff --git a/src/legacy/core_plugins/tile_map/index.js b/src/legacy/core_plugins/tile_map/index.js index 850027afc7515..502b17d23bb24 100644 --- a/src/legacy/core_plugins/tile_map/index.js +++ b/src/legacy/core_plugins/tile_map/index.js @@ -25,6 +25,7 @@ export default function (kibana) { return new kibana.Plugin({ uiExports: { visTypes: ['plugins/tile_map/tile_map_vis'], + interpreter: ['plugins/tile_map/tilemap_fn'], styleSheetPaths: resolve(__dirname, 'public/index.scss'), }, init(server) { diff --git a/src/legacy/core_plugins/interpreter/public/functions/__snapshots__/tilemap.test.js.snap b/src/legacy/core_plugins/tile_map/public/__snapshots__/tilemap_fn.test.js.snap similarity index 100% rename from src/legacy/core_plugins/interpreter/public/functions/__snapshots__/tilemap.test.js.snap rename to src/legacy/core_plugins/tile_map/public/__snapshots__/tilemap_fn.test.js.snap diff --git a/src/legacy/core_plugins/tile_map/public/__tests__/coordinate_maps_visualization.js b/src/legacy/core_plugins/tile_map/public/__tests__/coordinate_maps_visualization.js index 3d83fdfe12aa8..608ded804e5a7 100644 --- a/src/legacy/core_plugins/tile_map/public/__tests__/coordinate_maps_visualization.js +++ b/src/legacy/core_plugins/tile_map/public/__tests__/coordinate_maps_visualization.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { CoordinateMapsVisualizationProvider } from '../coordinate_maps_visualization'; import LogstashIndexPatternStubProvider from 'fixtures/stubbed_logstash_index_pattern'; diff --git a/src/legacy/core_plugins/tile_map/public/__tests__/geohash_layer.js b/src/legacy/core_plugins/tile_map/public/__tests__/geohash_layer.js index e5a73e734ddde..628175e4fd2b3 100644 --- a/src/legacy/core_plugins/tile_map/public/__tests__/geohash_layer.js +++ b/src/legacy/core_plugins/tile_map/public/__tests__/geohash_layer.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { KibanaMap } from 'ui/vis/map/kibana_map'; import { GeohashLayer } from '../geohash_layer'; // import heatmapPng from './heatmap.png'; diff --git a/src/legacy/core_plugins/interpreter/public/functions/tilemap.js b/src/legacy/core_plugins/tile_map/public/tilemap_fn.js similarity index 91% rename from src/legacy/core_plugins/interpreter/public/functions/tilemap.js rename to src/legacy/core_plugins/tile_map/public/tilemap_fn.js index cf77acc3d3ea9..210212c704b66 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/tilemap.js +++ b/src/legacy/core_plugins/tile_map/public/tilemap_fn.js @@ -17,6 +17,7 @@ * under the License. */ +import { functionsRegistry } from 'plugins/interpreter/registries'; import { convertToGeoJson } from 'ui/vis/map/convert_to_geojson'; import { i18n } from '@kbn/i18n'; @@ -28,7 +29,7 @@ export const tilemap = () => ({ 'kibana_datatable' ], }, - help: i18n.translate('interpreter.functions.tilemap.help', { + help: i18n.translate('tileMap.function.help', { defaultMessage: 'Tilemap visualization' }), args: { @@ -61,3 +62,5 @@ export const tilemap = () => ({ }; }, }); + +functionsRegistry.register(tilemap); diff --git a/src/legacy/core_plugins/interpreter/public/functions/tilemap.test.js b/src/legacy/core_plugins/tile_map/public/tilemap_fn.test.js similarity index 96% rename from src/legacy/core_plugins/interpreter/public/functions/tilemap.test.js rename to src/legacy/core_plugins/tile_map/public/tilemap_fn.test.js index 429428a122c72..ec680502fd236 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/tilemap.test.js +++ b/src/legacy/core_plugins/tile_map/public/tilemap_fn.test.js @@ -17,8 +17,8 @@ * under the License. */ -import { functionWrapper } from '../../test_helpers'; -import { tilemap } from './tilemap'; +import { functionWrapper } from '../../interpreter/test_helpers'; +import { tilemap } from './tilemap_fn'; jest.mock('ui/vis/map/convert_to_geojson', () => ({ convertToGeoJson: jest.fn().mockReturnValue({ diff --git a/src/legacy/core_plugins/timelion/index.js b/src/legacy/core_plugins/timelion/index.js index a3375cb4d3a86..4a9c968bf9c41 100644 --- a/src/legacy/core_plugins/timelion/index.js +++ b/src/legacy/core_plugins/timelion/index.js @@ -59,6 +59,7 @@ export default function (kibana) { visTypes: [ 'plugins/timelion/vis' ], + interpreter: ['plugins/timelion/timelion_vis_fn'], home: [ 'plugins/timelion/register_feature' ], diff --git a/src/legacy/core_plugins/timelion/public/__tests__/_tick_generator.js b/src/legacy/core_plugins/timelion/public/__tests__/_tick_generator.js index 3d7a62ea1b2f6..508cc5cd856d2 100644 --- a/src/legacy/core_plugins/timelion/public/__tests__/_tick_generator.js +++ b/src/legacy/core_plugins/timelion/public/__tests__/_tick_generator.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; describe('Tick Generator', function () { diff --git a/src/legacy/core_plugins/timelion/public/__tests__/services/tick_formatters.js b/src/legacy/core_plugins/timelion/public/__tests__/services/tick_formatters.js index f447ad0adf1aa..8e140b9bf992a 100644 --- a/src/legacy/core_plugins/timelion/public/__tests__/services/tick_formatters.js +++ b/src/legacy/core_plugins/timelion/public/__tests__/services/tick_formatters.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; describe('Tick Formatters', function () { diff --git a/src/legacy/core_plugins/timelion/public/app.js b/src/legacy/core_plugins/timelion/public/app.js index 013fc4677dab9..589724a77c08e 100644 --- a/src/legacy/core_plugins/timelion/public/app.js +++ b/src/legacy/core_plugins/timelion/public/app.js @@ -32,6 +32,14 @@ import 'uiExports/fieldFormats'; import 'uiExports/savedObjectTypes'; require('ui/autoload/all'); + +// TODO: remove ui imports completely (move to plugins) +import 'ui/directives/input_focus'; +import 'ui/directives/saved_object_finder'; +import 'ui/listen'; +import 'ui/kbn_top_nav'; +import 'ui/saved_objects/ui/saved_object_save_as_checkbox'; + require('plugins/timelion/directives/cells/cells'); require('plugins/timelion/directives/fixed_element'); require('plugins/timelion/directives/fullscreen/fullscreen'); diff --git a/src/legacy/core_plugins/timelion/public/directives/__tests__/timelion_expression_input_helpers.js b/src/legacy/core_plugins/timelion/public/directives/__tests__/timelion_expression_input_helpers.js index 7f8ca9a136f53..16f44e2835b21 100644 --- a/src/legacy/core_plugins/timelion/public/directives/__tests__/timelion_expression_input_helpers.js +++ b/src/legacy/core_plugins/timelion/public/directives/__tests__/timelion_expression_input_helpers.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import PEG from 'pegjs'; import grammar from 'raw-loader!../../chain.peg'; import { diff --git a/src/legacy/core_plugins/timelion/public/directives/timelion_expression_suggestions/__tests__/timelion_expression_suggestions.js b/src/legacy/core_plugins/timelion/public/directives/timelion_expression_suggestions/__tests__/timelion_expression_suggestions.js index 1a1ecceabef10..59d77a9ec0f1b 100644 --- a/src/legacy/core_plugins/timelion/public/directives/timelion_expression_suggestions/__tests__/timelion_expression_suggestions.js +++ b/src/legacy/core_plugins/timelion/public/directives/timelion_expression_suggestions/__tests__/timelion_expression_suggestions.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import '../timelion_expression_suggestions'; diff --git a/src/legacy/core_plugins/interpreter/public/functions/timelion_vis.js b/src/legacy/core_plugins/timelion/public/timelion_vis_fn.js similarity index 89% rename from src/legacy/core_plugins/interpreter/public/functions/timelion_vis.js rename to src/legacy/core_plugins/timelion/public/timelion_vis_fn.js index 66e89e9e4c660..9161715d28022 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/timelion_vis.js +++ b/src/legacy/core_plugins/timelion/public/timelion_vis_fn.js @@ -17,9 +17,10 @@ * under the License. */ +import { functionsRegistry } from 'plugins/interpreter/registries'; import { get } from 'lodash'; import { i18n } from '@kbn/i18n'; -import { TimelionRequestHandlerProvider } from 'plugins/timelion/vis/timelion_request_handler'; +import { TimelionRequestHandlerProvider } from './vis/timelion_request_handler'; import chrome from 'ui/chrome'; @@ -33,7 +34,7 @@ export const timelionVis = () => ({ 'null', ], }, - help: i18n.translate('interpreter.functions.timelion.help', { + help: i18n.translate('timelion.function.help', { defaultMessage: 'Timelion visualization' }), args: { @@ -75,3 +76,5 @@ export const timelionVis = () => ({ }; }, }); + +functionsRegistry.register(timelionVis); diff --git a/src/legacy/core_plugins/timelion/server/lib/offset_time.test.js b/src/legacy/core_plugins/timelion/server/lib/offset_time.test.js index 4a4d524f77735..9250d3898638d 100644 --- a/src/legacy/core_plugins/timelion/server/lib/offset_time.test.js +++ b/src/legacy/core_plugins/timelion/server/lib/offset_time.test.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import moment from 'moment'; import { preprocessOffset } from './offset_time'; diff --git a/src/legacy/core_plugins/timelion/server/series_functions/__tests__/fixtures/tlConfig.js b/src/legacy/core_plugins/timelion/server/series_functions/__tests__/fixtures/tlConfig.js index aaabfc420031a..3ad6b0a549b87 100644 --- a/src/legacy/core_plugins/timelion/server/series_functions/__tests__/fixtures/tlConfig.js +++ b/src/legacy/core_plugins/timelion/server/series_functions/__tests__/fixtures/tlConfig.js @@ -42,7 +42,7 @@ export default function () { } }, newPlatform: { - start: { + setup: { core: { elasticsearch: { legacy: { config$: of({ shardTimeout: moment.duration(30000) }) } diff --git a/src/legacy/core_plugins/timelion/server/series_functions/es/index.js b/src/legacy/core_plugins/timelion/server/series_functions/es/index.js index c38d1c2a4af44..1497b7e1953f9 100644 --- a/src/legacy/core_plugins/timelion/server/series_functions/es/index.js +++ b/src/legacy/core_plugins/timelion/server/series_functions/es/index.js @@ -127,7 +127,7 @@ export default new Datasource('es', { }); } - const esShardTimeout = await tlConfig.server.newPlatform.start.core.elasticsearch.legacy.config$.pipe( + const esShardTimeout = await tlConfig.server.newPlatform.setup.core.elasticsearch.legacy.config$.pipe( first(), map(config => config.shardTimeout.asMilliseconds()) ).toPromise(); diff --git a/src/legacy/core_plugins/user_action/server/routes/api/user_action.ts b/src/legacy/core_plugins/user_action/server/routes/api/user_action.ts index f7d1067e8024e..004f6e2b6953d 100644 --- a/src/legacy/core_plugins/user_action/server/routes/api/user_action.ts +++ b/src/legacy/core_plugins/user_action/server/routes/api/user_action.ts @@ -25,20 +25,23 @@ export const registerUserActionRoute = (server: Server) => { * Increment a count on an object representing a specific user action. */ server.route({ - path: '/api/user_action/{appName}/{actionType}', + path: '/api/user_action/{appName}/{actionTypes}', method: 'POST', handler: async (request: any) => { - const { appName, actionType } = request.params; + const { appName, actionTypes } = request.params; try { const { getSavedObjectsRepository } = server.savedObjects; const { callWithInternalUser } = server.plugins.elasticsearch.getCluster('admin'); const internalRepository = getSavedObjectsRepository(callWithInternalUser); - const savedObjectId = `${appName}:${actionType}`; - // This object is created if it doesn't already exist. - await internalRepository.incrementCounter('user-action', savedObjectId, 'count'); + const incrementRequests = actionTypes.split(',').map((actionType: string) => { + const savedObjectId = `${appName}:${actionType}`; + // This object is created if it doesn't already exist. + return internalRepository.incrementCounter('user-action', savedObjectId, 'count'); + }); + await Promise.all(incrementRequests); return {}; } catch (error) { return new Boom('Something went wrong', { statusCode: error.status }); diff --git a/src/legacy/core_plugins/vega/index.js b/src/legacy/core_plugins/vega/index.js index 067dba30a4e10..cd6245193eff1 100644 --- a/src/legacy/core_plugins/vega/index.js +++ b/src/legacy/core_plugins/vega/index.js @@ -25,6 +25,7 @@ export default kibana => new kibana.Plugin({ uiExports: { visTypes: ['plugins/vega/vega_type'], + interpreter: ['plugins/vega/vega_fn'], injectDefaultVars: server => ({ vegaConfig: server.config().get('vega') }), styleSheetPaths: resolve(__dirname, 'public/index.scss'), }, diff --git a/src/legacy/core_plugins/vega/public/__tests__/vega_visualization.js b/src/legacy/core_plugins/vega/public/__tests__/vega_visualization.js index 141bf4d061fd5..d40ba8c345681 100644 --- a/src/legacy/core_plugins/vega/public/__tests__/vega_visualization.js +++ b/src/legacy/core_plugins/vega/public/__tests__/vega_visualization.js @@ -18,7 +18,7 @@ */ import Promise from 'bluebird'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import $ from 'jquery'; import { VegaVisualizationProvider } from '../vega_visualization'; diff --git a/src/legacy/core_plugins/vega/public/data_model/__tests__/es_query_parser.js b/src/legacy/core_plugins/vega/public/data_model/__tests__/es_query_parser.js index af83c75a0fec5..40cbbb203deb8 100644 --- a/src/legacy/core_plugins/vega/public/data_model/__tests__/es_query_parser.js +++ b/src/legacy/core_plugins/vega/public/data_model/__tests__/es_query_parser.js @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import moment from 'moment'; import { EsQueryParser } from '../es_query_parser'; diff --git a/src/legacy/core_plugins/vega/public/data_model/__tests__/search_cache.js b/src/legacy/core_plugins/vega/public/data_model/__tests__/search_cache.js index 4d712a39af779..57057a74e997a 100644 --- a/src/legacy/core_plugins/vega/public/data_model/__tests__/search_cache.js +++ b/src/legacy/core_plugins/vega/public/data_model/__tests__/search_cache.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { SearchCache } from '../search_cache'; describe(`SearchCache`, () => { diff --git a/src/legacy/core_plugins/vega/public/data_model/__tests__/time_cache.js b/src/legacy/core_plugins/vega/public/data_model/__tests__/time_cache.js index 8a7f263970bf4..0ab31fb8c5da8 100644 --- a/src/legacy/core_plugins/vega/public/data_model/__tests__/time_cache.js +++ b/src/legacy/core_plugins/vega/public/data_model/__tests__/time_cache.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { TimeCache } from '../time_cache'; describe(`TimeCache`, () => { diff --git a/src/legacy/core_plugins/vega/public/data_model/__tests__/vega_parser.js b/src/legacy/core_plugins/vega/public/data_model/__tests__/vega_parser.js index de8bb8a5006fc..3fa8af0e04c70 100644 --- a/src/legacy/core_plugins/vega/public/data_model/__tests__/vega_parser.js +++ b/src/legacy/core_plugins/vega/public/data_model/__tests__/vega_parser.js @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { VegaParser } from '../vega_parser'; import { bypassExternalUrlCheck } from '../../vega_view/vega_base_view'; diff --git a/src/legacy/core_plugins/interpreter/public/functions/vega.js b/src/legacy/core_plugins/vega/public/vega_fn.js similarity index 89% rename from src/legacy/core_plugins/interpreter/public/functions/vega.js rename to src/legacy/core_plugins/vega/public/vega_fn.js index b1f014f83fc8f..86e6980f3d213 100644 --- a/src/legacy/core_plugins/interpreter/public/functions/vega.js +++ b/src/legacy/core_plugins/vega/public/vega_fn.js @@ -17,10 +17,11 @@ * under the License. */ +import { functionsRegistry } from 'plugins/interpreter/registries'; import { get } from 'lodash'; import { i18n } from '@kbn/i18n'; import chrome from 'ui/chrome'; -import { VegaRequestHandlerProvider } from 'plugins/vega/vega_request_handler'; +import { VegaRequestHandlerProvider } from './vega_request_handler'; export const vega = () => ({ name: 'vega', @@ -31,7 +32,7 @@ export const vega = () => ({ 'null', ], }, - help: i18n.translate('interpreter.functions.vega.help', { + help: i18n.translate('vega.function.help', { defaultMessage: 'Vega visualization' }), args: { @@ -66,3 +67,5 @@ export const vega = () => ({ }; } }); + +functionsRegistry.register(vega); diff --git a/src/legacy/deprecation/__tests__/create_transform.js b/src/legacy/deprecation/__tests__/create_transform.js index 5e8292761c785..0a02a081e41e6 100644 --- a/src/legacy/deprecation/__tests__/create_transform.js +++ b/src/legacy/deprecation/__tests__/create_transform.js @@ -18,7 +18,7 @@ */ import { createTransform } from '../create_transform'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; describe('deprecation', function () { diff --git a/src/legacy/deprecation/deprecations/__tests__/rename.js b/src/legacy/deprecation/deprecations/__tests__/rename.js index 5a1d60a65bf97..eb7b0f6449325 100644 --- a/src/legacy/deprecation/deprecations/__tests__/rename.js +++ b/src/legacy/deprecation/deprecations/__tests__/rename.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { rename } from '../rename'; import sinon from 'sinon'; diff --git a/src/legacy/deprecation/deprecations/__tests__/unused.js b/src/legacy/deprecation/deprecations/__tests__/unused.js index cda113442ca79..41e4e9192f83d 100644 --- a/src/legacy/deprecation/deprecations/__tests__/unused.js +++ b/src/legacy/deprecation/deprecations/__tests__/unused.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { unused } from '../unused'; diff --git a/src/legacy/plugin_discovery/__tests__/find_plugin_specs.js b/src/legacy/plugin_discovery/__tests__/find_plugin_specs.js index 563ea9043fce8..f8d1cfc865a1e 100644 --- a/src/legacy/plugin_discovery/__tests__/find_plugin_specs.js +++ b/src/legacy/plugin_discovery/__tests__/find_plugin_specs.js @@ -20,7 +20,7 @@ import { resolve } from 'path'; import { toArray } from 'rxjs/operators'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { isEqual } from 'lodash'; import { findPluginSpecs } from '../find_plugin_specs'; import { PluginSpec } from '../plugin_spec'; diff --git a/src/legacy/plugin_discovery/plugin_config/__tests__/extend_config_service.js b/src/legacy/plugin_discovery/plugin_config/__tests__/extend_config_service.js index a7028b73d704d..e0c965ee6c4bb 100644 --- a/src/legacy/plugin_discovery/plugin_config/__tests__/extend_config_service.js +++ b/src/legacy/plugin_discovery/plugin_config/__tests__/extend_config_service.js @@ -18,7 +18,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { Config } from '../../../server/config'; import { PluginPack } from '../../plugin_pack'; diff --git a/src/legacy/plugin_discovery/plugin_config/__tests__/schema.js b/src/legacy/plugin_discovery/plugin_config/__tests__/schema.js index 2e00936653d0d..fb768a0335531 100644 --- a/src/legacy/plugin_discovery/plugin_config/__tests__/schema.js +++ b/src/legacy/plugin_discovery/plugin_config/__tests__/schema.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { PluginPack } from '../../plugin_pack'; import { getSchema, getStubSchema } from '../schema'; diff --git a/src/legacy/plugin_discovery/plugin_config/__tests__/settings.js b/src/legacy/plugin_discovery/plugin_config/__tests__/settings.js index 780f48165f1b7..a53ada44fad48 100644 --- a/src/legacy/plugin_discovery/plugin_config/__tests__/settings.js +++ b/src/legacy/plugin_discovery/plugin_config/__tests__/settings.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { PluginPack } from '../../plugin_pack'; diff --git a/src/legacy/plugin_discovery/plugin_exports/__tests__/reduce_export_specs.js b/src/legacy/plugin_discovery/plugin_exports/__tests__/reduce_export_specs.js index 6635cfcbc43e9..7df87ca5cc5db 100644 --- a/src/legacy/plugin_discovery/plugin_exports/__tests__/reduce_export_specs.js +++ b/src/legacy/plugin_discovery/plugin_exports/__tests__/reduce_export_specs.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { PluginPack } from '../../plugin_pack'; import { reduceExportSpecs } from '../reduce_export_specs'; diff --git a/src/legacy/plugin_discovery/plugin_pack/__tests__/create_pack.js b/src/legacy/plugin_discovery/plugin_pack/__tests__/create_pack.js index 740b4ebed63af..3a39b5d0182c0 100644 --- a/src/legacy/plugin_discovery/plugin_pack/__tests__/create_pack.js +++ b/src/legacy/plugin_discovery/plugin_pack/__tests__/create_pack.js @@ -20,7 +20,7 @@ import { resolve } from 'path'; import * as Rx from 'rxjs'; import { toArray } from 'rxjs/operators'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { createPack$ } from '../create_pack'; import { PluginPack } from '../plugin_pack'; diff --git a/src/legacy/plugin_discovery/plugin_pack/__tests__/package_json_at_path.js b/src/legacy/plugin_discovery/plugin_pack/__tests__/package_json_at_path.js index 59ac6050f803b..008a5d3299cce 100644 --- a/src/legacy/plugin_discovery/plugin_pack/__tests__/package_json_at_path.js +++ b/src/legacy/plugin_discovery/plugin_pack/__tests__/package_json_at_path.js @@ -20,7 +20,7 @@ import { resolve } from 'path'; import { toArray } from 'rxjs/operators'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { createPackageJsonAtPath$ } from '../package_json_at_path'; import { diff --git a/src/legacy/plugin_discovery/plugin_pack/__tests__/package_jsons_in_directory.js b/src/legacy/plugin_discovery/plugin_pack/__tests__/package_jsons_in_directory.js index f86cbd3bb6c1a..93bc69e2d3bd4 100644 --- a/src/legacy/plugin_discovery/plugin_pack/__tests__/package_jsons_in_directory.js +++ b/src/legacy/plugin_discovery/plugin_pack/__tests__/package_jsons_in_directory.js @@ -20,7 +20,7 @@ import { resolve } from 'path'; import { toArray } from 'rxjs/operators'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { createPackageJsonsInDirectory$ } from '../package_jsons_in_directory'; diff --git a/src/legacy/plugin_discovery/plugin_pack/__tests__/plugin_pack.js b/src/legacy/plugin_discovery/plugin_pack/__tests__/plugin_pack.js index d4ced575a6ead..425f026ef3b92 100644 --- a/src/legacy/plugin_discovery/plugin_pack/__tests__/plugin_pack.js +++ b/src/legacy/plugin_discovery/plugin_pack/__tests__/plugin_pack.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { PluginPack } from '../plugin_pack'; diff --git a/src/legacy/plugin_discovery/plugin_spec/__tests__/is_version_compatible.js b/src/legacy/plugin_discovery/plugin_spec/__tests__/is_version_compatible.js index 637fc0422cdf5..897184496af37 100644 --- a/src/legacy/plugin_discovery/plugin_spec/__tests__/is_version_compatible.js +++ b/src/legacy/plugin_discovery/plugin_spec/__tests__/is_version_compatible.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { isVersionCompatible } from '../is_version_compatible'; diff --git a/src/legacy/plugin_discovery/plugin_spec/__tests__/plugin_spec.js b/src/legacy/plugin_discovery/plugin_spec/__tests__/plugin_spec.js index 6709e4996f6f9..dc57e0a099d05 100644 --- a/src/legacy/plugin_discovery/plugin_spec/__tests__/plugin_spec.js +++ b/src/legacy/plugin_discovery/plugin_spec/__tests__/plugin_spec.js @@ -19,7 +19,7 @@ import { resolve } from 'path'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { PluginPack } from '../../plugin_pack'; diff --git a/src/legacy/server/config/__tests__/deprecation_warnings.js b/src/legacy/server/config/__tests__/deprecation_warnings.js index 6e4d5e2fd57d7..ecaa6fa22f54c 100644 --- a/src/legacy/server/config/__tests__/deprecation_warnings.js +++ b/src/legacy/server/config/__tests__/deprecation_warnings.js @@ -19,7 +19,7 @@ import { spawn } from 'child_process'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; const RUN_KBN_SERVER_STARTUP = require.resolve('./fixtures/run_kbn_server_startup'); const SETUP_NODE_ENV = require.resolve('../../../../setup_node_env'); diff --git a/src/legacy/server/config/schema.js b/src/legacy/server/config/schema.js index 97d7da4d8f192..0d136d831a6b3 100644 --- a/src/legacy/server/config/schema.js +++ b/src/legacy/server/config/schema.js @@ -197,6 +197,7 @@ export default () => Joi.object({ ) .default('#cheap-source-map'), }), + workers: Joi.number().min(1), profile: Joi.boolean().default(false) }).default(), status: Joi.object({ diff --git a/src/legacy/server/kbn_server.d.ts b/src/legacy/server/kbn_server.d.ts index ad4d3b92c5c66..3bb885dbee756 100644 --- a/src/legacy/server/kbn_server.d.ts +++ b/src/legacy/server/kbn_server.d.ts @@ -62,7 +62,7 @@ type KbnMixinFunc = (kbnServer: KbnServer, server: Server, config: any) => Promi type Unpromise = T extends Promise ? U : T; export default class KbnServer { public readonly newPlatform: { - start: { + setup: { core: { elasticsearch: ElasticsearchServiceSetup; }; diff --git a/src/legacy/server/kbn_server.js b/src/legacy/server/kbn_server.js index a0426869d736e..c571785dd51e9 100644 --- a/src/legacy/server/kbn_server.js +++ b/src/legacy/server/kbn_server.js @@ -57,7 +57,7 @@ export default class KbnServer { const { plugins, elasticsearch, serverOptions, handledConfigPaths } = core; this.newPlatform = { - start: { + setup: { core: { elasticsearch, }, diff --git a/src/legacy/server/saved_objects/service/lib/included_fields.js b/src/legacy/server/saved_objects/service/lib/included_fields.js index 0a05b59fb9163..ce972d89afeae 100644 --- a/src/legacy/server/saved_objects/service/lib/included_fields.js +++ b/src/legacy/server/saved_objects/service/lib/included_fields.js @@ -35,5 +35,8 @@ export function includedFields(type, fields) { .map(f => `${sourceType}.${f}`) .concat('namespace') .concat('type') + .concat('references') + .concat('migrationVersion') + .concat('updated_at') .concat(fields); // v5 compatibility } diff --git a/src/legacy/server/saved_objects/service/lib/included_fields.test.js b/src/legacy/server/saved_objects/service/lib/included_fields.test.js index 37935ab9153db..d0b01638aff1a 100644 --- a/src/legacy/server/saved_objects/service/lib/included_fields.test.js +++ b/src/legacy/server/saved_objects/service/lib/included_fields.test.js @@ -26,33 +26,51 @@ describe('includedFields', () => { it('includes type', () => { const fields = includedFields('config', 'foo'); - expect(fields).toHaveLength(4); + expect(fields).toHaveLength(7); expect(fields).toContain('type'); }); it('includes namespace', () => { const fields = includedFields('config', 'foo'); - expect(fields).toHaveLength(4); + expect(fields).toHaveLength(7); expect(fields).toContain('namespace'); }); + it('includes references', () => { + const fields = includedFields('config', 'foo'); + expect(fields).toHaveLength(7); + expect(fields).toContain('references'); + }); + + it('includes migrationVersion', () => { + const fields = includedFields('config', 'foo'); + expect(fields).toHaveLength(7); + expect(fields).toContain('migrationVersion'); + }); + + it('includes updated_at', () => { + const fields = includedFields('config', 'foo'); + expect(fields).toHaveLength(7); + expect(fields).toContain('updated_at'); + }); + it('accepts field as string', () => { const fields = includedFields('config', 'foo'); - expect(fields).toHaveLength(4); + expect(fields).toHaveLength(7); expect(fields).toContain('config.foo'); }); it('accepts fields as an array', () => { const fields = includedFields('config', ['foo', 'bar']); - expect(fields).toHaveLength(6); + expect(fields).toHaveLength(9); expect(fields).toContain('config.foo'); expect(fields).toContain('config.bar'); }); it('uses wildcard when type is not provided', () => { const fields = includedFields(undefined, 'foo'); - expect(fields).toHaveLength(4); + expect(fields).toHaveLength(7); expect(fields).toContain('*.foo'); }); @@ -60,7 +78,7 @@ describe('includedFields', () => { it('includes legacy field path', () => { const fields = includedFields('config', ['foo', 'bar']); - expect(fields).toHaveLength(6); + expect(fields).toHaveLength(9); expect(fields).toContain('foo'); expect(fields).toContain('bar'); }); diff --git a/src/legacy/server/saved_objects/service/lib/repository.test.js b/src/legacy/server/saved_objects/service/lib/repository.test.js index 0f3ab394195db..d336e334557c4 100644 --- a/src/legacy/server/saved_objects/service/lib/repository.test.js +++ b/src/legacy/server/saved_objects/service/lib/repository.test.js @@ -1224,7 +1224,15 @@ describe('SavedObjectsRepository', () => { expect(callAdminCluster).toHaveBeenCalledWith( expect.any(String), expect.objectContaining({ - _source: ['foo.title', 'namespace', 'type', 'title'], + _source: [ + 'foo.title', + 'namespace', + 'type', + 'references', + 'migrationVersion', + 'updated_at', + 'title', + ], }) ); diff --git a/src/legacy/server/usage/classes/__tests__/collector_set.js b/src/legacy/server/usage/classes/__tests__/collector_set.js index 3d1a23b8dc5d6..bdd490ab6f221 100644 --- a/src/legacy/server/usage/classes/__tests__/collector_set.js +++ b/src/legacy/server/usage/classes/__tests__/collector_set.js @@ -19,7 +19,7 @@ import { noop } from 'lodash'; import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { Collector } from '../collector'; import { CollectorSet } from '../collector_set'; diff --git a/src/legacy/ui/__tests__/ui_exports_replace_injected_vars.js b/src/legacy/ui/__tests__/ui_exports_replace_injected_vars.js index f75ac5d09f164..9243a715625d8 100644 --- a/src/legacy/ui/__tests__/ui_exports_replace_injected_vars.js +++ b/src/legacy/ui/__tests__/ui_exports_replace_injected_vars.js @@ -20,7 +20,7 @@ import { resolve } from 'path'; import { delay } from 'bluebird'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import cheerio from 'cheerio'; import { noop } from 'lodash'; diff --git a/src/legacy/ui/field_formats/__tests__/field_format.js b/src/legacy/ui/field_formats/__tests__/field_format.js index 7bd7e7e225db4..bf8ff9f33b18c 100644 --- a/src/legacy/ui/field_formats/__tests__/field_format.js +++ b/src/legacy/ui/field_formats/__tests__/field_format.js @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { asPrettyString } from '../../../core_plugins/kibana/common/utils/as_pretty_string'; import { FieldFormat } from '../field_format'; diff --git a/src/legacy/ui/field_formats/__tests__/field_formats_mixin.js b/src/legacy/ui/field_formats/__tests__/field_formats_mixin.js index 3159705f3d8ed..8f513fe28c98b 100644 --- a/src/legacy/ui/field_formats/__tests__/field_formats_mixin.js +++ b/src/legacy/ui/field_formats/__tests__/field_formats_mixin.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { FieldFormat } from '../field_format'; diff --git a/src/legacy/ui/field_formats/__tests__/field_formats_service.js b/src/legacy/ui/field_formats/__tests__/field_formats_service.js index 2110859f53551..9ae80462c2a07 100644 --- a/src/legacy/ui/field_formats/__tests__/field_formats_service.js +++ b/src/legacy/ui/field_formats/__tests__/field_formats_service.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { FieldFormat } from '../field_format'; import { FieldFormatsService } from '../field_formats_service'; import { createNumberFormat } from '../../../core_plugins/kibana/common/field_formats/types/number'; diff --git a/src/legacy/ui/public/.eslintrc b/src/legacy/ui/public/.eslintrc index 4285d367bdb5b..95e3757201989 100644 --- a/src/legacy/ui/public/.eslintrc +++ b/src/legacy/ui/public/.eslintrc @@ -1,6 +1,3 @@ -plugins: [ - '@elastic/eslint-plugin-kibana-custom' -] rules: no-console: 2 - '@elastic/kibana-custom/no-default-export': error + '@kbn/eslint/no-default-export': error diff --git a/src/legacy/ui/public/__tests__/errors.js b/src/legacy/ui/public/__tests__/errors.js index d328a6dc4e0ca..cc861ffd8e969 100644 --- a/src/legacy/ui/public/__tests__/errors.js +++ b/src/legacy/ui/public/__tests__/errors.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { RequestFailure, FetchFailure, diff --git a/src/legacy/ui/public/__tests__/events.js b/src/legacy/ui/public/__tests__/events.js index 95f9024e3c849..da4217bc90d1b 100644 --- a/src/legacy/ui/public/__tests__/events.js +++ b/src/legacy/ui/public/__tests__/events.js @@ -17,25 +17,236 @@ * under the License. */ +import _ from 'lodash'; import sinon from 'sinon'; import ngMock from 'ng_mock'; import { EventsProvider } from '../events'; +import expect from '@kbn/expect'; +import '../private'; +import { createLegacyClass } from '../utils/legacy_class'; -describe('events', function () { +describe('Events', function () { require('test_utils/no_digest_promises').activateForSuite(); - let events; + let Events; + let Promise; + let eventsInstance; beforeEach(ngMock.module('kibana')); - beforeEach(ngMock.inject(function (Private) { - const Events = Private(EventsProvider); - events = new Events(); + beforeEach(ngMock.inject(function ($injector, Private) { + Promise = $injector.get('Promise'); + Events = Private(EventsProvider); + eventsInstance = new Events(); })); + it('should handle on events', function () { + const obj = new Events(); + const prom = obj.on('test', function (message) { + expect(message).to.equal('Hello World'); + }); + + obj.emit('test', 'Hello World'); + + return prom; + }); + + it('should work with inherited objects', function () { + createLegacyClass(MyEventedObject).inherits(Events); + function MyEventedObject() { + MyEventedObject.Super.call(this); + } + const obj = new MyEventedObject(); + + const prom = obj.on('test', function (message) { + expect(message).to.equal('Hello World'); + }); + + obj.emit('test', 'Hello World'); + + return prom; + }); + + it('should clear events when off is called', function () { + const obj = new Events(); + obj.on('test', _.noop); + expect(obj._listeners).to.have.property('test'); + expect(obj._listeners.test).to.have.length(1); + obj.off(); + expect(obj._listeners).to.not.have.property('test'); + }); + + it('should clear a specific handler when off is called for an event', function () { + const obj = new Events(); + const handler1 = sinon.stub(); + const handler2 = sinon.stub(); + obj.on('test', handler1); + obj.on('test', handler2); + expect(obj._listeners).to.have.property('test'); + obj.off('test', handler1); + + return obj.emit('test', 'Hello World') + .then(function () { + sinon.assert.calledOnce(handler2); + sinon.assert.notCalled(handler1); + }); + }); + + it('should clear a all handlers when off is called for an event', function () { + const obj = new Events(); + const handler1 = sinon.stub(); + obj.on('test', handler1); + expect(obj._listeners).to.have.property('test'); + obj.off('test'); + expect(obj._listeners).to.not.have.property('test'); + + return obj.emit('test', 'Hello World') + .then(function () { + sinon.assert.notCalled(handler1); + }); + }); + + it('should handle multiple identical emits in the same tick', function () { + const obj = new Events(); + const handler1 = sinon.stub(); + + obj.on('test', handler1); + const emits = [ + obj.emit('test', 'one'), + obj.emit('test', 'two'), + obj.emit('test', 'three') + ]; + + return Promise + .all(emits) + .then(function () { + expect(handler1.callCount).to.be(emits.length); + expect(handler1.getCall(0).calledWith('one')).to.be(true); + expect(handler1.getCall(1).calledWith('two')).to.be(true); + expect(handler1.getCall(2).calledWith('three')).to.be(true); + }); + }); + + it('should handle emits from the handler', function () { + const obj = new Events(); + const secondEmit = Promise.defer(); + const handler1 = sinon.spy(function () { + if (handler1.calledTwice) { + return; + } + obj.emit('test').then(_.bindKey(secondEmit, 'resolve')); + }); + + obj.on('test', handler1); + + return Promise + .all([ + obj.emit('test'), + secondEmit.promise + ]) + .then(function () { + expect(handler1.callCount).to.be(2); + }); + }); + + it('should only emit to handlers registered before emit is called', function () { + const obj = new Events(); + const handler1 = sinon.stub(); + const handler2 = sinon.stub(); + + obj.on('test', handler1); + const emits = [ + obj.emit('test', 'one'), + obj.emit('test', 'two'), + obj.emit('test', 'three') + ]; + + + return Promise.all(emits).then(function () { + expect(handler1.callCount).to.be(emits.length); + + obj.on('test', handler2); + + const emits2 = [ + obj.emit('test', 'four'), + obj.emit('test', 'five'), + obj.emit('test', 'six') + ]; + + return Promise.all(emits2) + .then(function () { + expect(handler1.callCount).to.be(emits.length + emits2.length); + expect(handler2.callCount).to.be(emits2.length); + }); + }); + }); + + it('should pass multiple arguments from the emitter', function () { + const obj = new Events(); + const handler = sinon.stub(); + const payload = [ + 'one', + { hello: 'tests' }, + null + ]; + + obj.on('test', handler); + + return obj.emit('test', payload[0], payload[1], payload[2]) + .then(function () { + expect(handler.callCount).to.be(1); + expect(handler.calledWithExactly(payload[0], payload[1], payload[2])).to.be(true); + }); + }); + + it('should preserve the scope of the handler', function () { + const obj = new Events(); + const expected = 'some value'; + let testValue; + + function handler() { + testValue = this.getVal(); + } + handler.getVal = _.constant(expected); + + obj.on('test', handler); + return obj.emit('test') + .then(function () { + expect(testValue).to.equal(expected); + }); + }); + + it('should always emit in the same order', function () { + const handler = sinon.stub(); + + const obj = new Events(); + obj.on('block', _.partial(handler, 'block')); + obj.on('last', _.partial(handler, 'last')); + + return Promise + .all([ + obj.emit('block'), + obj.emit('block'), + obj.emit('block'), + obj.emit('block'), + obj.emit('block'), + obj.emit('block'), + obj.emit('block'), + obj.emit('block'), + obj.emit('block'), + obj.emit('last') + ]) + .then(function () { + expect(handler.callCount).to.be(10); + handler.args.forEach(function (args, i) { + expect(args[0]).to.be(i < 9 ? 'block' : 'last'); + }); + }); + }); + it('calls emitted handlers asynchronously', (done) => { const listenerStub = sinon.stub(); - events.on('test', listenerStub); - events.emit('test'); + eventsInstance.on('test', listenerStub); + eventsInstance.emit('test'); sinon.assert.notCalled(listenerStub); setTimeout(() => { @@ -46,11 +257,11 @@ describe('events', function () { it('calling off after an emit that has not yet triggered the handler, will not call the handler', (done) => { const listenerStub = sinon.stub(); - events.on('test', listenerStub); - events.emit('test'); + eventsInstance.on('test', listenerStub); + eventsInstance.emit('test'); // It's called asynchronously so it shouldn't be called yet. sinon.assert.notCalled(listenerStub); - events.off('test', listenerStub); + eventsInstance.off('test', listenerStub); setTimeout(() => { sinon.assert.notCalled(listenerStub); diff --git a/src/legacy/ui/public/__tests__/metadata.js b/src/legacy/ui/public/__tests__/metadata.js index 9cb5841f0d409..56866efcbc27d 100644 --- a/src/legacy/ui/public/__tests__/metadata.js +++ b/src/legacy/ui/public/__tests__/metadata.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { metadata } from '../metadata'; describe('ui/metadata', () => { it('is immutable', () => { diff --git a/src/legacy/ui/public/accessibility/__tests__/kbn_accessible_click.js b/src/legacy/ui/public/accessibility/__tests__/kbn_accessible_click.js index 93b3f5b094e65..b120a1c6fff36 100644 --- a/src/legacy/ui/public/accessibility/__tests__/kbn_accessible_click.js +++ b/src/legacy/ui/public/accessibility/__tests__/kbn_accessible_click.js @@ -19,7 +19,7 @@ import angular from 'angular'; import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import '../kbn_accessible_click'; import { keyCodes } from '@elastic/eui'; diff --git a/src/legacy/ui/public/accessibility/__tests__/kbn_ui_ace_keyboard_mode.js b/src/legacy/ui/public/accessibility/__tests__/kbn_ui_ace_keyboard_mode.js index 7845284479953..a8a6f0cd0db2f 100644 --- a/src/legacy/ui/public/accessibility/__tests__/kbn_ui_ace_keyboard_mode.js +++ b/src/legacy/ui/public/accessibility/__tests__/kbn_ui_ace_keyboard_mode.js @@ -19,7 +19,7 @@ import angular from 'angular'; import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import '../kbn_ui_ace_keyboard_mode'; import { keyCodes } from '@elastic/eui'; diff --git a/src/legacy/ui/public/accessibility/__tests__/scrollto_activedescendant.js b/src/legacy/ui/public/accessibility/__tests__/scrollto_activedescendant.js index f843c7f865791..38091d45ff9af 100644 --- a/src/legacy/ui/public/accessibility/__tests__/scrollto_activedescendant.js +++ b/src/legacy/ui/public/accessibility/__tests__/scrollto_activedescendant.js @@ -18,7 +18,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import '../scrollto_activedescendant'; diff --git a/src/legacy/ui/public/agg_response/hierarchical/__tests__/collect_branch.js b/src/legacy/ui/public/agg_response/hierarchical/__tests__/collect_branch.js index 02417e35cae40..310247657f0cd 100644 --- a/src/legacy/ui/public/agg_response/hierarchical/__tests__/collect_branch.js +++ b/src/legacy/ui/public/agg_response/hierarchical/__tests__/collect_branch.js @@ -20,7 +20,7 @@ import _ from 'lodash'; import collectBranch from '../_collect_branch'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; describe('collectBranch()', function () { let results; const convert = function (name) { diff --git a/src/legacy/ui/public/agg_response/hierarchical/_collect_branch.js b/src/legacy/ui/public/agg_response/hierarchical/_collect_branch.js index 1dc0b442d08d9..5339d453a7770 100644 --- a/src/legacy/ui/public/agg_response/hierarchical/_collect_branch.js +++ b/src/legacy/ui/public/agg_response/hierarchical/_collect_branch.js @@ -17,7 +17,7 @@ * under the License. */ -// eslint-disable-next-line @elastic/kibana-custom/no-default-export +// eslint-disable-next-line @kbn/eslint/no-default-export export default function (leaf) { // walk up the branch for each parent function walk(item, memo) { diff --git a/src/legacy/ui/public/agg_response/point_series/__tests__/_add_to_siri.js b/src/legacy/ui/public/agg_response/point_series/__tests__/_add_to_siri.js index 7365f30511b35..8c2efbd608ed9 100644 --- a/src/legacy/ui/public/agg_response/point_series/__tests__/_add_to_siri.js +++ b/src/legacy/ui/public/agg_response/point_series/__tests__/_add_to_siri.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { addToSiri } from '../_add_to_siri'; describe('addToSiri', function () { diff --git a/src/legacy/ui/public/agg_response/point_series/__tests__/_fake_x_aspect.js b/src/legacy/ui/public/agg_response/point_series/__tests__/_fake_x_aspect.js index 7aa75105704c8..3ae59d1639b05 100644 --- a/src/legacy/ui/public/agg_response/point_series/__tests__/_fake_x_aspect.js +++ b/src/legacy/ui/public/agg_response/point_series/__tests__/_fake_x_aspect.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { makeFakeXAspect } from '../_fake_x_aspect'; describe('makeFakeXAspect', function () { diff --git a/src/legacy/ui/public/agg_response/point_series/__tests__/_get_aspects.js b/src/legacy/ui/public/agg_response/point_series/__tests__/_get_aspects.js index ad4e04fa2aaed..45b32084a4d20 100644 --- a/src/legacy/ui/public/agg_response/point_series/__tests__/_get_aspects.js +++ b/src/legacy/ui/public/agg_response/point_series/__tests__/_get_aspects.js @@ -18,7 +18,7 @@ */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getAspects } from '../_get_aspects'; describe('getAspects', function () { diff --git a/src/legacy/ui/public/agg_response/point_series/__tests__/_get_point.js b/src/legacy/ui/public/agg_response/point_series/__tests__/_get_point.js index 98d5c7c317619..bde46b3b4be17 100644 --- a/src/legacy/ui/public/agg_response/point_series/__tests__/_get_point.js +++ b/src/legacy/ui/public/agg_response/point_series/__tests__/_get_point.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getPoint } from '../_get_point'; describe('getPoint', function () { diff --git a/src/legacy/ui/public/agg_response/point_series/__tests__/_get_series.js b/src/legacy/ui/public/agg_response/point_series/__tests__/_get_series.js index 68e212bd8c159..6eee6e21a9849 100644 --- a/src/legacy/ui/public/agg_response/point_series/__tests__/_get_series.js +++ b/src/legacy/ui/public/agg_response/point_series/__tests__/_get_series.js @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getSeries } from '../_get_series'; diff --git a/src/legacy/ui/public/agg_response/point_series/__tests__/_init_x_axis.js b/src/legacy/ui/public/agg_response/point_series/__tests__/_init_x_axis.js index 83314d2ca1cf1..93ed9c2cc18dd 100644 --- a/src/legacy/ui/public/agg_response/point_series/__tests__/_init_x_axis.js +++ b/src/legacy/ui/public/agg_response/point_series/__tests__/_init_x_axis.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { initXAxis } from '../_init_x_axis'; import { makeFakeXAspect } from '../_fake_x_aspect'; diff --git a/src/legacy/ui/public/agg_response/point_series/__tests__/_init_y_axis.js b/src/legacy/ui/public/agg_response/point_series/__tests__/_init_y_axis.js index 5a730a78cfdd1..a05c019b7e4be 100644 --- a/src/legacy/ui/public/agg_response/point_series/__tests__/_init_y_axis.js +++ b/src/legacy/ui/public/agg_response/point_series/__tests__/_init_y_axis.js @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { initYAxis } from '../_init_y_axis'; describe('initYAxis', function () { diff --git a/src/legacy/ui/public/agg_response/point_series/__tests__/_main.js b/src/legacy/ui/public/agg_response/point_series/__tests__/_main.js index ba6f82c9bc70e..470a03ef0ffd6 100644 --- a/src/legacy/ui/public/agg_response/point_series/__tests__/_main.js +++ b/src/legacy/ui/public/agg_response/point_series/__tests__/_main.js @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { buildPointSeriesData } from '../point_series'; describe('pointSeriesChartDataFromTable', function () { diff --git a/src/legacy/ui/public/agg_response/point_series/__tests__/_ordered_date_axis.js b/src/legacy/ui/public/agg_response/point_series/__tests__/_ordered_date_axis.js index ea08ca56d28bb..f689c0b8d8aa5 100644 --- a/src/legacy/ui/public/agg_response/point_series/__tests__/_ordered_date_axis.js +++ b/src/legacy/ui/public/agg_response/point_series/__tests__/_ordered_date_axis.js @@ -19,7 +19,7 @@ import moment from 'moment'; import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { orderedDateAxis } from '../_ordered_date_axis'; describe('orderedDateAxis', function () { diff --git a/src/legacy/ui/public/agg_response/point_series/__tests__/_tooltip_formatter.js b/src/legacy/ui/public/agg_response/point_series/__tests__/_tooltip_formatter.js index c431e0ed9ee03..472836af52b90 100644 --- a/src/legacy/ui/public/agg_response/point_series/__tests__/_tooltip_formatter.js +++ b/src/legacy/ui/public/agg_response/point_series/__tests__/_tooltip_formatter.js @@ -19,7 +19,7 @@ import _ from 'lodash'; import $ from 'jquery'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { PointSeriesTooltipFormatter } from '../_tooltip_formatter'; diff --git a/src/legacy/ui/public/agg_response/tabify/__tests__/_buckets.js b/src/legacy/ui/public/agg_response/tabify/__tests__/_buckets.js index dfc475a949b43..9d17a508223a2 100644 --- a/src/legacy/ui/public/agg_response/tabify/__tests__/_buckets.js +++ b/src/legacy/ui/public/agg_response/tabify/__tests__/_buckets.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { TabifyBuckets } from '../_buckets'; describe('Buckets wrapper', function () { diff --git a/src/legacy/ui/public/agg_response/tabify/__tests__/_get_columns.js b/src/legacy/ui/public/agg_response/tabify/__tests__/_get_columns.js index fbc42aaa04c37..4e15f8cc4e619 100644 --- a/src/legacy/ui/public/agg_response/tabify/__tests__/_get_columns.js +++ b/src/legacy/ui/public/agg_response/tabify/__tests__/_get_columns.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { tabifyGetColumns } from '../_get_columns'; import { VisProvider } from '../../../vis'; diff --git a/src/legacy/ui/public/agg_response/tabify/__tests__/_integration.js b/src/legacy/ui/public/agg_response/tabify/__tests__/_integration.js index ad6732add3542..c11f38f38298c 100644 --- a/src/legacy/ui/public/agg_response/tabify/__tests__/_integration.js +++ b/src/legacy/ui/public/agg_response/tabify/__tests__/_integration.js @@ -19,7 +19,7 @@ import _ from 'lodash'; import fixtures from 'fixtures/fake_hierarchical_data'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { tabifyAggResponse } from '../tabify'; import { VisProvider } from '../../../vis'; diff --git a/src/legacy/ui/public/agg_response/tabify/__tests__/_response_writer.js b/src/legacy/ui/public/agg_response/tabify/__tests__/_response_writer.js index b395467146762..09668c638d695 100644 --- a/src/legacy/ui/public/agg_response/tabify/__tests__/_response_writer.js +++ b/src/legacy/ui/public/agg_response/tabify/__tests__/_response_writer.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { TabbedAggResponseWriter } from '../_response_writer'; import { VisProvider } from '../../../vis'; diff --git a/src/legacy/ui/public/agg_table/__tests__/_group.js b/src/legacy/ui/public/agg_table/__tests__/_group.js index cd0a432006fc4..89c21f9169be8 100644 --- a/src/legacy/ui/public/agg_table/__tests__/_group.js +++ b/src/legacy/ui/public/agg_table/__tests__/_group.js @@ -19,7 +19,7 @@ import $ from 'jquery'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import fixtures from 'fixtures/fake_hierarchical_data'; import { LegacyResponseHandlerProvider } from '../../vis/response_handlers/legacy'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; diff --git a/src/legacy/ui/public/agg_table/__tests__/_table.js b/src/legacy/ui/public/agg_table/__tests__/_table.js index 299da94902143..357d473de47c1 100644 --- a/src/legacy/ui/public/agg_table/__tests__/_table.js +++ b/src/legacy/ui/public/agg_table/__tests__/_table.js @@ -20,7 +20,7 @@ import $ from 'jquery'; import moment from 'moment'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import fixtures from 'fixtures/fake_hierarchical_data'; import sinon from 'sinon'; import { LegacyResponseHandlerProvider } from '../../vis/response_handlers/legacy'; diff --git a/src/legacy/ui/public/agg_types/__tests__/agg_param_writer.js b/src/legacy/ui/public/agg_types/__tests__/agg_param_writer.js index c4c619730092c..e162f59881376 100644 --- a/src/legacy/ui/public/agg_types/__tests__/agg_param_writer.js +++ b/src/legacy/ui/public/agg_types/__tests__/agg_param_writer.js @@ -22,7 +22,7 @@ import { VisProvider } from '../../vis'; import { aggTypes } from '..'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; -// eslint-disable-next-line @elastic/kibana-custom/no-default-export +// eslint-disable-next-line @kbn/eslint/no-default-export export default function AggParamWriterHelper(Private) { const Vis = Private(VisProvider); const stubbedLogstashIndexPattern = Private(FixturesStubbedLogstashIndexPatternProvider); diff --git a/src/legacy/ui/public/agg_types/__tests__/agg_params.js b/src/legacy/ui/public/agg_types/__tests__/agg_params.js index bddfa725165ad..99a9347c934a6 100644 --- a/src/legacy/ui/public/agg_types/__tests__/agg_params.js +++ b/src/legacy/ui/public/agg_types/__tests__/agg_params.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { AggParams } from '../agg_params'; import { BaseParamType } from '../param_types/base'; import { FieldParamType } from '../param_types/field'; diff --git a/src/legacy/ui/public/agg_types/__tests__/agg_type.js b/src/legacy/ui/public/agg_types/__tests__/agg_type.js index 659809175db82..496e5515c75ef 100644 --- a/src/legacy/ui/public/agg_types/__tests__/agg_type.js +++ b/src/legacy/ui/public/agg_types/__tests__/agg_type.js @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import '../../private'; import { AggParams } from '../agg_params'; diff --git a/src/legacy/ui/public/agg_types/__tests__/buckets/_geo_hash.js b/src/legacy/ui/public/agg_types/__tests__/buckets/_geo_hash.js index 041030a9afb2a..39c27f0b8db24 100644 --- a/src/legacy/ui/public/agg_types/__tests__/buckets/_geo_hash.js +++ b/src/legacy/ui/public/agg_types/__tests__/buckets/_geo_hash.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { geoHashBucketAgg } from '../../buckets/geo_hash'; import * as AggConfigModule from '../../../vis/agg_config'; diff --git a/src/legacy/ui/public/agg_types/__tests__/buckets/_histogram.js b/src/legacy/ui/public/agg_types/__tests__/buckets/_histogram.js index 02b33cf7059eb..9de472e91fc88 100644 --- a/src/legacy/ui/public/agg_types/__tests__/buckets/_histogram.js +++ b/src/legacy/ui/public/agg_types/__tests__/buckets/_histogram.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import ngMock from 'ng_mock'; import { aggTypes } from '../..'; diff --git a/src/legacy/ui/public/agg_types/__tests__/buckets/_range.js b/src/legacy/ui/public/agg_types/__tests__/buckets/_range.js index bbfc46eee1813..8aabf464e7b1c 100644 --- a/src/legacy/ui/public/agg_types/__tests__/buckets/_range.js +++ b/src/legacy/ui/public/agg_types/__tests__/buckets/_range.js @@ -19,7 +19,7 @@ import { values } from 'lodash'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import resp from 'fixtures/agg_resp/range'; import { VisProvider } from '../../../vis'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; diff --git a/src/legacy/ui/public/agg_types/__tests__/buckets/_terms_other_bucket_helper.js b/src/legacy/ui/public/agg_types/__tests__/buckets/_terms_other_bucket_helper.js index 3ea1c45d42897..d6840699074b4 100644 --- a/src/legacy/ui/public/agg_types/__tests__/buckets/_terms_other_bucket_helper.js +++ b/src/legacy/ui/public/agg_types/__tests__/buckets/_terms_other_bucket_helper.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { buildOtherBucketAgg, mergeOtherBucketAggResponse, updateMissingBucket } from '../../buckets/_terms_other_bucket_helper'; import { VisProvider } from '../../../vis'; diff --git a/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/date_histogram.js b/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/date_histogram.js index df6b9ed9ec807..a02da38511dfa 100644 --- a/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/date_histogram.js +++ b/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/date_histogram.js @@ -21,7 +21,7 @@ import _ from 'lodash'; import moment from 'moment'; import aggResp from 'fixtures/agg_resp/date_histogram'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { VisProvider } from '../../../../vis'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; import { createFilterDateHistogram } from '../../../buckets/create_filter/date_histogram'; diff --git a/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/date_range.js b/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/date_range.js index f2344bb38c178..b6557ed6d762f 100644 --- a/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/date_range.js +++ b/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/date_range.js @@ -18,7 +18,7 @@ */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import moment from 'moment'; import { VisProvider } from '../../../../vis'; diff --git a/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/filters.js b/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/filters.js index abe6be806c68a..01337f2725045 100644 --- a/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/filters.js +++ b/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/filters.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { VisProvider } from '../../../../vis'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; diff --git a/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/histogram.js b/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/histogram.js index df729aa371b10..23e66cf5f1ae7 100644 --- a/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/histogram.js +++ b/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/histogram.js @@ -18,7 +18,7 @@ */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { VisProvider } from '../../../../vis'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; diff --git a/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/ip_range.js b/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/ip_range.js index fb08d5ca6e36d..cbab24745acd7 100644 --- a/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/ip_range.js +++ b/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/ip_range.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { VisProvider } from '../../../../vis'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; diff --git a/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/range.js b/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/range.js index bc7bd22ee8287..58e7e0203c596 100644 --- a/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/range.js +++ b/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/range.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { VisProvider } from '../../../../vis'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; diff --git a/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/terms.js b/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/terms.js index 9195df7b1b662..8753806babfa2 100644 --- a/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/terms.js +++ b/src/legacy/ui/public/agg_types/__tests__/buckets/create_filter/terms.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { VisProvider } from '../../../../vis'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; diff --git a/src/legacy/ui/public/agg_types/__tests__/buckets/date_histogram/_editor.js b/src/legacy/ui/public/agg_types/__tests__/buckets/date_histogram/_editor.js index afacdc522562e..69d898be5c438 100644 --- a/src/legacy/ui/public/agg_types/__tests__/buckets/date_histogram/_editor.js +++ b/src/legacy/ui/public/agg_types/__tests__/buckets/date_histogram/_editor.js @@ -20,7 +20,7 @@ import _ from 'lodash'; import $ from 'jquery'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; import { VisProvider } from '../../../../vis'; import { intervalOptions } from '../../../buckets/_interval_options'; diff --git a/src/legacy/ui/public/agg_types/__tests__/buckets/date_histogram/_params.js b/src/legacy/ui/public/agg_types/__tests__/buckets/date_histogram/_params.js index 394ff6e526907..856da584cb68f 100644 --- a/src/legacy/ui/public/agg_types/__tests__/buckets/date_histogram/_params.js +++ b/src/legacy/ui/public/agg_types/__tests__/buckets/date_histogram/_params.js @@ -19,7 +19,7 @@ import _ from 'lodash'; import moment from 'moment'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import ngMock from 'ng_mock'; import AggParamWriterProvider from '../../agg_param_writer'; diff --git a/src/legacy/ui/public/agg_types/__tests__/buckets/terms.js b/src/legacy/ui/public/agg_types/__tests__/buckets/terms.js index 923f662451240..a5ddb1849bdbf 100644 --- a/src/legacy/ui/public/agg_types/__tests__/buckets/terms.js +++ b/src/legacy/ui/public/agg_types/__tests__/buckets/terms.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { aggTypes } from '../..'; diff --git a/src/legacy/ui/public/agg_types/__tests__/controls/number_list.js b/src/legacy/ui/public/agg_types/__tests__/controls/number_list.js index bbbdb822e0be4..12856b3363bf8 100644 --- a/src/legacy/ui/public/agg_types/__tests__/controls/number_list.js +++ b/src/legacy/ui/public/agg_types/__tests__/controls/number_list.js @@ -18,7 +18,7 @@ */ import $ from 'jquery'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import simulateKeys from 'test_utils/simulate_keys'; import ngMock from 'ng_mock'; import '../../../number_list'; diff --git a/src/legacy/ui/public/agg_types/__tests__/directives/auto_select_if_only_one.js b/src/legacy/ui/public/agg_types/__tests__/directives/auto_select_if_only_one.js index 94bbb2addebe0..9e83243811d95 100644 --- a/src/legacy/ui/public/agg_types/__tests__/directives/auto_select_if_only_one.js +++ b/src/legacy/ui/public/agg_types/__tests__/directives/auto_select_if_only_one.js @@ -18,7 +18,7 @@ */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import '../../directives/auto_select_if_only_one'; diff --git a/src/legacy/ui/public/agg_types/__tests__/directives/input_number.js b/src/legacy/ui/public/agg_types/__tests__/directives/input_number.js index 6d3a3bf19fb35..5d7937f5275a3 100644 --- a/src/legacy/ui/public/agg_types/__tests__/directives/input_number.js +++ b/src/legacy/ui/public/agg_types/__tests__/directives/input_number.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import '../../directives/input_number'; diff --git a/src/legacy/ui/public/agg_types/__tests__/directives/validate_cidr_mask.js b/src/legacy/ui/public/agg_types/__tests__/directives/validate_cidr_mask.js index 05dffe754a99a..3d5d2531ee85f 100644 --- a/src/legacy/ui/public/agg_types/__tests__/directives/validate_cidr_mask.js +++ b/src/legacy/ui/public/agg_types/__tests__/directives/validate_cidr_mask.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import '../../directives/validate_cidr_mask'; diff --git a/src/legacy/ui/public/agg_types/__tests__/directives/validate_date_math.js b/src/legacy/ui/public/agg_types/__tests__/directives/validate_date_math.js index 39bab01c96f97..5f264386a1fbc 100644 --- a/src/legacy/ui/public/agg_types/__tests__/directives/validate_date_math.js +++ b/src/legacy/ui/public/agg_types/__tests__/directives/validate_date_math.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import '../../directives/validate_date_math'; diff --git a/src/legacy/ui/public/agg_types/__tests__/directives/validate_ip.js b/src/legacy/ui/public/agg_types/__tests__/directives/validate_ip.js index 625ff4183519f..ad4c91e9081bf 100644 --- a/src/legacy/ui/public/agg_types/__tests__/directives/validate_ip.js +++ b/src/legacy/ui/public/agg_types/__tests__/directives/validate_ip.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import '../../directives/validate_ip'; diff --git a/src/legacy/ui/public/agg_types/__tests__/index.js b/src/legacy/ui/public/agg_types/__tests__/index.js index 0af05397cdc08..321fe0fa27f46 100644 --- a/src/legacy/ui/public/agg_types/__tests__/index.js +++ b/src/legacy/ui/public/agg_types/__tests__/index.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import './agg_type'; import './agg_params'; import './buckets/_histogram'; diff --git a/src/legacy/ui/public/agg_types/__tests__/metrics/lib/make_nested_label.js b/src/legacy/ui/public/agg_types/__tests__/metrics/lib/make_nested_label.js index d5bff445dc137..f122a48c29313 100644 --- a/src/legacy/ui/public/agg_types/__tests__/metrics/lib/make_nested_label.js +++ b/src/legacy/ui/public/agg_types/__tests__/metrics/lib/make_nested_label.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { makeNestedLabel } from '../../../metrics/lib/make_nested_label'; describe('metric agg make_nested_label', function () { diff --git a/src/legacy/ui/public/agg_types/__tests__/metrics/median.js b/src/legacy/ui/public/agg_types/__tests__/metrics/median.js index de81913494bae..eb1abd7450115 100644 --- a/src/legacy/ui/public/agg_types/__tests__/metrics/median.js +++ b/src/legacy/ui/public/agg_types/__tests__/metrics/median.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { VisProvider } from '../../../vis'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; diff --git a/src/legacy/ui/public/agg_types/__tests__/metrics/parent_pipeline.js b/src/legacy/ui/public/agg_types/__tests__/metrics/parent_pipeline.js index 78a9ad4d10797..606080627d86b 100644 --- a/src/legacy/ui/public/agg_types/__tests__/metrics/parent_pipeline.js +++ b/src/legacy/ui/public/agg_types/__tests__/metrics/parent_pipeline.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import ngMock from 'ng_mock'; import { derivativeMetricAgg } from '../../metrics/derivative'; diff --git a/src/legacy/ui/public/agg_types/__tests__/metrics/percentile_ranks.js b/src/legacy/ui/public/agg_types/__tests__/metrics/percentile_ranks.js index ba0f8eef5ffb1..3e3ee89b14d10 100644 --- a/src/legacy/ui/public/agg_types/__tests__/metrics/percentile_ranks.js +++ b/src/legacy/ui/public/agg_types/__tests__/metrics/percentile_ranks.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { percentileRanksMetricAgg } from '../../metrics/percentile_ranks'; import { VisProvider } from '../../../vis'; diff --git a/src/legacy/ui/public/agg_types/__tests__/metrics/percentiles.js b/src/legacy/ui/public/agg_types/__tests__/metrics/percentiles.js index b26ffe2168e65..cd790729783d3 100644 --- a/src/legacy/ui/public/agg_types/__tests__/metrics/percentiles.js +++ b/src/legacy/ui/public/agg_types/__tests__/metrics/percentiles.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { percentilesMetricAgg } from '../../metrics/percentiles'; import { VisProvider } from '../../../vis'; diff --git a/src/legacy/ui/public/agg_types/__tests__/metrics/sibling_pipeline.js b/src/legacy/ui/public/agg_types/__tests__/metrics/sibling_pipeline.js index 43ae223eaf17e..c80f7f6a9ad2c 100644 --- a/src/legacy/ui/public/agg_types/__tests__/metrics/sibling_pipeline.js +++ b/src/legacy/ui/public/agg_types/__tests__/metrics/sibling_pipeline.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import ngMock from 'ng_mock'; import { bucketSumMetricAgg } from '../../metrics/bucket_sum'; diff --git a/src/legacy/ui/public/agg_types/__tests__/metrics/std_deviation.js b/src/legacy/ui/public/agg_types/__tests__/metrics/std_deviation.js index c012d9c1f29d3..181fc9e9b37c4 100644 --- a/src/legacy/ui/public/agg_types/__tests__/metrics/std_deviation.js +++ b/src/legacy/ui/public/agg_types/__tests__/metrics/std_deviation.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { stdDeviationMetricAgg } from '../../metrics/std_deviation'; import { VisProvider } from '../../../vis'; diff --git a/src/legacy/ui/public/agg_types/__tests__/metrics/top_hit.js b/src/legacy/ui/public/agg_types/__tests__/metrics/top_hit.js index 01fc774b2d49a..d206b8f47df9b 100644 --- a/src/legacy/ui/public/agg_types/__tests__/metrics/top_hit.js +++ b/src/legacy/ui/public/agg_types/__tests__/metrics/top_hit.js @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { topHitMetricAgg } from '../../metrics/top_hit'; import { VisProvider } from '../../../vis'; diff --git a/src/legacy/ui/public/agg_types/__tests__/param_types/_field.js b/src/legacy/ui/public/agg_types/__tests__/param_types/_field.js index 01eab6866718b..94a976f98e984 100644 --- a/src/legacy/ui/public/agg_types/__tests__/param_types/_field.js +++ b/src/legacy/ui/public/agg_types/__tests__/param_types/_field.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { reject } from 'lodash'; import ngMock from 'ng_mock'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; diff --git a/src/legacy/ui/public/agg_types/__tests__/param_types/_json.js b/src/legacy/ui/public/agg_types/__tests__/param_types/_json.js index 8c2a3f96073e8..efac833cb061b 100644 --- a/src/legacy/ui/public/agg_types/__tests__/param_types/_json.js +++ b/src/legacy/ui/public/agg_types/__tests__/param_types/_json.js @@ -18,11 +18,11 @@ */ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { BaseParamType } from '../../param_types/base'; import { JsonParamType } from '../../param_types/json'; -// eslint-disable-next-line @elastic/kibana-custom/no-default-export +// eslint-disable-next-line @kbn/eslint/no-default-export export default describe('JSON', function () { const paramName = 'json_test'; let aggParam; diff --git a/src/legacy/ui/public/agg_types/__tests__/param_types/_optioned.js b/src/legacy/ui/public/agg_types/__tests__/param_types/_optioned.js index 0491976665c76..4e66f6cfbd41b 100644 --- a/src/legacy/ui/public/agg_types/__tests__/param_types/_optioned.js +++ b/src/legacy/ui/public/agg_types/__tests__/param_types/_optioned.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { BaseParamType } from '../../param_types/base'; import { OptionedParamType } from '../../param_types/optioned'; diff --git a/src/legacy/ui/public/agg_types/__tests__/param_types/_regex.js b/src/legacy/ui/public/agg_types/__tests__/param_types/_regex.js index acfb7d248f114..896a9241dbfc7 100644 --- a/src/legacy/ui/public/agg_types/__tests__/param_types/_regex.js +++ b/src/legacy/ui/public/agg_types/__tests__/param_types/_regex.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { BaseParamType } from '../../param_types/base'; import { RegexParamType } from '../../param_types/regex'; diff --git a/src/legacy/ui/public/agg_types/__tests__/param_types/_string.js b/src/legacy/ui/public/agg_types/__tests__/param_types/_string.js index 88d10c683f7c9..261b974279802 100644 --- a/src/legacy/ui/public/agg_types/__tests__/param_types/_string.js +++ b/src/legacy/ui/public/agg_types/__tests__/param_types/_string.js @@ -18,11 +18,11 @@ */ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { BaseParamType } from '../../param_types/base'; import { StringParamType } from '../../param_types/string'; -// eslint-disable-next-line @elastic/kibana-custom/no-default-export +// eslint-disable-next-line @kbn/eslint/no-default-export export default describe('String', function () { const paramName = 'json_test'; let aggParam; diff --git a/src/legacy/ui/public/agg_types/__tests__/utils.test.tsx b/src/legacy/ui/public/agg_types/__tests__/utils.test.tsx new file mode 100644 index 0000000000000..b2e2b931f9133 --- /dev/null +++ b/src/legacy/ui/public/agg_types/__tests__/utils.test.tsx @@ -0,0 +1,49 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { isValidJson } from '../utils'; + +const input = { + valid: '{ "test": "json input" }', + invalid: 'strings are not json', +}; + +describe('AggType utils', () => { + describe('isValidJson', () => { + it('should return true when empty string', () => { + expect(isValidJson('')).toBe(true); + }); + + it('should return true when undefine', () => { + expect(isValidJson(undefined as any)).toBe(true); + }); + + it('should return false when invalid string', () => { + expect(isValidJson(input.invalid)).toBe(false); + }); + + it('should return true when valid string', () => { + expect(isValidJson(input.valid)).toBe(true); + }); + + it('should return false if a number', () => { + expect(isValidJson('0')).toBe(false); + }); + }); +}); diff --git a/src/legacy/ui/public/agg_types/__tests__/utils/_stub_agg_params.js b/src/legacy/ui/public/agg_types/__tests__/utils/_stub_agg_params.js index 5f3eb734aaf7d..a9c46b09b5370 100644 --- a/src/legacy/ui/public/agg_types/__tests__/utils/_stub_agg_params.js +++ b/src/legacy/ui/public/agg_types/__tests__/utils/_stub_agg_params.js @@ -46,7 +46,7 @@ function ParamClassStub(parent, body) { * @param {PrivateLoader} Private - The private module loader, inject by passing this function to ngMock.inject() * @return {undefined} */ -// eslint-disable-next-line @elastic/kibana-custom/no-default-export +// eslint-disable-next-line @kbn/eslint/no-default-export export default function stubParamClasses(Private) { const BaseAggParam = Private.stub( BaseParamType, diff --git a/src/legacy/ui/public/agg_types/controls/raw_json.html b/src/legacy/ui/public/agg_types/controls/raw_json.html deleted file mode 100644 index f7d3f78a1f663..0000000000000 --- a/src/legacy/ui/public/agg_types/controls/raw_json.html +++ /dev/null @@ -1,23 +0,0 @@ -
- - - -

- -

-
diff --git a/src/legacy/ui/public/agg_types/controls/raw_json.tsx b/src/legacy/ui/public/agg_types/controls/raw_json.tsx new file mode 100644 index 0000000000000..5dcd555ea969b --- /dev/null +++ b/src/legacy/ui/public/agg_types/controls/raw_json.tsx @@ -0,0 +1,76 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; + +import { EuiFormRow, EuiIconTip, EuiTextArea } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { AggParamEditorProps } from '../../vis/editors/default'; +import { isValidJson } from '../utils'; + +function RawJsonParamEditor({ + agg, + value, + setValue, + isInvalid, + setValidity, +}: AggParamEditorProps) { + const label = ( + <> + {' '} + + + ); + + const onChange = (ev: React.ChangeEvent) => { + const textValue = ev.target.value; + setValue(textValue); + setValidity(isValidJson(textValue)); + }; + + setValidity(isValidJson(value)); + + return ( + + + + ); +} + +export { RawJsonParamEditor }; diff --git a/src/legacy/ui/public/agg_types/controls/string.tsx b/src/legacy/ui/public/agg_types/controls/string.tsx index c29a54cebd319..330be44b9da88 100644 --- a/src/legacy/ui/public/agg_types/controls/string.tsx +++ b/src/legacy/ui/public/agg_types/controls/string.tsx @@ -26,8 +26,8 @@ function StringParamEditor({ agg, aggParam, value, setValue }: AggParamEditorPro return ( - -
- diff --git a/src/legacy/ui/public/angular-bootstrap/alert/alert.js b/src/legacy/ui/public/angular-bootstrap/alert/alert.js deleted file mode 100755 index fd16aa49014c1..0000000000000 --- a/src/legacy/ui/public/angular-bootstrap/alert/alert.js +++ /dev/null @@ -1,20 +0,0 @@ -angular.module('ui.bootstrap.alert', []) - -.controller('AlertController', ['$scope', '$attrs', function ($scope, $attrs) { - $scope.closeable = 'close' in $attrs; - this.close = $scope.close; -}]) - -.directive('alert', function () { - return { - restrict:'EA', - controller:'AlertController', - templateUrl:'template/alert/alert.html', - transclude:true, - replace:true, - scope: { - type: '@', - close: '&' - } - }; -}) diff --git a/src/legacy/ui/public/angular-bootstrap/index.js b/src/legacy/ui/public/angular-bootstrap/index.js index 6743511a55eb0..c86da04f5bc41 100644 --- a/src/legacy/ui/public/angular-bootstrap/index.js +++ b/src/legacy/ui/public/angular-bootstrap/index.js @@ -23,49 +23,22 @@ uiModules.get('kibana', [ angular.module('ui.bootstrap', [ 'ui.bootstrap.tpls', 'ui.bootstrap.transition', - 'ui.bootstrap.alert', 'ui.bootstrap.bindHtml', - 'ui.bootstrap.position', 'ui.bootstrap.modal', - 'ui.bootstrap.pagination', 'ui.bootstrap.tooltip', - 'ui.bootstrap.progressbar', - 'ui.bootstrap.timepicker', - 'ui.bootstrap.typeahead' ]); angular.module('ui.bootstrap.tpls', [ - 'template/alert/alert.html', 'template/modal/backdrop.html', 'template/modal/window.html', - 'template/pagination/pager.html', - 'template/pagination/pagination.html', 'template/tooltip/tooltip-html-unsafe-popup.html', 'template/tooltip/tooltip-popup.html', - 'template/progressbar/bar.html', - 'template/progressbar/progress.html', - 'template/progressbar/progressbar.html', - 'template/timepicker/timepicker.html', - 'template/typeahead/typeahead-match.html', - 'template/typeahead/typeahead-popup.html' ]); -import './alert/alert'; import './bindHtml/bindHtml'; import './modal/modal'; -import './pagination/pagination'; -import './position/position'; -import './progressbar/progressbar'; -import './timepicker/timepicker'; import './tooltip/tooltip'; import './transition/transition'; -import './typeahead/typeahead'; - -import alert from './alert/alert.html'; - -angular.module('template/alert/alert.html', []).run(['$templateCache', function($templateCache) { - $templateCache.put('template/alert/alert.html', alert); -}]); import backdrop from './modal/backdrop.html'; @@ -79,62 +52,14 @@ angular.module('template/modal/window.html', []).run(['$templateCache', function $templateCache.put('template/modal/window.html', modal); }]); -import pager from './pagination/pager.html'; - -angular.module('template/pagination/pager.html', []).run(['$templateCache', function($templateCache) { - $templateCache.put('template/pagination/pager.html', pager); -}]); - -import pagination from './pagination/pagination.html'; - -angular.module('template/pagination/pagination.html', []).run(['$templateCache', function($templateCache) { - $templateCache.put('template/pagination/pagination.html', pagination); -}]); - -import tooltipUnsafePopup from './tooltip/tooltip-html-unsafe-popup.html'; - -angular.module('template/tooltip/tooltip-html-unsafe-popup.html', []).run(['$templateCache', function($templateCache) { - $templateCache.put('template/tooltip/tooltip-html-unsafe-popup.html', tooltipUnsafePopup); -}]); - -import tooltipPopup from './tooltip/tooltip-popup.html'; - -angular.module('template/tooltip/tooltip-popup.html', []).run(['$templateCache', function($templateCache) { - $templateCache.put('template/tooltip/tooltip-popup.html', tooltipPopup); -}]); - -import bar from './progressbar/bar.html'; - -angular.module('template/progressbar/bar.html', []).run(['$templateCache', function($templateCache) { - $templateCache.put('template/progressbar/bar.html', bar); -}]); - -import progress from './progressbar/progress.html'; - -angular.module('template/progressbar/progress.html', []).run(['$templateCache', function($templateCache) { - $templateCache.put('template/progressbar/progress.html', progress); -}]); - -import progressbar from './progressbar/progressbar.html'; +import tooltipUnsafePopup from './tooltip/tooltip-html-unsafe-popup.html'; -angular.module('template/progressbar/progressbar.html', []).run(['$templateCache', function($templateCache) { - $templateCache.put('template/progressbar/progressbar.html', progressbar); -}]); - -import timepicker from './timepicker/timepicker.html'; - -angular.module('template/timepicker/timepicker.html', []).run(['$templateCache', function($templateCache) { - $templateCache.put('template/timepicker/timepicker.html', timepicker); -}]); - -import typeaheadMatch from './typeahead/typeahead-match.html'; - -angular.module('template/typeahead/typeahead-match.html', []).run(['$templateCache', function($templateCache) { - $templateCache.put('template/typeahead/typeahead-match.html', typeaheadMatch); -}]); +angular.module('template/tooltip/tooltip-html-unsafe-popup.html', []).run(['$templateCache', function($templateCache) { + $templateCache.put('template/tooltip/tooltip-html-unsafe-popup.html', tooltipUnsafePopup); +}]); -import typeaheadPopup from './typeahead/typeahead-popup.html'; +import tooltipPopup from './tooltip/tooltip-popup.html'; -angular.module('template/typeahead/typeahead-popup.html', []).run(['$templateCache', function($templateCache) { - $templateCache.put('template/typeahead/typeahead-popup.html', typeaheadPopup); +angular.module('template/tooltip/tooltip-popup.html', []).run(['$templateCache', function($templateCache) { + $templateCache.put('template/tooltip/tooltip-popup.html', tooltipPopup); }]); diff --git a/src/legacy/ui/public/angular-bootstrap/pagination/pager.html b/src/legacy/ui/public/angular-bootstrap/pagination/pager.html deleted file mode 100755 index ca150de164255..0000000000000 --- a/src/legacy/ui/public/angular-bootstrap/pagination/pager.html +++ /dev/null @@ -1,4 +0,0 @@ - \ No newline at end of file diff --git a/src/legacy/ui/public/angular-bootstrap/pagination/pagination.html b/src/legacy/ui/public/angular-bootstrap/pagination/pagination.html deleted file mode 100755 index cd45d290d5142..0000000000000 --- a/src/legacy/ui/public/angular-bootstrap/pagination/pagination.html +++ /dev/null @@ -1,7 +0,0 @@ - \ No newline at end of file diff --git a/src/legacy/ui/public/angular-bootstrap/pagination/pagination.js b/src/legacy/ui/public/angular-bootstrap/pagination/pagination.js deleted file mode 100755 index dee4bbb2199f0..0000000000000 --- a/src/legacy/ui/public/angular-bootstrap/pagination/pagination.js +++ /dev/null @@ -1,228 +0,0 @@ -import { i18n } from '@kbn/i18n'; - -angular.module('ui.bootstrap.pagination', []) - -.controller('PaginationController', ['$scope', '$attrs', '$parse', function ($scope, $attrs, $parse) { - var self = this, - ngModelCtrl = { $setViewValue: angular.noop }, // nullModelCtrl - setNumPages = $attrs.numPages ? $parse($attrs.numPages).assign : angular.noop; - - this.init = function(ngModelCtrl_, config) { - ngModelCtrl = ngModelCtrl_; - this.config = config; - - ngModelCtrl.$render = function() { - self.render(); - }; - - if ($attrs.itemsPerPage) { - $scope.$parent.$watch($parse($attrs.itemsPerPage), function(value) { - self.itemsPerPage = parseInt(value, 10); - $scope.totalPages = self.calculateTotalPages(); - }); - } else { - this.itemsPerPage = config.itemsPerPage; - } - }; - - this.calculateTotalPages = function() { - var totalPages = this.itemsPerPage < 1 ? 1 : Math.ceil($scope.totalItems / this.itemsPerPage); - return Math.max(totalPages || 0, 1); - }; - - this.render = function() { - $scope.page = parseInt(ngModelCtrl.$viewValue, 10) || 1; - }; - - $scope.selectPage = function(page) { - if ( $scope.page !== page && page > 0 && page <= $scope.totalPages) { - ngModelCtrl.$setViewValue(page); - ngModelCtrl.$render(); - } - }; - - $scope.getText = function( key ) { - return $scope[key + 'Text'] || self.config[key + 'Text']; - }; - $scope.noPrevious = function() { - return $scope.page === 1; - }; - $scope.noNext = function() { - return $scope.page === $scope.totalPages; - }; - - $scope.$watch('totalItems', function() { - $scope.totalPages = self.calculateTotalPages(); - }); - - $scope.$watch('totalPages', function(value) { - setNumPages($scope.$parent, value); // Readonly variable - - if ( $scope.page > value ) { - $scope.selectPage(value); - } else { - ngModelCtrl.$render(); - } - }); -}]) - -.constant('paginationConfig', { - itemsPerPage: 10, - boundaryLinks: false, - directionLinks: true, - firstText: i18n.translate('common.ui.angularBootstrap.pagination.paginationConfig.firstLabel', { - defaultMessage: 'First' - }), - previousText: i18n.translate('common.ui.angularBootstrap.pagination.paginationConfig.previousLabel', { - defaultMessage: 'Previous' - }), - nextText: i18n.translate('common.ui.angularBootstrap.pagination.paginationConfig.nextLabel', { - defaultMessage: 'Next' - }), - lastText: i18n.translate('common.ui.angularBootstrap.pagination.paginationConfig.lastLabel', { - defaultMessage: 'Last' - }), - rotate: true -}) - -.directive('pagination', ['$parse', 'paginationConfig', function($parse, paginationConfig) { - return { - restrict: 'EA', - scope: { - totalItems: '=', - firstText: '@', - previousText: '@', - nextText: '@', - lastText: '@' - }, - require: ['pagination', '?ngModel'], - controller: 'PaginationController', - templateUrl: 'template/pagination/pagination.html', - replace: true, - link: function(scope, element, attrs, ctrls) { - var paginationCtrl = ctrls[0], ngModelCtrl = ctrls[1]; - - if (!ngModelCtrl) { - return; // do nothing if no ng-model - } - - // Setup configuration parameters - var maxSize = angular.isDefined(attrs.maxSize) ? scope.$parent.$eval(attrs.maxSize) : paginationConfig.maxSize, - rotate = angular.isDefined(attrs.rotate) ? scope.$parent.$eval(attrs.rotate) : paginationConfig.rotate; - scope.boundaryLinks = angular.isDefined(attrs.boundaryLinks) ? scope.$parent.$eval(attrs.boundaryLinks) : paginationConfig.boundaryLinks; - scope.directionLinks = angular.isDefined(attrs.directionLinks) ? scope.$parent.$eval(attrs.directionLinks) : paginationConfig.directionLinks; - - paginationCtrl.init(ngModelCtrl, paginationConfig); - - if (attrs.maxSize) { - scope.$parent.$watch($parse(attrs.maxSize), function(value) { - maxSize = parseInt(value, 10); - paginationCtrl.render(); - }); - } - - // Create page object used in template - function makePage(number, text, isActive) { - return { - number: number, - text: text, - active: isActive - }; - } - - function getPages(currentPage, totalPages) { - var pages = []; - - // Default page limits - var startPage = 1, endPage = totalPages; - var isMaxSized = ( angular.isDefined(maxSize) && maxSize < totalPages ); - - // recompute if maxSize - if ( isMaxSized ) { - if ( rotate ) { - // Current page is displayed in the middle of the visible ones - startPage = Math.max(currentPage - Math.floor(maxSize/2), 1); - endPage = startPage + maxSize - 1; - - // Adjust if limit is exceeded - if (endPage > totalPages) { - endPage = totalPages; - startPage = endPage - maxSize + 1; - } - } else { - // Visible pages are paginated with maxSize - startPage = ((Math.ceil(currentPage / maxSize) - 1) * maxSize) + 1; - - // Adjust last page if limit is exceeded - endPage = Math.min(startPage + maxSize - 1, totalPages); - } - } - - // Add page number links - for (var number = startPage; number <= endPage; number++) { - var page = makePage(number, number, number === currentPage); - pages.push(page); - } - - // Add links to move between page sets - if ( isMaxSized && ! rotate ) { - if ( startPage > 1 ) { - var previousPageSet = makePage(startPage - 1, '...', false); - pages.unshift(previousPageSet); - } - - if ( endPage < totalPages ) { - var nextPageSet = makePage(endPage + 1, '...', false); - pages.push(nextPageSet); - } - } - - return pages; - } - - var originalRender = paginationCtrl.render; - paginationCtrl.render = function() { - originalRender(); - if (scope.page > 0 && scope.page <= scope.totalPages) { - scope.pages = getPages(scope.page, scope.totalPages); - } - }; - } - }; -}]) - -.constant('pagerConfig', { - itemsPerPage: 10, - previousText: i18n.translate('common.ui.angularBootstrap.pagination.pagerConfig.previousLabel', { - defaultMessage: '« Previous' - }), - nextText: i18n.translate('common.ui.angularBootstrap.pagination.pagerConfig.nextLabel', { - defaultMessage: 'Next »' - }), - align: true -}) - -.directive('pager', ['pagerConfig', function(pagerConfig) { - return { - restrict: 'EA', - scope: { - totalItems: '=', - previousText: '@', - nextText: '@' - }, - require: ['pager', '?ngModel'], - controller: 'PaginationController', - templateUrl: 'template/pagination/pager.html', - replace: true, - link: function(scope, element, attrs, ctrls) { - var paginationCtrl = ctrls[0], ngModelCtrl = ctrls[1]; - - if (!ngModelCtrl) { - return; // do nothing if no ng-model - } - - scope.align = angular.isDefined(attrs.align) ? scope.$parent.$eval(attrs.align) : pagerConfig.align; - paginationCtrl.init(ngModelCtrl, pagerConfig); - } - }; -}]); diff --git a/src/legacy/ui/public/angular-bootstrap/progressbar/bar.html b/src/legacy/ui/public/angular-bootstrap/progressbar/bar.html deleted file mode 100755 index bde46dca5515f..0000000000000 --- a/src/legacy/ui/public/angular-bootstrap/progressbar/bar.html +++ /dev/null @@ -1 +0,0 @@ -
\ No newline at end of file diff --git a/src/legacy/ui/public/angular-bootstrap/progressbar/progress.html b/src/legacy/ui/public/angular-bootstrap/progressbar/progress.html deleted file mode 100755 index 1968537006087..0000000000000 --- a/src/legacy/ui/public/angular-bootstrap/progressbar/progress.html +++ /dev/null @@ -1 +0,0 @@ -
\ No newline at end of file diff --git a/src/legacy/ui/public/angular-bootstrap/progressbar/progressbar.html b/src/legacy/ui/public/angular-bootstrap/progressbar/progressbar.html deleted file mode 100755 index efb6503302e32..0000000000000 --- a/src/legacy/ui/public/angular-bootstrap/progressbar/progressbar.html +++ /dev/null @@ -1,3 +0,0 @@ -
-
-
\ No newline at end of file diff --git a/src/legacy/ui/public/angular-bootstrap/progressbar/progressbar.js b/src/legacy/ui/public/angular-bootstrap/progressbar/progressbar.js deleted file mode 100755 index 9a6a6355d78b3..0000000000000 --- a/src/legacy/ui/public/angular-bootstrap/progressbar/progressbar.js +++ /dev/null @@ -1,81 +0,0 @@ -angular.module('ui.bootstrap.progressbar', []) - -.constant('progressConfig', { - animate: true, - max: 100 -}) - -.controller('ProgressController', ['$scope', '$attrs', 'progressConfig', function($scope, $attrs, progressConfig) { - var self = this, - animate = angular.isDefined($attrs.animate) ? $scope.$parent.$eval($attrs.animate) : progressConfig.animate; - - this.bars = []; - $scope.max = angular.isDefined($attrs.max) ? $scope.$parent.$eval($attrs.max) : progressConfig.max; - - this.addBar = function(bar, element) { - if ( !animate ) { - element.css({'transition': 'none'}); - } - - this.bars.push(bar); - - bar.$watch('value', function( value ) { - bar.percent = +(100 * value / $scope.max).toFixed(2); - }); - - bar.$on('$destroy', function() { - element = null; - self.removeBar(bar); - }); - }; - - this.removeBar = function(bar) { - this.bars.splice(this.bars.indexOf(bar), 1); - }; -}]) - -.directive('progress', function() { - return { - restrict: 'EA', - replace: true, - transclude: true, - controller: 'ProgressController', - require: 'progress', - scope: {}, - templateUrl: 'template/progressbar/progress.html' - }; -}) - -.directive('bar', function() { - return { - restrict: 'EA', - replace: true, - transclude: true, - require: '^progress', - scope: { - value: '=', - type: '@' - }, - templateUrl: 'template/progressbar/bar.html', - link: function(scope, element, attrs, progressCtrl) { - progressCtrl.addBar(scope, element); - } - }; -}) - -.directive('progressbar', function() { - return { - restrict: 'EA', - replace: true, - transclude: true, - controller: 'ProgressController', - scope: { - value: '=', - type: '@' - }, - templateUrl: 'template/progressbar/progressbar.html', - link: function(scope, element, attrs, progressCtrl) { - progressCtrl.addBar(scope, angular.element(element.children()[0])); - } - }; -}); \ No newline at end of file diff --git a/src/legacy/ui/public/angular-bootstrap/timepicker/timepicker.html b/src/legacy/ui/public/angular-bootstrap/timepicker/timepicker.html deleted file mode 100755 index dabca515438b8..0000000000000 --- a/src/legacy/ui/public/angular-bootstrap/timepicker/timepicker.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - -
 
- - : - -
 
diff --git a/src/legacy/ui/public/angular-bootstrap/timepicker/timepicker.js b/src/legacy/ui/public/angular-bootstrap/timepicker/timepicker.js deleted file mode 100755 index 91ac86bcee3ff..0000000000000 --- a/src/legacy/ui/public/angular-bootstrap/timepicker/timepicker.js +++ /dev/null @@ -1,254 +0,0 @@ -angular.module('ui.bootstrap.timepicker', []) - -.constant('timepickerConfig', { - hourStep: 1, - minuteStep: 1, - showMeridian: true, - meridians: null, - readonlyInput: false, - mousewheel: true -}) - -.controller('TimepickerController', ['$scope', '$attrs', '$parse', '$log', '$locale', 'timepickerConfig', function($scope, $attrs, $parse, $log, $locale, timepickerConfig) { - var selected = new Date(), - ngModelCtrl = { $setViewValue: angular.noop }, // nullModelCtrl - meridians = angular.isDefined($attrs.meridians) ? $scope.$parent.$eval($attrs.meridians) : timepickerConfig.meridians || $locale.DATETIME_FORMATS.AMPMS; - - this.init = function( ngModelCtrl_, inputs ) { - ngModelCtrl = ngModelCtrl_; - ngModelCtrl.$render = this.render; - - var hoursInputEl = inputs.eq(0), - minutesInputEl = inputs.eq(1); - - var mousewheel = angular.isDefined($attrs.mousewheel) ? $scope.$parent.$eval($attrs.mousewheel) : timepickerConfig.mousewheel; - if ( mousewheel ) { - this.setupMousewheelEvents( hoursInputEl, minutesInputEl ); - } - - $scope.readonlyInput = angular.isDefined($attrs.readonlyInput) ? $scope.$parent.$eval($attrs.readonlyInput) : timepickerConfig.readonlyInput; - this.setupInputEvents( hoursInputEl, minutesInputEl ); - }; - - var hourStep = timepickerConfig.hourStep; - if ($attrs.hourStep) { - $scope.$parent.$watch($parse($attrs.hourStep), function(value) { - hourStep = parseInt(value, 10); - }); - } - - var minuteStep = timepickerConfig.minuteStep; - if ($attrs.minuteStep) { - $scope.$parent.$watch($parse($attrs.minuteStep), function(value) { - minuteStep = parseInt(value, 10); - }); - } - - // 12H / 24H mode - $scope.showMeridian = timepickerConfig.showMeridian; - if ($attrs.showMeridian) { - $scope.$parent.$watch($parse($attrs.showMeridian), function(value) { - $scope.showMeridian = !!value; - - if ( ngModelCtrl.$error.time ) { - // Evaluate from template - var hours = getHoursFromTemplate(), minutes = getMinutesFromTemplate(); - if (angular.isDefined( hours ) && angular.isDefined( minutes )) { - selected.setHours( hours ); - refresh(); - } - } else { - updateTemplate(); - } - }); - } - - // Get $scope.hours in 24H mode if valid - function getHoursFromTemplate ( ) { - var hours = parseInt( $scope.hours, 10 ); - var valid = ( $scope.showMeridian ) ? (hours > 0 && hours < 13) : (hours >= 0 && hours < 24); - if ( !valid ) { - return undefined; - } - - if ( $scope.showMeridian ) { - if ( hours === 12 ) { - hours = 0; - } - if ( $scope.meridian === meridians[1] ) { - hours = hours + 12; - } - } - return hours; - } - - function getMinutesFromTemplate() { - var minutes = parseInt($scope.minutes, 10); - return ( minutes >= 0 && minutes < 60 ) ? minutes : undefined; - } - - function pad( value ) { - return ( angular.isDefined(value) && value.toString().length < 2 ) ? '0' + value : value; - } - - // Respond on mousewheel spin - this.setupMousewheelEvents = function( hoursInputEl, minutesInputEl ) { - var isScrollingUp = function(e) { - if (e.originalEvent) { - e = e.originalEvent; - } - //pick correct delta variable depending on event - var delta = (e.wheelDelta) ? e.wheelDelta : -e.deltaY; - return (e.detail || delta > 0); - }; - - hoursInputEl.bind('mousewheel wheel', function(e) { - $scope.$apply( (isScrollingUp(e)) ? $scope.incrementHours() : $scope.decrementHours() ); - e.preventDefault(); - }); - - minutesInputEl.bind('mousewheel wheel', function(e) { - $scope.$apply( (isScrollingUp(e)) ? $scope.incrementMinutes() : $scope.decrementMinutes() ); - e.preventDefault(); - }); - - }; - - this.setupInputEvents = function( hoursInputEl, minutesInputEl ) { - if ( $scope.readonlyInput ) { - $scope.updateHours = angular.noop; - $scope.updateMinutes = angular.noop; - return; - } - - var invalidate = function(invalidHours, invalidMinutes) { - ngModelCtrl.$setViewValue( null ); - ngModelCtrl.$setValidity('time', false); - if (angular.isDefined(invalidHours)) { - $scope.invalidHours = invalidHours; - } - if (angular.isDefined(invalidMinutes)) { - $scope.invalidMinutes = invalidMinutes; - } - }; - - $scope.updateHours = function() { - var hours = getHoursFromTemplate(); - - if ( angular.isDefined(hours) ) { - selected.setHours( hours ); - refresh( 'h' ); - } else { - invalidate(true); - } - }; - - hoursInputEl.bind('blur', function(e) { - if ( !$scope.invalidHours && $scope.hours < 10) { - $scope.$apply( function() { - $scope.hours = pad( $scope.hours ); - }); - } - }); - - $scope.updateMinutes = function() { - var minutes = getMinutesFromTemplate(); - - if ( angular.isDefined(minutes) ) { - selected.setMinutes( minutes ); - refresh( 'm' ); - } else { - invalidate(undefined, true); - } - }; - - minutesInputEl.bind('blur', function(e) { - if ( !$scope.invalidMinutes && $scope.minutes < 10 ) { - $scope.$apply( function() { - $scope.minutes = pad( $scope.minutes ); - }); - } - }); - - }; - - this.render = function() { - var date = ngModelCtrl.$modelValue ? new Date( ngModelCtrl.$modelValue ) : null; - - if ( isNaN(date) ) { - ngModelCtrl.$setValidity('time', false); - $log.error('Timepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.'); - } else { - if ( date ) { - selected = date; - } - makeValid(); - updateTemplate(); - } - }; - - // Call internally when we know that model is valid. - function refresh( keyboardChange ) { - makeValid(); - ngModelCtrl.$setViewValue( new Date(selected) ); - updateTemplate( keyboardChange ); - } - - function makeValid() { - ngModelCtrl.$setValidity('time', true); - $scope.invalidHours = false; - $scope.invalidMinutes = false; - } - - function updateTemplate( keyboardChange ) { - var hours = selected.getHours(), minutes = selected.getMinutes(); - - if ( $scope.showMeridian ) { - hours = ( hours === 0 || hours === 12 ) ? 12 : hours % 12; // Convert 24 to 12 hour system - } - - $scope.hours = keyboardChange === 'h' ? hours : pad(hours); - $scope.minutes = keyboardChange === 'm' ? minutes : pad(minutes); - $scope.meridian = selected.getHours() < 12 ? meridians[0] : meridians[1]; - } - - function addMinutes( minutes ) { - var dt = new Date( selected.getTime() + minutes * 60000 ); - selected.setHours( dt.getHours(), dt.getMinutes() ); - refresh(); - } - - $scope.incrementHours = function() { - addMinutes( hourStep * 60 ); - }; - $scope.decrementHours = function() { - addMinutes( - hourStep * 60 ); - }; - $scope.incrementMinutes = function() { - addMinutes( minuteStep ); - }; - $scope.decrementMinutes = function() { - addMinutes( - minuteStep ); - }; - $scope.toggleMeridian = function() { - addMinutes( 12 * 60 * (( selected.getHours() < 12 ) ? 1 : -1) ); - }; -}]) - -.directive('timepicker', function () { - return { - restrict: 'EA', - require: ['timepicker', '?^ngModel'], - controller:'TimepickerController', - replace: true, - scope: {}, - templateUrl: 'template/timepicker/timepicker.html', - link: function(scope, element, attrs, ctrls) { - var timepickerCtrl = ctrls[0], ngModelCtrl = ctrls[1]; - - if ( ngModelCtrl ) { - timepickerCtrl.init( ngModelCtrl, element.find('input') ); - } - } - }; -}); diff --git a/src/legacy/ui/public/angular-bootstrap/position/position.js b/src/legacy/ui/public/angular-bootstrap/tooltip/position.js similarity index 100% rename from src/legacy/ui/public/angular-bootstrap/position/position.js rename to src/legacy/ui/public/angular-bootstrap/tooltip/position.js diff --git a/src/legacy/ui/public/angular-bootstrap/tooltip/tooltip-html-unsafe-popup.html b/src/legacy/ui/public/angular-bootstrap/tooltip/tooltip-html-unsafe-popup.html old mode 100755 new mode 100644 index 8203297276be9..b48bf70498906 --- a/src/legacy/ui/public/angular-bootstrap/tooltip/tooltip-html-unsafe-popup.html +++ b/src/legacy/ui/public/angular-bootstrap/tooltip/tooltip-html-unsafe-popup.html @@ -1,4 +1,4 @@ -
-
-
-
+
+
+
+
\ No newline at end of file diff --git a/src/legacy/ui/public/angular-bootstrap/tooltip/tooltip-popup.html b/src/legacy/ui/public/angular-bootstrap/tooltip/tooltip-popup.html old mode 100755 new mode 100644 index b464bbb0f3090..eed4ca7d93016 --- a/src/legacy/ui/public/angular-bootstrap/tooltip/tooltip-popup.html +++ b/src/legacy/ui/public/angular-bootstrap/tooltip/tooltip-popup.html @@ -1,4 +1,4 @@ -
-
-
-
+
+
+
+
\ No newline at end of file diff --git a/src/legacy/ui/public/angular-bootstrap/tooltip/tooltip.js b/src/legacy/ui/public/angular-bootstrap/tooltip/tooltip.js index 94199dadb8dbd..b59b2922d8089 100755 --- a/src/legacy/ui/public/angular-bootstrap/tooltip/tooltip.js +++ b/src/legacy/ui/public/angular-bootstrap/tooltip/tooltip.js @@ -1,9 +1,11 @@ +import './position'; + /** * The following features are still outstanding: animation as a * function, placement as a function, inside, support for more triggers than * just mouse enter/leave, html tooltips, and selector delegation. */ -angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap.bindHtml' ] ) +angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position' ] ) /** * The $tooltip service creates tooltip- and popover-like directives as well as @@ -345,28 +347,28 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap }]; }) -.directive( 'tooltipPopup', function () { - return { - restrict: 'EA', - replace: true, - scope: { content: '@', placement: '@', animation: '&', isOpen: '&' }, - templateUrl: 'template/tooltip/tooltip-popup.html' - }; -}) - .directive( 'tooltip', [ '$tooltip', function ( $tooltip ) { return $tooltip( 'tooltip', 'tooltip', 'mouseenter' ); }]) -.directive( 'tooltipHtmlUnsafePopup', function () { - return { - restrict: 'EA', - replace: true, - scope: { content: '@', placement: '@', animation: '&', isOpen: '&' }, - templateUrl: 'template/tooltip/tooltip-html-unsafe-popup.html' - }; +.directive( 'tooltipPopup', function () { + return { + restrict: 'EA', + replace: true, + scope: { content: '@', placement: '@', animation: '&', isOpen: '&' }, + templateUrl: 'template/tooltip/tooltip-popup.html' + }; }) .directive( 'tooltipHtmlUnsafe', [ '$tooltip', function ( $tooltip ) { return $tooltip( 'tooltipHtmlUnsafe', 'tooltip', 'mouseenter' ); -}]); +}]) + +.directive( 'tooltipHtmlUnsafePopup', function () { + return { + restrict: 'EA', + replace: true, + scope: { content: '@', placement: '@', animation: '&', isOpen: '&' }, + templateUrl: 'template/tooltip/tooltip-html-unsafe-popup.html' + }; +}); \ No newline at end of file diff --git a/src/legacy/ui/public/angular-bootstrap/typeahead/typeahead-match.html b/src/legacy/ui/public/angular-bootstrap/typeahead/typeahead-match.html deleted file mode 100755 index d79e10a18f8a0..0000000000000 --- a/src/legacy/ui/public/angular-bootstrap/typeahead/typeahead-match.html +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/legacy/ui/public/angular-bootstrap/typeahead/typeahead-popup.html b/src/legacy/ui/public/angular-bootstrap/typeahead/typeahead-popup.html deleted file mode 100755 index e1bd0c1c476d8..0000000000000 --- a/src/legacy/ui/public/angular-bootstrap/typeahead/typeahead-popup.html +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/src/legacy/ui/public/angular-bootstrap/typeahead/typeahead.js b/src/legacy/ui/public/angular-bootstrap/typeahead/typeahead.js deleted file mode 100755 index 53d7162da84b2..0000000000000 --- a/src/legacy/ui/public/angular-bootstrap/typeahead/typeahead.js +++ /dev/null @@ -1,398 +0,0 @@ -angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap.bindHtml']) - -/** - * A helper service that can parse typeahead's syntax (string provided by users) - * Extracted to a separate service for ease of unit testing - */ - .factory('typeaheadParser', ['$parse', function ($parse) { - - // 00000111000000000000022200000000000000003333333333333330000000000044000 - var TYPEAHEAD_REGEXP = /^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w\d]*))\s+in\s+([\s\S]+?)$/; - - return { - parse:function (input) { - - var match = input.match(TYPEAHEAD_REGEXP); - if (!match) { - throw new Error( - 'Expected typeahead specification in form of "_modelValue_ (as _label_)? for _item_ in _collection_"' + - ' but got "' + input + '".'); - } - - return { - itemName:match[3], - source:$parse(match[4]), - viewMapper:$parse(match[2] || match[1]), - modelMapper:$parse(match[1]) - }; - } - }; -}]) - - .directive('typeahead', ['$compile', '$parse', '$q', '$timeout', '$document', '$position', 'typeaheadParser', - function ($compile, $parse, $q, $timeout, $document, $position, typeaheadParser) { - - var HOT_KEYS = [9, 13, 27, 38, 40]; - - return { - require:'ngModel', - link:function (originalScope, element, attrs, modelCtrl) { - - //SUPPORTED ATTRIBUTES (OPTIONS) - - //minimal no of characters that needs to be entered before typeahead kicks-in - var minSearch = originalScope.$eval(attrs.typeaheadMinLength) || 1; - - //minimal wait time after last character typed before typehead kicks-in - var waitTime = originalScope.$eval(attrs.typeaheadWaitMs) || 0; - - //should it restrict model values to the ones selected from the popup only? - var isEditable = originalScope.$eval(attrs.typeaheadEditable) !== false; - - //binding to a variable that indicates if matches are being retrieved asynchronously - var isLoadingSetter = $parse(attrs.typeaheadLoading).assign || angular.noop; - - //a callback executed when a match is selected - var onSelectCallback = $parse(attrs.typeaheadOnSelect); - - var inputFormatter = attrs.typeaheadInputFormatter ? $parse(attrs.typeaheadInputFormatter) : undefined; - - var appendToBody = attrs.typeaheadAppendToBody ? originalScope.$eval(attrs.typeaheadAppendToBody) : false; - - var focusFirst = originalScope.$eval(attrs.typeaheadFocusFirst) !== false; - - //INTERNAL VARIABLES - - //model setter executed upon match selection - var $setModelValue = $parse(attrs.ngModel).assign; - - //expressions used by typeahead - var parserResult = typeaheadParser.parse(attrs.typeahead); - - var hasFocus; - - //create a child scope for the typeahead directive so we are not polluting original scope - //with typeahead-specific data (matches, query etc.) - var scope = originalScope.$new(); - originalScope.$on('$destroy', function(){ - scope.$destroy(); - }); - - // WAI-ARIA - var popupId = 'typeahead-' + scope.$id + '-' + Math.floor(Math.random() * 10000); - element.attr({ - 'aria-autocomplete': 'list', - 'aria-expanded': false, - 'aria-owns': popupId - }); - - //pop-up element used to display matches - var popUpEl = angular.element('
'); - popUpEl.attr({ - id: popupId, - matches: 'matches', - active: 'activeIdx', - select: 'select(activeIdx)', - query: 'query', - position: 'position' - }); - //custom item template - if (angular.isDefined(attrs.typeaheadTemplateUrl)) { - popUpEl.attr('template-url', attrs.typeaheadTemplateUrl); - } - - var resetMatches = function() { - scope.matches = []; - scope.activeIdx = -1; - element.attr('aria-expanded', false); - }; - - var getMatchId = function(index) { - return popupId + '-option-' + index; - }; - - // Indicate that the specified match is the active (pre-selected) item in the list owned by this typeahead. - // This attribute is added or removed automatically when the `activeIdx` changes. - scope.$watch('activeIdx', function(index) { - if (index < 0) { - element.removeAttr('aria-activedescendant'); - } else { - element.attr('aria-activedescendant', getMatchId(index)); - } - }); - - var getMatchesAsync = function(inputValue) { - - var locals = {$viewValue: inputValue}; - isLoadingSetter(originalScope, true); - $q.when(parserResult.source(originalScope, locals)).then(function(matches) { - - //it might happen that several async queries were in progress if a user were typing fast - //but we are interested only in responses that correspond to the current view value - var onCurrentRequest = (inputValue === modelCtrl.$viewValue); - if (onCurrentRequest && hasFocus) { - if (matches.length > 0) { - - scope.activeIdx = focusFirst ? 0 : -1; - scope.matches.length = 0; - - //transform labels - for(var i=0; i= minSearch) { - if (waitTime > 0) { - cancelPreviousTimeout(); - scheduleSearchWithTimeout(inputValue); - } else { - getMatchesAsync(inputValue); - } - } else { - isLoadingSetter(originalScope, false); - cancelPreviousTimeout(); - resetMatches(); - } - - if (isEditable) { - return inputValue; - } else { - if (!inputValue) { - // Reset in case user had typed something previously. - modelCtrl.$setValidity('editable', true); - return inputValue; - } else { - modelCtrl.$setValidity('editable', false); - return undefined; - } - } - }); - - modelCtrl.$formatters.push(function (modelValue) { - - var candidateViewValue, emptyViewValue; - var locals = {}; - - if (inputFormatter) { - - locals.$model = modelValue; - return inputFormatter(originalScope, locals); - - } else { - - //it might happen that we don't have enough info to properly render input value - //we need to check for this situation and simply return model value if we can't apply custom formatting - locals[parserResult.itemName] = modelValue; - candidateViewValue = parserResult.viewMapper(originalScope, locals); - locals[parserResult.itemName] = undefined; - emptyViewValue = parserResult.viewMapper(originalScope, locals); - - return candidateViewValue!== emptyViewValue ? candidateViewValue : modelValue; - } - }); - - scope.select = function (activeIdx) { - //called from within the $digest() cycle - var locals = {}; - var model, item; - - locals[parserResult.itemName] = item = scope.matches[activeIdx].model; - model = parserResult.modelMapper(originalScope, locals); - $setModelValue(originalScope, model); - modelCtrl.$setValidity('editable', true); - - onSelectCallback(originalScope, { - $item: item, - $model: model, - $label: parserResult.viewMapper(originalScope, locals) - }); - - resetMatches(); - - //return focus to the input element if a match was selected via a mouse click event - // use timeout to avoid $rootScope:inprog error - $timeout(function() { element[0].focus(); }, 0, false); - }; - - //bind keyboard events: arrows up(38) / down(40), enter(13) and tab(9), esc(27) - element.bind('keydown', function (evt) { - - //typeahead is open and an "interesting" key was pressed - if (scope.matches.length === 0 || HOT_KEYS.indexOf(evt.which) === -1) { - return; - } - - // if there's nothing selected (i.e. focusFirst) and enter is hit, don't do anything - if (scope.activeIdx == -1 && (evt.which === 13 || evt.which === 9)) { - return; - } - - evt.preventDefault(); - - if (evt.which === 40) { - scope.activeIdx = (scope.activeIdx + 1) % scope.matches.length; - scope.$digest(); - - } else if (evt.which === 38) { - scope.activeIdx = (scope.activeIdx > 0 ? scope.activeIdx : scope.matches.length) - 1; - scope.$digest(); - - } else if (evt.which === 13 || evt.which === 9) { - scope.$apply(function () { - scope.select(scope.activeIdx); - }); - - } else if (evt.which === 27) { - evt.stopPropagation(); - - resetMatches(); - scope.$digest(); - } - }); - - element.bind('blur', function (evt) { - hasFocus = false; - }); - - // Keep reference to click handler to unbind it. - var dismissClickHandler = function (evt) { - if (element[0] !== evt.target) { - resetMatches(); - scope.$digest(); - } - }; - - $document.bind('click', dismissClickHandler); - - originalScope.$on('$destroy', function(){ - $document.unbind('click', dismissClickHandler); - if (appendToBody) { - $popup.remove(); - } - }); - - var $popup = $compile(popUpEl)(scope); - if (appendToBody) { - $document.find('body').append($popup); - } else { - element.after($popup); - } - } - }; - -}]) - - .directive('typeaheadPopup', function () { - return { - restrict:'EA', - scope:{ - matches:'=', - query:'=', - active:'=', - position:'=', - select:'&' - }, - replace:true, - templateUrl:'template/typeahead/typeahead-popup.html', - link:function (scope, element, attrs) { - - scope.templateUrl = attrs.templateUrl; - - scope.isOpen = function () { - return scope.matches.length > 0; - }; - - scope.isActive = function (matchIdx) { - return scope.active == matchIdx; - }; - - scope.selectActive = function (matchIdx) { - scope.active = matchIdx; - }; - - scope.selectMatch = function (activeIdx) { - scope.select({activeIdx:activeIdx}); - }; - } - }; - }) - - .directive('typeaheadMatch', ['$http', '$templateCache', '$compile', '$parse', function ($http, $templateCache, $compile, $parse) { - return { - restrict:'EA', - scope:{ - index:'=', - match:'=', - query:'=' - }, - link:function (scope, element, attrs) { - var tplUrl = $parse(attrs.templateUrl)(scope.$parent) || 'template/typeahead/typeahead-match.html'; - $http.get(tplUrl, {cache: $templateCache}).then(function(resp){ - element.replaceWith($compile(resp.data.trim())(scope)); - }); - } - }; - }]) - - .filter('typeaheadHighlight', function() { - - function escapeRegexp(queryToEscape) { - return queryToEscape.replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1'); - } - - return function(matchItem, query) { - return query ? ('' + matchItem).replace(new RegExp(escapeRegexp(query), 'gi'), '$&') : matchItem; - }; - }); diff --git a/src/legacy/ui/public/autoload/all.js b/src/legacy/ui/public/autoload/all.js index b1aa11cb72494..9ecfbfcf307c5 100644 --- a/src/legacy/ui/public/autoload/all.js +++ b/src/legacy/ui/public/autoload/all.js @@ -19,7 +19,6 @@ import './accessibility'; import './modules'; -import './directives'; import './filters'; import './settings'; import './styles'; diff --git a/src/legacy/ui/public/autoload/modules.js b/src/legacy/ui/public/autoload/modules.js index 698d3ff8e27c0..511c2eed3dd9b 100644 --- a/src/legacy/ui/public/autoload/modules.js +++ b/src/legacy/ui/public/autoload/modules.js @@ -19,23 +19,10 @@ import 'angular'; import '../chrome'; -import '../bind'; -import '../kbn_top_nav'; -import '../bound_to_config_obj'; import '../config'; import '../courier'; -import '../debounce'; -import '../doc_title'; import '../es'; -import '../events'; -import '../fancy_forms'; -import '../filter_bar'; -import '../filter_manager'; -import '../index_patterns'; -import '../listen'; import '../notify'; -import '../parse_query'; -import '../persisted_log'; import '../private'; import '../promises'; import '../modals'; @@ -43,15 +30,11 @@ import '../state_management/app_state'; import '../state_management/global_state'; import '../storage'; import '../style_compile'; -import '../timefilter'; -import '../timepicker'; import '../tooltip'; import '../url'; import '../watch_multi'; -import '../saved_objects/ui/saved_object_save_as_checkbox'; import '../react_components'; import '../i18n'; -import '../query_bar/directive'; import '@elastic/ui-ace'; import { uiModules } from 'ui/modules'; diff --git a/src/legacy/ui/public/bind/__tests__/bind.js b/src/legacy/ui/public/bind/__tests__/bind.js index ce59076df923d..e439ea7dbcdda 100644 --- a/src/legacy/ui/public/bind/__tests__/bind.js +++ b/src/legacy/ui/public/bind/__tests__/bind.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; describe('$scope.$bind', function () { diff --git a/src/legacy/ui/public/binder/__tests__/binder.js b/src/legacy/ui/public/binder/__tests__/binder.js index 3a0ddff2137a4..703b9ec413313 100644 --- a/src/legacy/ui/public/binder/__tests__/binder.js +++ b/src/legacy/ui/public/binder/__tests__/binder.js @@ -18,7 +18,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { Binder } from '..'; diff --git a/src/legacy/ui/public/chrome/__tests__/nav_controls.js b/src/legacy/ui/public/chrome/__tests__/nav_controls.js index cf664b943190c..9d43d83248703 100644 --- a/src/legacy/ui/public/chrome/__tests__/nav_controls.js +++ b/src/legacy/ui/public/chrome/__tests__/nav_controls.js @@ -19,7 +19,7 @@ import ngMock from 'ng_mock'; import $ from 'jquery'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { chromeNavControlsRegistry } from '../../registry/chrome_nav_controls'; import { uiRegistry } from '../../registry/_registry'; diff --git a/src/legacy/ui/public/chrome/api/__tests__/apps.js b/src/legacy/ui/public/chrome/api/__tests__/apps.js index e640d1717c2cb..8515332efa36f 100644 --- a/src/legacy/ui/public/chrome/api/__tests__/apps.js +++ b/src/legacy/ui/public/chrome/api/__tests__/apps.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import setup from '../apps'; diff --git a/src/legacy/ui/public/chrome/api/__tests__/nav.js b/src/legacy/ui/public/chrome/api/__tests__/nav.js index 4b42c33ec8227..faf43058259e8 100644 --- a/src/legacy/ui/public/chrome/api/__tests__/nav.js +++ b/src/legacy/ui/public/chrome/api/__tests__/nav.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { initChromeNavApi } from '../nav'; import { StubBrowserStorage } from 'test_utils/stub_browser_storage'; diff --git a/src/legacy/ui/public/chrome/api/__tests__/xsrf.js b/src/legacy/ui/public/chrome/api/__tests__/xsrf.js index 27b8a400adf47..52da8fb545c7d 100644 --- a/src/legacy/ui/public/chrome/api/__tests__/xsrf.js +++ b/src/legacy/ui/public/chrome/api/__tests__/xsrf.js @@ -18,7 +18,7 @@ */ import $ from 'jquery'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import ngMock from 'ng_mock'; diff --git a/src/legacy/ui/public/chrome/api/apps.js b/src/legacy/ui/public/chrome/api/apps.js index feb339e163a64..7779b9612b63e 100644 --- a/src/legacy/ui/public/chrome/api/apps.js +++ b/src/legacy/ui/public/chrome/api/apps.js @@ -20,7 +20,7 @@ import { clone, get } from 'lodash'; import { resolve } from 'url'; -// eslint-disable-next-line @elastic/kibana-custom/no-default-export +// eslint-disable-next-line @kbn/eslint/no-default-export export default function (chrome, internals) { if (get(internals, 'app.navLink.url')) { diff --git a/src/legacy/ui/public/chrome/api/template.js b/src/legacy/ui/public/chrome/api/template.js index d1295dc8dddaa..58281c1af6c9d 100644 --- a/src/legacy/ui/public/chrome/api/template.js +++ b/src/legacy/ui/public/chrome/api/template.js @@ -17,7 +17,7 @@ * under the License. */ -// eslint-disable-next-line @elastic/kibana-custom/no-default-export +// eslint-disable-next-line @kbn/eslint/no-default-export export default function (chrome, internals) { /** diff --git a/src/legacy/ui/public/chrome/directives/__tests__/sub_url_route_filter.js b/src/legacy/ui/public/chrome/directives/__tests__/sub_url_route_filter.js index fc411b5638b3b..5ce42b9c72916 100644 --- a/src/legacy/ui/public/chrome/directives/__tests__/sub_url_route_filter.js +++ b/src/legacy/ui/public/chrome/directives/__tests__/sub_url_route_filter.js @@ -18,7 +18,7 @@ */ import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { SubUrlRouteFilterProvider } from '../sub_url_route_filter'; diff --git a/src/legacy/ui/public/chrome/directives/header_global_nav/components/header.tsx b/src/legacy/ui/public/chrome/directives/header_global_nav/components/header.tsx index d8426805f57ba..d8aec7997fdbf 100644 --- a/src/legacy/ui/public/chrome/directives/header_global_nav/components/header.tsx +++ b/src/legacy/ui/public/chrome/directives/header_global_nav/components/header.tsx @@ -54,6 +54,7 @@ import { HeaderBreadcrumbs } from './header_breadcrumbs'; import { HeaderHelpMenu } from './header_help_menu'; import { HeaderNavControls } from './header_nav_controls'; +import { i18n } from '@kbn/i18n'; import { InjectedIntl, injectI18n } from '@kbn/i18n/react'; import chrome, { NavLink } from 'ui/chrome'; import { HelpExtension } from 'ui/chrome'; @@ -88,10 +89,23 @@ function extendRecentlyAccessedHistoryItem( const href = relativeToAbsolute(chrome.addBasePath(recentlyAccessed.link)); const navLink = navLinks.find(nl => href.startsWith(nl.subUrlBase)); + let titleAndAriaLabel = recentlyAccessed.label; + if (navLink) { + const objectTypeForAriaAppendix = navLink.title; + titleAndAriaLabel = i18n.translate('common.ui.recentLinks.linkItem.screenReaderLabel', { + defaultMessage: '{recentlyAccessedItemLinklabel}, type: {pageType}', + values: { + recentlyAccessedItemLinklabel: recentlyAccessed.label, + pageType: objectTypeForAriaAppendix, + }, + }); + } + return { ...recentlyAccessed, href, euiIconType: navLink ? navLink.euiIconType : undefined, + title: titleAndAriaLabel, }; } @@ -248,9 +262,8 @@ class HeaderUI extends Component { }), listItems: recentlyAccessed.map(item => ({ label: truncateRecentItemLabel(item.label), - // TODO: Add what type of app/saved object to title attr - title: `${item.label}`, - 'aria-label': item.label, + title: item.title, + 'aria-label': item.title, href: item.href, iconType: item.euiIconType, })), diff --git a/src/legacy/ui/public/chrome/index.js b/src/legacy/ui/public/chrome/index.js index ad62192704a1e..a322485b25513 100644 --- a/src/legacy/ui/public/chrome/index.js +++ b/src/legacy/ui/public/chrome/index.js @@ -19,5 +19,5 @@ import { chrome } from './chrome'; -// eslint-disable-next-line @elastic/kibana-custom/no-default-export +// eslint-disable-next-line @kbn/eslint/no-default-export export default chrome; diff --git a/src/legacy/ui/public/config/__tests__/config.js b/src/legacy/ui/public/config/__tests__/config.js index 55dcbd65880f8..52a573417f3c5 100644 --- a/src/legacy/ui/public/config/__tests__/config.js +++ b/src/legacy/ui/public/config/__tests__/config.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import ngMock from 'ng_mock'; diff --git a/src/legacy/ui/public/courier/courier.js b/src/legacy/ui/public/courier/courier.js index 2689f914065c9..f34f47e0571be 100644 --- a/src/legacy/ui/public/courier/courier.js +++ b/src/legacy/ui/public/courier/courier.js @@ -22,6 +22,7 @@ import _ from 'lodash'; import { timefilter } from 'ui/timefilter'; import '../es'; +import '../listen'; import '../index_patterns'; import { uiModules } from '../modules'; import { addFatalErrorCallback } from '../notify'; diff --git a/src/legacy/ui/public/courier/fetch/__tests__/call_client.js b/src/legacy/ui/public/courier/fetch/__tests__/call_client.js index ec261d65dd6fa..bdaef283f2d35 100644 --- a/src/legacy/ui/public/courier/fetch/__tests__/call_client.js +++ b/src/legacy/ui/public/courier/fetch/__tests__/call_client.js @@ -18,7 +18,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import NoDigestPromises from 'test_utils/no_digest_promises'; import { delay } from 'bluebird'; diff --git a/src/legacy/ui/public/courier/fetch/__tests__/fetch_now.js b/src/legacy/ui/public/courier/fetch/__tests__/fetch_now.js index 079a7893785f0..19032ce1f4ca3 100644 --- a/src/legacy/ui/public/courier/fetch/__tests__/fetch_now.js +++ b/src/legacy/ui/public/courier/fetch/__tests__/fetch_now.js @@ -18,7 +18,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { CallClientProvider } from '../call_client'; diff --git a/src/legacy/ui/public/courier/fetch/request/search_request/__tests__/search_request.js b/src/legacy/ui/public/courier/fetch/request/search_request/__tests__/search_request.js index aeddc6e065455..ecac8cd474098 100644 --- a/src/legacy/ui/public/courier/fetch/request/search_request/__tests__/search_request.js +++ b/src/legacy/ui/public/courier/fetch/request/search_request/__tests__/search_request.js @@ -19,7 +19,7 @@ import ngMock from 'ng_mock'; import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { SearchRequestProvider } from '../search_request'; import { searchRequestQueue } from '../../../../search_request_queue'; diff --git a/src/legacy/ui/public/courier/fetch/request/segmented_search_request/__tests__/segmented_search_request.create_queue.js b/src/legacy/ui/public/courier/fetch/request/segmented_search_request/__tests__/segmented_search_request.create_queue.js deleted file mode 100644 index 714bbb340969d..0000000000000 --- a/src/legacy/ui/public/courier/fetch/request/segmented_search_request/__tests__/segmented_search_request.create_queue.js +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import sinon from 'sinon'; -import expect from 'expect.js'; -import ngMock from 'ng_mock'; - -import StubbedSearchSourceProvider from 'fixtures/stubbed_search_source'; - -import { SegmentedSearchRequestProvider } from '../segmented_search_request'; - -describe('SegmentedSearchRequest _createQueue', () => { - let Promise; - let SegmentedSearchRequest; - let MockSource; - - require('test_utils/no_digest_promises').activateForSuite(); - - beforeEach(ngMock.module('kibana')); - beforeEach(ngMock.inject((Private, $injector) => { - Promise = $injector.get('Promise'); - SegmentedSearchRequest = Private(SegmentedSearchRequestProvider); - - MockSource = class { - constructor() { - return $injector.invoke(StubbedSearchSourceProvider); - } - }; - })); - - it('manages the req._queueCreated flag', async function () { - const req = new SegmentedSearchRequest({ source: new MockSource(), errorHandler: () => {} }); - req._queueCreated = null; - - const promise = req._createQueue(); - expect(req._queueCreated).to.be(false); - await promise; - expect(req._queueCreated).to.be(true); - }); - - it('relies on indexPattern.toDetailedIndexList to generate queue', async function () { - const searchSource = new MockSource(); - const indexPattern = searchSource.getField('index'); - const indices = [1, 2, 3]; - sinon.stub(indexPattern, 'toDetailedIndexList').returns(Promise.resolve(indices)); - - const req = new SegmentedSearchRequest({ source: searchSource, errorHandler: () => {} }); - const output = await req._createQueue(); - expect(output).to.equal(indices); - }); - - it('tells the index pattern its direction', async function () { - const searchSource = new MockSource(); - const indexPattern = searchSource.getField('index'); - const req = new SegmentedSearchRequest({ source: searchSource, errorHandler: () => {} }); - sinon.stub(indexPattern, 'toDetailedIndexList').returns(Promise.resolve([1, 2, 3])); - - req.setDirection('asc'); - await req._createQueue(); - expect(indexPattern.toDetailedIndexList.lastCall.args[2]).to.be('asc'); - - req.setDirection('desc'); - await req._createQueue(); - expect(indexPattern.toDetailedIndexList.lastCall.args[2]).to.be('desc'); - }); -}); diff --git a/src/legacy/ui/public/courier/fetch/request/segmented_search_request/__tests__/segmented_search_request.index_selection.js b/src/legacy/ui/public/courier/fetch/request/segmented_search_request/__tests__/segmented_search_request.index_selection.js deleted file mode 100644 index b1cc13d057f90..0000000000000 --- a/src/legacy/ui/public/courier/fetch/request/segmented_search_request/__tests__/segmented_search_request.index_selection.js +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import ngMock from 'ng_mock'; -import expect from 'expect.js'; -import { times } from 'lodash'; -import sinon from 'sinon'; - -import HitSortFnProv from 'plugins/kibana/discover/_hit_sort_fn'; -import NoDigestPromises from 'test_utils/no_digest_promises'; -import StubbedSearchSourceProvider from 'fixtures/stubbed_search_source'; - -import { SegmentedSearchRequestProvider } from '../segmented_search_request'; - -describe('SegmentedSearchRequest index selection', function () { - let Promise; - let SegmentedSearchRequest; - let MockSource; - let HitSortFn; - - NoDigestPromises.activateForSuite(); - - beforeEach(ngMock.module('kibana')); - beforeEach(ngMock.inject((Private, $injector) => { - Promise = $injector.get('Promise'); - HitSortFn = Private(HitSortFnProv); - SegmentedSearchRequest = Private(SegmentedSearchRequestProvider); - - MockSource = class { - constructor() { - return $injector.invoke(StubbedSearchSourceProvider); - } - }; - })); - - it('queries with size until all 500 docs returned', async function () { - const searchSource = new MockSource(); - const indexPattern = searchSource.getField('index'); - sinon.stub(indexPattern, 'toDetailedIndexList').returns(Promise.resolve([ - { index: 'one', min: 0, max: 1 }, - { index: 'two', min: 0, max: 1 }, - { index: 'three', min: 0, max: 1 }, - { index: 'four', min: 0, max: 1 }, - { index: 'five', min: 0, max: 1 }, - ])); - - const req = new SegmentedSearchRequest({ source: searchSource, errorHandler: () => {} }); - req._handle.setDirection('desc'); - req._handle.setSortFn(new HitSortFn('desc')); - req._handle.setSize(500); - await req.start(); - - // first 200 - expect((await req.getFetchParams()).body.size).to.be(500); - await req.handleResponse({ - hits: { total: 1000, hits: times(200, (i) => ({ i })) } - }); - - // total = 400 - expect((await req.getFetchParams()).body.size).to.be(500); - await req.handleResponse({ - hits: { total: 1000, hits: times(200, (i) => ({ i })) } - }); - - // total = 600 - expect((await req.getFetchParams()).body.size).to.be(500); - await req.handleResponse({ - hits: { total: 1000, hits: times(200, (i) => ({ i })) } - }); - - expect((await req.getFetchParams()).body.size).to.be(0); - await req.handleResponse({ - hits: { total: 1000, hits: times(200, (i) => ({ i })) } - }); - - expect((await req.getFetchParams()).body.size).to.be(0); - await req.handleResponse({ - hits: { total: 1000, hits: times(200, (i) => ({ i })) } - }); - }); - - it(`sets size 0 for indices that couldn't preclude hits`, async function () { - const searchSource = new MockSource(); - const indexPattern = searchSource.getField('index'); - - // the segreq is looking for 10 documents, and we will give it ten docs with time:5 in the first response. - // on the second index it should still request 10 documents because it could produce documents with time:5. - // the next two indexes will get size 0, since they couldn't produce documents with the time:5 - // the final index will get size:10, because it too can produce docs with time:5 - sinon.stub(indexPattern, 'toDetailedIndexList').returns(Promise.resolve([ - { index: 'one', min: 0, max: 10 }, - { index: 'two', min: 0, max: 10 }, - { index: 'three', min: 12, max: 20 }, - { index: 'four', min: 15, max: 20 }, - { index: 'five', min: 5, max: 50 }, - ])); - - const req = new SegmentedSearchRequest({ source: searchSource, errorHandler: () => {} }); - req._handle.setDirection('desc'); - req._handle.setSortFn(new HitSortFn('desc')); - req._handle.setSize(10); - await req.start(); - - // first 10 - expect((await req.getFetchParams()).body.size).to.be(10); - await req.handleResponse({ - hits: { total: 1000, hits: times(10, () => ({ _source: { time: 5 } })) } - }); - - // total = 400 - expect((await req.getFetchParams()).body.size).to.be(10); - await req.handleResponse({ - hits: { total: 1000, hits: times(10, () => ({ _source: { time: 5 } })) } - }); - - // total = 600 - expect((await req.getFetchParams()).body.size).to.be(0); - await req.handleResponse({ - hits: { total: 1000, hits: [] } - }); - - expect((await req.getFetchParams()).body.size).to.be(0); - await req.handleResponse({ - hits: { total: 1000, hits: [] } - }); - - expect((await req.getFetchParams()).body.size).to.be(10); - await req.handleResponse({ - hits: { total: 1000, hits: times(10, () => ({ _source: { time: 5 } })) } - }); - }); -}); diff --git a/src/legacy/ui/public/courier/fetch/request/segmented_search_request/__tests__/segmented_search_request.js b/src/legacy/ui/public/courier/fetch/request/segmented_search_request/__tests__/segmented_search_request.js deleted file mode 100644 index b875e57e5d3cf..0000000000000 --- a/src/legacy/ui/public/courier/fetch/request/segmented_search_request/__tests__/segmented_search_request.js +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import sinon from 'sinon'; -import expect from 'expect.js'; -import ngMock from 'ng_mock'; - -import { SegmentedSearchRequestProvider } from '../segmented_search_request'; -import { SearchRequestProvider } from '../../search_request'; - -describe('SegmentedSearchRequest', () => { - let Promise; - let SegmentedSearchRequest; - let segmentedReq; - let abstractReqStart; - - beforeEach(ngMock.module('kibana')); - - beforeEach(ngMock.inject((Private, $injector) => { - Promise = $injector.get('Promise'); - SegmentedSearchRequest = Private(SegmentedSearchRequestProvider); - - const SearchRequest = Private(SearchRequestProvider); - abstractReqStart = sinon.stub(SearchRequest.prototype, 'start').callsFake(() => { - const promise = Promise.resolve(); - sinon.spy(promise, 'then'); - return promise; - }); - })); - - describe('#start()', () => { - let returned; - beforeEach(() => { - init(); - returned = segmentedReq.start(); - }); - - it('returns promise', () => { - expect(returned.then).to.be.Function; - }); - - it('calls AbstractReq#start()', () => { - sinon.assert.calledOnce(abstractReqStart); - }); - - it('listens to promise from super.start()', () => { - sinon.assert.calledOnce(abstractReqStart); - const promise = abstractReqStart.firstCall.returnValue; - sinon.assert.calledOnce(promise.then); - }); - }); - - function init() { - segmentedReq = new SegmentedSearchRequest({ source: mockSource(), errorHandler: () => {} }); - } - - function mockSource() { - return { - get: sinon.stub().returns(mockIndexPattern()), - }; - } - - function mockIndexPattern() { - return { - toDetailedIndexList: sinon.stub().returns(Promise.resolve([ - { index: 1, min: 0, max: 1 }, - { index: 2, min: 0, max: 1 }, - { index: 3, min: 0, max: 1 }, - ])) - }; - } -}); diff --git a/src/legacy/ui/public/courier/fetch/request/segmented_search_request/__tests__/segmented_search_request.size_picking.js b/src/legacy/ui/public/courier/fetch/request/segmented_search_request/__tests__/segmented_search_request.size_picking.js deleted file mode 100644 index b882b3ae5fedf..0000000000000 --- a/src/legacy/ui/public/courier/fetch/request/segmented_search_request/__tests__/segmented_search_request.size_picking.js +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import ngMock from 'ng_mock'; -import expect from 'expect.js'; - -import HitSortFnProv from 'plugins/kibana/discover/_hit_sort_fn'; -import NoDigestPromises from 'test_utils/no_digest_promises'; -import StubbedSearchSourceProvider from 'fixtures/stubbed_search_source'; - -import { SegmentedSearchRequestProvider } from '../segmented_search_request'; - -describe('SegmentedSearchRequest size picking', function () { - let SegmentedSearchRequest; - let MockSource; - let HitSortFn; - - NoDigestPromises.activateForSuite(); - - beforeEach(ngMock.module('kibana')); - beforeEach(ngMock.inject((Private, $injector) => { - HitSortFn = Private(HitSortFnProv); - SegmentedSearchRequest = Private(SegmentedSearchRequestProvider); - - MockSource = class { - constructor() { - return $injector.invoke(StubbedSearchSourceProvider); - } - }; - })); - - describe('without a size', function () { - it('does not set the request size', async function () { - const req = new SegmentedSearchRequest({ source: new MockSource(), errorHandler: () => {} }); - req._handle.setDirection('desc'); - req._handle.setSortFn(new HitSortFn('desc')); - await req.start(); - - expect((await req.getFetchParams()).body).to.not.have.property('size'); - }); - }); - - describe('with a size', function () { - it('sets the request size to the entire desired size', async function () { - const req = new SegmentedSearchRequest({ source: new MockSource(), errorHandler: () => {} }); - req._handle.setDirection('desc'); - req._handle.setSize(555); - req._handle.setSortFn(new HitSortFn('desc')); - await req.start(); - - expect((await req.getFetchParams()).body).to.have.property('size', 555); - }); - }); -}); diff --git a/src/legacy/ui/public/courier/fetch/request/segmented_search_request/segmented_handle.js b/src/legacy/ui/public/courier/fetch/request/segmented_search_request/segmented_handle.js deleted file mode 100644 index b7a638b4ed159..0000000000000 --- a/src/legacy/ui/public/courier/fetch/request/segmented_search_request/segmented_handle.js +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { EventsProvider } from '../../../../events'; - -export function SegmentedHandleProvider(Private) { - const Events = Private(EventsProvider); - - const segmentedRequest = Symbol('Actual Segmented Request'); - - /** - * Simple class for creating an object to send to the - * requester of a SegmentedSearchRequest. Since the SegmentedSearchRequest - * extends AbstractRequest, it wasn't able to be the event - * emitter it was born to be. This provides a channel for - * setting values on the segmented request, and an event - * emitter for the request to speak outwardly - * - * @param {SegmentedSearchRequest} - req - the request this handle relates to - */ - return class SegmentedHandle extends Events { - constructor(req) { - super(); - this[segmentedRequest] = req; - } - - setDirection(...args) { - this[segmentedRequest].setDirection(...args); - } - - setSize(...args) { - this[segmentedRequest].setSize(...args); - } - - setMaxSegments(...args) { - this[segmentedRequest].setMaxSegments(...args); - } - - setSortFn(...args) { - this[segmentedRequest].setSortFn(...args); - } - }; -} diff --git a/src/legacy/ui/public/courier/fetch/request/segmented_search_request/segmented_search_request.js b/src/legacy/ui/public/courier/fetch/request/segmented_search_request/segmented_search_request.js deleted file mode 100644 index 6ab49eee4fe65..0000000000000 --- a/src/legacy/ui/public/courier/fetch/request/segmented_search_request/segmented_search_request.js +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import _ from 'lodash'; -import { timefilter } from 'ui/timefilter'; -import { SearchRequestProvider } from '../search_request'; -import { SegmentedHandleProvider } from './segmented_handle'; -import { pushAll } from '../../../../utils/collection'; - -export function SegmentedSearchRequestProvider(Private, config) { - const SearchRequest = Private(SearchRequestProvider); - const SegmentedHandle = Private(SegmentedHandleProvider); - - class SegmentedSearchRequest extends SearchRequest { - constructor({ source, defer, errorHandler, initFn }) { - super({ source, defer, errorHandler }); - - this.type = 'segmented'; - - // segmented request specific state - this._initFn = initFn; - - this._desiredSize = null; - this._maxSegments = config.get('courier:maxSegmentCount'); - this._direction = 'desc'; - this._sortFn = null; - this._queueCreated = false; - this._handle = new SegmentedHandle(this); - - this._hitWindow = null; - - // prevent the source from changing between requests, - // all calls will return the same promise - this._getFlattenedSource = _.once(this._getFlattenedSource); - } - - /********* - ** SearchReq overrides - *********/ - - start() { - return super.start().then(() => { - this._complete = []; - this._active = null; - this._segments = []; - this._all = []; - this._queue = []; - - this._mergedResp = { - took: 0, - hits: { - hits: [], - total: 0, - max_score: 0 - } - }; - - // give the request consumer a chance to receive each segment and set - // parameters via the handle - if (_.isFunction(this._initFn)) this._initFn(this._handle); - return this._createQueue(); - }) - .then((queue) => { - if (this.stopped) return; - - this._all = queue.slice(0); - - // Send the initial fetch status - return this._reportStatus(); - }); - } - - continue() { - return this._reportStatus(); - } - - getFetchParams() { - return this._getFlattenedSource().then(flatSource => { - const params = _.cloneDeep(flatSource); - - // calculate the number of indices to fetch in this request in order to prevent - // more than this._maxSegments requests. We use Math.max(1, n) to ensure that each request - // has at least one index pattern, and Math.floor() to make sure that if the - // number of indices does not round out evenly the extra index is tacked onto the last - // request, making sure the first request returns faster. - const remainingSegments = this._maxSegments - this._segments.length; - const indexCount = Math.max(1, Math.floor(this._queue.length / remainingSegments)); - - const indices = this._active = this._queue.splice(0, indexCount); - params.index = indices.map(({ index }) => index).join(','); - - if (_.isNumber(this._desiredSize)) { - params.body.size = this._pickSizeForIndices(indices); - } - - return params; - }); - } - - handleResponse(resp) { - return this._consumeSegment(resp); - } - - filterError(resp) { - if (/ClusterBlockException.*index\sclosed/.test(resp.error)) { - this._consumeSegment(false); - return true; - } - } - - isIncomplete() { - const queueNotCreated = !this._queueCreated; - const queueNotEmpty = this._queue.length > 0; - return queueNotCreated || queueNotEmpty; - } - - clone() { - return new SegmentedSearchRequest(this.source, this.defer, this._initFn); - } - - complete() { - this._reportStatus(); - this._handle.emit('complete'); - return super.complete(); - } - - /********* - ** SegmentedSearchRequest specific methods - *********/ - - - /** - * Set the sort total number of segments to emit - * - * @param {number} - */ - setMaxSegments(maxSegments) { - this._maxSegments = Math.max(_.parseInt(maxSegments), 1); - } - - /** - * Set the sort direction for the request. - * - * @param {string} dir - one of 'asc' or 'desc' - */ - setDirection(dir) { - switch (dir) { - case 'asc': - case 'desc': - return (this._direction = dir); - default: - throw new TypeError('unknown sort direction "' + dir + '"'); - } - } - - /** - * Set the function that will be used to sort the rows - * - * @param {fn} - */ - setSortFn(sortFn) { - this._sortFn = sortFn; - } - - /** - * Set the sort total number of documents to - * emit - * - * Setting to false will not limit the documents, - * if a number is set the size of the request to es - * will be updated on each new request - * - * @param {number|false} - */ - setSize(totalSize) { - this._desiredSize = _.parseInt(totalSize); - if (isNaN(this._desiredSize)) this._desiredSize = null; - } - - _createQueue() { - const timeBounds = timefilter.getBounds(); - const indexPattern = this.source.getField('index'); - this._queueCreated = false; - - return indexPattern.toDetailedIndexList(timeBounds.min, timeBounds.max, this._direction) - .then(queue => { - this._queue = queue; - this._queueCreated = true; - return queue; - }); - } - - _reportStatus() { - return this._handle.emit('status', { - total: this._queueCreated ? this._all.length : NaN, - complete: this._queueCreated ? this._complete.length : NaN, - remaining: this._queueCreated ? this._queue.length : NaN, - hitCount: this._queueCreated ? this._mergedResp.hits.hits.length : NaN - }); - } - - _getFlattenedSource() { - return this.source._flatten(); - } - - _consumeSegment(seg) { - const index = this._active; - this._complete.push(index); - if (!seg) return; // segment was ignored/filtered, don't store it - - const hadHits = _.get(this._mergedResp, 'hits.hits.length') > 0; - const gotHits = _.get(seg, 'hits.hits.length') > 0; - const firstHits = !hadHits && gotHits; - const haveHits = hadHits || gotHits; - - this._mergeSegment(seg); - this.resp = _.omit(this._mergedResp, '_bucketIndex'); - - if (firstHits) this._handle.emit('first', seg); - gotHits ? this._handle.emit('segment', seg) : this._handle.emit('emptySegment', seg); - if (haveHits) this._handle.emit('mergedSegment', this.resp); - } - - _mergeHits(hits) { - const mergedHits = this._mergedResp.hits.hits; - const desiredSize = this._desiredSize; - const sortFn = this._sortFn; - - pushAll(hits, mergedHits); - - if (sortFn) { - mergedHits.sort(sortFn); - } - - if (_.isNumber(desiredSize)) { - this._mergedResp.hits.hits = mergedHits.slice(0, desiredSize); - } - } - - _mergeSegment(seg) { - const merged = this._mergedResp; - - this._segments.push(seg); - - merged.took += seg.took; - merged.hits.total += seg.hits.total; - merged.hits.max_score = Math.max(merged.hits.max_score, seg.hits.max_score); - - if (_.size(seg.hits.hits)) { - this._mergeHits(seg.hits.hits); - this._detectHitsWindow(merged.hits.hits); - } - - if (!seg.aggregations) return; - - Object.keys(seg.aggregations).forEach(function (aggKey) { - - if (!merged.aggregations) { - // start merging aggregations - merged.aggregations = {}; - merged._bucketIndex = {}; - } - - if (!merged.aggregations[aggKey]) { - merged.aggregations[aggKey] = { - buckets: [] - }; - } - - seg.aggregations[aggKey].buckets.forEach(function (bucket) { - let mbucket = merged._bucketIndex[bucket.key]; - if (mbucket) { - mbucket.doc_count += bucket.doc_count; - return; - } - - mbucket = merged._bucketIndex[bucket.key] = bucket; - merged.aggregations[aggKey].buckets.push(mbucket); - }); - }); - } - - _detectHitsWindow(hits) { - hits = hits || []; - const indexPattern = this.source.getField('index'); - const desiredSize = this._desiredSize; - - const size = _.size(hits); - if (!_.isNumber(desiredSize) || size < desiredSize) { - this._hitWindow = { - size: size, - min: -Infinity, - max: Infinity - }; - return; - } - - let min; - let max; - - hits.forEach(function (deepHit) { - const hit = indexPattern.flattenHit(deepHit); - const time = hit[indexPattern.timeFieldName]; - if (min == null || time < min) min = time; - if (max == null || time > max) max = time; - }); - - this._hitWindow = { size, min, max }; - } - - _pickSizeForIndices(indices) { - const hitWindow = this._hitWindow; - const desiredSize = this._desiredSize; - - if (!_.isNumber(desiredSize)) return null; - // we don't have any hits yet, get us more info! - if (!hitWindow) return desiredSize; - // the order of documents isn't important, just get us more - if (!this._sortFn) return Math.max(desiredSize - hitWindow.size, 0); - // if all of the documents in every index fall outside of our current doc set, we can ignore them. - const someOverlap = indices.some(function (index) { - return index.min <= hitWindow.max && hitWindow.min <= index.max; - }); - - return someOverlap ? desiredSize : 0; - } - } - - return SegmentedSearchRequest; -} diff --git a/src/legacy/ui/public/courier/fetch/request/serialize_fetch_params/__tests__/serialize_fetch_params.js b/src/legacy/ui/public/courier/fetch/request/serialize_fetch_params/__tests__/serialize_fetch_params.js index 84548e6626752..47c50d726c9fc 100644 --- a/src/legacy/ui/public/courier/fetch/request/serialize_fetch_params/__tests__/serialize_fetch_params.js +++ b/src/legacy/ui/public/courier/fetch/request/serialize_fetch_params/__tests__/serialize_fetch_params.js @@ -18,7 +18,7 @@ */ import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import StubIndexPatternProvider from 'test_utils/stub_index_pattern'; diff --git a/src/legacy/ui/public/courier/search_request_queue/__tests__/search_request_queue.js b/src/legacy/ui/public/courier/search_request_queue/__tests__/search_request_queue.js index 434894e07c21a..f6b4e4bef20c2 100644 --- a/src/legacy/ui/public/courier/search_request_queue/__tests__/search_request_queue.js +++ b/src/legacy/ui/public/courier/search_request_queue/__tests__/search_request_queue.js @@ -18,7 +18,7 @@ */ import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { searchRequestQueue } from '../search_request_queue'; diff --git a/src/legacy/ui/public/courier/search_source/__tests__/normalize_sort_request.js b/src/legacy/ui/public/courier/search_source/__tests__/normalize_sort_request.js index 810f9cf045495..2358fdb520715 100644 --- a/src/legacy/ui/public/courier/search_source/__tests__/normalize_sort_request.js +++ b/src/legacy/ui/public/courier/search_source/__tests__/normalize_sort_request.js @@ -19,7 +19,7 @@ import '../../../private'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { NormalizeSortRequestProvider } from '../_normalize_sort_request'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; import _ from 'lodash'; diff --git a/src/legacy/ui/public/courier/search_source/__tests__/search_source.js b/src/legacy/ui/public/courier/search_source/__tests__/search_source.js index 2034c63e0605f..8297c751da5fe 100644 --- a/src/legacy/ui/public/courier/search_source/__tests__/search_source.js +++ b/src/legacy/ui/public/courier/search_source/__tests__/search_source.js @@ -18,7 +18,7 @@ */ import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { searchRequestQueue } from '../../search_request_queue'; diff --git a/src/legacy/ui/public/courier/search_source/search_source.js b/src/legacy/ui/public/courier/search_source/search_source.js index 8fc71bff40a84..7943973bf51ed 100644 --- a/src/legacy/ui/public/courier/search_source/search_source.js +++ b/src/legacy/ui/public/courier/search_source/search_source.js @@ -76,7 +76,6 @@ import { buildEsQuery, getEsQueryConfig, filterMatchesIndex } from '@kbn/es-quer import '../../promises'; import { NormalizeSortRequestProvider } from './_normalize_sort_request'; import { SearchRequestProvider } from '../fetch/request'; -import { SegmentedSearchRequestProvider } from '../fetch/request/segmented_search_request'; import { searchRequestQueue } from '../search_request_queue'; import { FetchSoonProvider } from '../fetch'; @@ -117,7 +116,6 @@ function isIndexPattern(val) { export function SearchSourceProvider(Promise, Private, config) { const SearchRequest = Private(SearchRequestProvider); - const SegmentedSearchRequest = Private(SegmentedSearchRequestProvider); const normalizeSortRequest = Private(NormalizeSortRequestProvider); const fetchSoon = Private(FetchSoonProvider); const { fieldWildcardFilter } = Private(FieldWildcardProvider); @@ -390,26 +388,6 @@ export function SearchSourceProvider(Promise, Private, config) { }); } - onBeginSegmentedFetch(initFunction) { - const self = this; - return new Promise((resolve, reject) => { - function addRequest() { - const defer = Promise.defer(); - const errorHandler = (request, error) => { - reject(error); - request.abort(); - }; - const req = new SegmentedSearchRequest({ source: self, defer, errorHandler, initFn: initFunction }); - - // Return promises created by the completion handler so that - // errors will bubble properly - return req.getCompletePromise().then(addRequest); - } - - addRequest(); - }); - } - async getSearchRequestBody() { const searchRequest = await this._flatten(); return searchRequest.body; diff --git a/src/legacy/ui/public/debounce/__tests__/debounce.js b/src/legacy/ui/public/debounce/__tests__/debounce.js index 5aa4233613ce1..e5138643101f5 100644 --- a/src/legacy/ui/public/debounce/__tests__/debounce.js +++ b/src/legacy/ui/public/debounce/__tests__/debounce.js @@ -19,7 +19,7 @@ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { DebounceProvider } from '..'; diff --git a/src/legacy/ui/public/directives/__tests__/css_truncate.js b/src/legacy/ui/public/directives/__tests__/css_truncate.js index 3c851a7df6842..ec46448962dc3 100644 --- a/src/legacy/ui/public/directives/__tests__/css_truncate.js +++ b/src/legacy/ui/public/directives/__tests__/css_truncate.js @@ -18,7 +18,7 @@ */ import angular from 'angular'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import 'plugins/kibana/discover/index'; diff --git a/src/legacy/ui/public/directives/__tests__/fixed_scroll.js b/src/legacy/ui/public/directives/__tests__/fixed_scroll.js index cec917cf4d1f7..651e3af550e44 100644 --- a/src/legacy/ui/public/directives/__tests__/fixed_scroll.js +++ b/src/legacy/ui/public/directives/__tests__/fixed_scroll.js @@ -18,7 +18,7 @@ */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import '../../fixed_scroll'; import $ from 'jquery'; diff --git a/src/legacy/ui/public/directives/__tests__/inequality.js b/src/legacy/ui/public/directives/__tests__/inequality.js index a513520e49791..0e6a537d69f7c 100644 --- a/src/legacy/ui/public/directives/__tests__/inequality.js +++ b/src/legacy/ui/public/directives/__tests__/inequality.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import '../inequality'; @@ -33,7 +33,6 @@ describe('greater_than model validator directive', function () { $rootScope = _$rootScope_; })); - // no value is the same as 0 describe('without value', function () { let element; beforeEach(function () { @@ -60,6 +59,33 @@ describe('greater_than model validator directive', function () { }); }); + describe('with string values', function () { + let element; + beforeEach(function () { + html = ``; + element = $compile(html)($rootScope); + }); + + it('should be valid for greater than 10', function () { + $rootScope.value = '15'; + $rootScope.$digest(); + expect(element.hasClass('ng-valid')).to.be.ok(); + }); + + it('should be invalid for 10', function () { + $rootScope.value = '10'; + $rootScope.$digest(); + expect(element.hasClass('ng-invalid')).to.be.ok(); + }); + + // Edge case because '5' > '10' as strings + it('should be invalid less than 10', function () { + $rootScope.value = '5'; + $rootScope.$digest(); + expect(element.hasClass('ng-invalid')).to.be.ok(); + }); + }); + [0, 1, 10, 42, -12].forEach(function (num) { describe('with value ' + num, function () { let element; @@ -85,7 +111,14 @@ describe('greater_than model validator directive', function () { $rootScope.$digest(); expect(element.hasClass('ng-invalid')).to.be.ok(); }); + + it('should be valid for empty model values', () => { + [undefined, null, ''].forEach(val => { + $rootScope.value = val; + $rootScope.$digest(); + expect(element.hasClass('ng-valid')).to.be.ok(); + }); + }); }); }); - }); diff --git a/src/legacy/ui/public/directives/__tests__/input_focus.js b/src/legacy/ui/public/directives/__tests__/input_focus.js index 9b1bbe25c844c..5336c01d74d80 100644 --- a/src/legacy/ui/public/directives/__tests__/input_focus.js +++ b/src/legacy/ui/public/directives/__tests__/input_focus.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import $ from 'jquery'; import '../input_focus'; diff --git a/src/legacy/ui/public/directives/__tests__/json_input.js b/src/legacy/ui/public/directives/__tests__/json_input.js index 43ecea162f166..b2ad6c8c47321 100644 --- a/src/legacy/ui/public/directives/__tests__/json_input.js +++ b/src/legacy/ui/public/directives/__tests__/json_input.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import '../json_input'; diff --git a/src/legacy/ui/public/directives/__tests__/paginated_selectable_list.js b/src/legacy/ui/public/directives/__tests__/paginated_selectable_list.js index 5246cc3568fd8..319b16c6a3233 100644 --- a/src/legacy/ui/public/directives/__tests__/paginated_selectable_list.js +++ b/src/legacy/ui/public/directives/__tests__/paginated_selectable_list.js @@ -18,7 +18,7 @@ */ import angular from 'angular'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import _ from 'lodash'; diff --git a/src/legacy/ui/public/directives/__tests__/parse_query.js b/src/legacy/ui/public/directives/__tests__/parse_query.js index 3239bbceae248..12d9d12053286 100644 --- a/src/legacy/ui/public/directives/__tests__/parse_query.js +++ b/src/legacy/ui/public/directives/__tests__/parse_query.js @@ -18,7 +18,7 @@ */ import angular from 'angular'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; // Load the kibana app dependencies. diff --git a/src/legacy/ui/public/directives/__tests__/truncate.js b/src/legacy/ui/public/directives/__tests__/truncate.js index 864db63805691..7cf0d2e3799b1 100644 --- a/src/legacy/ui/public/directives/__tests__/truncate.js +++ b/src/legacy/ui/public/directives/__tests__/truncate.js @@ -18,7 +18,7 @@ */ import angular from 'angular'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import 'plugins/kibana/discover/index'; diff --git a/src/legacy/ui/public/directives/__tests__/validate_json.js b/src/legacy/ui/public/directives/__tests__/validate_json.js deleted file mode 100644 index b59ee7bccf7ec..0000000000000 --- a/src/legacy/ui/public/directives/__tests__/validate_json.js +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import angular from 'angular'; -import expect from 'expect.js'; -import ngMock from 'ng_mock'; -import '../validate_json'; - -// Load the kibana app dependencies. - -let $parentScope; -let $elemScope; -let $elem; -const mockScope = ''; - -const input = { - valid: '{ "test": "json input" }', - invalid: 'strings are not json' -}; - -const markup = { - textarea: '', - input: '' -}; - -const init = function (type) { - // Load the application - ngMock.module('kibana'); - type = type || 'input'; - const elMarkup = markup[type]; - - // Create the scope - ngMock.inject(function ($injector, $rootScope, $compile) { - // Give us a scope - $parentScope = $rootScope; - $parentScope.mockModel = mockScope; - - $elem = angular.element(elMarkup); - $compile($elem)($parentScope); - $elemScope = $elem.isolateScope(); - }); -}; - -describe('validate-json directive', function () { - const checkValid = function (inputVal, className) { - $parentScope.mockModel = inputVal; - $elem.scope().$digest(); - expect($elem.hasClass(className)).to.be(true); - }; - - describe('initialization', function () { - beforeEach(function () { - init(); - }); - - it('should use the model', function () { - expect($elemScope).to.have.property('ngModel'); - }); - - }); - - Object.keys(markup).forEach(function (inputType) { - describe(inputType, function () { - beforeEach(function () { - init(inputType); - }); - - it('should be an input', function () { - expect($elem.get(0).tagName).to.be(inputType.toUpperCase()); - }); - - it('should set valid state', function () { - checkValid(input.valid, 'ng-valid'); - }); - - it('should be valid when empty', function () { - checkValid('', 'ng-valid'); - }); - - it('should set invalid state', function () { - checkValid(input.invalid, 'ng-invalid'); - }); - - it('should be invalid if a number', function () { - checkValid('0', 'ng-invalid'); - }); - - it('should update validity on changes', function () { - checkValid(input.valid, 'ng-valid'); - checkValid(input.invalid, 'ng-invalid'); - checkValid(input.valid, 'ng-valid'); - }); - }); - }); -}); diff --git a/src/legacy/ui/public/directives/inequality.js b/src/legacy/ui/public/directives/inequality.js index d3c80d1ff2e96..a08b617ceb929 100644 --- a/src/legacy/ui/public/directives/inequality.js +++ b/src/legacy/ui/public/directives/inequality.js @@ -24,12 +24,7 @@ function makeDirectiveDef(id, compare) { return { require: 'ngModel', link: function ($scope, $el, $attr, ngModel) { - const getBound = function () { return $parse($attr[id])(); }; - const defaultVal = { - 'greaterThan': -Infinity, - 'greaterOrEqualThan': -Infinity, - 'lessThan': Infinity - }[id]; + const getBound = function () { return $parse($attr[id])($scope); }; ngModel.$parsers.push(validate); ngModel.$formatters.push(validate); @@ -38,12 +33,20 @@ function makeDirectiveDef(id, compare) { validate(ngModel.$viewValue); }); + // We only set it to invalid when both the model value and the value to compare against are + // provided, and the values do not meet the condition. function validate(val) { - const bound = !isNaN(getBound()) ? +getBound() : defaultVal; - const valid = !isNaN(bound) && !isNaN(val) && compare(val, bound); - ngModel.$setValidity(id, valid); + const bound = getBound(); + const left = parseFloat(val); + const right = parseFloat(bound); + const isValid = isEmpty(val) || isEmpty(bound) || compare(left, right); + ngModel.$setValidity(id, isValid); return val; } + + function isEmpty(val) { + return typeof val === 'undefined' || val === null || val === ''; + } } }; }; diff --git a/src/legacy/ui/public/directives/paginated_selectable_list.js b/src/legacy/ui/public/directives/paginated_selectable_list.js index 417273668dae7..7484e2a1840b5 100644 --- a/src/legacy/ui/public/directives/paginated_selectable_list.js +++ b/src/legacy/ui/public/directives/paginated_selectable_list.js @@ -19,6 +19,8 @@ import _ from 'lodash'; import { uiModules } from '../modules'; +import './paginate'; +import './kbn_href'; import paginatedSelectableListTemplate from '../partials/paginated_selectable_list.html'; const module = uiModules.get('kibana'); diff --git a/src/legacy/ui/public/directives/saved_object_finder.js b/src/legacy/ui/public/directives/saved_object_finder.js index 0b107dc085f2d..f73e378f8ba8a 100644 --- a/src/legacy/ui/public/directives/saved_object_finder.js +++ b/src/legacy/ui/public/directives/saved_object_finder.js @@ -23,6 +23,8 @@ import { keyMap } from '../utils/key_map'; import { SavedObjectRegistryProvider } from '../saved_objects/saved_object_registry'; import { uiModules } from '../modules'; import savedObjectFinderTemplate from '../partials/saved_object_finder.html'; +import './input_focus'; +import './paginate'; const module = uiModules.get('kibana'); diff --git a/src/legacy/ui/public/directives/validate_json.js b/src/legacy/ui/public/directives/validate_json.js deleted file mode 100644 index 396cfd13daf88..0000000000000 --- a/src/legacy/ui/public/directives/validate_json.js +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { uiModules } from '../modules'; - -const module = uiModules.get('kibana'); - -module.directive('validateJson', function () { - return { - restrict: 'A', - require: 'ngModel', - scope: { - 'ngModel': '=', - 'queryInput': '=?', - }, - link: function ($scope, $elem, attr, ngModel) { - $scope.$watch('ngModel', validator); - - function validator(newValue) { - if (!newValue || newValue.length === 0) { - setValid(); - return; - } - - // We actually need a proper object in all JSON inputs - newValue = (newValue || '').trim(); - if (newValue[0] === '{' || newValue[0] === '[') { - try { - JSON.parse(newValue); - setValid(); - } catch (e) { - setInvalid(); - } - } else { - setInvalid(); - } - } - - function setValid() { - ngModel.$setValidity('jsonInput', true); - } - - function setInvalid() { - ngModel.$setValidity('jsonInput', false); - } - } - }; -}); diff --git a/src/legacy/ui/public/doc_table/__tests__/actions/filter.js b/src/legacy/ui/public/doc_table/__tests__/actions/filter.js index 4a050797f94f7..496ec7dc87396 100644 --- a/src/legacy/ui/public/doc_table/__tests__/actions/filter.js +++ b/src/legacy/ui/public/doc_table/__tests__/actions/filter.js @@ -21,7 +21,7 @@ import { addFilter } from '../../actions/filter'; import { FilterManagerProvider } from '../../../filter_manager'; import StubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; import NoDigestPromises from 'test_utils/no_digest_promises'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import sinon from 'sinon'; diff --git a/src/legacy/ui/public/doc_table/__tests__/doc_table.js b/src/legacy/ui/public/doc_table/__tests__/doc_table.js index 5395ddb4f216f..56cd15b66b37e 100644 --- a/src/legacy/ui/public/doc_table/__tests__/doc_table.js +++ b/src/legacy/ui/public/doc_table/__tests__/doc_table.js @@ -18,7 +18,7 @@ */ import angular from 'angular'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import _ from 'lodash'; import ngMock from 'ng_mock'; import '../../private'; diff --git a/src/legacy/ui/public/doc_table/__tests__/lib/get_sort.js b/src/legacy/ui/public/doc_table/__tests__/lib/get_sort.js index 3ea586f457993..bec26d38d0fa7 100644 --- a/src/legacy/ui/public/doc_table/__tests__/lib/get_sort.js +++ b/src/legacy/ui/public/doc_table/__tests__/lib/get_sort.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { getSort } from '../../lib/get_sort'; diff --git a/src/legacy/ui/public/doc_table/__tests__/lib/rows_headers.js b/src/legacy/ui/public/doc_table/__tests__/lib/rows_headers.js index 1cbe730aace39..b2660facf7a5a 100644 --- a/src/legacy/ui/public/doc_table/__tests__/lib/rows_headers.js +++ b/src/legacy/ui/public/doc_table/__tests__/lib/rows_headers.js @@ -20,7 +20,7 @@ import angular from 'angular'; import _ from 'lodash'; import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { getFakeRow, getFakeRowVals } from 'fixtures/fake_row'; import $ from 'jquery'; diff --git a/src/legacy/ui/public/doc_table/doc_table.js b/src/legacy/ui/public/doc_table/doc_table.js index 05311556869e1..4c33f8a526704 100644 --- a/src/legacy/ui/public/doc_table/doc_table.js +++ b/src/legacy/ui/public/doc_table/doc_table.js @@ -20,7 +20,7 @@ import _ from 'lodash'; import html from './doc_table.html'; import { getSort } from './lib/get_sort'; -import '../directives/infinite_scroll'; +import './infinite_scroll'; import './components/table_header'; import './components/table_row'; import { dispatchRenderComplete } from '../render_complete'; diff --git a/src/legacy/ui/public/directives/infinite_scroll.js b/src/legacy/ui/public/doc_table/infinite_scroll.js similarity index 97% rename from src/legacy/ui/public/directives/infinite_scroll.js rename to src/legacy/ui/public/doc_table/infinite_scroll.js index 6f8132e1ee7d9..67913062eb2a5 100644 --- a/src/legacy/ui/public/directives/infinite_scroll.js +++ b/src/legacy/ui/public/doc_table/infinite_scroll.js @@ -19,7 +19,7 @@ import $ from 'jquery'; import { uiModules } from '../modules'; -const module = uiModules.get('kibana'); +const module = uiModules.get('app/discover'); module.directive('kbnInfiniteScroll', function () { return { diff --git a/src/legacy/ui/public/doc_title/__tests__/doc_title.js b/src/legacy/ui/public/doc_title/__tests__/doc_title.js index 4c459a17a6c69..2c0ec6766cb14 100644 --- a/src/legacy/ui/public/doc_title/__tests__/doc_title.js +++ b/src/legacy/ui/public/doc_title/__tests__/doc_title.js @@ -19,7 +19,7 @@ import _ from 'lodash'; import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { DocTitleProvider } from '..'; diff --git a/src/legacy/ui/public/doc_viewer/__tests__/doc_viewer.js b/src/legacy/ui/public/doc_viewer/__tests__/doc_viewer.js index e55718374be16..b6ba1f7206a19 100644 --- a/src/legacy/ui/public/doc_viewer/__tests__/doc_viewer.js +++ b/src/legacy/ui/public/doc_viewer/__tests__/doc_viewer.js @@ -19,7 +19,7 @@ import angular from 'angular'; import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import '../../private'; diff --git a/src/legacy/ui/public/documentation_links/__tests__/documentation_links.js b/src/legacy/ui/public/documentation_links/__tests__/documentation_links.js index 22e6d8ecfbff6..60ab7a03576c3 100644 --- a/src/legacy/ui/public/documentation_links/__tests__/documentation_links.js +++ b/src/legacy/ui/public/documentation_links/__tests__/documentation_links.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { documentationLinks } from '../documentation_links'; import { metadata } from '../../metadata'; diff --git a/src/legacy/ui/public/draggable/__tests__/draggable.js b/src/legacy/ui/public/draggable/__tests__/draggable.js index 8cba8a8ebb11c..fc0601a9b67e9 100644 --- a/src/legacy/ui/public/draggable/__tests__/draggable.js +++ b/src/legacy/ui/public/draggable/__tests__/draggable.js @@ -18,7 +18,7 @@ */ import angular from 'angular'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; let init; diff --git a/src/legacy/ui/public/embeddable/context_menu_actions/index.ts b/src/legacy/ui/public/embeddable/context_menu_actions/index.ts index 152fdee9f7fff..d43f1d16aefd1 100644 --- a/src/legacy/ui/public/embeddable/context_menu_actions/index.ts +++ b/src/legacy/ui/public/embeddable/context_menu_actions/index.ts @@ -21,3 +21,4 @@ export { ContextMenuPanel } from './context_menu_panel'; export { ContextMenuAction } from './context_menu_action'; export { ContextMenuActionsRegistryProvider } from './context_menu_actions_registry'; export { buildEuiContextMenuPanels } from './build_eui_context_menu_panels'; +export { PanelActionAPI } from './types'; diff --git a/src/legacy/ui/public/error_url_overflow/__tests__/ie_regex.js b/src/legacy/ui/public/error_url_overflow/__tests__/ie_regex.js index 75d114e397fb8..48b92b79c0b7e 100644 --- a/src/legacy/ui/public/error_url_overflow/__tests__/ie_regex.js +++ b/src/legacy/ui/public/error_url_overflow/__tests__/ie_regex.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { IE_REGEX } from '../url_overflow_service.js'; describe('IE_REGEX', () => { diff --git a/src/legacy/ui/public/exit_full_screen/exit_full_screen_button.js b/src/legacy/ui/public/exit_full_screen/exit_full_screen_button.tsx similarity index 76% rename from src/legacy/ui/public/exit_full_screen/exit_full_screen_button.js rename to src/legacy/ui/public/exit_full_screen/exit_full_screen_button.tsx index 9e985426e8f41..4fc17a7dbca38 100644 --- a/src/legacy/ui/public/exit_full_screen/exit_full_screen_button.js +++ b/src/legacy/ui/public/exit_full_screen/exit_full_screen_button.tsx @@ -17,39 +17,37 @@ * under the License. */ +import { FormattedMessage, injectI18n } from '@kbn/i18n/react'; import React, { PureComponent } from 'react'; -import PropTypes from 'prop-types'; import chrome from 'ui/chrome'; -import { injectI18n, FormattedMessage } from '@kbn/i18n/react'; -import { - KuiButton, -} from '@kbn/ui-framework/components'; +// @ts-ignore +import { KuiButton } from '@kbn/ui-framework/components'; -import { - keyCodes, - EuiScreenReaderOnly, -} from '@elastic/eui'; +import { EuiScreenReaderOnly, keyCodes } from '@elastic/eui'; -class ExitFullScreenButtonUi extends PureComponent { +interface Props extends ReactIntl.InjectedIntlProps { + onExitFullScreenMode: () => void; +} - onKeyDown = (e) => { +class ExitFullScreenButtonUi extends PureComponent { + public onKeyDown = (e: KeyboardEvent) => { if (e.keyCode === keyCodes.ESCAPE) { this.props.onExitFullScreenMode(); } }; - componentWillMount() { + public componentWillMount() { document.addEventListener('keydown', this.onKeyDown, false); chrome.setVisible(false); } - componentWillUnmount() { + public componentWillUnmount() { document.removeEventListener('keydown', this.onKeyDown, false); chrome.setVisible(true); } - render() { + public render() { const { intl } = this.props; return ( @@ -62,9 +60,7 @@ class ExitFullScreenButtonUi extends PureComponent { />

-
+
- + - +
@@ -89,8 +88,4 @@ class ExitFullScreenButtonUi extends PureComponent { } } -ExitFullScreenButtonUi.propTypes = { - onExitFullScreenMode: PropTypes.func.isRequired, -}; - export const ExitFullScreenButton = injectI18n(ExitFullScreenButtonUi); diff --git a/src/legacy/ui/public/exit_full_screen/index.js b/src/legacy/ui/public/exit_full_screen/index.ts similarity index 100% rename from src/legacy/ui/public/exit_full_screen/index.js rename to src/legacy/ui/public/exit_full_screen/index.ts diff --git a/src/legacy/ui/public/factories/__tests__/events.js b/src/legacy/ui/public/factories/__tests__/events.js deleted file mode 100644 index c9ba7f5798544..0000000000000 --- a/src/legacy/ui/public/factories/__tests__/events.js +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - - -import _ from 'lodash'; -import sinon from 'sinon'; -import expect from 'expect.js'; -import ngMock from 'ng_mock'; -import '../../private'; -import { EventsProvider } from '../../events'; -import { createLegacyClass } from '../../utils/legacy_class'; - -describe('Events', function () { - require('test_utils/no_digest_promises').activateForSuite(); - - let Events; - let Promise; - - beforeEach(ngMock.module('kibana')); - beforeEach(ngMock.inject(function ($injector, Private) { - Promise = $injector.get('Promise'); - Events = Private(EventsProvider); - })); - - it('should handle on events', function () { - const obj = new Events(); - const prom = obj.on('test', function (message) { - expect(message).to.equal('Hello World'); - }); - - obj.emit('test', 'Hello World'); - - return prom; - }); - - it('should work with inherited objects', function () { - createLegacyClass(MyEventedObject).inherits(Events); - function MyEventedObject() { - MyEventedObject.Super.call(this); - } - const obj = new MyEventedObject(); - - const prom = obj.on('test', function (message) { - expect(message).to.equal('Hello World'); - }); - - obj.emit('test', 'Hello World'); - - return prom; - }); - - it('should clear events when off is called', function () { - const obj = new Events(); - obj.on('test', _.noop); - expect(obj._listeners).to.have.property('test'); - expect(obj._listeners.test).to.have.length(1); - obj.off(); - expect(obj._listeners).to.not.have.property('test'); - }); - - it('should clear a specific handler when off is called for an event', function () { - const obj = new Events(); - const handler1 = sinon.stub(); - const handler2 = sinon.stub(); - obj.on('test', handler1); - obj.on('test', handler2); - expect(obj._listeners).to.have.property('test'); - obj.off('test', handler1); - - return obj.emit('test', 'Hello World') - .then(function () { - sinon.assert.calledOnce(handler2); - sinon.assert.notCalled(handler1); - }); - }); - - it('should clear a all handlers when off is called for an event', function () { - const obj = new Events(); - const handler1 = sinon.stub(); - obj.on('test', handler1); - expect(obj._listeners).to.have.property('test'); - obj.off('test'); - expect(obj._listeners).to.not.have.property('test'); - - return obj.emit('test', 'Hello World') - .then(function () { - sinon.assert.notCalled(handler1); - }); - }); - - it('should handle multiple identical emits in the same tick', function () { - const obj = new Events(); - const handler1 = sinon.stub(); - - obj.on('test', handler1); - const emits = [ - obj.emit('test', 'one'), - obj.emit('test', 'two'), - obj.emit('test', 'three') - ]; - - return Promise - .all(emits) - .then(function () { - expect(handler1.callCount).to.be(emits.length); - expect(handler1.getCall(0).calledWith('one')).to.be(true); - expect(handler1.getCall(1).calledWith('two')).to.be(true); - expect(handler1.getCall(2).calledWith('three')).to.be(true); - }); - }); - - it('should handle emits from the handler', function () { - const obj = new Events(); - const secondEmit = Promise.defer(); - const handler1 = sinon.spy(function () { - if (handler1.calledTwice) { - return; - } - obj.emit('test').then(_.bindKey(secondEmit, 'resolve')); - }); - - obj.on('test', handler1); - - return Promise - .all([ - obj.emit('test'), - secondEmit.promise - ]) - .then(function () { - expect(handler1.callCount).to.be(2); - }); - }); - - it('should only emit to handlers registered before emit is called', function () { - const obj = new Events(); - const handler1 = sinon.stub(); - const handler2 = sinon.stub(); - - obj.on('test', handler1); - const emits = [ - obj.emit('test', 'one'), - obj.emit('test', 'two'), - obj.emit('test', 'three') - ]; - - - return Promise.all(emits).then(function () { - expect(handler1.callCount).to.be(emits.length); - - obj.on('test', handler2); - - const emits2 = [ - obj.emit('test', 'four'), - obj.emit('test', 'five'), - obj.emit('test', 'six') - ]; - - return Promise.all(emits2) - .then(function () { - expect(handler1.callCount).to.be(emits.length + emits2.length); - expect(handler2.callCount).to.be(emits2.length); - }); - }); - }); - - it('should pass multiple arguments from the emitter', function () { - const obj = new Events(); - const handler = sinon.stub(); - const payload = [ - 'one', - { hello: 'tests' }, - null - ]; - - obj.on('test', handler); - - return obj.emit('test', payload[0], payload[1], payload[2]) - .then(function () { - expect(handler.callCount).to.be(1); - expect(handler.calledWithExactly(payload[0], payload[1], payload[2])).to.be(true); - }); - }); - - it('should preserve the scope of the handler', function () { - const obj = new Events(); - const expected = 'some value'; - let testValue; - - function handler() { - testValue = this.getVal(); - } - handler.getVal = _.constant(expected); - - obj.on('test', handler); - return obj.emit('test') - .then(function () { - expect(testValue).to.equal(expected); - }); - }); - - it('should always emit in the same order', function () { - const handler = sinon.stub(); - - const obj = new Events(); - obj.on('block', _.partial(handler, 'block')); - obj.on('last', _.partial(handler, 'last')); - - return Promise - .all([ - obj.emit('block'), - obj.emit('block'), - obj.emit('block'), - obj.emit('block'), - obj.emit('block'), - obj.emit('block'), - obj.emit('block'), - obj.emit('block'), - obj.emit('block'), - obj.emit('last') - ]) - .then(function () { - expect(handler.callCount).to.be(10); - handler.args.forEach(function (args, i) { - expect(args[0]).to.be(i < 9 ? 'block' : 'last'); - }); - }); - }); -}); diff --git a/src/legacy/ui/public/fancy_forms/__tests__/fancy_forms.js b/src/legacy/ui/public/fancy_forms/__tests__/fancy_forms.js index 401255ba44d6b..4e1cbb2595c2c 100644 --- a/src/legacy/ui/public/fancy_forms/__tests__/fancy_forms.js +++ b/src/legacy/ui/public/fancy_forms/__tests__/fancy_forms.js @@ -18,7 +18,7 @@ */ import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import $ from 'jquery'; describe('fancy forms', function () { diff --git a/src/legacy/ui/public/fancy_forms/__tests__/nested_fancy_forms.js b/src/legacy/ui/public/fancy_forms/__tests__/nested_fancy_forms.js index 005e6441b03a8..095007004ae7f 100644 --- a/src/legacy/ui/public/fancy_forms/__tests__/nested_fancy_forms.js +++ b/src/legacy/ui/public/fancy_forms/__tests__/nested_fancy_forms.js @@ -18,7 +18,8 @@ */ import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; +import testSubjSelector from '@kbn/test-subj-selector'; import sinon from 'sinon'; import $ from 'jquery'; @@ -85,7 +86,7 @@ describe('fancy forms', function () { expect($scope.person.errorCount()).to.be(1); expect($scope.person.softErrorCount()).to.be(0); - $el.findTestSubject('submit').click(); + $el.find(testSubjSelector('submit')).click(); expect($scope.person.errorCount()).to.be(1); expect($scope.person.softErrorCount()).to.be(1); }); @@ -96,7 +97,7 @@ describe('fancy forms', function () { expect($scope.person.errorCount()).to.be(1); sinon.assert.notCalled(onSubmit); - $el.findTestSubject('submit').click(); + $el.find(testSubjSelector('submit')).click(); expect($scope.person.errorCount()).to.be(1); sinon.assert.notCalled(onSubmit); @@ -106,7 +107,7 @@ describe('fancy forms', function () { expect($scope.person.errorCount()).to.be(0); sinon.assert.notCalled(onSubmit); - $el.findTestSubject('submit').click(); + $el.find(testSubjSelector('submit')).click(); expect($scope.person.errorCount()).to.be(0); sinon.assert.calledOnce(onSubmit); }); @@ -114,7 +115,7 @@ describe('fancy forms', function () { it('new fields are no longer soft after blur', function () { const { $scope, $el } = setup({ name: '' }); expect($scope.person.softErrorCount()).to.be(0); - $el.findTestSubject('name').blur(); + $el.find(testSubjSelector('name')).blur(); expect($scope.person.softErrorCount()).to.be(1); }); @@ -139,7 +140,7 @@ describe('fancy forms', function () { expect($scope.person.errorCount()).to.be(2); expect($scope.person.softErrorCount()).to.be(0); - $el.findTestSubject('taskDesc').first().blur(); + $el.find(testSubjSelector('taskDesc')).first().blur(); expect($scope.person.errorCount()).to.be(2); expect($scope.person.softErrorCount()).to.be(1); @@ -177,7 +178,7 @@ describe('fancy forms', function () { expect(form.softErrorCount()).to.be(0); // blurs only count locally - $task.findTestSubject('taskDesc').blur(); + $task.find(testSubjSelector('taskDesc')).blur(); expect(form.softErrorCount()).to.be(1); // but parent form see them diff --git a/src/legacy/ui/public/field_editor/components/scripting_help/__snapshots__/help_flyout.test.js.snap b/src/legacy/ui/public/field_editor/components/scripting_help/__snapshots__/help_flyout.test.js.snap index 8a0efdef72011..12492b0bb7b68 100644 --- a/src/legacy/ui/public/field_editor/components/scripting_help/__snapshots__/help_flyout.test.js.snap +++ b/src/legacy/ui/public/field_editor/components/scripting_help/__snapshots__/help_flyout.test.js.snap @@ -14,7 +14,7 @@ exports[`ScriptingHelpFlyout should render normally 1`] = ` , + "content": , "data-test-subj": "syntaxTab", "id": "syntax", "name": "Syntax", @@ -23,7 +23,7 @@ exports[`ScriptingHelpFlyout should render normally 1`] = ` tabs={ Array [ Object { - "content": , + "content": , "data-test-subj": "syntaxTab", "id": "syntax", "name": "Syntax", diff --git a/src/legacy/ui/public/field_wildcard/__tests__/field_wildcard.js b/src/legacy/ui/public/field_wildcard/__tests__/field_wildcard.js index 0bd5fe8e8ed77..aeffdbc8bfa6c 100644 --- a/src/legacy/ui/public/field_wildcard/__tests__/field_wildcard.js +++ b/src/legacy/ui/public/field_wildcard/__tests__/field_wildcard.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { FieldWildcardProvider } from '../../field_wildcard'; diff --git a/src/legacy/ui/public/filter_bar/__tests__/_add_filters.js b/src/legacy/ui/public/filter_bar/__tests__/_add_filters.js index faa2378ad8bf5..49fbafdf4ee92 100644 --- a/src/legacy/ui/public/filter_bar/__tests__/_add_filters.js +++ b/src/legacy/ui/public/filter_bar/__tests__/_add_filters.js @@ -19,7 +19,7 @@ import _ from 'lodash'; import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import MockState from 'fixtures/mock_state'; import { FilterBarQueryFilterProvider } from '../query_filter'; diff --git a/src/legacy/ui/public/filter_bar/__tests__/_get_filters.js b/src/legacy/ui/public/filter_bar/__tests__/_get_filters.js index 5b0abd9efcdf4..3805ce1ccaf1e 100644 --- a/src/legacy/ui/public/filter_bar/__tests__/_get_filters.js +++ b/src/legacy/ui/public/filter_bar/__tests__/_get_filters.js @@ -19,7 +19,7 @@ import _ from 'lodash'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import MockState from 'fixtures/mock_state'; import { FilterBarQueryFilterProvider } from '../query_filter'; diff --git a/src/legacy/ui/public/filter_bar/__tests__/_invert_filters.js b/src/legacy/ui/public/filter_bar/__tests__/_invert_filters.js index 06e6ccea2eca5..e705cf22cf7fe 100644 --- a/src/legacy/ui/public/filter_bar/__tests__/_invert_filters.js +++ b/src/legacy/ui/public/filter_bar/__tests__/_invert_filters.js @@ -19,7 +19,7 @@ import _ from 'lodash'; import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import MockState from 'fixtures/mock_state'; import { FilterBarQueryFilterProvider } from '../query_filter'; diff --git a/src/legacy/ui/public/filter_bar/__tests__/_pin_filters.js b/src/legacy/ui/public/filter_bar/__tests__/_pin_filters.js index d200cbec52c4d..2c9eb4f730ada 100644 --- a/src/legacy/ui/public/filter_bar/__tests__/_pin_filters.js +++ b/src/legacy/ui/public/filter_bar/__tests__/_pin_filters.js @@ -19,7 +19,7 @@ import _ from 'lodash'; import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import MockState from 'fixtures/mock_state'; import { FilterBarQueryFilterProvider } from '../query_filter'; diff --git a/src/legacy/ui/public/filter_bar/__tests__/_remove_filters.js b/src/legacy/ui/public/filter_bar/__tests__/_remove_filters.js index 617a56da4c03c..a723031f67c4c 100644 --- a/src/legacy/ui/public/filter_bar/__tests__/_remove_filters.js +++ b/src/legacy/ui/public/filter_bar/__tests__/_remove_filters.js @@ -19,7 +19,7 @@ import _ from 'lodash'; import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import MockState from 'fixtures/mock_state'; import { FilterBarQueryFilterProvider } from '../query_filter'; diff --git a/src/legacy/ui/public/filter_bar/__tests__/_toggle_filters.js b/src/legacy/ui/public/filter_bar/__tests__/_toggle_filters.js index 0fe5be25a12ef..d1eb26641a770 100644 --- a/src/legacy/ui/public/filter_bar/__tests__/_toggle_filters.js +++ b/src/legacy/ui/public/filter_bar/__tests__/_toggle_filters.js @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import sinon from 'sinon'; import MockState from 'fixtures/mock_state'; diff --git a/src/legacy/ui/public/filter_bar/__tests__/push_filter.js b/src/legacy/ui/public/filter_bar/__tests__/push_filter.js index 7d8e38b8af7f8..81b418e5665c6 100644 --- a/src/legacy/ui/public/filter_bar/__tests__/push_filter.js +++ b/src/legacy/ui/public/filter_bar/__tests__/push_filter.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { FilterBarPushFilterProvider } from '../push_filter'; describe('Filter Bar pushFilter()', function () { diff --git a/src/legacy/ui/public/filter_bar/__tests__/query_filter.js b/src/legacy/ui/public/filter_bar/__tests__/query_filter.js index e3d8a0e8b61d2..9e5d3b8973c09 100644 --- a/src/legacy/ui/public/filter_bar/__tests__/query_filter.js +++ b/src/legacy/ui/public/filter_bar/__tests__/query_filter.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import './_get_filters'; import './_add_filters'; diff --git a/src/legacy/ui/public/filter_bar/lib/__tests__/change_time_filter.test.js b/src/legacy/ui/public/filter_bar/lib/__tests__/change_time_filter.test.js index b9916c1f08a06..52c54a4937cc8 100644 --- a/src/legacy/ui/public/filter_bar/lib/__tests__/change_time_filter.test.js +++ b/src/legacy/ui/public/filter_bar/lib/__tests__/change_time_filter.test.js @@ -36,7 +36,7 @@ jest.mock('ui/chrome', }, }), { virtual: true }); -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { changeTimeFilter } from '../change_time_filter'; import { timefilter } from 'ui/timefilter'; diff --git a/src/legacy/ui/public/filter_bar/lib/__tests__/dedup_filters.js b/src/legacy/ui/public/filter_bar/lib/__tests__/dedup_filters.js index 9b6b56f8f2c10..cbe511b326c0b 100644 --- a/src/legacy/ui/public/filter_bar/lib/__tests__/dedup_filters.js +++ b/src/legacy/ui/public/filter_bar/lib/__tests__/dedup_filters.js @@ -18,7 +18,7 @@ */ import { dedupFilters } from '../dedup_filters'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; describe('Filter Bar Directive', function () { describe('dedupFilters(existing, filters)', function () { diff --git a/src/legacy/ui/public/filter_bar/lib/__tests__/extract_time_filter.js b/src/legacy/ui/public/filter_bar/lib/__tests__/extract_time_filter.js index da85160ef1944..970d175526841 100644 --- a/src/legacy/ui/public/filter_bar/lib/__tests__/extract_time_filter.js +++ b/src/legacy/ui/public/filter_bar/lib/__tests__/extract_time_filter.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { FilterBarLibExtractTimeFilterProvider } from '../extract_time_filter'; diff --git a/src/legacy/ui/public/filter_bar/lib/__tests__/generate_mapping_chain.js b/src/legacy/ui/public/filter_bar/lib/__tests__/generate_mapping_chain.js index bcf6829184787..49f70b457f996 100644 --- a/src/legacy/ui/public/filter_bar/lib/__tests__/generate_mapping_chain.js +++ b/src/legacy/ui/public/filter_bar/lib/__tests__/generate_mapping_chain.js @@ -18,7 +18,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { FilterBarLibGenerateMappingChainProvider } from '../generate_mapping_chain'; diff --git a/src/legacy/ui/public/filter_bar/lib/__tests__/map_and_flatten_filters.js b/src/legacy/ui/public/filter_bar/lib/__tests__/map_and_flatten_filters.js index e09da2a0baed7..f979c4fd1450e 100644 --- a/src/legacy/ui/public/filter_bar/lib/__tests__/map_and_flatten_filters.js +++ b/src/legacy/ui/public/filter_bar/lib/__tests__/map_and_flatten_filters.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { FilterBarLibMapAndFlattenFiltersProvider } from '../map_and_flatten_filters'; diff --git a/src/legacy/ui/public/filter_bar/lib/__tests__/map_default.js b/src/legacy/ui/public/filter_bar/lib/__tests__/map_default.js index 52400ceeb2a21..e22f4639d97e1 100644 --- a/src/legacy/ui/public/filter_bar/lib/__tests__/map_default.js +++ b/src/legacy/ui/public/filter_bar/lib/__tests__/map_default.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { FilterBarLibMapDefaultProvider } from '../map_default'; diff --git a/src/legacy/ui/public/filter_bar/lib/__tests__/map_exists.js b/src/legacy/ui/public/filter_bar/lib/__tests__/map_exists.js index 8a36d5cf82af6..f0b09da6ba687 100644 --- a/src/legacy/ui/public/filter_bar/lib/__tests__/map_exists.js +++ b/src/legacy/ui/public/filter_bar/lib/__tests__/map_exists.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { FilterBarLibMapExistsProvider } from '../map_exists'; diff --git a/src/legacy/ui/public/filter_bar/lib/__tests__/map_filter.js b/src/legacy/ui/public/filter_bar/lib/__tests__/map_filter.js index e15baab9e1182..0e307e2669ac2 100644 --- a/src/legacy/ui/public/filter_bar/lib/__tests__/map_filter.js +++ b/src/legacy/ui/public/filter_bar/lib/__tests__/map_filter.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { FilterBarLibMapFilterProvider } from '../map_filter'; diff --git a/src/legacy/ui/public/filter_bar/lib/__tests__/map_flatten_and_wrap_filters.js b/src/legacy/ui/public/filter_bar/lib/__tests__/map_flatten_and_wrap_filters.js index 7f71845deed95..8b0ca4715d284 100644 --- a/src/legacy/ui/public/filter_bar/lib/__tests__/map_flatten_and_wrap_filters.js +++ b/src/legacy/ui/public/filter_bar/lib/__tests__/map_flatten_and_wrap_filters.js @@ -19,7 +19,7 @@ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { FilterBarLibMapFlattenAndWrapFiltersProvider } from '../map_flatten_and_wrap_filters'; diff --git a/src/legacy/ui/public/filter_bar/lib/__tests__/map_geo_bounding_box.js b/src/legacy/ui/public/filter_bar/lib/__tests__/map_geo_bounding_box.js index 0a61d20f3ba35..6f9d757f4b9b8 100644 --- a/src/legacy/ui/public/filter_bar/lib/__tests__/map_geo_bounding_box.js +++ b/src/legacy/ui/public/filter_bar/lib/__tests__/map_geo_bounding_box.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { FilterBarLibMapGeoBoundingBoxProvider } from '../map_geo_bounding_box'; diff --git a/src/legacy/ui/public/filter_bar/lib/__tests__/map_geo_polygon.js b/src/legacy/ui/public/filter_bar/lib/__tests__/map_geo_polygon.js index 9f501d68c1c9f..6b17ac5b6b691 100644 --- a/src/legacy/ui/public/filter_bar/lib/__tests__/map_geo_polygon.js +++ b/src/legacy/ui/public/filter_bar/lib/__tests__/map_geo_polygon.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { FilterBarLibMapGeoPolygonProvider } from '../map_geo_polygon'; diff --git a/src/legacy/ui/public/filter_bar/lib/__tests__/map_match_all.js b/src/legacy/ui/public/filter_bar/lib/__tests__/map_match_all.js index d092e6d7979c4..b12128929903b 100644 --- a/src/legacy/ui/public/filter_bar/lib/__tests__/map_match_all.js +++ b/src/legacy/ui/public/filter_bar/lib/__tests__/map_match_all.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { FilterBarLibMapMatchAllProvider } from '../map_match_all'; diff --git a/src/legacy/ui/public/filter_bar/lib/__tests__/map_missing.js b/src/legacy/ui/public/filter_bar/lib/__tests__/map_missing.js index 551898c8fbdda..005b8883be51c 100644 --- a/src/legacy/ui/public/filter_bar/lib/__tests__/map_missing.js +++ b/src/legacy/ui/public/filter_bar/lib/__tests__/map_missing.js @@ -18,7 +18,7 @@ */ import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { FilterBarLibMapMissingProvider } from '../map_missing'; describe('Filter Bar Directive', function () { diff --git a/src/legacy/ui/public/filter_bar/lib/__tests__/map_phrase.js b/src/legacy/ui/public/filter_bar/lib/__tests__/map_phrase.js index 0e646088a2dfc..4a0262d93a194 100644 --- a/src/legacy/ui/public/filter_bar/lib/__tests__/map_phrase.js +++ b/src/legacy/ui/public/filter_bar/lib/__tests__/map_phrase.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { FilterBarLibMapPhraseProvider } from '../map_phrase'; diff --git a/src/legacy/ui/public/filter_bar/lib/__tests__/map_query_string.js b/src/legacy/ui/public/filter_bar/lib/__tests__/map_query_string.js index a0d7a8f5b2876..056ba8b8a7de1 100644 --- a/src/legacy/ui/public/filter_bar/lib/__tests__/map_query_string.js +++ b/src/legacy/ui/public/filter_bar/lib/__tests__/map_query_string.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { FilterBarLibMapQueryStringProvider } from '../map_query_string'; diff --git a/src/legacy/ui/public/filter_bar/lib/__tests__/map_range.js b/src/legacy/ui/public/filter_bar/lib/__tests__/map_range.js index 9ec5725be2b2c..866a692751170 100644 --- a/src/legacy/ui/public/filter_bar/lib/__tests__/map_range.js +++ b/src/legacy/ui/public/filter_bar/lib/__tests__/map_range.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { FilterBarLibMapRangeProvider } from '../map_range'; diff --git a/src/legacy/ui/public/filter_bar/lib/__tests__/only_disabled.js b/src/legacy/ui/public/filter_bar/lib/__tests__/only_disabled.js index 7bc9c6c58d2ed..a6f4c74a70bab 100644 --- a/src/legacy/ui/public/filter_bar/lib/__tests__/only_disabled.js +++ b/src/legacy/ui/public/filter_bar/lib/__tests__/only_disabled.js @@ -18,7 +18,7 @@ */ import { onlyDisabled } from '../only_disabled'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; describe('Filter Bar Directive', function () { describe('onlyDisabled()', function () { diff --git a/src/legacy/ui/public/filter_bar/lib/__tests__/uniq_filters.js b/src/legacy/ui/public/filter_bar/lib/__tests__/uniq_filters.js index e42cc71485ab5..569f03f28192b 100644 --- a/src/legacy/ui/public/filter_bar/lib/__tests__/uniq_filters.js +++ b/src/legacy/ui/public/filter_bar/lib/__tests__/uniq_filters.js @@ -18,7 +18,7 @@ */ import { uniqFilters } from '../uniq_filters'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; describe('Filter Bar Directive', function () { describe('uniqFilter', function () { diff --git a/src/legacy/ui/public/filter_manager/__tests__/filter_manager.js b/src/legacy/ui/public/filter_manager/__tests__/filter_manager.js index 87a0ed052a1c3..f1f374e0a7c3e 100644 --- a/src/legacy/ui/public/filter_manager/__tests__/filter_manager.js +++ b/src/legacy/ui/public/filter_manager/__tests__/filter_manager.js @@ -20,7 +20,7 @@ import _ from 'lodash'; import sinon from 'sinon'; import MockState from 'fixtures/mock_state'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { FilterManagerProvider } from '..'; import { FilterBarQueryFilterProvider } from '../../filter_bar/query_filter'; diff --git a/src/legacy/ui/public/filters/__tests__/comma_list.js b/src/legacy/ui/public/filters/__tests__/comma_list.js index ec1333b1c616f..f5b155b989ac2 100644 --- a/src/legacy/ui/public/filters/__tests__/comma_list.js +++ b/src/legacy/ui/public/filters/__tests__/comma_list.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import '../comma_list'; diff --git a/src/legacy/ui/public/filters/__tests__/field_type.js b/src/legacy/ui/public/filters/__tests__/field_type.js index da1b5f3537d59..0b969095eb499 100644 --- a/src/legacy/ui/public/filters/__tests__/field_type.js +++ b/src/legacy/ui/public/filters/__tests__/field_type.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import _ from 'lodash'; import ngMock from 'ng_mock'; import 'plugins/kibana/discover/index'; diff --git a/src/legacy/ui/public/filters/__tests__/label.js b/src/legacy/ui/public/filters/__tests__/label.js index 7f702896b58c9..1696415229749 100644 --- a/src/legacy/ui/public/filters/__tests__/label.js +++ b/src/legacy/ui/public/filters/__tests__/label.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import 'plugins/kibana/discover/index'; diff --git a/src/legacy/ui/public/filters/__tests__/moment.js b/src/legacy/ui/public/filters/__tests__/moment.js index e3550df031ee7..39d7a520851d4 100644 --- a/src/legacy/ui/public/filters/__tests__/moment.js +++ b/src/legacy/ui/public/filters/__tests__/moment.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import moment from 'moment'; import ngMock from 'ng_mock'; diff --git a/src/legacy/ui/public/filters/__tests__/prop_filter.js b/src/legacy/ui/public/filters/__tests__/prop_filter.js index 2b125c47c408b..ec60121960ecb 100644 --- a/src/legacy/ui/public/filters/__tests__/prop_filter.js +++ b/src/legacy/ui/public/filters/__tests__/prop_filter.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { propFilter } from '../_prop_filter'; describe('prop filter', function () { diff --git a/src/legacy/ui/public/filters/__tests__/rison.js b/src/legacy/ui/public/filters/__tests__/rison.js index 671ef5debc659..62accfa8118a7 100644 --- a/src/legacy/ui/public/filters/__tests__/rison.js +++ b/src/legacy/ui/public/filters/__tests__/rison.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import 'plugins/kibana/discover/index'; diff --git a/src/legacy/ui/public/filters/__tests__/short_dots.js b/src/legacy/ui/public/filters/__tests__/short_dots.js index 2d23715f7a9e2..747c2c280750e 100644 --- a/src/legacy/ui/public/filters/__tests__/short_dots.js +++ b/src/legacy/ui/public/filters/__tests__/short_dots.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import 'plugins/kibana/discover/index'; import '../short_dots'; diff --git a/src/legacy/ui/public/filters/__tests__/start_from.js b/src/legacy/ui/public/filters/__tests__/start_from.js index 4b93042779111..389522bcbf944 100644 --- a/src/legacy/ui/public/filters/__tests__/start_from.js +++ b/src/legacy/ui/public/filters/__tests__/start_from.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import '../start_from'; diff --git a/src/legacy/ui/public/filters/__tests__/uriescape.js b/src/legacy/ui/public/filters/__tests__/uriescape.js index 2e9e14d3b0783..49a7034593821 100644 --- a/src/legacy/ui/public/filters/__tests__/uriescape.js +++ b/src/legacy/ui/public/filters/__tests__/uriescape.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import 'plugins/kibana/discover/index'; diff --git a/src/legacy/ui/public/index_patterns/__tests__/_get_computed_fields.js b/src/legacy/ui/public/index_patterns/__tests__/_get_computed_fields.js index 101032413cc2d..3d5fd961c9b51 100644 --- a/src/legacy/ui/public/index_patterns/__tests__/_get_computed_fields.js +++ b/src/legacy/ui/public/index_patterns/__tests__/_get_computed_fields.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; import { getComputedFields } from '../_get_computed_fields'; diff --git a/src/legacy/ui/public/index_patterns/__tests__/_index_pattern.js b/src/legacy/ui/public/index_patterns/__tests__/_index_pattern.js index 023e61bdf8a01..bf1234e95f9fc 100644 --- a/src/legacy/ui/public/index_patterns/__tests__/_index_pattern.js +++ b/src/legacy/ui/public/index_patterns/__tests__/_index_pattern.js @@ -20,7 +20,7 @@ import _ from 'lodash'; import sinon from 'sinon'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import Promise from 'bluebird'; import { DuplicateField } from '../../errors'; import { IndexedArray } from '../../indexed_array'; diff --git a/src/legacy/ui/public/index_patterns/__tests__/flatten_hit.js b/src/legacy/ui/public/index_patterns/__tests__/flatten_hit.js index 5615edad3453a..6470c0ae04749 100644 --- a/src/legacy/ui/public/index_patterns/__tests__/flatten_hit.js +++ b/src/legacy/ui/public/index_patterns/__tests__/flatten_hit.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { IndexPatternsFlattenHitProvider } from '../_flatten_hit'; diff --git a/src/legacy/ui/public/index_patterns/__tests__/index_patterns.js b/src/legacy/ui/public/index_patterns/__tests__/index_patterns.js index 6b32674b5e3ea..5a6cf3ba51c67 100644 --- a/src/legacy/ui/public/index_patterns/__tests__/index_patterns.js +++ b/src/legacy/ui/public/index_patterns/__tests__/index_patterns.js @@ -18,7 +18,7 @@ */ import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { IndexPatternProvider } from '../_index_pattern'; import { IndexPatternsProvider } from '../index_patterns'; diff --git a/src/legacy/ui/public/index_patterns/__tests__/intervals.js b/src/legacy/ui/public/index_patterns/__tests__/intervals.js index 07e4ec81e2097..cc2ba5d5f4745 100644 --- a/src/legacy/ui/public/index_patterns/__tests__/intervals.js +++ b/src/legacy/ui/public/index_patterns/__tests__/intervals.js @@ -18,7 +18,7 @@ */ import moment from 'moment'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { IndexPatternsIntervalsProvider } from '../_intervals'; diff --git a/src/legacy/ui/public/index_patterns/__tests__/unsupported_time_patterns.js b/src/legacy/ui/public/index_patterns/__tests__/unsupported_time_patterns.js index 1a6c472593712..a3af1332136a8 100644 --- a/src/legacy/ui/public/index_patterns/__tests__/unsupported_time_patterns.js +++ b/src/legacy/ui/public/index_patterns/__tests__/unsupported_time_patterns.js @@ -18,7 +18,7 @@ */ import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import Chance from 'chance'; import { Storage } from '../../storage'; diff --git a/src/legacy/ui/public/index_patterns/route_setup/load_default.js b/src/legacy/ui/public/index_patterns/route_setup/load_default.js index 6de1eb2b812a8..669b33d731983 100644 --- a/src/legacy/ui/public/index_patterns/route_setup/load_default.js +++ b/src/legacy/ui/public/index_patterns/route_setup/load_default.js @@ -59,7 +59,7 @@ function displayBanner() { }, 15000); } -// eslint-disable-next-line @elastic/kibana-custom/no-default-export +// eslint-disable-next-line @kbn/eslint/no-default-export export default function (opts) { opts = opts || {}; const whenMissingRedirectTo = opts.whenMissingRedirectTo || null; diff --git a/src/legacy/ui/public/index_patterns/static_utils/__tests__/index.js b/src/legacy/ui/public/index_patterns/static_utils/__tests__/index.js index e825df5d294ca..04503be6f7f78 100644 --- a/src/legacy/ui/public/index_patterns/static_utils/__tests__/index.js +++ b/src/legacy/ui/public/index_patterns/static_utils/__tests__/index.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { isFilterable } from '../index'; const mockField = { diff --git a/src/legacy/ui/public/indexed_array/__tests__/indexed_array.js b/src/legacy/ui/public/indexed_array/__tests__/indexed_array.js index 66966fe095198..ccce39cdfa4d1 100644 --- a/src/legacy/ui/public/indexed_array/__tests__/indexed_array.js +++ b/src/legacy/ui/public/indexed_array/__tests__/indexed_array.js @@ -19,7 +19,7 @@ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { IndexedArray } from '..'; // this is generally a data-structure that IndexedArray is good for managing diff --git a/src/legacy/ui/public/indexed_array/__tests__/inflector.js b/src/legacy/ui/public/indexed_array/__tests__/inflector.js index ffdbbee361085..49ac79094e501 100644 --- a/src/legacy/ui/public/indexed_array/__tests__/inflector.js +++ b/src/legacy/ui/public/indexed_array/__tests__/inflector.js @@ -18,7 +18,7 @@ */ import { inflector } from '../inflector'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; describe('IndexedArray Inflector', function () { it('returns a function', function () { diff --git a/src/legacy/ui/public/inspector/ui/__snapshots__/inspector_panel.test.js.snap b/src/legacy/ui/public/inspector/ui/__snapshots__/inspector_panel.test.js.snap index 9d5e8fe0725a0..aa16a91a4c9ad 100644 --- a/src/legacy/ui/public/inspector/ui/__snapshots__/inspector_panel.test.js.snap +++ b/src/legacy/ui/public/inspector/ui/__snapshots__/inspector_panel.test.js.snap @@ -242,8 +242,11 @@ exports[`InspectorPanel should render as expected 1`] = `
').attr('data-test-subj', subject); -} - -describe('jQuery.findTestSubject', function () { - it('finds all of the element with a subject', function () { - const $container = $('
'); - const $match = $make('subject').appendTo($container); - const $noMatch = $make('notSubject').appendTo($container); - - const $found = $container.findTestSubject('subject'); - expect($found.is($match)).to.be(true); - expect($found.is($noMatch)).to.be(false); - }); - - it('finds multiple elements with a subject', function () { - const $container = $('
'); - const $match = $make('subject').appendTo($container); - const $otherMatch = $make('subject').appendTo($container); - - const $found = $container.findTestSubject('subject'); - expect($found.filter($match).length).to.be(1); - expect($found.filter($otherMatch).length).to.be(1); - }); - - it('finds all of the elements with either subject', function () { - const $container = $('
'); - const $match1 = $make('subject').appendTo($container); - const $match2 = $make('alsoSubject').appendTo($container); - const $noMatch = $make('notSubject').appendTo($container); - - const $found = $container.findTestSubject('subject', 'alsoSubject'); - expect($found.filter($match1).length).to.be(1); - expect($found.filter($match2).length).to.be(1); - expect($found.filter($noMatch).length).to.be(0); - }); - - it('finds all of the elements with a descendant selector', function () { - const $container = $('
'); - const $parent = $make('foo name').appendTo($container); - const $bar = $make('bar othername').appendTo($parent); - const $baz = $make('baz third name').appendTo($parent); - - expect($container.findTestSubject('foo bar').is($bar)).to.be(true); - expect($container.findTestSubject('foo bar').is($baz)).to.be(false); - - expect($container.findTestSubject('foo baz').is($bar)).to.be(false); - expect($container.findTestSubject('foo baz').is($baz)).to.be(true); - }); - - it('finds elements with compound subjects', function () { - const $container = $('
'); - const $bar = $make('button bar').appendTo($container); - const $baz = $make('button baz').appendTo($container); - - expect($container.findTestSubject('button&bar').is($bar)).to.be(true); - expect($container.findTestSubject('button& bar').is($bar)).to.be(true); - expect($container.findTestSubject('button & bar').is($bar)).to.be(true); - expect($container.findTestSubject('button &bar').is($bar)).to.be(true); - - expect($container.findTestSubject('button&baz').is($baz)).to.be(true); - expect($container.findTestSubject('button& baz').is($baz)).to.be(true); - expect($container.findTestSubject('button & baz').is($baz)).to.be(true); - expect($container.findTestSubject('button &baz').is($baz)).to.be(true); - }); -}); diff --git a/src/legacy/ui/public/jquery/find_test_subject.js b/src/legacy/ui/public/jquery/find_test_subject.js deleted file mode 100644 index 857909d554ee2..0000000000000 --- a/src/legacy/ui/public/jquery/find_test_subject.js +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import testSubjSelector from '@kbn/test-subj-selector'; - -// eslint-disable-next-line @elastic/kibana-custom/no-default-export -export default function bindToJquery($) { - - /** - * Find elements with the `data-test-subj` attribute by the terms in that attribute. - * - * ```js - * // this - * let $button = $('[data-test-subj~="saveButton"]'); - * - * // becomes this - * let $button = $.findTestSubject('saveButton'); - * ``` - * - * Supports multiple subjects - * ```js - * // find any saveButton or cancelButton - * let $buttons = $.findTestSubject('saveButton', 'cancelButton'); - * ``` - * - * Supports subject "selectors" - * ```js - * // find any saveButton inside a savedObjectForm - * let $button = $.findTestSubject('savedObjectForm saveButton'); - * ``` - * - * Supports selecting compound subjects - * ```js - * // find any smallButton that is also a saveButton inside a savedObjectForm - * let $input = $.findTestSubject('savedObjectForm smallButton&saveButton'); - * ``` - * - * @return {jQueryCollection} - */ - $.findTestSubject = function () { - return findTestSubject.apply($(document.body), arguments); - }; - - /** - * Just like $.findTestSubject, except only finds elements within another element. - * @return {jQueryCollection} - */ - $.fn.findTestSubject = findTestSubject; - - function findTestSubject(...subjectSelectors) { - let $els = $(); - const $context = this; - - subjectSelectors.forEach(function (selector) { - $els = $els.add($context.find(testSubjSelector(selector))); - }); - - return $els; - } - -} diff --git a/src/legacy/ui/public/kbn_top_nav/__tests__/kbn_top_nav.js b/src/legacy/ui/public/kbn_top_nav/__tests__/kbn_top_nav.js index 953e903bb414d..6aff951f581e5 100644 --- a/src/legacy/ui/public/kbn_top_nav/__tests__/kbn_top_nav.js +++ b/src/legacy/ui/public/kbn_top_nav/__tests__/kbn_top_nav.js @@ -18,7 +18,7 @@ */ import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { assign, pluck } from 'lodash'; import $ from 'jquery'; diff --git a/src/legacy/ui/public/kbn_top_nav/__tests__/kbn_top_nav_controller.js b/src/legacy/ui/public/kbn_top_nav/__tests__/kbn_top_nav_controller.js index ec1a82349eed5..e0ad7ecceb9ca 100644 --- a/src/legacy/ui/public/kbn_top_nav/__tests__/kbn_top_nav_controller.js +++ b/src/legacy/ui/public/kbn_top_nav/__tests__/kbn_top_nav_controller.js @@ -18,7 +18,7 @@ */ import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { pluck } from 'lodash'; import sinon from 'sinon'; import { KbnTopNavControllerProvider } from '../kbn_top_nav_controller'; diff --git a/src/legacy/ui/public/kbn_top_nav/kbn_top_nav.js b/src/legacy/ui/public/kbn_top_nav/kbn_top_nav.js index 5daac89f97121..24d0f612dc5f7 100644 --- a/src/legacy/ui/public/kbn_top_nav/kbn_top_nav.js +++ b/src/legacy/ui/public/kbn_top_nav/kbn_top_nav.js @@ -55,6 +55,7 @@ import _ from 'lodash'; import angular from 'angular'; +import '../timepicker'; import '../watch_multi'; import '../directives/input_focus'; import { uiModules } from '../modules'; diff --git a/src/legacy/ui/public/listen/__tests__/listen.js b/src/legacy/ui/public/listen/__tests__/listen.js index a82c791016ee3..84838549b2a34 100644 --- a/src/legacy/ui/public/listen/__tests__/listen.js +++ b/src/legacy/ui/public/listen/__tests__/listen.js @@ -18,7 +18,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import '..'; import { EventsProvider } from '../../events'; diff --git a/src/legacy/ui/public/management/__tests__/index.js b/src/legacy/ui/public/management/__tests__/index.js index 1fbfe74bb7963..6c794b3c189f0 100644 --- a/src/legacy/ui/public/management/__tests__/index.js +++ b/src/legacy/ui/public/management/__tests__/index.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { management } from '..'; import { ManagementSection } from '../section'; diff --git a/src/legacy/ui/public/management/__tests__/section.js b/src/legacy/ui/public/management/__tests__/section.js index 4f21b0b2caa59..cc49d346213d6 100644 --- a/src/legacy/ui/public/management/__tests__/section.js +++ b/src/legacy/ui/public/management/__tests__/section.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { ManagementSection } from '../section'; import { IndexedArray } from '../../indexed_array'; diff --git a/src/legacy/ui/public/modals/__tests__/confirm_modal.js b/src/legacy/ui/public/modals/__tests__/confirm_modal.js index c700e6bf2b8a5..83b0155607f21 100644 --- a/src/legacy/ui/public/modals/__tests__/confirm_modal.js +++ b/src/legacy/ui/public/modals/__tests__/confirm_modal.js @@ -18,7 +18,7 @@ */ import angular from 'angular'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import sinon from 'sinon'; import _ from 'lodash'; diff --git a/src/legacy/ui/public/modals/__tests__/confirm_modal_promise.js b/src/legacy/ui/public/modals/__tests__/confirm_modal_promise.js index 016617b80bf31..76b730e5b2708 100644 --- a/src/legacy/ui/public/modals/__tests__/confirm_modal_promise.js +++ b/src/legacy/ui/public/modals/__tests__/confirm_modal_promise.js @@ -17,7 +17,8 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; +import testSubjSelector from '@kbn/test-subj-selector'; import ngMock from 'ng_mock'; import sinon from 'sinon'; import $ from 'jquery'; @@ -43,7 +44,7 @@ describe('ui/modals/confirm_modal_promise', function () { afterEach(function () { $rootScope.$digest(); - $.findTestSubject('confirmModalConfirmButton').click(); + $(testSubjSelector('confirmModalConfirmButton')).click(); }); describe('before timeout completes', function () { @@ -58,7 +59,7 @@ describe('ui/modals/confirm_modal_promise', function () { describe('after timeout completes', function () { it('confirmation dialogue is loaded to dom with message', function () { $rootScope.$digest(); - const confirmModalElement = $.findTestSubject('confirmModal'); + const confirmModalElement = $(testSubjSelector('confirmModal')); expect(confirmModalElement).to.not.be(undefined); const htmlString = confirmModalElement[0].innerHTML; @@ -73,7 +74,7 @@ describe('ui/modals/confirm_modal_promise', function () { promise.then(confirmCallback, cancelCallback); $rootScope.$digest(); - const confirmButton = $.findTestSubject('confirmModalConfirmButton'); + const confirmButton = $(testSubjSelector('confirmModalConfirmButton')); confirmButton.click(); expect(confirmCallback.called).to.be(true); @@ -88,7 +89,7 @@ describe('ui/modals/confirm_modal_promise', function () { promise.then(confirmCallback, cancelCallback); $rootScope.$digest(); - const noButton = $.findTestSubject('confirmModalCancelButton'); + const noButton = $(testSubjSelector('confirmModalCancelButton')); noButton.click(); expect(cancelCallback.called).to.be(true); diff --git a/src/legacy/ui/public/new_platform/new_platform.ts b/src/legacy/ui/public/new_platform/new_platform.ts index 7c6e5380cea1a..d6ea22e4e703f 100644 --- a/src/legacy/ui/public/new_platform/new_platform.ts +++ b/src/legacy/ui/public/new_platform/new_platform.ts @@ -38,18 +38,18 @@ interface CoreSetup { } const runtimeContext = { - start: { + setup: { core: null as CoreSetup | null, plugins: {}, }, }; export function __newPlatformInit__(core: CoreSetup) { - if (runtimeContext.start.core) { + if (runtimeContext.setup.core) { throw new Error('New platform core api was already initialized'); } - runtimeContext.start.core = core; + runtimeContext.setup.core = core; } export function getNewPlatform() { diff --git a/src/legacy/ui/public/notify/__tests__/notifier.js b/src/legacy/ui/public/notify/__tests__/notifier.js index 6e4b101e59f6d..f12a1e917cc0c 100644 --- a/src/legacy/ui/public/notify/__tests__/notifier.js +++ b/src/legacy/ui/public/notify/__tests__/notifier.js @@ -19,7 +19,7 @@ import _ from 'lodash'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { Notifier } from '..'; import { metadata } from 'ui/metadata'; diff --git a/src/legacy/ui/public/notify/lib/format_es_msg.test.js b/src/legacy/ui/public/notify/lib/format_es_msg.test.js index 4df4f54f1796c..b6484a23f720c 100644 --- a/src/legacy/ui/public/notify/lib/format_es_msg.test.js +++ b/src/legacy/ui/public/notify/lib/format_es_msg.test.js @@ -18,7 +18,7 @@ */ import { formatESMsg } from './format_es_msg'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; describe('formatESMsg', () => { test('should return undefined if passed a basic error', () => { diff --git a/src/legacy/ui/public/notify/lib/format_msg.test.js b/src/legacy/ui/public/notify/lib/format_msg.test.js index 96e532bfa54b5..d58b97455e8e9 100644 --- a/src/legacy/ui/public/notify/lib/format_msg.test.js +++ b/src/legacy/ui/public/notify/lib/format_msg.test.js @@ -18,7 +18,7 @@ */ import { formatMsg } from './format_msg'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; describe('formatMsg', () => { test('should prepend the second argument to result', () => { diff --git a/src/legacy/ui/public/number_list/number_list.js b/src/legacy/ui/public/number_list/number_list.js index 1102cae032cea..3d1a23bd69d20 100644 --- a/src/legacy/ui/public/number_list/number_list.js +++ b/src/legacy/ui/public/number_list/number_list.js @@ -20,6 +20,7 @@ import _ from 'lodash'; import { parseRange } from '../utils/range'; import './number_list_input'; +import '../directives/input_focus'; import { uiModules } from '../modules'; import numberListTemplate from './number_list.html'; diff --git a/src/legacy/ui/public/number_list/number_list_input.js b/src/legacy/ui/public/number_list/number_list_input.js index a055d7898bf5e..98dd0d9b0be62 100644 --- a/src/legacy/ui/public/number_list/number_list_input.js +++ b/src/legacy/ui/public/number_list/number_list_input.js @@ -18,6 +18,7 @@ */ import { keyMap } from '../utils/key_map'; +import '../fancy_forms'; import { uiModules } from '../modules'; const INVALID = {}; // invalid flag diff --git a/src/legacy/ui/public/paginated_table/__tests__/index.js b/src/legacy/ui/public/paginated_table/__tests__/index.js index 2a8ab16b6b0f8..dcaed42464036 100644 --- a/src/legacy/ui/public/paginated_table/__tests__/index.js +++ b/src/legacy/ui/public/paginated_table/__tests__/index.js @@ -19,7 +19,7 @@ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import '..'; import $ from 'jquery'; diff --git a/src/legacy/ui/public/paginated_table/paginated_table.js b/src/legacy/ui/public/paginated_table/paginated_table.js index b7725fce32210..23d3c57b3dafe 100644 --- a/src/legacy/ui/public/paginated_table/paginated_table.js +++ b/src/legacy/ui/public/paginated_table/paginated_table.js @@ -20,6 +20,9 @@ import _ from 'lodash'; import { uiModules } from '../modules'; import paginatedTableTemplate from './paginated_table.html'; + +import '../directives/paginate'; + uiModules .get('kibana') .directive('paginatedTable', function ($filter) { diff --git a/src/legacy/ui/public/persisted_state/__tests__/persisted_state_provider.js b/src/legacy/ui/public/persisted_state/__tests__/persisted_state_provider.js index 420fc5dff4fb6..7300bd159337c 100644 --- a/src/legacy/ui/public/persisted_state/__tests__/persisted_state_provider.js +++ b/src/legacy/ui/public/persisted_state/__tests__/persisted_state_provider.js @@ -21,7 +21,7 @@ import _ from 'lodash'; import sinon from 'sinon'; import noDigestPromises from 'test_utils/no_digest_promises'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { PersistedStateError } from '../../errors'; import '..'; diff --git a/src/legacy/ui/public/private/__tests__/private.js b/src/legacy/ui/public/private/__tests__/private.js index 297016d77ad16..d0859bb00bade 100644 --- a/src/legacy/ui/public/private/__tests__/private.js +++ b/src/legacy/ui/public/private/__tests__/private.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; describe('Private module loader', function () { diff --git a/src/legacy/ui/public/promises/__tests__/promises.js b/src/legacy/ui/public/promises/__tests__/promises.js index b0f6971784b4e..85c5835637b8e 100644 --- a/src/legacy/ui/public/promises/__tests__/promises.js +++ b/src/legacy/ui/public/promises/__tests__/promises.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import sinon from 'sinon'; diff --git a/src/legacy/ui/public/query_bar/components/__snapshots__/language_switcher.test.tsx.snap b/src/legacy/ui/public/query_bar/components/__snapshots__/language_switcher.test.tsx.snap index c58cab79fdc4e..0f07889998768 100644 --- a/src/legacy/ui/public/query_bar/components/__snapshots__/language_switcher.test.tsx.snap +++ b/src/legacy/ui/public/query_bar/components/__snapshots__/language_switcher.test.tsx.snap @@ -47,9 +47,7 @@ exports[`LanguageSwitcher should toggle off if language is lucene 1`] = ` >

{ + return { + getBasePath: () => `foo`, + getUiSettingsClient: () => { + return { + get: (key: string) => { + switch (key) { + case 'history:limit': + return 10; + default: + throw new Error(`Unexpected config key: ${key}`); + } + }, + }; + }, + }; +}); + +export const mockPersistedLog = { + add: jest.fn(), + get: jest.fn(() => ['response:200']), +}; + +export const mockPersistedLogFactory = jest.fn, any>(() => { + return mockPersistedLog; +}); + +export const mockGetAutocompleteSuggestions = jest.fn(() => Promise.resolve([])); +const mockAutocompleteProvider = jest.fn(() => mockGetAutocompleteSuggestions); +export const mockGetAutocompleteProvider = jest.fn(() => mockAutocompleteProvider); + +jest.mock('ui/chrome', () => mockChromeFactory()); +jest.mock('../../chrome', () => mockChromeFactory()); +jest.mock('ui/persisted_log', () => ({ + PersistedLog: mockPersistedLogFactory, +})); +jest.mock('../../metadata', () => ({ + metadata: { + branch: 'foo', + }, +})); +jest.mock('../../autocomplete_providers', () => ({ + getAutocompleteProvider: mockGetAutocompleteProvider, +})); + +import _ from 'lodash'; +// Using doMock to avoid hoisting so that I can override only the debounce method in lodash +jest.doMock('lodash', () => ({ + ..._, + debounce: (func: () => any) => func, +})); diff --git a/src/legacy/ui/public/query_bar/components/query_bar.test.tsx b/src/legacy/ui/public/query_bar/components/query_bar.test.tsx index fdcfb77043919..f6947574bee16 100644 --- a/src/legacy/ui/public/query_bar/components/query_bar.test.tsx +++ b/src/legacy/ui/public/query_bar/components/query_bar.test.tsx @@ -17,57 +17,12 @@ * under the License. */ -const mockChromeFactory = jest.fn(() => { - return { - getBasePath: () => `foo`, - getUiSettingsClient: () => { - return { - get: (key: string) => { - switch (key) { - case 'history:limit': - return 10; - default: - throw new Error(`Unexpected config key: ${key}`); - } - }, - }; - }, - }; -}); - -const mockPersistedLog = { - add: jest.fn(), - get: jest.fn(() => ['response:200']), -}; - -const mockPersistedLogFactory = jest.fn, any>(() => { - return mockPersistedLog; -}); - -const mockGetAutocompleteSuggestions = jest.fn(() => Promise.resolve([])); -const mockAutocompleteProvider = jest.fn(() => mockGetAutocompleteSuggestions); -const mockGetAutocompleteProvider = jest.fn(() => mockAutocompleteProvider); - -jest.mock('ui/chrome', () => mockChromeFactory()); -jest.mock('../../chrome', () => mockChromeFactory()); -jest.mock('ui/persisted_log', () => ({ - PersistedLog: mockPersistedLogFactory, -})); -jest.mock('../../metadata', () => ({ - metadata: { - branch: 'foo', - }, -})); -jest.mock('../../autocomplete_providers', () => ({ - getAutocompleteProvider: mockGetAutocompleteProvider, -})); - -import _ from 'lodash'; -// Using doMock to avoid hoisting so that I can override only the debounce method in lodash -jest.doMock('lodash', () => ({ - ..._, - debounce: (func: () => any) => func, -})); +import { + mockGetAutocompleteProvider, + mockGetAutocompleteSuggestions, + mockPersistedLog, + mockPersistedLogFactory, +} from 'ui/query_bar/components/query_bar.test.mocks'; import { EuiFieldText } from '@elastic/eui'; import React from 'react'; diff --git a/src/legacy/ui/public/query_bar/components/query_bar.tsx b/src/legacy/ui/public/query_bar/components/query_bar.tsx index 1f8a66cba723d..d7d52881567ed 100644 --- a/src/legacy/ui/public/query_bar/components/query_bar.tsx +++ b/src/legacy/ui/public/query_bar/components/query_bar.tsx @@ -97,6 +97,7 @@ interface Props { refreshInterval?: number; showAutoRefreshOnly?: boolean; onRefreshChange?: (options: { isPaused: boolean; refreshInterval: number }) => void; + customSubmitButton?: any; } interface State { @@ -634,7 +635,9 @@ export class QueryBarUI extends Component { } private renderUpdateButton() { - const button = ( + const button = this.props.customSubmitButton ? ( + React.cloneElement(this.props.customSubmitButton, { onClick: this.onClickSubmitButton }) + ) : ( { data-test-subj="querySubmitButton" /> ); - if (this.props.showDatePicker) { - return ( - - {this.renderDatePicker()} - {button} - - ); - } else { + + if (!this.props.showDatePicker) { return button; } + + return ( + + {this.renderDatePicker()} + {button} + + ); } private renderDatePicker() { diff --git a/src/legacy/ui/public/query_bar/components/typeahead/__snapshots__/suggestion_component.test.tsx.snap b/src/legacy/ui/public/query_bar/components/typeahead/__snapshots__/suggestion_component.test.tsx.snap index 56875f1f1c3f1..92ca296ed8058 100644 --- a/src/legacy/ui/public/query_bar/components/typeahead/__snapshots__/suggestion_component.test.tsx.snap +++ b/src/legacy/ui/public/query_bar/components/typeahead/__snapshots__/suggestion_component.test.tsx.snap @@ -26,12 +26,9 @@ exports[`SuggestionComponent Should display the suggestion and use the provided

+ > + This is not a helpful suggestion +
`; @@ -62,12 +59,9 @@ exports[`SuggestionComponent Should make the element active if the selected prop
+ > + This is not a helpful suggestion +
`; diff --git a/src/legacy/ui/public/query_bar/components/typeahead/__snapshots__/suggestions_component.test.tsx.snap b/src/legacy/ui/public/query_bar/components/typeahead/__snapshots__/suggestions_component.test.tsx.snap index 6388a57832c0a..3b51c1db50d00 100644 --- a/src/legacy/ui/public/query_bar/components/typeahead/__snapshots__/suggestions_component.test.tsx.snap +++ b/src/legacy/ui/public/query_bar/components/typeahead/__snapshots__/suggestions_component.test.tsx.snap @@ -16,7 +16,7 @@ exports[`SuggestionsComponent Passing the index should control which suggestion onScroll={[Function]} role="listbox" > - - - - = props => {
{props.suggestion.text}
-
+
{props.suggestion.description}
); diff --git a/src/legacy/ui/public/registry/__tests__/registry.js b/src/legacy/ui/public/registry/__tests__/registry.js index e6bcaa3e94b0f..56a19814058c1 100644 --- a/src/legacy/ui/public/registry/__tests__/registry.js +++ b/src/legacy/ui/public/registry/__tests__/registry.js @@ -18,7 +18,7 @@ */ import { uiRegistry } from '../_registry'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; describe('Registry', function () { diff --git a/src/legacy/ui/public/render_directive/__tests__/render_directive.js b/src/legacy/ui/public/render_directive/__tests__/render_directive.js index bea391e95469c..ff7225271e301 100644 --- a/src/legacy/ui/public/render_directive/__tests__/render_directive.js +++ b/src/legacy/ui/public/render_directive/__tests__/render_directive.js @@ -19,7 +19,7 @@ import angular from 'angular'; import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import '..'; diff --git a/src/legacy/ui/public/resize_checker/__tests__/resize_checker.js b/src/legacy/ui/public/resize_checker/__tests__/resize_checker.js index 50533ac3fb248..5fccf77f8f13d 100644 --- a/src/legacy/ui/public/resize_checker/__tests__/resize_checker.js +++ b/src/legacy/ui/public/resize_checker/__tests__/resize_checker.js @@ -19,7 +19,7 @@ import $ from 'jquery'; import { delay } from 'bluebird'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import ngMock from 'ng_mock'; diff --git a/src/legacy/ui/public/routes/__tests__/_route_manager.js b/src/legacy/ui/public/routes/__tests__/_route_manager.js index 40a8a779ccb75..d6d4c869b4b7e 100644 --- a/src/legacy/ui/public/routes/__tests__/_route_manager.js +++ b/src/legacy/ui/public/routes/__tests__/_route_manager.js @@ -21,7 +21,7 @@ import _ from 'lodash'; import ngMock from 'ng_mock'; import sinon from 'sinon'; import RouteManager from '../route_manager'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; let routes; // will contain an new instance of RouteManager for each test const chainableMethods = [ diff --git a/src/legacy/ui/public/routes/__tests__/_work_queue.js b/src/legacy/ui/public/routes/__tests__/_work_queue.js index bdbda577718be..f5ecebd8e596b 100644 --- a/src/legacy/ui/public/routes/__tests__/_work_queue.js +++ b/src/legacy/ui/public/routes/__tests__/_work_queue.js @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { WorkQueue } from '../work_queue'; import sinon from 'sinon'; diff --git a/src/legacy/ui/public/routes/__tests__/_wrap_route_with_prep.js b/src/legacy/ui/public/routes/__tests__/_wrap_route_with_prep.js index aac016082ade3..44b99a72b402c 100644 --- a/src/legacy/ui/public/routes/__tests__/_wrap_route_with_prep.js +++ b/src/legacy/ui/public/routes/__tests__/_wrap_route_with_prep.js @@ -18,7 +18,7 @@ */ import RouteManager from '../route_manager'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import _ from 'lodash'; diff --git a/src/legacy/ui/public/routes/index.js b/src/legacy/ui/public/routes/index.js index cf92b7de94e05..74e2613c66449 100644 --- a/src/legacy/ui/public/routes/index.js +++ b/src/legacy/ui/public/routes/index.js @@ -19,5 +19,5 @@ import { uiRoutes } from './routes'; -// eslint-disable-next-line @elastic/kibana-custom/no-default-export +// eslint-disable-next-line @kbn/eslint/no-default-export export default uiRoutes; diff --git a/src/legacy/ui/public/routes/route_manager.js b/src/legacy/ui/public/routes/route_manager.js index 94c7182b369a4..6cedf775cf576 100644 --- a/src/legacy/ui/public/routes/route_manager.js +++ b/src/legacy/ui/public/routes/route_manager.js @@ -23,7 +23,7 @@ import { wrapRouteWithPrep } from './wrap_route_with_prep'; import { RouteSetupManager } from './route_setup_manager'; import { parsePathToBreadcrumbs } from './breadcrumbs'; -// eslint-disable-next-line @elastic/kibana-custom/no-default-export +// eslint-disable-next-line @kbn/eslint/no-default-export export default function RouteManager() { const self = this; const setup = new RouteSetupManager(); diff --git a/src/legacy/ui/public/saved_objects/__tests__/find_object_by_title.js b/src/legacy/ui/public/saved_objects/__tests__/find_object_by_title.js index 7df77b43adde1..6539f8c034136 100644 --- a/src/legacy/ui/public/saved_objects/__tests__/find_object_by_title.js +++ b/src/legacy/ui/public/saved_objects/__tests__/find_object_by_title.js @@ -18,7 +18,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { findObjectByTitle } from '../find_object_by_title'; import { SimpleSavedObject } from '../simple_saved_object'; diff --git a/src/legacy/ui/public/saved_objects/__tests__/saved_object.js b/src/legacy/ui/public/saved_objects/__tests__/saved_object.js index 7cfa41b301198..c7f3a3da6259d 100644 --- a/src/legacy/ui/public/saved_objects/__tests__/saved_object.js +++ b/src/legacy/ui/public/saved_objects/__tests__/saved_object.js @@ -18,7 +18,7 @@ */ import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import BluebirdPromise from 'bluebird'; diff --git a/src/legacy/ui/public/saved_objects/__tests__/simple_saved_object.js b/src/legacy/ui/public/saved_objects/__tests__/simple_saved_object.js index 5fe05690c0859..a6583b97972ab 100644 --- a/src/legacy/ui/public/saved_objects/__tests__/simple_saved_object.js +++ b/src/legacy/ui/public/saved_objects/__tests__/simple_saved_object.js @@ -18,7 +18,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { SimpleSavedObject } from '../simple_saved_object'; describe('SimpleSavedObject', () => { diff --git a/src/legacy/ui/public/share/components/__snapshots__/url_panel_content.test.js.snap b/src/legacy/ui/public/share/components/__snapshots__/url_panel_content.test.js.snap index 404352f10fa01..3cdc655743eda 100644 --- a/src/legacy/ui/public/share/components/__snapshots__/url_panel_content.test.js.snap +++ b/src/legacy/ui/public/share/components/__snapshots__/url_panel_content.test.js.snap @@ -54,8 +54,7 @@ exports[`render 1`] = ` aria-label="Info" content={ @@ -207,8 +203,7 @@ exports[`should enable saved object export option when objectId is provided 1`] aria-label="Info" content={ diff --git a/src/legacy/ui/public/share/lib/url_shortener.test.js b/src/legacy/ui/public/share/lib/url_shortener.test.js index 0c45220ff78d1..859873bd4989f 100644 --- a/src/legacy/ui/public/share/lib/url_shortener.test.js +++ b/src/legacy/ui/public/share/lib/url_shortener.test.js @@ -21,7 +21,7 @@ jest.mock('ui/kfetch', () => ({})); jest.mock('../../chrome', () => ({})); import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { shortenUrl } from './url_shortener'; describe('Url shortener', () => { diff --git a/src/legacy/ui/public/state_management/__tests__/app_state.js b/src/legacy/ui/public/state_management/__tests__/app_state.js index 9cc80b77b93a1..6f59ba744a135 100644 --- a/src/legacy/ui/public/state_management/__tests__/app_state.js +++ b/src/legacy/ui/public/state_management/__tests__/app_state.js @@ -18,7 +18,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { AppStateProvider } from '../app_state'; diff --git a/src/legacy/ui/public/state_management/__tests__/config_provider.js b/src/legacy/ui/public/state_management/__tests__/config_provider.js index 13171e08909d4..c16300cb7aa32 100644 --- a/src/legacy/ui/public/state_management/__tests__/config_provider.js +++ b/src/legacy/ui/public/state_management/__tests__/config_provider.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import '../config_provider'; diff --git a/src/legacy/ui/public/state_management/__tests__/global_state.js b/src/legacy/ui/public/state_management/__tests__/global_state.js index 76d0e0c2c2826..10b127aa1b80d 100644 --- a/src/legacy/ui/public/state_management/__tests__/global_state.js +++ b/src/legacy/ui/public/state_management/__tests__/global_state.js @@ -18,7 +18,7 @@ */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import '../global_state'; diff --git a/src/legacy/ui/public/state_management/__tests__/state.js b/src/legacy/ui/public/state_management/__tests__/state.js index 95e275471a1f7..cbeb5e3650a16 100644 --- a/src/legacy/ui/public/state_management/__tests__/state.js +++ b/src/legacy/ui/public/state_management/__tests__/state.js @@ -18,7 +18,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { encode as encodeRison } from 'rison-node'; import '../../private'; diff --git a/src/legacy/ui/public/state_management/__tests__/state_monitor_factory.js b/src/legacy/ui/public/state_management/__tests__/state_monitor_factory.js index 581625f463056..75dd5024708af 100644 --- a/src/legacy/ui/public/state_management/__tests__/state_monitor_factory.js +++ b/src/legacy/ui/public/state_management/__tests__/state_monitor_factory.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { cloneDeep } from 'lodash'; import { stateMonitorFactory } from '../state_monitor_factory'; diff --git a/src/legacy/ui/public/state_management/state_hashing/__tests__/hash_url.js b/src/legacy/ui/public/state_management/state_hashing/__tests__/hash_url.js index 79641f3cf3c57..1d5b88a22d9c6 100644 --- a/src/legacy/ui/public/state_management/state_hashing/__tests__/hash_url.js +++ b/src/legacy/ui/public/state_management/state_hashing/__tests__/hash_url.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import sinon from 'sinon'; import { parse as parseUrl } from 'url'; diff --git a/src/legacy/ui/public/state_management/state_hashing/__tests__/unhash_url.js b/src/legacy/ui/public/state_management/state_hashing/__tests__/unhash_url.js index 7a3cb67e0d735..671194ecb50f5 100644 --- a/src/legacy/ui/public/state_management/state_hashing/__tests__/unhash_url.js +++ b/src/legacy/ui/public/state_management/state_hashing/__tests__/unhash_url.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import sinon from 'sinon'; diff --git a/src/legacy/ui/public/state_management/state_storage/__tests__/hashed_item_store.js b/src/legacy/ui/public/state_management/state_storage/__tests__/hashed_item_store.js index 15d6e4e5c040f..dfb726ce53299 100644 --- a/src/legacy/ui/public/state_management/state_storage/__tests__/hashed_item_store.js +++ b/src/legacy/ui/public/state_management/state_storage/__tests__/hashed_item_store.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { StubBrowserStorage } from 'test_utils/stub_browser_storage'; diff --git a/src/legacy/ui/public/state_management/state_storage/__tests__/state_hash.js b/src/legacy/ui/public/state_management/state_storage/__tests__/state_hash.js index 09f875a18e696..71fcf33274fc6 100644 --- a/src/legacy/ui/public/state_management/state_storage/__tests__/state_hash.js +++ b/src/legacy/ui/public/state_management/state_storage/__tests__/state_hash.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { encode as encodeRison } from 'rison-node'; import { diff --git a/src/legacy/ui/public/storage/__tests__/storage.js b/src/legacy/ui/public/storage/__tests__/storage.js index 51ef371b736d4..2f72fff129ef0 100644 --- a/src/legacy/ui/public/storage/__tests__/storage.js +++ b/src/legacy/ui/public/storage/__tests__/storage.js @@ -18,7 +18,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import '..'; diff --git a/src/legacy/ui/public/style_compile/__tests__/style_compile.js b/src/legacy/ui/public/style_compile/__tests__/style_compile.js index e141b9fbb1a20..75700259d7bc5 100644 --- a/src/legacy/ui/public/style_compile/__tests__/style_compile.js +++ b/src/legacy/ui/public/style_compile/__tests__/style_compile.js @@ -18,7 +18,7 @@ */ import $ from 'jquery'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; describe('styleCompile directive', function () { diff --git a/src/legacy/ui/public/system_api/__tests__/system_api.js b/src/legacy/ui/public/system_api/__tests__/system_api.js index 45a1cd6449684..2e44bac2eef53 100644 --- a/src/legacy/ui/public/system_api/__tests__/system_api.js +++ b/src/legacy/ui/public/system_api/__tests__/system_api.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { addSystemApiHeader, isSystemApiRequest } from '../system_api'; describe('system_api', () => { diff --git a/src/legacy/ui/public/test_harness/test_harness.js b/src/legacy/ui/public/test_harness/test_harness.js index 36dc38b1c3b82..178971c582d66 100644 --- a/src/legacy/ui/public/test_harness/test_harness.js +++ b/src/legacy/ui/public/test_harness/test_harness.js @@ -18,8 +18,6 @@ */ // chrome expects to be loaded first, let it get its way -import $ from 'jquery'; -import bindJqueryToFindTestSubject from 'ui/jquery/find_test_subject'; import chrome from '../chrome'; import { parse as parseUrl } from 'url'; @@ -32,8 +30,6 @@ import './test_harness.css'; import 'ng_mock'; import { setupTestSharding } from './test_sharding'; -bindJqueryToFindTestSubject($); - const { query } = parseUrl(window.location.href, true); if (query && query.mocha) { try { diff --git a/src/legacy/ui/public/timefilter/get_time.test.ts b/src/legacy/ui/public/timefilter/get_time.test.ts index 42f89335338de..582ecae82a587 100644 --- a/src/legacy/ui/public/timefilter/get_time.test.ts +++ b/src/legacy/ui/public/timefilter/get_time.test.ts @@ -18,7 +18,7 @@ */ // @ts-ignore -import expect from 'expect.js'; +import expect from '@kbn/expect'; import moment from 'moment'; import sinon from 'sinon'; import { Filter, getTime } from './get_time'; diff --git a/src/legacy/ui/public/timefilter/lib/diff_time_picker_vals.test.js b/src/legacy/ui/public/timefilter/lib/diff_time_picker_vals.test.js index e441c351d735b..12d729dd0136b 100644 --- a/src/legacy/ui/public/timefilter/lib/diff_time_picker_vals.test.js +++ b/src/legacy/ui/public/timefilter/lib/diff_time_picker_vals.test.js @@ -19,7 +19,7 @@ import moment from 'moment'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { areTimePickerValsDifferent } from './diff_time_picker_vals'; describe('Diff Time Picker Values', () => { diff --git a/src/legacy/ui/public/timefilter/timefilter.test.js b/src/legacy/ui/public/timefilter/timefilter.test.js index eb07711126e48..c1431782baaf2 100644 --- a/src/legacy/ui/public/timefilter/timefilter.test.js +++ b/src/legacy/ui/public/timefilter/timefilter.test.js @@ -47,7 +47,7 @@ jest.mock('ui/timefilter/lib/parse_querystring', }), { virtual: true }); import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import moment from 'moment'; import { timefilter } from './timefilter'; diff --git a/src/legacy/ui/public/url/__tests__/extract_app_path_and_id.js b/src/legacy/ui/public/url/__tests__/extract_app_path_and_id.js index 1df0b14d5d4ad..9c2b79705456e 100644 --- a/src/legacy/ui/public/url/__tests__/extract_app_path_and_id.js +++ b/src/legacy/ui/public/url/__tests__/extract_app_path_and_id.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { extractAppPathAndId } from '../extract_app_path_and_id'; diff --git a/src/legacy/ui/public/url/__tests__/kibana_parsed_url.js b/src/legacy/ui/public/url/__tests__/kibana_parsed_url.js index cbca2c6aff001..5dd005480e5b5 100644 --- a/src/legacy/ui/public/url/__tests__/kibana_parsed_url.js +++ b/src/legacy/ui/public/url/__tests__/kibana_parsed_url.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { KibanaParsedUrl } from '../kibana_parsed_url'; diff --git a/src/legacy/ui/public/url/__tests__/prepend_path.js b/src/legacy/ui/public/url/__tests__/prepend_path.js index 1ab4698ffd5de..b31449322a024 100644 --- a/src/legacy/ui/public/url/__tests__/prepend_path.js +++ b/src/legacy/ui/public/url/__tests__/prepend_path.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { prependPath } from '../prepend_path'; diff --git a/src/legacy/ui/public/url/__tests__/url.js b/src/legacy/ui/public/url/__tests__/url.js index 7f779d594669c..52af742492aed 100644 --- a/src/legacy/ui/public/url/__tests__/url.js +++ b/src/legacy/ui/public/url/__tests__/url.js @@ -19,7 +19,7 @@ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import faker from 'faker'; import _ from 'lodash'; diff --git a/src/legacy/ui/public/factories/__tests__/base_object.js b/src/legacy/ui/public/utils/__tests__/base_object.js similarity index 95% rename from src/legacy/ui/public/factories/__tests__/base_object.js rename to src/legacy/ui/public/utils/__tests__/base_object.js index 913f647db3360..dfc5688c7b2f4 100644 --- a/src/legacy/ui/public/factories/__tests__/base_object.js +++ b/src/legacy/ui/public/utils/__tests__/base_object.js @@ -17,11 +17,11 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import '../../private'; -import { BaseObject } from '../../utils/base_object'; +import { BaseObject } from '../base_object'; describe('Base Object', function () { beforeEach(ngMock.module('kibana')); diff --git a/src/legacy/ui/public/utils/__tests__/brush_event.test.js b/src/legacy/ui/public/utils/__tests__/brush_event.test.js index 6b27dd79eedc4..c7c1804cde780 100644 --- a/src/legacy/ui/public/utils/__tests__/brush_event.test.js +++ b/src/legacy/ui/public/utils/__tests__/brush_event.test.js @@ -38,7 +38,7 @@ jest.mock('ui/chrome', import _ from 'lodash'; import moment from 'moment'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { onBrushEvent } from '../brush_event'; import { timefilter } from 'ui/timefilter'; diff --git a/src/legacy/ui/public/utils/__tests__/cidr_mask.ts b/src/legacy/ui/public/utils/__tests__/cidr_mask.ts index 8624bb1b6e0b2..5343328e55786 100644 --- a/src/legacy/ui/public/utils/__tests__/cidr_mask.ts +++ b/src/legacy/ui/public/utils/__tests__/cidr_mask.ts @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { CidrMask } from '../cidr_mask'; describe('CidrMask', () => { diff --git a/src/legacy/ui/public/utils/__tests__/collection.js b/src/legacy/ui/public/utils/__tests__/collection.js index a733b8b2433bc..978c6e75cece7 100644 --- a/src/legacy/ui/public/utils/__tests__/collection.js +++ b/src/legacy/ui/public/utils/__tests__/collection.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { groupBy } from 'lodash'; import { move, pushAll, organizeBy } from '../collection'; diff --git a/src/legacy/ui/public/utils/__tests__/decode_geo_hash.js b/src/legacy/ui/public/utils/__tests__/decode_geo_hash.js index 5b09a0cc8b4cd..5a0a447e345c4 100644 --- a/src/legacy/ui/public/utils/__tests__/decode_geo_hash.js +++ b/src/legacy/ui/public/utils/__tests__/decode_geo_hash.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { geohashColumns } from '../decode_geo_hash'; describe('decode_geo_hash', function () { diff --git a/src/legacy/ui/public/utils/__tests__/diff_object.js b/src/legacy/ui/public/utils/__tests__/diff_object.js index 919dfdfcbc9ee..cc9463c163d4b 100644 --- a/src/legacy/ui/public/utils/__tests__/diff_object.js +++ b/src/legacy/ui/public/utils/__tests__/diff_object.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import _ from 'lodash'; import { applyDiff } from '../diff_object'; diff --git a/src/legacy/ui/public/utils/__tests__/ipv4_address.ts b/src/legacy/ui/public/utils/__tests__/ipv4_address.ts index 5e967da189e87..ad4efec6f1e52 100644 --- a/src/legacy/ui/public/utils/__tests__/ipv4_address.ts +++ b/src/legacy/ui/public/utils/__tests__/ipv4_address.ts @@ -17,7 +17,7 @@ * under the License. */ // @ts-ignore -import expect from 'expect.js'; +import expect from '@kbn/expect'; import Ipv4Address from '../ipv4_address'; describe('Ipv4Address', () => { diff --git a/src/legacy/ui/public/utils/__tests__/mapping_setup.js b/src/legacy/ui/public/utils/__tests__/mapping_setup.js index 48dd210b9af4f..944dfaa35ed82 100644 --- a/src/legacy/ui/public/utils/__tests__/mapping_setup.js +++ b/src/legacy/ui/public/utils/__tests__/mapping_setup.js @@ -19,7 +19,7 @@ import _ from 'lodash'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import UtilsMappingSetupProvider from '../mapping_setup'; let mappingSetup; diff --git a/src/legacy/ui/public/utils/__tests__/obj_define.js b/src/legacy/ui/public/utils/__tests__/obj_define.js index 64a699ad3c68e..5e89ba03530af 100644 --- a/src/legacy/ui/public/utils/__tests__/obj_define.js +++ b/src/legacy/ui/public/utils/__tests__/obj_define.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { ObjDefine } from '../obj_define'; describe('ObjDefine Utility', function () { diff --git a/src/legacy/ui/public/utils/__tests__/ordinal_suffix.js b/src/legacy/ui/public/utils/__tests__/ordinal_suffix.js index bde297a456fff..dae12d41cfb5b 100644 --- a/src/legacy/ui/public/utils/__tests__/ordinal_suffix.js +++ b/src/legacy/ui/public/utils/__tests__/ordinal_suffix.js @@ -19,7 +19,7 @@ import _ from 'lodash'; import { ordinalSuffix } from '../ordinal_suffix'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; describe('ordinal suffix util', function () { const checks = { diff --git a/src/legacy/ui/public/utils/__tests__/parse_interval.js b/src/legacy/ui/public/utils/__tests__/parse_interval.js index b068ce170e128..bce134be4336d 100644 --- a/src/legacy/ui/public/utils/__tests__/parse_interval.js +++ b/src/legacy/ui/public/utils/__tests__/parse_interval.js @@ -18,7 +18,7 @@ */ import { parseInterval } from '../parse_interval'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; describe('parseInterval', function () { it('should correctly parse an interval containing unit and value', function () { diff --git a/src/legacy/ui/public/utils/__tests__/range.js b/src/legacy/ui/public/utils/__tests__/range.js index e6421c3101753..e7947894d3e22 100644 --- a/src/legacy/ui/public/utils/__tests__/range.js +++ b/src/legacy/ui/public/utils/__tests__/range.js @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { parseRange } from '../range'; describe('Range parsing utility', function () { diff --git a/src/legacy/ui/public/utils/__tests__/simple_emitter.js b/src/legacy/ui/public/utils/__tests__/simple_emitter.js index 6dbacbe4adfe9..25224a409f8f4 100644 --- a/src/legacy/ui/public/utils/__tests__/simple_emitter.js +++ b/src/legacy/ui/public/utils/__tests__/simple_emitter.js @@ -18,7 +18,7 @@ */ import { SimpleEmitter } from '../simple_emitter'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; describe('SimpleEmitter class', function () { diff --git a/src/legacy/ui/public/utils/__tests__/sort_prefix_first.js b/src/legacy/ui/public/utils/__tests__/sort_prefix_first.js index e820ffff5aa3c..016e13b372c3d 100644 --- a/src/legacy/ui/public/utils/__tests__/sort_prefix_first.js +++ b/src/legacy/ui/public/utils/__tests__/sort_prefix_first.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { sortPrefixFirst } from '../sort_prefix_first'; describe('sortPrefixFirst', function () { diff --git a/src/legacy/ui/public/utils/ipv4_address.ts b/src/legacy/ui/public/utils/ipv4_address.ts index b8bf3917c471d..5268d1ad97d24 100644 --- a/src/legacy/ui/public/utils/ipv4_address.ts +++ b/src/legacy/ui/public/utils/ipv4_address.ts @@ -30,7 +30,7 @@ function isIntegerInRange(integer: number, min: number, max: number) { ); } -// eslint-disable-next-line @elastic/kibana-custom/no-default-export +// eslint-disable-next-line @kbn/eslint/no-default-export // tslint:disable:no-default-export export default class Ipv4Address { private value: number; diff --git a/src/legacy/ui/public/utils/mapping_setup.js b/src/legacy/ui/public/utils/mapping_setup.js index b2589ca6b16b2..d02c6ea686b03 100644 --- a/src/legacy/ui/public/utils/mapping_setup.js +++ b/src/legacy/ui/public/utils/mapping_setup.js @@ -20,7 +20,7 @@ import angular from 'angular'; import _ from 'lodash'; -// eslint-disable-next-line @elastic/kibana-custom/no-default-export +// eslint-disable-next-line @kbn/eslint/no-default-export export default function MappingSetupService() { const mappingSetup = this; diff --git a/src/legacy/ui/public/utils/subscribe_with_scope.test.mocks.ts b/src/legacy/ui/public/utils/subscribe_with_scope.test.mocks.ts new file mode 100644 index 0000000000000..815d2f09150c7 --- /dev/null +++ b/src/legacy/ui/public/utils/subscribe_with_scope.test.mocks.ts @@ -0,0 +1,23 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export const mockFatalError = jest.fn(); +jest.mock('ui/notify/fatal_error', () => ({ + fatalError: mockFatalError, +})); diff --git a/src/legacy/ui/public/utils/subscribe_with_scope.test.ts b/src/legacy/ui/public/utils/subscribe_with_scope.test.ts index a5a3312bad4bf..077875c5ac6e5 100644 --- a/src/legacy/ui/public/utils/subscribe_with_scope.test.ts +++ b/src/legacy/ui/public/utils/subscribe_with_scope.test.ts @@ -16,11 +16,7 @@ * specific language governing permissions and limitations * under the License. */ - -const mockFatalError = jest.fn(); -jest.mock('ui/notify/fatal_error', () => ({ - fatalError: mockFatalError, -})); +import { mockFatalError } from './subscribe_with_scope.test.mocks'; import * as Rx from 'rxjs'; import { subscribeWithScope } from './subscribe_with_scope'; diff --git a/src/legacy/ui/public/vis/__tests__/_agg_config.js b/src/legacy/ui/public/vis/__tests__/_agg_config.js index 707ccf2d6f17a..1929b4312e14f 100644 --- a/src/legacy/ui/public/vis/__tests__/_agg_config.js +++ b/src/legacy/ui/public/vis/__tests__/_agg_config.js @@ -18,7 +18,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { VisProvider } from '..'; import { AggType } from '../../agg_types/agg_type'; diff --git a/src/legacy/ui/public/vis/__tests__/_agg_config_result.js b/src/legacy/ui/public/vis/__tests__/_agg_config_result.js index 22254dc36d7f8..988c4dc872152 100644 --- a/src/legacy/ui/public/vis/__tests__/_agg_config_result.js +++ b/src/legacy/ui/public/vis/__tests__/_agg_config_result.js @@ -18,7 +18,7 @@ */ import AggConfigResult from '../agg_config_result'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { VisProvider } from '..'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; diff --git a/src/legacy/ui/public/vis/__tests__/_agg_configs.js b/src/legacy/ui/public/vis/__tests__/_agg_configs.js index 4ae10aed6a53e..2c663800a4d28 100644 --- a/src/legacy/ui/public/vis/__tests__/_agg_configs.js +++ b/src/legacy/ui/public/vis/__tests__/_agg_configs.js @@ -19,7 +19,7 @@ import _ from 'lodash'; import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { AggConfig } from '../agg_config'; import { VisProvider } from '..'; diff --git a/src/legacy/ui/public/vis/__tests__/_vis.js b/src/legacy/ui/public/vis/__tests__/_vis.js index ed1c767137a88..5c162bd45ace2 100644 --- a/src/legacy/ui/public/vis/__tests__/_vis.js +++ b/src/legacy/ui/public/vis/__tests__/_vis.js @@ -19,7 +19,7 @@ import _ from 'lodash'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { VisProvider } from '..'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; import { VisTypesRegistryProvider } from '../../registry/vis_types'; diff --git a/src/legacy/ui/public/vis/__tests__/components/color.js b/src/legacy/ui/public/vis/__tests__/components/color.js index 5eda6b12fbb50..ba8e4479d2d63 100644 --- a/src/legacy/ui/public/vis/__tests__/components/color.js +++ b/src/legacy/ui/public/vis/__tests__/components/color.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import _ from 'lodash'; import d3 from 'd3'; diff --git a/src/legacy/ui/public/vis/__tests__/map/ems_client.js b/src/legacy/ui/public/vis/__tests__/map/ems_client.js index 022bb2417615d..6ac25c6f53f00 100644 --- a/src/legacy/ui/public/vis/__tests__/map/ems_client.js +++ b/src/legacy/ui/public/vis/__tests__/map/ems_client.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import EMS_CATALOGUE from './ems_mocks/sample_manifest.json'; import EMS_FILES from './ems_mocks/sample_files.json'; import EMS_TILES from './ems_mocks/sample_tiles.json'; diff --git a/src/legacy/ui/public/vis/__tests__/map/kibana_map.js b/src/legacy/ui/public/vis/__tests__/map/kibana_map.js index ed1c4e1e4b8fd..e67d4b5f7603b 100644 --- a/src/legacy/ui/public/vis/__tests__/map/kibana_map.js +++ b/src/legacy/ui/public/vis/__tests__/map/kibana_map.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { KibanaMap } from '../../map/kibana_map'; import { KibanaMapLayer } from '../../map/kibana_map_layer'; import L from 'leaflet'; diff --git a/src/legacy/ui/public/vis/__tests__/map/service_settings.js b/src/legacy/ui/public/vis/__tests__/map/service_settings.js index 51ce93a376044..20097697bd0a2 100644 --- a/src/legacy/ui/public/vis/__tests__/map/service_settings.js +++ b/src/legacy/ui/public/vis/__tests__/map/service_settings.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import url from 'url'; diff --git a/src/legacy/ui/public/vis/__tests__/response_handlers/_build_chart_data.js b/src/legacy/ui/public/vis/__tests__/response_handlers/_build_chart_data.js index 51c03d5338f44..5b1f8c7c55475 100644 --- a/src/legacy/ui/public/vis/__tests__/response_handlers/_build_chart_data.js +++ b/src/legacy/ui/public/vis/__tests__/response_handlers/_build_chart_data.js @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { aggResponseIndex } from '../../../agg_response'; import { VislibSeriesResponseHandlerProvider as vislibReponseHandler } from '../../response_handlers/vislib'; diff --git a/src/legacy/ui/public/vis/__tests__/response_handlers/basic.js b/src/legacy/ui/public/vis/__tests__/response_handlers/basic.js index a8281b95742b6..b80cf4abc02dd 100644 --- a/src/legacy/ui/public/vis/__tests__/response_handlers/basic.js +++ b/src/legacy/ui/public/vis/__tests__/response_handlers/basic.js @@ -18,7 +18,7 @@ */ import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { VislibSeriesResponseHandlerProvider } from '../../response_handlers/vislib'; describe('Basic Response Handler', function () { diff --git a/src/legacy/ui/public/vis/__tests__/vis_types/base_vis_type.js b/src/legacy/ui/public/vis/__tests__/vis_types/base_vis_type.js index 2a79b40e7496a..7590ff93d2b47 100644 --- a/src/legacy/ui/public/vis/__tests__/vis_types/base_vis_type.js +++ b/src/legacy/ui/public/vis/__tests__/vis_types/base_vis_type.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { BaseVisTypeProvider } from '../../vis_types/base_vis_type'; diff --git a/src/legacy/ui/public/vis/__tests__/vis_types/react_vis_type.js b/src/legacy/ui/public/vis/__tests__/vis_types/react_vis_type.js index cf2fbab880814..99b485e8ef55d 100644 --- a/src/legacy/ui/public/vis/__tests__/vis_types/react_vis_type.js +++ b/src/legacy/ui/public/vis/__tests__/vis_types/react_vis_type.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { ReactVisTypeProvider } from '../../vis_types/react_vis_type'; diff --git a/src/legacy/ui/public/vis/__tests__/vis_types/vislib_vis_type.js b/src/legacy/ui/public/vis/__tests__/vis_types/vislib_vis_type.js index aee36e7f330da..9e6c98e94a9c4 100644 --- a/src/legacy/ui/public/vis/__tests__/vis_types/vislib_vis_type.js +++ b/src/legacy/ui/public/vis/__tests__/vis_types/vislib_vis_type.js @@ -18,7 +18,7 @@ */ import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { VislibVisTypeProvider } from '../../vis_types/vislib_vis_type'; describe('Vislib Vis Type', function () { diff --git a/src/legacy/ui/public/vis/agg_config_result.js b/src/legacy/ui/public/vis/agg_config_result.js index 75da837e6ee1c..f82c12585753a 100644 --- a/src/legacy/ui/public/vis/agg_config_result.js +++ b/src/legacy/ui/public/vis/agg_config_result.js @@ -19,7 +19,7 @@ import chrome from '../chrome'; -// eslint-disable-next-line @elastic/kibana-custom/no-default-export +// eslint-disable-next-line @kbn/eslint/no-default-export export default function AggConfigResult(aggConfig, parent, value, key, filters) { this.key = key; this.value = value; diff --git a/src/legacy/ui/public/vis/components/tooltip/__tests__/positioning.js b/src/legacy/ui/public/vis/components/tooltip/__tests__/positioning.js index c5568ec833d70..b72e947fee6cd 100644 --- a/src/legacy/ui/public/vis/components/tooltip/__tests__/positioning.js +++ b/src/legacy/ui/public/vis/components/tooltip/__tests__/positioning.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import $ from 'jquery'; import _ from 'lodash'; import sinon from 'sinon'; diff --git a/src/legacy/ui/public/vis/editors/default/__tests__/agg.js b/src/legacy/ui/public/vis/editors/default/__tests__/agg.js index 0f5c76f2f428f..c38ba179f3a5a 100644 --- a/src/legacy/ui/public/vis/editors/default/__tests__/agg.js +++ b/src/legacy/ui/public/vis/editors/default/__tests__/agg.js @@ -20,7 +20,7 @@ import angular from 'angular'; import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import '../agg'; diff --git a/src/legacy/ui/public/vis/editors/default/__tests__/agg_params.js b/src/legacy/ui/public/vis/editors/default/__tests__/agg_params.js index 3538b1ab5ae70..4f3c78e1469d9 100644 --- a/src/legacy/ui/public/vis/editors/default/__tests__/agg_params.js +++ b/src/legacy/ui/public/vis/editors/default/__tests__/agg_params.js @@ -20,7 +20,7 @@ import angular from 'angular'; import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import '../agg_params'; import { VisProvider } from '../../..'; diff --git a/src/legacy/ui/public/vis/editors/default/__tests__/default_editor_utils.test.tsx b/src/legacy/ui/public/vis/editors/default/__tests__/default_editor_utils.test.tsx new file mode 100644 index 0000000000000..423c66cfe7edb --- /dev/null +++ b/src/legacy/ui/public/vis/editors/default/__tests__/default_editor_utils.test.tsx @@ -0,0 +1,194 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { groupAggregationsBy } from '../default_editor_utils'; + +const aggs = [ + { + title: 'Count', + type: 'metrics', + subtype: 'Metric Aggregations', + }, + { + title: 'Average', + type: 'metrics', + subtype: 'Metric Aggregations', + }, + { + title: 'Cumulative Sum', + type: 'metrics', + subtype: 'Parent Pipeline Aggregations', + }, + { + title: 'Min Bucket', + type: 'metrics', + subtype: 'Parent Pipeline Aggregations', + }, + { + title: 'Sub string agg', + type: 'string', + subtype: 'Sub-String aggregations', + }, + { + title: 'String agg', + type: 'string', + subtype: 'String aggregations', + }, +]; + +describe('Default Editor groupAggregationsBy', () => { + it('should return aggs grouped by default type field', () => { + const groupedAggs = [ + { + label: 'metrics', + options: [ + { + label: 'Average', + value: { + title: 'Average', + type: 'metrics', + subtype: 'Metric Aggregations', + }, + }, + { + label: 'Count', + value: { + title: 'Count', + type: 'metrics', + subtype: 'Metric Aggregations', + }, + }, + { + label: 'Cumulative Sum', + value: { + title: 'Cumulative Sum', + type: 'metrics', + subtype: 'Parent Pipeline Aggregations', + }, + }, + + { + label: 'Min Bucket', + value: { + title: 'Min Bucket', + type: 'metrics', + subtype: 'Parent Pipeline Aggregations', + }, + }, + ], + }, + { + label: 'string', + options: [ + { + label: 'String agg', + value: { + title: 'String agg', + type: 'string', + subtype: 'String aggregations', + }, + }, + { + label: 'Sub string agg', + value: { + title: 'Sub string agg', + type: 'string', + subtype: 'Sub-String aggregations', + }, + }, + ], + }, + ]; + expect(groupAggregationsBy(aggs)).toEqual(groupedAggs); + }); + it('should return aggs grouped by subtype field', () => { + const groupedAggs = [ + { + label: 'Metric Aggregations', + options: [ + { + label: 'Average', + value: { + title: 'Average', + type: 'metrics', + subtype: 'Metric Aggregations', + }, + }, + { + label: 'Count', + value: { + title: 'Count', + type: 'metrics', + subtype: 'Metric Aggregations', + }, + }, + ], + }, + { + label: 'Parent Pipeline Aggregations', + options: [ + { + label: 'Cumulative Sum', + value: { + title: 'Cumulative Sum', + type: 'metrics', + subtype: 'Parent Pipeline Aggregations', + }, + }, + + { + label: 'Min Bucket', + value: { + title: 'Min Bucket', + type: 'metrics', + subtype: 'Parent Pipeline Aggregations', + }, + }, + ], + }, + { + label: 'String aggregations', + options: [ + { + label: 'String agg', + value: { + title: 'String agg', + type: 'string', + subtype: 'String aggregations', + }, + }, + ], + }, + { + label: 'Sub-String aggregations', + options: [ + { + label: 'Sub string agg', + value: { + title: 'Sub string agg', + type: 'string', + subtype: 'Sub-String aggregations', + }, + }, + ], + }, + ]; + expect(groupAggregationsBy(aggs, 'subtype')).toEqual(groupedAggs); + }); +}); diff --git a/src/legacy/ui/public/vis/editors/default/__tests__/keyboard_move.js b/src/legacy/ui/public/vis/editors/default/__tests__/keyboard_move.js index 6daf8a8d41ec0..b24e2918ac07d 100644 --- a/src/legacy/ui/public/vis/editors/default/__tests__/keyboard_move.js +++ b/src/legacy/ui/public/vis/editors/default/__tests__/keyboard_move.js @@ -18,7 +18,7 @@ */ import angular from 'angular'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import sinon from 'sinon'; import { Direction } from '../keyboard_move'; diff --git a/src/legacy/ui/public/vis/editors/default/_agg_select.scss b/src/legacy/ui/public/vis/editors/default/_agg_select.scss index 501344bc1e4cf..cd3a84cb9d3af 100644 --- a/src/legacy/ui/public/vis/editors/default/_agg_select.scss +++ b/src/legacy/ui/public/vis/editors/default/_agg_select.scss @@ -20,3 +20,7 @@ .visEditorAggSelect__helpLink { @include euiFontSizeXS; } + +.visEditorAggSelect__formRow { + margin-bottom: $euiSizeS; +} diff --git a/src/legacy/ui/public/vis/editors/default/_sidebar.scss b/src/legacy/ui/public/vis/editors/default/_sidebar.scss index ca5961c5ff851..2fcc0e79f4a42 100644 --- a/src/legacy/ui/public/vis/editors/default/_sidebar.scss +++ b/src/legacy/ui/public/vis/editors/default/_sidebar.scss @@ -221,3 +221,7 @@ } } +.visEditorSidebar__aggParamFormRow { + margin-top: $euiSizeS; + margin-bottom: $euiSizeS; +} diff --git a/src/legacy/ui/public/vis/editors/default/agg.js b/src/legacy/ui/public/vis/editors/default/agg.js index ce3de939dca4d..9c6493048b25b 100644 --- a/src/legacy/ui/public/vis/editors/default/agg.js +++ b/src/legacy/ui/public/vis/editors/default/agg.js @@ -21,6 +21,7 @@ import './agg_params'; import './agg_add'; import { Direction } from './keyboard_move'; import _ from 'lodash'; +import '../../../fancy_forms'; import { uiModules } from '../../../modules'; import aggTemplate from './agg.html'; import { move } from '../../../utils/collection'; @@ -53,7 +54,7 @@ uiModules * @return {[type]} [description] */ $scope.describe = function () { - if (!$scope.agg.type.makeLabel) return ''; + if (!$scope.agg.type || !$scope.agg.type.makeLabel) return ''; const label = $scope.agg.type.makeLabel($scope.agg); return label ? label : ''; }; diff --git a/src/legacy/ui/public/vis/editors/default/agg_group.js b/src/legacy/ui/public/vis/editors/default/agg_group.js index 015a259f209c1..b8fbb716ba1e1 100644 --- a/src/legacy/ui/public/vis/editors/default/agg_group.js +++ b/src/legacy/ui/public/vis/editors/default/agg_group.js @@ -39,6 +39,12 @@ uiModules $scope.groupNameLabel = aggGroupNameMaps()[$scope.groupName]; $scope.$bind('group', 'state.aggs.bySchemaGroup["' + $scope.groupName + '"]'); $scope.$bind('schemas', 'vis.type.schemas["' + $scope.groupName + '"]'); + // We use `editorState` to access the state of the editor in the options panels. + // There are some aggregations (dot size metric) that needs to set parameters on the + // editorState too. Since we have the editor state here available as `state`, we're just + // binding it to the same name `editorState` so the controls look the same if they are in + // the data tab or within any other options tab. + $scope.$bind('editorState', 'state'); $scope.$watchMulti([ 'schemas', diff --git a/src/legacy/ui/public/vis/editors/default/agg_param.js b/src/legacy/ui/public/vis/editors/default/agg_param.js index ec2e6891f6932..75f67091cf981 100644 --- a/src/legacy/ui/public/vis/editors/default/agg_param.js +++ b/src/legacy/ui/public/vis/editors/default/agg_param.js @@ -29,7 +29,9 @@ uiModules ['aggParam', { watchDepth: 'reference' }], ['paramEditor', { wrapApply: false }], ['onChange', { watchDepth: 'reference' }], + ['setValidity', { watchDepth: 'reference' }], 'value', + 'isInvalid' ])) .directive('visAggParamEditor', function (config) { return { @@ -54,6 +56,8 @@ uiModules agg-param="aggParam" on-change="onChange" value="paramValue" + is-invalid="isInvalid" + set-validity="setValidity" >`; } @@ -93,6 +97,13 @@ uiModules ngModelCtrl.$setDirty(); } }; + + $scope.setValidity = (isValid) => { + if(ngModelCtrl) { + $scope.isInvalid = !isValid; + ngModelCtrl.$setValidity(`agg${$scope.agg.id}${$scope.aggParam.name}`, isValid); + } + }; } } }; diff --git a/src/legacy/ui/public/vis/editors/default/agg_param_editor_props.ts b/src/legacy/ui/public/vis/editors/default/agg_param_editor_props.ts index 3e7623b6c25fc..9a38de80dc3b1 100644 --- a/src/legacy/ui/public/vis/editors/default/agg_param_editor_props.ts +++ b/src/legacy/ui/public/vis/editors/default/agg_param_editor_props.ts @@ -20,11 +20,15 @@ import { AggParam } from '../../../agg_types'; import { AggConfig } from '../../agg_config'; -interface AggParamEditorProps { +// NOTE: we cannot export the interface with export { InterfaceName } +// as there is currently a bug on babel typescript transform plugin for it +// https://github.com/babel/babel/issues/7641 +// +export interface AggParamEditorProps { agg: AggConfig; aggParam: AggParam; value: T; + isInvalid: boolean; setValue(value: T): void; + setValidity(isValid: boolean): void; } - -export { AggParamEditorProps }; diff --git a/src/legacy/ui/public/vis/editors/default/agg_param_react_wrapper.tsx b/src/legacy/ui/public/vis/editors/default/agg_param_react_wrapper.tsx index 4b5380c92559c..3146c205dceae 100644 --- a/src/legacy/ui/public/vis/editors/default/agg_param_react_wrapper.tsx +++ b/src/legacy/ui/public/vis/editors/default/agg_param_react_wrapper.tsx @@ -28,12 +28,31 @@ interface AggParamReactWrapperProps { aggParam: AggParam; paramEditor: React.FunctionComponent>; value: T; + isInvalid: boolean; onChange(value: T): void; + setValidity(isValid: boolean): void; } function AggParamReactWrapper(props: AggParamReactWrapperProps) { - const { agg, aggParam, paramEditor: ParamEditor, onChange, value } = props; - return ; + const { + agg, + aggParam, + paramEditor: ParamEditor, + onChange, + value, + isInvalid, + setValidity, + } = props; + return ( + + ); } export { AggParamReactWrapper }; diff --git a/src/legacy/ui/public/vis/editors/default/agg_params.html b/src/legacy/ui/public/vis/editors/default/agg_params.html index 28a2a3472faef..411357dbfa78e 100644 --- a/src/legacy/ui/public/vis/editors/default/agg_params.html +++ b/src/legacy/ui/public/vis/editors/default/agg_params.html @@ -33,4 +33,11 @@

+ + diff --git a/src/legacy/ui/public/vis/editors/default/agg_params.js b/src/legacy/ui/public/vis/editors/default/agg_params.js index 2663e09497498..b3005a2b0929d 100644 --- a/src/legacy/ui/public/vis/editors/default/agg_params.js +++ b/src/legacy/ui/public/vis/editors/default/agg_params.js @@ -18,18 +18,18 @@ */ import $ from 'jquery'; -import { get, has } from 'lodash'; +import { get } from 'lodash'; import { aggTypes } from '../../../agg_types'; import { aggTypeFilters } from '../../../agg_types/filter'; import { aggTypeFieldFilters } from '../../../agg_types/param_types/filter'; -import { documentationLinks } from '../../../documentation_links/documentation_links'; import '../../../filters/match_any'; import { uiModules } from '../../../modules'; import { editorConfigProviders } from '../config/editor_config_providers'; import advancedToggleHtml from './advanced_toggle.html'; import './agg_param'; +import './agg_select'; import aggParamsTemplate from './agg_params.html'; -import aggSelectHtml from './agg_select.html'; +import { groupAggregationsBy } from './default_editor_utils'; uiModules .get('app/visualize') @@ -56,6 +56,15 @@ uiModules updateEditorConfig('default'); }); + $scope.groupedAggTypeOptions = groupAggregationsBy($scope.aggTypeOptions, 'subtype'); + $scope.isSubAggregation = $scope.$index >= 1 && $scope.groupName === 'buckets'; + + $scope.onAggTypeChange = (agg, value) => { + if (agg.type !== value) { + agg.type = value; + } + }; + $scope.onParamChange = (agg, paramName, value) => { if(agg.params[paramName] !== value) { agg.params[paramName] = value; @@ -91,9 +100,6 @@ uiModules // controls for the agg, which is why they are first addSchemaEditor(); - // allow selection of an aggregation - addAggSelector(); - function addSchemaEditor() { const $schemaEditor = $('
').addClass('schemaEditors form-group').appendTo($el); @@ -103,21 +109,12 @@ uiModules } } - function addAggSelector() { - const $aggSelect = $(aggSelectHtml).appendTo($el); - $compile($aggSelect)($scope); - } - // params for the selected agg, these are rebuilt every time the agg in $aggSelect changes let $aggParamEditors; // container for agg type param editors let $aggParamEditorsScope; function updateAggParamEditor() { updateEditorConfig(); - $scope.aggHelpLink = null; - if (has($scope, 'agg.type.name')) { - $scope.aggHelpLink = get(documentationLinks, ['aggs', $scope.agg.type.name]); - } if ($aggParamEditors) { $aggParamEditors.remove(); diff --git a/src/legacy/ui/public/vis/editors/default/agg_select.html b/src/legacy/ui/public/vis/editors/default/agg_select.html deleted file mode 100644 index d899fb0e72026..0000000000000 --- a/src/legacy/ui/public/vis/editors/default/agg_select.html +++ /dev/null @@ -1,50 +0,0 @@ -
-
- - - - -
-
- - - {{$select.selected.title}} - - -
-
-
-
diff --git a/src/legacy/ui/public/vis/editors/default/agg_select.js b/src/legacy/ui/public/vis/editors/default/agg_select.js new file mode 100644 index 0000000000000..5bcf5aaeef717 --- /dev/null +++ b/src/legacy/ui/public/vis/editors/default/agg_select.js @@ -0,0 +1,91 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import 'ngreact'; +import { uiModules } from '../../../modules'; +import { DefaultEditorAggSelect } from './components/default_editor_agg_select'; +import { wrapInI18nContext } from 'ui/i18n'; + +uiModules + .get('app/visualize', ['react']) + .directive('visAggSelectReactWrapper', reactDirective => reactDirective(wrapInI18nContext(DefaultEditorAggSelect), [ + ['agg', { watchDepth: 'collection' }], + ['aggTypeOptions', { watchDepth: 'collection' }], + ['setValue', { watchDepth: 'reference' }], + ['setTouched', { watchDepth: 'reference' }], + ['setValidity', { watchDepth: 'reference' }], + 'value', + 'isSubAggregation', + 'aggHelpLink', + 'isSelectInvalid' + ])) + .directive('visAggSelect', function () { + return { + restrict: 'E', + scope: true, + require: '^ngModel', + template: function () { + return ``; + }, + link: { + pre: function ($scope, $el, attr) { + $scope.$bind('agg', attr.agg); + $scope.$bind('isSubAggregation', attr.isSubAggregation); + $scope.$bind('aggTypeOptions', attr.aggTypeOptions); + }, + post: function ($scope, $el, attr, ngModelCtrl) { + $scope.$watch('agg.type', (value) => { + // Whenever the value of the parameter changed (e.g. by a reset or actually by calling) + // we store the new value in $scope.paramValue, which will be passed as a new value to the react component. + $scope.paramValue = value; + }); + + $scope.onChange = (value) => { + // This is obviously not a good code quality, but without using scope binding (which we can't see above) + // to bind function values, this is right now the best temporary fix, until all of this will be gone. + $scope.$parent.onAggTypeChange($scope.agg, value); + + ngModelCtrl.$setDirty(); + }; + + $scope.setTouched = () => { + ngModelCtrl.$setTouched(); + $scope.isSelectInvalid = !$scope.paramValue; + }; + + $scope.setValidity = (isValid) => { + // The field will be marked as invalid when the value is empty and the field is touched. + $scope.isSelectInvalid = ngModelCtrl.$touched ? !isValid : false; + // Since aggType is required field, the form should become invalid when the aggregation field is set to empty. + ngModelCtrl.$setValidity(`agg${$scope.agg.id}`, isValid); + }; + } + } + }; + }); diff --git a/src/legacy/ui/public/vis/editors/default/components/default_editor_agg_select.tsx b/src/legacy/ui/public/vis/editors/default/components/default_editor_agg_select.tsx new file mode 100644 index 0000000000000..71d09288a2be6 --- /dev/null +++ b/src/legacy/ui/public/vis/editors/default/components/default_editor_agg_select.tsx @@ -0,0 +1,124 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { get, has, isFunction } from 'lodash'; +import React, { useEffect } from 'react'; + +import { EuiComboBox, EuiFormRow, EuiLink } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { AggType } from 'ui/agg_types'; +import { AggConfig } from 'ui/vis/agg_config'; +import { documentationLinks } from '../../../../documentation_links/documentation_links'; +import { ComboBoxGroupedOption } from '../default_editor_utils'; + +interface DefaultEditorAggSelectProps { + agg: AggConfig; + value: AggType; + setValue: (aggType: AggType) => void; + aggTypeOptions: AggType[]; + isSubAggregation: boolean; + isSelectInvalid: boolean; + setTouched: () => void; + setValidity: (isValid: boolean) => void; +} + +function DefaultEditorAggSelect({ + agg = {}, + value = { title: '' }, + setValue, + aggTypeOptions = [], + isSelectInvalid, + isSubAggregation, + setTouched, + setValidity, +}: DefaultEditorAggSelectProps) { + const isAggTypeDefined = value && Boolean(value.title); + const selectedOptions: ComboBoxGroupedOption[] = isAggTypeDefined + ? [{ label: value.title, value }] + : []; + + const label = isSubAggregation ? ( + + ) : ( + + ); + + let aggHelpLink = null; + if (has(agg, 'type.name')) { + aggHelpLink = get(documentationLinks, ['aggs', agg.type.name]); + } + + const helpLink = isAggTypeDefined && aggHelpLink && ( + + + + ); + + useEffect( + () => { + if (isFunction(setValidity)) { + setValidity(isAggTypeDefined); + } + }, + [isAggTypeDefined] + ); + + return ( + + setValue(get(options, '0.value'))} + data-test-subj="defaultEditorAggSelect" + isClearable={false} + isInvalid={isSelectInvalid} + fullWidth={true} + onBlur={() => setTouched()} + /> + + ); +} + +export { DefaultEditorAggSelect }; diff --git a/src/legacy/ui/public/vis/editors/default/default_editor_utils.tsx b/src/legacy/ui/public/vis/editors/default/default_editor_utils.tsx new file mode 100644 index 0000000000000..5d0c50012795d --- /dev/null +++ b/src/legacy/ui/public/vis/editors/default/default_editor_utils.tsx @@ -0,0 +1,79 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { EuiComboBoxOptionProps } from '@elastic/eui'; +import { AggType } from 'ui/agg_types'; + +export type ComboBoxGroupedOption = EuiComboBoxOptionProps & { + value?: AggType; + options?: ComboBoxGroupedOption[]; +}; + +/** + * Groups and sorts alphabetically aggregation objects and returns an array of options that are compatible with EuiComboBox options. + * + * @param aggs An array of aggregations that will be grouped. + * @param groupBy A field name which aggregations is grouped by. + * + * @returns An array of grouped and sorted alphabetically `aggs` that are compatible with EuiComboBox options. If `aggs` is not an array, the function returns an ampry array. + */ +function groupAggregationsBy( + aggs: AggType[], + groupBy: string = 'type' +): ComboBoxGroupedOption[] | [] { + if (!Array.isArray(aggs)) { + return []; + } + + const groupedOptions: ComboBoxGroupedOption[] = aggs.reduce((array: AggType[], type: AggType) => { + const group = array.find(element => element.label === type[groupBy]); + const option = { + label: type.title, + value: type, + }; + + if (group) { + group.options.push(option); + } else { + array.push({ label: type[groupBy], options: [option] }); + } + + return array; + }, []); + + groupedOptions.sort(sortByLabel); + + groupedOptions.forEach((group: ComboBoxGroupedOption) => { + if (Array.isArray(group.options)) { + group.options.sort(sortByLabel); + } + }); + + if (groupedOptions.length === 1 && !groupedOptions[0].label) { + return groupedOptions[0].options || []; + } + + return groupedOptions; +} + +function sortByLabel(a: { label: string }, b: { label: string }) { + return a.label.toLowerCase().localeCompare(b.label.toLowerCase()); +} + +export { groupAggregationsBy }; diff --git a/src/legacy/ui/public/vis/editors/default/sidebar.js b/src/legacy/ui/public/vis/editors/default/sidebar.js index 886de3fbd6e0d..a335880bcf917 100644 --- a/src/legacy/ui/public/vis/editors/default/sidebar.js +++ b/src/legacy/ui/public/vis/editors/default/sidebar.js @@ -20,6 +20,7 @@ import _ from 'lodash'; import './agg_group'; import './vis_options'; +import 'ui/directives/css_truncate'; import { uiModules } from '../../../modules'; import sidebarTemplate from './sidebar.html'; diff --git a/src/legacy/ui/public/vis/vis.js b/src/legacy/ui/public/vis/vis.js index 7729192e2a4fd..423e4b9e3a041 100644 --- a/src/legacy/ui/public/vis/vis.js +++ b/src/legacy/ui/public/vis/vis.js @@ -36,7 +36,9 @@ import { FilterBarQueryFilterProvider } from '../filter_bar/query_filter'; import { updateVisualizationConfig } from './vis_update'; import { SearchSourceProvider } from '../courier/search_source'; import { SavedObjectsClientProvider } from '../saved_objects'; -import { timefilter } from 'ui/timefilter'; + +import { timefilter } from '../timefilter'; +import '../bind'; export function VisProvider(Private, indexPatterns, getAppState) { const visTypes = Private(VisTypesRegistryProvider); diff --git a/src/legacy/ui/public/vis/vis_types/__tests__/vislib_vis_legend.js b/src/legacy/ui/public/vis/vis_types/__tests__/vislib_vis_legend.js index ab7bf8fab0abb..d539693a1209e 100644 --- a/src/legacy/ui/public/vis/vis_types/__tests__/vislib_vis_legend.js +++ b/src/legacy/ui/public/vis/vis_types/__tests__/vislib_vis_legend.js @@ -19,7 +19,7 @@ import $ from 'jquery'; import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { VisProvider } from '../../vis'; import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern'; diff --git a/src/legacy/ui/public/vislib/__tests__/components/heatmap_color.js b/src/legacy/ui/public/vislib/__tests__/components/heatmap_color.js index 8260b97dcc2f1..d4e2a168fdf29 100644 --- a/src/legacy/ui/public/vislib/__tests__/components/heatmap_color.js +++ b/src/legacy/ui/public/vislib/__tests__/components/heatmap_color.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { getHeatmapColors } from '../../components/color/heatmap_color'; diff --git a/src/legacy/ui/public/vislib/__tests__/components/labels.js b/src/legacy/ui/public/vislib/__tests__/components/labels.js index e454bc1cf11b8..999937305d5ca 100644 --- a/src/legacy/ui/public/vislib/__tests__/components/labels.js +++ b/src/legacy/ui/public/vislib/__tests__/components/labels.js @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { VislibComponentsLabelsLabelsProvider } from '../../components/labels/labels'; import { VislibComponentsLabelsDataArrayProvider } from '../../components/labels/data_array'; diff --git a/src/legacy/ui/public/vislib/__tests__/components/zero_injection.js b/src/legacy/ui/public/vislib/__tests__/components/zero_injection.js index 8cf0a2bdfa553..fb9e775ae2fe6 100644 --- a/src/legacy/ui/public/vislib/__tests__/components/zero_injection.js +++ b/src/legacy/ui/public/vislib/__tests__/components/zero_injection.js @@ -19,7 +19,7 @@ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { VislibComponentsZeroInjectionInjectZerosProvider } from '../../components/zero_injection/inject_zeros'; import { VislibComponentsZeroInjectionOrderedXKeysProvider } from '../../components/zero_injection/ordered_x_keys'; diff --git a/src/legacy/ui/public/vislib/__tests__/index.js b/src/legacy/ui/public/vislib/__tests__/index.js index cfed27d817063..ed58765df5a81 100644 --- a/src/legacy/ui/public/vislib/__tests__/index.js +++ b/src/legacy/ui/public/vislib/__tests__/index.js @@ -19,7 +19,7 @@ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import VislibProvider from '..'; diff --git a/src/legacy/ui/public/vislib/__tests__/lib/axis/axis.js b/src/legacy/ui/public/vislib/__tests__/lib/axis/axis.js index 52add55f50430..954d7dee6c4b1 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/axis/axis.js +++ b/src/legacy/ui/public/vislib/__tests__/lib/axis/axis.js @@ -20,7 +20,7 @@ import d3 from 'd3'; import _ from 'lodash'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import $ from 'jquery'; import '../../../../persisted_state'; import { VislibLibAxisProvider } from '../../../lib/axis'; diff --git a/src/legacy/ui/public/vislib/__tests__/lib/axis_title.js b/src/legacy/ui/public/vislib/__tests__/lib/axis_title.js index 0541261c089ad..9098a12d40fc6 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/axis_title.js +++ b/src/legacy/ui/public/vislib/__tests__/lib/axis_title.js @@ -21,7 +21,7 @@ import d3 from 'd3'; import _ from 'lodash'; import $ from 'jquery'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { VislibLibAxisTitleProvider } from '../../lib/axis/axis_title'; import { VislibLibAxisConfigProvider } from '../../lib/axis/axis_config'; import { VislibVisConfigProvider } from '../../lib/vis_config'; diff --git a/src/legacy/ui/public/vislib/__tests__/lib/chart_title.js b/src/legacy/ui/public/vislib/__tests__/lib/chart_title.js index e88896d70872d..15bca14400bbc 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/chart_title.js +++ b/src/legacy/ui/public/vislib/__tests__/lib/chart_title.js @@ -20,7 +20,7 @@ import d3 from 'd3'; import _ from 'lodash'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { VislibLibChartTitleProvider } from '../../lib/chart_title'; import { VislibVisConfigProvider } from '../../lib/vis_config'; import '../../../persisted_state'; diff --git a/src/legacy/ui/public/vislib/__tests__/lib/data.js b/src/legacy/ui/public/vislib/__tests__/lib/data.js index ae6e166b62ef0..4cb47a4c5006f 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/data.js +++ b/src/legacy/ui/public/vislib/__tests__/lib/data.js @@ -19,7 +19,7 @@ import _ from 'lodash'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { VislibLibDataProvider } from '../../lib/data'; import '../../../persisted_state'; diff --git a/src/legacy/ui/public/vislib/__tests__/lib/dispatch.js b/src/legacy/ui/public/vislib/__tests__/lib/dispatch.js index fb4794f147a15..5dc6854cf5ced 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/dispatch.js +++ b/src/legacy/ui/public/vislib/__tests__/lib/dispatch.js @@ -20,7 +20,7 @@ import _ from 'lodash'; import d3 from 'd3'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; // Data import data from 'fixtures/vislib/mock_data/date_histogram/_series'; diff --git a/src/legacy/ui/public/vislib/__tests__/lib/error_handler.js b/src/legacy/ui/public/vislib/__tests__/lib/error_handler.js index 804939001aa10..bb7d9eee51c28 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/error_handler.js +++ b/src/legacy/ui/public/vislib/__tests__/lib/error_handler.js @@ -18,7 +18,7 @@ */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { VislibLibErrorHandlerProvider } from '../../lib/_error_handler'; diff --git a/src/legacy/ui/public/vislib/__tests__/lib/handler/handler.js b/src/legacy/ui/public/vislib/__tests__/lib/handler/handler.js index 518fc9595ab8d..f40df40ed998a 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/handler/handler.js +++ b/src/legacy/ui/public/vislib/__tests__/lib/handler/handler.js @@ -18,7 +18,7 @@ */ import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; // Data import series from 'fixtures/vislib/mock_data/date_histogram/_series'; diff --git a/src/legacy/ui/public/vislib/__tests__/lib/layout/layout.js b/src/legacy/ui/public/vislib/__tests__/lib/layout/layout.js index 149f2e87cc302..93a6961b99aa7 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/layout/layout.js +++ b/src/legacy/ui/public/vislib/__tests__/lib/layout/layout.js @@ -19,7 +19,7 @@ import d3 from 'd3'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; // Data import series from 'fixtures/vislib/mock_data/date_histogram/_series'; diff --git a/src/legacy/ui/public/vislib/__tests__/lib/layout/layout_types.js b/src/legacy/ui/public/vislib/__tests__/lib/layout/layout_types.js index 8d4c80f728340..ec86a601d7b1a 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/layout/layout_types.js +++ b/src/legacy/ui/public/vislib/__tests__/lib/layout/layout_types.js @@ -19,7 +19,7 @@ import _ from 'lodash'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { VislibLibLayoutLayoutTypesProvider } from '../../../lib/layout/layout_types'; describe('Vislib Layout Types Test Suite', function () { diff --git a/src/legacy/ui/public/vislib/__tests__/lib/layout/splits/column_chart/splits.js b/src/legacy/ui/public/vislib/__tests__/lib/layout/splits/column_chart/splits.js index 185597f1ac3c1..c189232800d04 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/layout/splits/column_chart/splits.js +++ b/src/legacy/ui/public/vislib/__tests__/lib/layout/splits/column_chart/splits.js @@ -19,7 +19,7 @@ import d3 from 'd3'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import $ from 'jquery'; import { VislibLibLayoutSplitsColumnChartChartSplitProvider } from '../../../../../lib/layout/splits/column_chart/chart_split'; import { VislibLibLayoutSplitsColumnChartChartTitleSplitProvider } from '../../../../../lib/layout/splits/column_chart/chart_title_split'; diff --git a/src/legacy/ui/public/vislib/__tests__/lib/layout/splits/gauge_chart/splits.js b/src/legacy/ui/public/vislib/__tests__/lib/layout/splits/gauge_chart/splits.js index 2fe0cc2b7fbea..1ab8c0750ab00 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/layout/splits/gauge_chart/splits.js +++ b/src/legacy/ui/public/vislib/__tests__/lib/layout/splits/gauge_chart/splits.js @@ -19,7 +19,7 @@ import d3 from 'd3'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import $ from 'jquery'; import VislibLibLayoutSplitsGaugeChartChartSplitProvider from '../../../../../lib/layout/splits/gauge_chart/chart_split'; import VislibLibLayoutSplitsGaugeChartChartTitleSplitProvider from '../../../../../lib/layout/splits/gauge_chart/chart_title_split'; diff --git a/src/legacy/ui/public/vislib/__tests__/lib/layout/types/column_layout.js b/src/legacy/ui/public/vislib/__tests__/lib/layout/types/column_layout.js index 6086b7007af58..db721a754134f 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/layout/types/column_layout.js +++ b/src/legacy/ui/public/vislib/__tests__/lib/layout/types/column_layout.js @@ -20,7 +20,7 @@ import d3 from 'd3'; import _ from 'lodash'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { VislibLibLayoutLayoutTypesProvider } from '../../../../lib/layout/layout_types'; describe('Vislib Column Layout Test Suite', function () { diff --git a/src/legacy/ui/public/vislib/__tests__/lib/types/point_series.js b/src/legacy/ui/public/vislib/__tests__/lib/types/point_series.js index f5d8e16092e0b..3688fb834f9b5 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/types/point_series.js +++ b/src/legacy/ui/public/vislib/__tests__/lib/types/point_series.js @@ -18,7 +18,7 @@ */ import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import stackedSeries from 'fixtures/vislib/mock_data/date_histogram/_stacked_series'; import { VislibTypesPointSeries } from '../../../lib/types/point_series'; diff --git a/src/legacy/ui/public/vislib/__tests__/lib/vis_config.js b/src/legacy/ui/public/vislib/__tests__/lib/vis_config.js index 510263b37bce5..5e0f0f99c2d53 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/vis_config.js +++ b/src/legacy/ui/public/vislib/__tests__/lib/vis_config.js @@ -19,7 +19,7 @@ import d3 from 'd3'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { VislibVisConfigProvider } from '../../lib/vis_config'; import '../../../persisted_state'; diff --git a/src/legacy/ui/public/vislib/__tests__/lib/x_axis.js b/src/legacy/ui/public/vislib/__tests__/lib/x_axis.js index d55259132a794..3fad87ee851ad 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/x_axis.js +++ b/src/legacy/ui/public/vislib/__tests__/lib/x_axis.js @@ -20,7 +20,7 @@ import d3 from 'd3'; import _ from 'lodash'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import $ from 'jquery'; import '../../../persisted_state'; import { VislibLibAxisProvider } from '../../lib/axis'; diff --git a/src/legacy/ui/public/vislib/__tests__/lib/y_axis.js b/src/legacy/ui/public/vislib/__tests__/lib/y_axis.js index b59ba8e6e3158..965c1c49e1cc5 100644 --- a/src/legacy/ui/public/vislib/__tests__/lib/y_axis.js +++ b/src/legacy/ui/public/vislib/__tests__/lib/y_axis.js @@ -20,7 +20,7 @@ import _ from 'lodash'; import d3 from 'd3'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import $ from 'jquery'; import '../../../persisted_state'; import { VislibLibAxisProvider } from '../../lib/axis'; diff --git a/src/legacy/ui/public/vislib/__tests__/vis.js b/src/legacy/ui/public/vislib/__tests__/vis.js index acacf59fbfcdf..1079bd0ad3155 100644 --- a/src/legacy/ui/public/vislib/__tests__/vis.js +++ b/src/legacy/ui/public/vislib/__tests__/vis.js @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import series from 'fixtures/vislib/mock_data/date_histogram/_series'; diff --git a/src/legacy/ui/public/vislib/__tests__/visualizations/area_chart.js b/src/legacy/ui/public/vislib/__tests__/visualizations/area_chart.js index ac7944ae8dead..1390eecfa28dd 100644 --- a/src/legacy/ui/public/vislib/__tests__/visualizations/area_chart.js +++ b/src/legacy/ui/public/vislib/__tests__/visualizations/area_chart.js @@ -18,7 +18,7 @@ */ import d3 from 'd3'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import _ from 'lodash'; diff --git a/src/legacy/ui/public/vislib/__tests__/visualizations/chart.js b/src/legacy/ui/public/vislib/__tests__/visualizations/chart.js index 5a9cbc0494213..916337165fab2 100644 --- a/src/legacy/ui/public/vislib/__tests__/visualizations/chart.js +++ b/src/legacy/ui/public/vislib/__tests__/visualizations/chart.js @@ -18,7 +18,7 @@ */ import d3 from 'd3'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { VislibVisProvider } from '../../vis'; import '../../../persisted_state'; diff --git a/src/legacy/ui/public/vislib/__tests__/visualizations/column_chart.js b/src/legacy/ui/public/vislib/__tests__/visualizations/column_chart.js index af76a960d9635..18ed4b4e28f21 100644 --- a/src/legacy/ui/public/vislib/__tests__/visualizations/column_chart.js +++ b/src/legacy/ui/public/vislib/__tests__/visualizations/column_chart.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import _ from 'lodash'; import d3 from 'd3'; diff --git a/src/legacy/ui/public/vislib/__tests__/visualizations/gauge_chart.js b/src/legacy/ui/public/vislib/__tests__/visualizations/gauge_chart.js index 09d64beb95db3..04bcad2535538 100644 --- a/src/legacy/ui/public/vislib/__tests__/visualizations/gauge_chart.js +++ b/src/legacy/ui/public/vislib/__tests__/visualizations/gauge_chart.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import $ from 'jquery'; import _ from 'lodash'; diff --git a/src/legacy/ui/public/vislib/__tests__/visualizations/heatmap_chart.js b/src/legacy/ui/public/vislib/__tests__/visualizations/heatmap_chart.js index 4fbf607e334b3..294ca49a64ecf 100644 --- a/src/legacy/ui/public/vislib/__tests__/visualizations/heatmap_chart.js +++ b/src/legacy/ui/public/vislib/__tests__/visualizations/heatmap_chart.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import _ from 'lodash'; import d3 from 'd3'; diff --git a/src/legacy/ui/public/vislib/__tests__/visualizations/line_chart.js b/src/legacy/ui/public/vislib/__tests__/visualizations/line_chart.js index 064b422897445..98133413c8d97 100644 --- a/src/legacy/ui/public/vislib/__tests__/visualizations/line_chart.js +++ b/src/legacy/ui/public/vislib/__tests__/visualizations/line_chart.js @@ -18,7 +18,7 @@ */ import d3 from 'd3'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import _ from 'lodash'; diff --git a/src/legacy/ui/public/vislib/__tests__/visualizations/pie_chart.js b/src/legacy/ui/public/vislib/__tests__/visualizations/pie_chart.js index be0527ba6f462..7ce81065d524f 100644 --- a/src/legacy/ui/public/vislib/__tests__/visualizations/pie_chart.js +++ b/src/legacy/ui/public/vislib/__tests__/visualizations/pie_chart.js @@ -18,7 +18,7 @@ */ import d3 from 'd3'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import _ from 'lodash'; import fixtures from 'fixtures/fake_hierarchical_data'; diff --git a/src/legacy/ui/public/vislib/__tests__/visualizations/time_marker.js b/src/legacy/ui/public/vislib/__tests__/visualizations/time_marker.js index c5d4cfb268ee1..1c2c0d5d5c871 100644 --- a/src/legacy/ui/public/vislib/__tests__/visualizations/time_marker.js +++ b/src/legacy/ui/public/vislib/__tests__/visualizations/time_marker.js @@ -18,7 +18,7 @@ */ import d3 from 'd3'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import series from 'fixtures/vislib/mock_data/date_histogram/_series'; import terms from 'fixtures/vislib/mock_data/terms/_columns'; diff --git a/src/legacy/ui/public/vislib/__tests__/visualizations/vis_types.js b/src/legacy/ui/public/vislib/__tests__/visualizations/vis_types.js index f4621989ab7b2..5729de277f56f 100644 --- a/src/legacy/ui/public/vislib/__tests__/visualizations/vis_types.js +++ b/src/legacy/ui/public/vislib/__tests__/visualizations/vis_types.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import _ from 'lodash'; import { VislibVisualizationsVisTypesProvider } from '../../visualizations/vis_types'; diff --git a/src/legacy/ui/public/vislib/index.js b/src/legacy/ui/public/vislib/index.js index 0d527d08a28a0..515e5fc9da7f1 100644 --- a/src/legacy/ui/public/vislib/index.js +++ b/src/legacy/ui/public/vislib/index.js @@ -19,5 +19,5 @@ import { VislibProvider } from './vislib'; -// eslint-disable-next-line @elastic/kibana-custom/no-default-export +// eslint-disable-next-line @kbn/eslint/no-default-export export default VislibProvider; diff --git a/src/legacy/ui/public/vislib/lib/layout/splits/gauge_chart/chart_split.js b/src/legacy/ui/public/vislib/lib/layout/splits/gauge_chart/chart_split.js index 906483966dc22..8e87a8be0b52c 100644 --- a/src/legacy/ui/public/vislib/lib/layout/splits/gauge_chart/chart_split.js +++ b/src/legacy/ui/public/vislib/lib/layout/splits/gauge_chart/chart_split.js @@ -19,7 +19,7 @@ import d3 from 'd3'; -// eslint-disable-next-line @elastic/kibana-custom/no-default-export +// eslint-disable-next-line @kbn/eslint/no-default-export export default function ChartSplitFactory() { /* diff --git a/src/legacy/ui/public/vislib/lib/layout/splits/gauge_chart/chart_title_split.js b/src/legacy/ui/public/vislib/lib/layout/splits/gauge_chart/chart_title_split.js index ad30bf91e9f00..331a5a60ec4fd 100644 --- a/src/legacy/ui/public/vislib/lib/layout/splits/gauge_chart/chart_title_split.js +++ b/src/legacy/ui/public/vislib/lib/layout/splits/gauge_chart/chart_title_split.js @@ -19,7 +19,7 @@ import d3 from 'd3'; -// eslint-disable-next-line @elastic/kibana-custom/no-default-export +// eslint-disable-next-line @kbn/eslint/no-default-export export default function ChartTitleSplitFactory() { /* diff --git a/src/legacy/ui/public/visualize/loader/__tests__/visualization_loader.js b/src/legacy/ui/public/visualize/loader/__tests__/visualization_loader.js index 50eb3ef3d779c..ffce391fc1a07 100644 --- a/src/legacy/ui/public/visualize/loader/__tests__/visualization_loader.js +++ b/src/legacy/ui/public/visualize/loader/__tests__/visualization_loader.js @@ -18,7 +18,7 @@ */ import $ from 'jquery'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { setupAndTeardownInjectorStub } from 'test_utils/stub_get_active_injector'; diff --git a/src/legacy/ui/public/visualize/loader/__tests__/visualize_data_loader.js b/src/legacy/ui/public/visualize/loader/__tests__/visualize_data_loader.js index 4c2e31a46d7cb..e8586c6a94a79 100644 --- a/src/legacy/ui/public/visualize/loader/__tests__/visualize_data_loader.js +++ b/src/legacy/ui/public/visualize/loader/__tests__/visualize_data_loader.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { setupAndTeardownInjectorStub } from 'test_utils/stub_get_active_injector'; diff --git a/src/legacy/ui/public/visualize/loader/__tests__/visualize_loader.js b/src/legacy/ui/public/visualize/loader/__tests__/visualize_loader.js index 515c490eca97f..67daae80ea48d 100644 --- a/src/legacy/ui/public/visualize/loader/__tests__/visualize_loader.js +++ b/src/legacy/ui/public/visualize/loader/__tests__/visualize_loader.js @@ -18,7 +18,7 @@ */ import angular from 'angular'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import sinon from 'sinon'; import { cloneDeep } from 'lodash'; diff --git a/src/legacy/ui/public/visualize/loader/embedded_visualize_handler.test.mocks.ts b/src/legacy/ui/public/visualize/loader/embedded_visualize_handler.test.mocks.ts new file mode 100644 index 0000000000000..6adea30c94fb4 --- /dev/null +++ b/src/legacy/ui/public/visualize/loader/embedded_visualize_handler.test.mocks.ts @@ -0,0 +1,67 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +jest.useFakeTimers(); + +import { EventEmitter } from 'events'; + +jest.mock('ui/notify', () => ({ + toastNotifications: jest.fn(), +})); + +jest.mock('./utils', () => ({ + queryGeohashBounds: jest.fn(), +})); + +jest.mock('./pipeline_helpers/utilities', () => ({ + getFormat: jest.fn(), + getTableAggs: jest.fn(), +})); + +export const timefilter = new EventEmitter(); +jest.doMock('../../timefilter', () => ({ timefilter })); + +jest.mock('../../inspector', () => ({ + Inspector: { + open: jest.fn(), + isAvailable: jest.fn(), + }, +})); + +export const mockDataLoaderFetch = jest.fn().mockReturnValue({ + as: 'visualization', + value: { + visType: 'histogram', + visData: {}, + visConfig: {}, + params: {}, + }, +}); +const MockDataLoader = class { + public async fetch(data: any) { + return await mockDataLoaderFetch(data); + } +}; + +jest.mock('./pipeline_data_loader', () => ({ + PipelineDataLoader: MockDataLoader, +})); +jest.mock('./visualize_data_loader', () => ({ + VisualizeDataLoader: MockDataLoader, +})); diff --git a/src/legacy/ui/public/visualize/loader/embedded_visualize_handler.test.ts b/src/legacy/ui/public/visualize/loader/embedded_visualize_handler.test.ts index 3dc39ba7e2a90..e5a4eb122dc88 100644 --- a/src/legacy/ui/public/visualize/loader/embedded_visualize_handler.test.ts +++ b/src/legacy/ui/public/visualize/loader/embedded_visualize_handler.test.ts @@ -16,61 +16,13 @@ * specific language governing permissions and limitations * under the License. */ - -jest.useFakeTimers(); - -import { EventEmitter } from 'events'; +import { mockDataLoaderFetch, timefilter } from './embedded_visualize_handler.test.mocks'; // @ts-ignore import MockState from '../../../../../fixtures/mock_state'; import { RequestHandlerParams, Vis } from '../../vis'; import { VisResponseData } from './types'; -jest.mock('ui/notify', () => ({ - toastNotifications: jest.fn(), -})); - -jest.mock('./utils', () => ({ - queryGeohashBounds: jest.fn(), -})); - -jest.mock('./pipeline_helpers/utilities', () => ({ - getFormat: jest.fn(), - getTableAggs: jest.fn(), -})); - -const timefilter = new EventEmitter(); -jest.mock('../../timefilter', () => ({ timefilter })); - -jest.mock('../../inspector', () => ({ - Inspector: { - open: jest.fn(), - isAvailable: jest.fn(), - }, -})); - -const mockDataLoaderFetch = jest.fn().mockReturnValue({ - as: 'visualization', - value: { - visType: 'histogram', - visData: {}, - visConfig: {}, - params: {}, - }, -}); -const MockDataLoader = class { - public async fetch(data: any) { - return await mockDataLoaderFetch(data); - } -}; - -jest.mock('./pipeline_data_loader', () => ({ - PipelineDataLoader: MockDataLoader, -})); -jest.mock('./visualize_data_loader', () => ({ - VisualizeDataLoader: MockDataLoader, -})); - import { Inspector } from '../../inspector'; import { EmbeddedVisualizeHandler } from './embedded_visualize_handler'; diff --git a/src/legacy/ui/public/visualize/loader/pipeline_helpers/utilities.ts b/src/legacy/ui/public/visualize/loader/pipeline_helpers/utilities.ts index fe9a36a0e5a63..3617c77e42b0f 100644 --- a/src/legacy/ui/public/visualize/loader/pipeline_helpers/utilities.ts +++ b/src/legacy/ui/public/visualize/loader/pipeline_helpers/utilities.ts @@ -31,7 +31,7 @@ import { fieldFormats } from '../../../registry/field_formats'; const config = chrome.getUiSettingsClient(); const defaultFormat = { convert: identity }; -const getConfig = (...args: any[]): any => (config.get as any)(...args); +const getConfig = (...args: any[]): any => config.get(...args); const getFieldFormat = (id: string, params: object) => { const Format = fieldFormats.byId[id]; diff --git a/src/legacy/ui/public/watch_multi/__tests__/watch_multi.js b/src/legacy/ui/public/watch_multi/__tests__/watch_multi.js index 9ad0c7787a93e..8c90b6c1dfbac 100644 --- a/src/legacy/ui/public/watch_multi/__tests__/watch_multi.js +++ b/src/legacy/ui/public/watch_multi/__tests__/watch_multi.js @@ -20,7 +20,7 @@ import _ from 'lodash'; import ngMock from 'ng_mock'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; describe('$scope.$watchMulti', function () { diff --git a/src/legacy/ui/ui_apps/__tests__/ui_app.js b/src/legacy/ui/ui_apps/__tests__/ui_app.js index 9d5a1a585d746..1e367e3d809a3 100644 --- a/src/legacy/ui/ui_apps/__tests__/ui_app.js +++ b/src/legacy/ui/ui_apps/__tests__/ui_app.js @@ -18,7 +18,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { UiApp } from '../ui_app'; import { UiNavLink } from '../../ui_nav_links'; diff --git a/src/legacy/ui/ui_bundles/__tests__/app_entry_template.js b/src/legacy/ui/ui_bundles/__tests__/app_entry_template.js index 79b57955ebd60..3a0e40073ca3e 100644 --- a/src/legacy/ui/ui_bundles/__tests__/app_entry_template.js +++ b/src/legacy/ui/ui_bundles/__tests__/app_entry_template.js @@ -18,7 +18,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { appEntryTemplate } from '../app_entry_template'; diff --git a/src/legacy/ui/ui_bundles/__tests__/ui_bundle.js b/src/legacy/ui/ui_bundles/__tests__/ui_bundle.js index f92cc79303ce6..c323e06adb599 100644 --- a/src/legacy/ui/ui_bundles/__tests__/ui_bundle.js +++ b/src/legacy/ui/ui_bundles/__tests__/ui_bundle.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { UiBundle } from '../ui_bundle'; diff --git a/src/legacy/ui/ui_bundles/app_entry_template.js b/src/legacy/ui/ui_bundles/app_entry_template.js index 2d92dc30556fb..625ce5e381d21 100644 --- a/src/legacy/ui/ui_bundles/app_entry_template.js +++ b/src/legacy/ui/ui_bundles/app_entry_template.js @@ -33,7 +33,7 @@ import 'dll/set_csp_nonce'; __webpack_nonce__ = window.__kbnNonce__; // import global polyfills -import 'babel-polyfill'; +import '@babel/polyfill'; import 'custom-event-polyfill'; import 'whatwg-fetch'; import 'abortcontroller-polyfill'; diff --git a/src/legacy/ui/ui_exports/__tests__/collect_ui_exports.js b/src/legacy/ui/ui_exports/__tests__/collect_ui_exports.js index 85b77c6f304de..de9a26814969d 100644 --- a/src/legacy/ui/ui_exports/__tests__/collect_ui_exports.js +++ b/src/legacy/ui/ui_exports/__tests__/collect_ui_exports.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { PluginPack } from '../../../plugin_discovery'; diff --git a/src/legacy/ui/ui_nav_links/__tests__/ui_nav_link.js b/src/legacy/ui/ui_nav_links/__tests__/ui_nav_link.js index be20ac0bded72..7969329256aa4 100644 --- a/src/legacy/ui/ui_nav_links/__tests__/ui_nav_link.js +++ b/src/legacy/ui/ui_nav_links/__tests__/ui_nav_link.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { UiNavLink } from '../ui_nav_link'; diff --git a/src/legacy/ui/ui_render/ui_render_mixin.js b/src/legacy/ui/ui_render/ui_render_mixin.js index de17e8d09472a..cab15b2017f42 100644 --- a/src/legacy/ui/ui_render/ui_render_mixin.js +++ b/src/legacy/ui/ui_render/ui_render_mixin.js @@ -216,7 +216,7 @@ export function uiRenderMixin(kbnServer, server, config) { // Get the list of new platform plugins. // Convert the Map into an array of objects so it is JSON serializable and order is preserved. const uiPlugins = [ - ...kbnServer.newPlatform.start.plugins.uiPlugins.public.entries() + ...kbnServer.newPlatform.setup.plugins.uiPlugins.public.entries() ].map(([id, plugin]) => ({ id, plugin })); const nonce = await generateCSPNonce(); diff --git a/src/legacy/ui/ui_settings/__tests__/lib/create_objects_client_stub.js b/src/legacy/ui/ui_settings/__tests__/lib/create_objects_client_stub.js index 6dbef853719e0..457ddd866c758 100644 --- a/src/legacy/ui/ui_settings/__tests__/lib/create_objects_client_stub.js +++ b/src/legacy/ui/ui_settings/__tests__/lib/create_objects_client_stub.js @@ -18,7 +18,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { SavedObjectsClient } from '../../../../server/saved_objects'; export const savedObjectsClientErrors = SavedObjectsClient.errors; diff --git a/src/legacy/ui/ui_settings/__tests__/ui_settings_mixin_integration.js b/src/legacy/ui/ui_settings/__tests__/ui_settings_mixin_integration.js index b3723f89ada3b..9e8413a0f99e0 100644 --- a/src/legacy/ui/ui_settings/__tests__/ui_settings_mixin_integration.js +++ b/src/legacy/ui/ui_settings/__tests__/ui_settings_mixin_integration.js @@ -18,7 +18,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { Config } from '../../../server/config'; diff --git a/src/legacy/ui/ui_settings/__tests__/ui_settings_service.js b/src/legacy/ui/ui_settings/__tests__/ui_settings_service.js index 4aa7acc5bc629..3106ba429f7ce 100644 --- a/src/legacy/ui/ui_settings/__tests__/ui_settings_service.js +++ b/src/legacy/ui/ui_settings/__tests__/ui_settings_service.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { errors as esErrors } from 'elasticsearch'; import Chance from 'chance'; import sinon from 'sinon'; diff --git a/src/legacy/ui/ui_settings/create_or_upgrade_saved_config/__tests__/create_or_upgrade_integration.js b/src/legacy/ui/ui_settings/create_or_upgrade_saved_config/__tests__/create_or_upgrade_integration.js index 4bbb715862820..55de8a32199c5 100644 --- a/src/legacy/ui/ui_settings/create_or_upgrade_saved_config/__tests__/create_or_upgrade_integration.js +++ b/src/legacy/ui/ui_settings/create_or_upgrade_saved_config/__tests__/create_or_upgrade_integration.js @@ -18,7 +18,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { startTestServers } from '../../../../../test_utils/kbn_server'; import { createOrUpgradeSavedConfig } from '../create_or_upgrade_saved_config'; diff --git a/src/legacy/ui/ui_settings/create_or_upgrade_saved_config/__tests__/create_or_upgrade_saved_config.js b/src/legacy/ui/ui_settings/create_or_upgrade_saved_config/__tests__/create_or_upgrade_saved_config.js index 8d865f81555ef..d047fd8bb2576 100644 --- a/src/legacy/ui/ui_settings/create_or_upgrade_saved_config/__tests__/create_or_upgrade_saved_config.js +++ b/src/legacy/ui/ui_settings/create_or_upgrade_saved_config/__tests__/create_or_upgrade_saved_config.js @@ -18,7 +18,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import Chance from 'chance'; import * as getUpgradeableConfigNS from '../get_upgradeable_config'; diff --git a/src/legacy/ui/ui_settings/create_or_upgrade_saved_config/__tests__/is_config_version_upgradeable.js b/src/legacy/ui/ui_settings/create_or_upgrade_saved_config/__tests__/is_config_version_upgradeable.js index 4ee79350a5e6a..734d579d23404 100644 --- a/src/legacy/ui/ui_settings/create_or_upgrade_saved_config/__tests__/is_config_version_upgradeable.js +++ b/src/legacy/ui/ui_settings/create_or_upgrade_saved_config/__tests__/is_config_version_upgradeable.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { isConfigVersionUpgradeable } from '../is_config_version_upgradeable'; import { pkg } from '../../../../utils'; diff --git a/src/legacy/ui/ui_settings/routes/__tests__/doc_exists.js b/src/legacy/ui/ui_settings/routes/__tests__/doc_exists.js index 3b1af1dea88c9..824194ae1788f 100644 --- a/src/legacy/ui/ui_settings/routes/__tests__/doc_exists.js +++ b/src/legacy/ui/ui_settings/routes/__tests__/doc_exists.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { diff --git a/src/legacy/ui/ui_settings/routes/__tests__/doc_missing.js b/src/legacy/ui/ui_settings/routes/__tests__/doc_missing.js index ee05eb7d08c0e..a1fbec8ad39df 100644 --- a/src/legacy/ui/ui_settings/routes/__tests__/doc_missing.js +++ b/src/legacy/ui/ui_settings/routes/__tests__/doc_missing.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { diff --git a/src/legacy/ui/ui_settings/routes/__tests__/doc_missing_and_index_read_only.js b/src/legacy/ui/ui_settings/routes/__tests__/doc_missing_and_index_read_only.js index fa51f61e0f97e..4ef004843054c 100644 --- a/src/legacy/ui/ui_settings/routes/__tests__/doc_missing_and_index_read_only.js +++ b/src/legacy/ui/ui_settings/routes/__tests__/doc_missing_and_index_read_only.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { diff --git a/src/legacy/utils/__tests__/kbn_field_types.js b/src/legacy/utils/__tests__/kbn_field_types.js index af4e633c98c1f..f94438b10ca58 100644 --- a/src/legacy/utils/__tests__/kbn_field_types.js +++ b/src/legacy/utils/__tests__/kbn_field_types.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import Chance from 'chance'; const chance = new Chance(); diff --git a/src/legacy/utils/__tests__/unset.js b/src/legacy/utils/__tests__/unset.js index 5540c2cc23aeb..69122e06ac572 100644 --- a/src/legacy/utils/__tests__/unset.js +++ b/src/legacy/utils/__tests__/unset.js @@ -18,7 +18,7 @@ */ import { unset } from '../unset'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; describe('unset(obj, key)', function () { describe('invalid input', function () { diff --git a/src/legacy/utils/strings/__tests__/comma_separated_list.js b/src/legacy/utils/strings/__tests__/comma_separated_list.js index a52187ef47e74..e8f16f045765a 100644 --- a/src/legacy/utils/strings/__tests__/comma_separated_list.js +++ b/src/legacy/utils/strings/__tests__/comma_separated_list.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { parseCommaSeparatedList } from '../comma_separated_list'; diff --git a/src/legacy/utils/strings/__tests__/prose.js b/src/legacy/utils/strings/__tests__/prose.js index 3655a828766f0..d99f5f196fb67 100644 --- a/src/legacy/utils/strings/__tests__/prose.js +++ b/src/legacy/utils/strings/__tests__/prose.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { formatListAsProse } from '../prose'; diff --git a/src/optimize/base_optimizer.js b/src/optimize/base_optimizer.js index deb914cf6cbe9..bb130e3869509 100644 --- a/src/optimize/base_optimizer.js +++ b/src/optimize/base_optimizer.js @@ -59,6 +59,7 @@ export default class BaseOptimizer { this.logWithMetadata = opts.logWithMetadata || (() => null); this.uiBundles = opts.uiBundles; this.profile = opts.profile || false; + this.workers = opts.workers; switch (opts.sourceMaps) { case true: @@ -122,10 +123,6 @@ export default class BaseOptimizer { BABEL_PRESET_PATH ]; - const nonDistributableOnlyModules = !IS_KIBANA_DISTRIBUTABLE - ? ['ts-loader'] - : []; - threadLoader.warmup( // pool options, like passed to loader options // must match loader options to boot the correct pool @@ -133,12 +130,15 @@ export default class BaseOptimizer { [ // modules to load on the pool ...baseModules, - ...nonDistributableOnlyModules ] ); } getThreadPoolCpuCount() { + if (this.workers) { + return this.workers; + } + const cpus = os.cpus(); if (!cpus) { // sometimes this call returns undefined so we fall back to 1: https://github.com/nodejs/node/issues/19022 @@ -363,7 +363,7 @@ export default class BaseOptimizer { } }, { - resource: createSourceFileResourceSelector(/\.js$/), + resource: createSourceFileResourceSelector(/\.(js|tsx?)$/), use: maybeAddCacheLoader('babel', [ { loader: 'thread-loader', @@ -389,7 +389,7 @@ export default class BaseOptimizer { }, resolve: { - extensions: ['.js', '.json'], + extensions: ['.js', '.ts', '.tsx', '.json'], mainFields: ['browser', 'browserify', 'main'], modules: [ 'webpackShims', @@ -424,47 +424,6 @@ export default class BaseOptimizer { ] }; - // when running from source transpile TypeScript automatically - const getSourceConfig = () => { - // dev/typescript is deleted from the distributable, so only require it if we actually need the source config - const { Project } = require('../dev/typescript'); - const browserProject = new Project(fromRoot('tsconfig.browser.json')); - - return { - module: { - rules: [ - { - resource: createSourceFileResourceSelector(/\.tsx?$/), - use: maybeAddCacheLoader('typescript', [ - { - loader: 'thread-loader', - options: this.getThreadLoaderPoolConfig() - }, - { - loader: 'ts-loader', - options: { - happyPackMode: true, - transpileOnly: true, - experimentalWatchApi: true, - onlyCompileBundledFiles: true, - configFile: fromRoot('tsconfig.json'), - compilerOptions: { - ...browserProject.config.compilerOptions, - sourceMap: Boolean(this.sourceMaps), - } - } - } - ]), - } - ] - }, - - resolve: { - extensions: ['.ts', '.tsx'], - }, - }; - }; - // We need to add react-addons (and a few other bits) for enzyme to work. // https://github.com/airbnb/enzyme/blob/master/docs/guides/webpack.md const supportEnzymeConfig = { @@ -511,7 +470,7 @@ export default class BaseOptimizer { commonConfig, IS_KIBANA_DISTRIBUTABLE ? isDistributableConfig - : getSourceConfig(), + : {}, this.uiBundles.isDevMode() ? webpackMerge(watchingConfig, supportEnzymeConfig) : productionConfig diff --git a/src/optimize/bundles_route/__tests__/bundles_route.js b/src/optimize/bundles_route/__tests__/bundles_route.js index 87638c311bca1..480e7e2a0fb8f 100644 --- a/src/optimize/bundles_route/__tests__/bundles_route.js +++ b/src/optimize/bundles_route/__tests__/bundles_route.js @@ -22,7 +22,7 @@ import { readFileSync } from 'fs'; import crypto from 'crypto'; import Chance from 'chance'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import Hapi from 'hapi'; import Inert from 'inert'; import sinon from 'sinon'; diff --git a/src/optimize/index.js b/src/optimize/index.js index 9cc62a6e1626d..e5f1e84d9733f 100644 --- a/src/optimize/index.js +++ b/src/optimize/index.js @@ -68,6 +68,7 @@ export default async (kbnServer, server, config) => { uiBundles, profile: config.get('optimize.profile'), sourceMaps: config.get('optimize.sourceMaps'), + workers: config.get('optimize.workers'), }); server.log( diff --git a/src/optimize/watch/optmzr_role.js b/src/optimize/watch/optmzr_role.js index d6b12f8c944b6..648d1b9f4e50d 100644 --- a/src/optimize/watch/optmzr_role.js +++ b/src/optimize/watch/optmzr_role.js @@ -32,13 +32,14 @@ export default async (kbnServer, kibanaHapiServer, config) => { uiBundles: kbnServer.uiBundles, profile: config.get('optimize.profile'), sourceMaps: config.get('optimize.sourceMaps'), + workers: config.get('optimize.workers'), prebuild: config.get('optimize.watchPrebuild'), watchCache: new WatchCache({ logWithMetadata, outputPath: config.get('path.data'), dllsPath: DllCompiler.getRawDllConfig().outputPath, cachePath: resolve(kbnServer.uiBundles.getCacheDirectory(), '../'), - }) + }), }); const server = new WatchServer( diff --git a/src/optimize/watch/watch_cache.ts b/src/optimize/watch/watch_cache.ts index 01afed1b2640f..ab11a8c5d2f11 100644 --- a/src/optimize/watch/watch_cache.ts +++ b/src/optimize/watch/watch_cache.ts @@ -95,16 +95,7 @@ export class WatchCache { await del(this.statePath, { force: true }); // delete everything in optimize/.cache directory - // except ts-node - await del( - await globby( - [ - normalizePosixPath(this.cachePath), - `${normalizePosixPath(`!${this.cachePath}/ts-node/**`)}`, - ], - { dot: true } - ) - ); + await del(await globby([normalizePosixPath(this.cachePath)], { dot: true })); // delete some empty folder that could be left // from the previous cache path reset action diff --git a/src/setup_node_env/babel_register/index.js b/src/setup_node_env/babel_register/index.js index 44b9427ed8e3e..1574be8937a29 100644 --- a/src/setup_node_env/babel_register/index.js +++ b/src/setup_node_env/babel_register/index.js @@ -17,16 +17,6 @@ * under the License. */ -// unless we are running a prebuilt/distributable version of -// kibana, automatically transpile typescript to js before babel -if (!global.__BUILT_WITH_BABEL__) { - var resolve = require('path').resolve; - require('ts-node').register({ - transpileOnly: true, - cacheDirectory: resolve(__dirname, '../../../optimize/.cache/ts-node') - }); -} - // register and polyfill need to happen in this // order and in separate files. Checkout each file // for a much more detailed explanation diff --git a/src/setup_node_env/babel_register/polyfill.js b/src/setup_node_env/babel_register/polyfill.js index e72a2eff001ad..4e92583f830e5 100644 --- a/src/setup_node_env/babel_register/polyfill.js +++ b/src/setup_node_env/babel_register/polyfill.js @@ -17,13 +17,13 @@ * under the License. */ -// `babel-preset-env` looks for and rewrites the following import +// `@babel/preset-env` looks for and rewrites the following import // statement into a list of import statements based on the polyfills // necessary for our target environment (the current version of node) -// but since it does that during compilation, `import 'babel-polyfill'` -// must be in a file that is loaded with `require()` AFTER `babel-register` +// but since it does that during compilation, `import '@babel/polyfill'` +// must be in a file that is loaded with `require()` AFTER `@babel/register` // is configured. // // This is why we have this single statement in it's own file and require // it from ./index.js -require('babel-polyfill'); +require('@babel/polyfill'); diff --git a/src/setup_node_env/babel_register/register.js b/src/setup_node_env/babel_register/register.js index f0898b245fb0e..217dc25a66c5c 100644 --- a/src/setup_node_env/babel_register/register.js +++ b/src/setup_node_env/babel_register/register.js @@ -19,16 +19,16 @@ var resolve = require('path').resolve; -// this must happen before `require('babel-register')` and can't be changed +// this must happen before `require('@babel/register')` and can't be changed // once the module has been loaded if (!process.env.BABEL_CACHE_PATH) { process.env.BABEL_CACHE_PATH = resolve(__dirname, '../../../optimize/.babelcache.json'); } -// paths that babel-register should ignore +// paths that @babel/register should ignore var ignore = [ - /\/bower_components\//, - /\/kbn-pm\/dist\//, + /[\/\\]bower_components[\/\\]/, + /[\/\\]kbn-pm[\/\\]dist[\/\\]/, // TODO: remove this and just transpile plugins at build time, but // has tricky edge cases that will probably require better eslint @@ -39,19 +39,19 @@ var ignore = [ // ignore paths matching `/node_modules/{a}/{b}`, unless `a` // is `x-pack` and `b` is not `node_modules` - /\/node_modules\/(?!x-pack\/(?!node_modules)([^\/]+))([^\/]+\/[^\/]+)/, + /[\/\\]node_modules[\/\\](?!x-pack[\/\\](?!node_modules)([^\/\\]+))([^\/\\]+[\/\\][^\/\\]+)/, // ignore paths matching `/canvas/canvas_plugin/` - /\/canvas\/canvas_plugin\//, + /[\/\\]canvas[\/\\]canvas_plugin[\/\\]/, ]; if (global.__BUILT_WITH_BABEL__) { // when building the Kibana source we replace the statement // `global.__BUILT_WITH_BABEL__` with the value `true` so that - // when babel-register is required for the first time by users + // when @babel/register is required for the first time by users // it will exclude kibana's `src` directory. // - // We still need babel-register for plugins though, we've been + // We still need @babel/register for plugins though, we've been // building their server code at require-time since version 4.2 // TODO: the plugin install process could transpile plugin server code... ignore.push(resolve(__dirname, '../../../src')); @@ -60,16 +60,17 @@ if (global.__BUILT_WITH_BABEL__) { // ignore any path in the packages, unless it is in the package's // root `src` directory, in any test or __tests__ directory, or it // ends with .test.js, .test.ts, or .test.tsx - /\/packages\/(eslint-|kbn-)[^\/]+\/(?!src\/.*|(.+\/)?(test|__tests__)\/.+|.+\.test\.(js|ts|tsx)$)(.+$)/ + /[\/\\]packages[\/\\](eslint-|kbn-)[^\/\\]+[\/\\](?!src[\/\\].*|(.+[\/\\])?(test|__tests__)[\/\\].+|.+\.test\.(js|ts|tsx)$)(.+$)/ ); } // modifies all future calls to require() to automatically // compile the required source with babel -require('babel-register')({ +require('@babel/register')({ ignore, babelrc: false, presets: [ require.resolve('@kbn/babel-preset/node_preset') ], + extensions: ['.js', '.ts', '.tsx'], }); diff --git a/src/setup_node_env/index.js b/src/setup_node_env/index.js index 6592fa9fd2424..a3fe8d938ba2b 100644 --- a/src/setup_node_env/index.js +++ b/src/setup_node_env/index.js @@ -17,5 +17,6 @@ * under the License. */ +require('./root'); require('./node_version_validator'); require('./babel_register'); diff --git a/src/setup_node_env/root/force.js b/src/setup_node_env/root/force.js new file mode 100644 index 0000000000000..5c5370aec6b15 --- /dev/null +++ b/src/setup_node_env/root/force.js @@ -0,0 +1,25 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +module.exports = function (argv) { + var rootIndex = argv.indexOf('--allow-root'); + var force = rootIndex >= 0; + if (force) argv.splice(rootIndex, 1); + return force; +}; diff --git a/src/setup_node_env/root/force.test.js b/src/setup_node_env/root/force.test.js new file mode 100644 index 0000000000000..df013349e57ed --- /dev/null +++ b/src/setup_node_env/root/force.test.js @@ -0,0 +1,39 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +var forceRoot = require('./force'); + +describe('forceRoot', function () { + + it('with flag', function () { + expect(forceRoot(['--allow-root'])).toBeTruthy(); + }); + + it('without flag', function () { + expect(forceRoot(['--foo'])).toBeFalsy(); + + }); + + test('remove argument', function () { + var args = ['--allow-root', 'foo']; + forceRoot(args); + expect(args.includes('--allow-root')).toBeFalsy(); + }); + +}); diff --git a/src/setup_node_env/root/index.js b/src/setup_node_env/root/index.js new file mode 100644 index 0000000000000..5a402dfcb4eeb --- /dev/null +++ b/src/setup_node_env/root/index.js @@ -0,0 +1,28 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +var force = require('./force')(process.argv); + +var uid = process.getuid && process.getuid(); +var isRoot = require('./is_root')(uid); + +if(isRoot && !force) { + console.error('Kibana should not be run as root. Use --allow-root to continue.'); + process.exit(1); +} diff --git a/src/legacy/ui/public/courier/fetch/request/segmented_search_request/index.js b/src/setup_node_env/root/is_root.js similarity index 91% rename from src/legacy/ui/public/courier/fetch/request/segmented_search_request/index.js rename to src/setup_node_env/root/is_root.js index b10169bd42eeb..e2eaaf6af5154 100644 --- a/src/legacy/ui/public/courier/fetch/request/segmented_search_request/index.js +++ b/src/setup_node_env/root/is_root.js @@ -17,4 +17,6 @@ * under the License. */ -export { SegmentedSearchRequestProvider } from './segmented_search_request'; +module.exports = function (uid) { + return uid === 0; +}; diff --git a/src/setup_node_env/root/is_root.test.js b/src/setup_node_env/root/is_root.test.js new file mode 100644 index 0000000000000..a976299cd5d5b --- /dev/null +++ b/src/setup_node_env/root/is_root.test.js @@ -0,0 +1,32 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +var isRoot = require('./is_root'); + + +describe('isRoot', function () { + + test('0 is root', function () { + expect(isRoot(0)).toBeTruthy(); + }); + + test('not 0 is not root', function () { + expect(isRoot(5)).toBeFalsy(); + }); +}); diff --git a/src/test_utils/__tests__/get_url.js b/src/test_utils/__tests__/get_url.js index b4fad9d0fa889..d071e34ee116e 100644 --- a/src/test_utils/__tests__/get_url.js +++ b/src/test_utils/__tests__/get_url.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import getUrl from '../get_url'; describe('getUrl', function () { diff --git a/src/test_utils/expect_deep_equal.js b/src/test_utils/expect_deep_equal.js index 0d4207c233b99..e3e24cbdf5dc9 100644 --- a/src/test_utils/expect_deep_equal.js +++ b/src/test_utils/expect_deep_equal.js @@ -18,7 +18,7 @@ */ import { isEqual } from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; // expect.js's `eql` method provides nice error messages but sometimes misses things // since it only tests loose (==) equality. This function uses lodash's `isEqual` as a diff --git a/src/test_utils/kbn_server.ts b/src/test_utils/kbn_server.ts index e5f63d73e9a60..5326b11852354 100644 --- a/src/test_utils/kbn_server.ts +++ b/src/test_utils/kbn_server.ts @@ -92,7 +92,7 @@ export function createRootWithSettings(...settings: Array>) */ function getSupertest(root: Root, method: HttpMethod, path: string) { const testUserCredentials = Buffer.from(`${kibanaTestUser.username}:${kibanaTestUser.password}`); - return supertest((root as any).server.http.service.httpServer.server.listener) + return supertest((root as any).server.http.httpServer.server.listener) [method](path) .set('Authorization', `Basic ${testUserCredentials.toString('base64')}`); } @@ -124,7 +124,7 @@ export function createRootWithCorePlugins(settings = {}) { * @param root */ export function getKbnServer(root: Root) { - return (root as any).server.legacy.service.kbnServer; + return (root as any).server.legacy.kbnServer; } export const request: Record< diff --git a/test/api_integration/apis/general/cookies.js b/test/api_integration/apis/general/cookies.js index d377ca1eac6ba..7791f3bde4061 100644 --- a/test/api_integration/apis/general/cookies.js +++ b/test/api_integration/apis/general/cookies.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); diff --git a/test/api_integration/apis/general/csp.js b/test/api_integration/apis/general/csp.js index 3ae7625677277..f3501aa55adaa 100644 --- a/test/api_integration/apis/general/csp.js +++ b/test/api_integration/apis/general/csp.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); diff --git a/test/api_integration/apis/home/sample_data.js b/test/api_integration/apis/home/sample_data.js index e71c98eb9679c..81fb6235520e0 100644 --- a/test/api_integration/apis/home/sample_data.js +++ b/test/api_integration/apis/home/sample_data.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { diff --git a/test/api_integration/apis/index_patterns/es_errors/errors.js b/test/api_integration/apis/index_patterns/es_errors/errors.js index 94ac82a6118dd..7e04e3f7204d7 100644 --- a/test/api_integration/apis/index_patterns/es_errors/errors.js +++ b/test/api_integration/apis/index_patterns/es_errors/errors.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { errors as esErrors } from 'elasticsearch'; import Boom from 'boom'; diff --git a/test/api_integration/apis/index_patterns/es_errors/lib/get_es_errors.js b/test/api_integration/apis/index_patterns/es_errors/lib/get_es_errors.js index da375e76d54b7..f303bca0da574 100644 --- a/test/api_integration/apis/index_patterns/es_errors/lib/get_es_errors.js +++ b/test/api_integration/apis/index_patterns/es_errors/lib/get_es_errors.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export async function getIndexNotFoundError(es) { try { diff --git a/test/api_integration/apis/index_patterns/fields_for_time_pattern_route/pattern.js b/test/api_integration/apis/index_patterns/fields_for_time_pattern_route/pattern.js index 58f5407f81de3..e0e18b4734ff6 100644 --- a/test/api_integration/apis/index_patterns/fields_for_time_pattern_route/pattern.js +++ b/test/api_integration/apis/index_patterns/fields_for_time_pattern_route/pattern.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); diff --git a/test/api_integration/apis/index_patterns/fields_for_time_pattern_route/query_params.js b/test/api_integration/apis/index_patterns/fields_for_time_pattern_route/query_params.js index c8030fd3e4e89..2201b56316657 100644 --- a/test/api_integration/apis/index_patterns/fields_for_time_pattern_route/query_params.js +++ b/test/api_integration/apis/index_patterns/fields_for_time_pattern_route/query_params.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); diff --git a/test/api_integration/apis/index_patterns/fields_for_wildcard_route/conflicts.js b/test/api_integration/apis/index_patterns/fields_for_wildcard_route/conflicts.js index f0f9d73dc6ec1..e2eebfa9e6d84 100644 --- a/test/api_integration/apis/index_patterns/fields_for_wildcard_route/conflicts.js +++ b/test/api_integration/apis/index_patterns/fields_for_wildcard_route/conflicts.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); diff --git a/test/api_integration/apis/index_patterns/fields_for_wildcard_route/response.js b/test/api_integration/apis/index_patterns/fields_for_wildcard_route/response.js index 26497d317f272..8a2af8040b2ff 100644 --- a/test/api_integration/apis/index_patterns/fields_for_wildcard_route/response.js +++ b/test/api_integration/apis/index_patterns/fields_for_wildcard_route/response.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { sortBy } from 'lodash'; export default function ({ getService }) { diff --git a/test/api_integration/apis/kql_telemetry/kql_telemetry.js b/test/api_integration/apis/kql_telemetry/kql_telemetry.js index 6ed48434064e7..b17dec2ef437b 100644 --- a/test/api_integration/apis/kql_telemetry/kql_telemetry.js +++ b/test/api_integration/apis/kql_telemetry/kql_telemetry.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import Promise from 'bluebird'; import { get } from 'lodash'; diff --git a/test/api_integration/apis/management/saved_objects/relationships.js b/test/api_integration/apis/management/saved_objects/relationships.js index e31a5fe3aaa7e..2a866245b1aa4 100644 --- a/test/api_integration/apis/management/saved_objects/relationships.js +++ b/test/api_integration/apis/management/saved_objects/relationships.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; const Joi = require('joi'); export default function ({ getService }) { diff --git a/test/api_integration/apis/saved_objects/bulk_create.js b/test/api_integration/apis/saved_objects/bulk_create.js index 44aaaf0fa55b1..e77e08d949f2b 100644 --- a/test/api_integration/apis/saved_objects/bulk_create.js +++ b/test/api_integration/apis/saved_objects/bulk_create.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); diff --git a/test/api_integration/apis/saved_objects/bulk_get.js b/test/api_integration/apis/saved_objects/bulk_get.js index da208a5cbe70a..1d129b7d738e2 100644 --- a/test/api_integration/apis/saved_objects/bulk_get.js +++ b/test/api_integration/apis/saved_objects/bulk_get.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); diff --git a/test/api_integration/apis/saved_objects/create.js b/test/api_integration/apis/saved_objects/create.js index 17b4fc55fbb4e..ccc436a757a8f 100644 --- a/test/api_integration/apis/saved_objects/create.js +++ b/test/api_integration/apis/saved_objects/create.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); diff --git a/test/api_integration/apis/saved_objects/delete.js b/test/api_integration/apis/saved_objects/delete.js index 72cf9a9cbf525..a9037bf697406 100644 --- a/test/api_integration/apis/saved_objects/delete.js +++ b/test/api_integration/apis/saved_objects/delete.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); diff --git a/test/api_integration/apis/saved_objects/export.js b/test/api_integration/apis/saved_objects/export.js index 078ecd44aa4c7..75829c7507870 100644 --- a/test/api_integration/apis/saved_objects/export.js +++ b/test/api_integration/apis/saved_objects/export.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); diff --git a/test/api_integration/apis/saved_objects/find.js b/test/api_integration/apis/saved_objects/find.js index f6e07fd4fb5c6..13722183f7720 100644 --- a/test/api_integration/apis/saved_objects/find.js +++ b/test/api_integration/apis/saved_objects/find.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); @@ -46,7 +46,17 @@ export default function ({ getService }) { attributes: { 'title': 'Count of requests' }, - references: [], + migrationVersion: { + visualization: '7.0.0', + }, + references: [ + { + id: '91200a00-9efd-11e7-acb3-3dab96693fab', + name: 'kibanaSavedObjectMeta.searchSourceJSON.index', + type: 'index-pattern', + }, + ], + updated_at: '2017-09-21T18:51:23.794Z', } ] }); diff --git a/test/api_integration/apis/saved_objects/get.js b/test/api_integration/apis/saved_objects/get.js index 0734918f5f3e4..58d12af7f9d06 100644 --- a/test/api_integration/apis/saved_objects/get.js +++ b/test/api_integration/apis/saved_objects/get.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); diff --git a/test/api_integration/apis/saved_objects/import.js b/test/api_integration/apis/saved_objects/import.js index b38109d32e7ef..19fd051e5f443 100644 --- a/test/api_integration/apis/saved_objects/import.js +++ b/test/api_integration/apis/saved_objects/import.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { join } from 'path'; export default function ({ getService }) { diff --git a/test/api_integration/apis/saved_objects/resolve_import_errors.js b/test/api_integration/apis/saved_objects/resolve_import_errors.js index adffbe03117ff..84867960a8e3b 100644 --- a/test/api_integration/apis/saved_objects/resolve_import_errors.js +++ b/test/api_integration/apis/saved_objects/resolve_import_errors.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { join } from 'path'; export default function ({ getService }) { diff --git a/test/api_integration/apis/saved_objects/update.js b/test/api_integration/apis/saved_objects/update.js index 4e56a9f120881..25a97d9e00b78 100644 --- a/test/api_integration/apis/saved_objects/update.js +++ b/test/api_integration/apis/saved_objects/update.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); diff --git a/test/api_integration/apis/scripts/languages.js b/test/api_integration/apis/scripts/languages.js index b8145f0344682..89da7ed2083ac 100644 --- a/test/api_integration/apis/scripts/languages.js +++ b/test/api_integration/apis/scripts/languages.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); diff --git a/test/api_integration/apis/search/count.js b/test/api_integration/apis/search/count.js index 1fc4cbf9b6ad1..de0d161551d95 100644 --- a/test/api_integration/apis/search/count.js +++ b/test/api_integration/apis/search/count.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const esArchiver = getService('esArchiver'); diff --git a/test/api_integration/apis/shorten/index.js b/test/api_integration/apis/shorten/index.js index fdd5421b7774f..5e6ab4c354d44 100644 --- a/test/api_integration/apis/shorten/index.js +++ b/test/api_integration/apis/shorten/index.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const esArchiver = getService('esArchiver'); diff --git a/test/api_integration/apis/stats/stats.js b/test/api_integration/apis/stats/stats.js index ef0d76e0e36a4..a02c3f1408c06 100644 --- a/test/api_integration/apis/stats/stats.js +++ b/test/api_integration/apis/stats/stats.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; const assertStatsAndMetrics = body => { expect(body.kibana.name).to.be.a('string'); diff --git a/test/api_integration/apis/status/status.js b/test/api_integration/apis/status/status.js index 08ab6fc7667a1..c0aa080ce2480 100644 --- a/test/api_integration/apis/status/status.js +++ b/test/api_integration/apis/status/status.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); diff --git a/test/api_integration/apis/user_action/user_action.js b/test/api_integration/apis/user_action/user_action.js index ca1d58d9dbb41..d0be6d6482004 100644 --- a/test/api_integration/apis/user_action/user_action.js +++ b/test/api_integration/apis/user_action/user_action.js @@ -17,8 +17,7 @@ * under the License. */ -import expect from 'expect.js'; -import { get } from 'lodash'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); @@ -35,9 +34,24 @@ export default function ({ getService }) { index: '.kibana', q: 'type:user-action', }).then(response => { - const doc = get(response, 'hits.hits[0]'); - expect(get(doc, '_source.user-action.count')).to.be(1); - expect(doc._id).to.be('user-action:myApp:myAction'); + const ids = response.hits.hits.map(({ _id }) => _id); + expect(ids.includes('user-action:myApp:myAction')); + }); + }); + + it('supports comma-delimited action types', async () => { + await supertest + .post('/api/user_action/myApp/myAction1,myAction2') + .set('kbn-xsrf', 'kibana') + .expect(200); + + return es.search({ + index: '.kibana', + q: 'type:user-action', + }).then(response => { + const ids = response.hits.hits.map(({ _id }) => _id); + expect(ids.includes('user-action:myApp:myAction1')); + expect(ids.includes('user-action:myApp:myAction2')); }); }); }); diff --git a/test/functional/apps/console/_console.ts b/test/functional/apps/console/_console.ts index d4937962a2241..1fda35f2bf1ae 100644 --- a/test/functional/apps/console/_console.ts +++ b/test/functional/apps/console/_console.ts @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; const DEFAULT_REQUEST = ` diff --git a/test/functional/apps/context/_discover_navigation.js b/test/functional/apps/context/_discover_navigation.js index 3a6c357c1ad07..19b43f5e3ffd3 100644 --- a/test/functional/apps/context/_discover_navigation.js +++ b/test/functional/apps/context/_discover_navigation.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; const TEST_DISCOVER_START_TIME = '2015-09-19 06:31:44.000'; const TEST_DISCOVER_END_TIME = '2015-09-23 18:31:44.000'; diff --git a/test/functional/apps/context/_filters.js b/test/functional/apps/context/_filters.js index fe3a16d2d42f4..6823d78e23305 100644 --- a/test/functional/apps/context/_filters.js +++ b/test/functional/apps/context/_filters.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; const TEST_INDEX_PATTERN = 'logstash-*'; const TEST_ANCHOR_TYPE = '_doc'; diff --git a/test/functional/apps/context/_size.js b/test/functional/apps/context/_size.js index 3513a2fc53768..749ab797fc6ce 100644 --- a/test/functional/apps/context/_size.js +++ b/test/functional/apps/context/_size.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; const TEST_INDEX_PATTERN = 'logstash-*'; const TEST_ANCHOR_TYPE = '_doc'; diff --git a/test/functional/apps/dashboard/bwc_shared_urls.js b/test/functional/apps/dashboard/bwc_shared_urls.js index 7c3acfba906a3..69ded31fcc1d1 100644 --- a/test/functional/apps/dashboard/bwc_shared_urls.js +++ b/test/functional/apps/dashboard/bwc_shared_urls.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const PageObjects = getPageObjects(['dashboard', 'header']); diff --git a/test/functional/apps/dashboard/create_and_add_embeddables.js b/test/functional/apps/dashboard/create_and_add_embeddables.js index c138e3462e801..84c16feef0b5a 100644 --- a/test/functional/apps/dashboard/create_and_add_embeddables.js +++ b/test/functional/apps/dashboard/create_and_add_embeddables.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { VisualizeConstants diff --git a/test/functional/apps/dashboard/dashboard_clone.js b/test/functional/apps/dashboard/dashboard_clone.js index 817d0e6dcd690..493c31578e357 100644 --- a/test/functional/apps/dashboard/dashboard_clone.js +++ b/test/functional/apps/dashboard/dashboard_clone.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const retry = getService('retry'); diff --git a/test/functional/apps/dashboard/dashboard_filter_bar.js b/test/functional/apps/dashboard/dashboard_filter_bar.js index a393a949377e1..1b29a67a0c778 100644 --- a/test/functional/apps/dashboard/dashboard_filter_bar.js +++ b/test/functional/apps/dashboard/dashboard_filter_bar.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const dashboardExpect = getService('dashboardExpect'); diff --git a/test/functional/apps/dashboard/dashboard_filtering.js b/test/functional/apps/dashboard/dashboard_filtering.js index 8c2ef2ea37a13..c3f426e7d5687 100644 --- a/test/functional/apps/dashboard/dashboard_filtering.js +++ b/test/functional/apps/dashboard/dashboard_filtering.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; /** * Test the querying capabilities of dashboard, and make sure visualizations show the expected results, especially diff --git a/test/functional/apps/dashboard/dashboard_grid.js b/test/functional/apps/dashboard/dashboard_grid.js index 6aacd82003bc4..f8eb220d60985 100644 --- a/test/functional/apps/dashboard/dashboard_grid.js +++ b/test/functional/apps/dashboard/dashboard_grid.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const browser = getService('browser'); diff --git a/test/functional/apps/dashboard/dashboard_listing.js b/test/functional/apps/dashboard/dashboard_listing.js index 2545ef1b4dae9..84ab47ae592e2 100644 --- a/test/functional/apps/dashboard/dashboard_listing.js +++ b/test/functional/apps/dashboard/dashboard_listing.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const PageObjects = getPageObjects(['dashboard', 'header', 'common']); diff --git a/test/functional/apps/dashboard/dashboard_options.js b/test/functional/apps/dashboard/dashboard_options.js index 02dc1e7a4af7b..db1c7091a78f5 100644 --- a/test/functional/apps/dashboard/dashboard_options.js +++ b/test/functional/apps/dashboard/dashboard_options.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const retry = getService('retry'); diff --git a/test/functional/apps/dashboard/dashboard_query_bar.js b/test/functional/apps/dashboard/dashboard_query_bar.js index 224ae819de8d1..f6f3b8a894518 100644 --- a/test/functional/apps/dashboard/dashboard_query_bar.js +++ b/test/functional/apps/dashboard/dashboard_query_bar.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const esArchiver = getService('esArchiver'); diff --git a/test/functional/apps/dashboard/dashboard_save.js b/test/functional/apps/dashboard/dashboard_save.js index 31b155916607a..83ddaf4804722 100644 --- a/test/functional/apps/dashboard/dashboard_save.js +++ b/test/functional/apps/dashboard/dashboard_save.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getPageObjects }) { const PageObjects = getPageObjects(['dashboard', 'header']); diff --git a/test/functional/apps/dashboard/dashboard_snapshots.js b/test/functional/apps/dashboard/dashboard_snapshots.js index 0f382f79cd09c..62c2e22546023 100644 --- a/test/functional/apps/dashboard/dashboard_snapshots.js +++ b/test/functional/apps/dashboard/dashboard_snapshots.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects, updateBaselines }) { const PageObjects = getPageObjects(['dashboard', 'header', 'visualize', 'common']); diff --git a/test/functional/apps/dashboard/dashboard_state.js b/test/functional/apps/dashboard/dashboard_state.js index ed8999eb5977e..ca50e81d924e5 100644 --- a/test/functional/apps/dashboard/dashboard_state.js +++ b/test/functional/apps/dashboard/dashboard_state.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { PIE_CHART_VIS_NAME, AREA_CHART_VIS_NAME } from '../../page_objects/dashboard_page'; import { diff --git a/test/functional/apps/dashboard/dashboard_time.js b/test/functional/apps/dashboard/dashboard_time.js index b34d061f608a0..8ce77f7ee46f5 100644 --- a/test/functional/apps/dashboard/dashboard_time.js +++ b/test/functional/apps/dashboard/dashboard_time.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; const dashboardName = 'Dashboard Test Time'; diff --git a/test/functional/apps/dashboard/data_shared_attributes.js b/test/functional/apps/dashboard/data_shared_attributes.js index 27ac2184071f8..8a760b6f35d01 100644 --- a/test/functional/apps/dashboard/data_shared_attributes.js +++ b/test/functional/apps/dashboard/data_shared_attributes.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const retry = getService('retry'); diff --git a/test/functional/apps/dashboard/embed_mode.js b/test/functional/apps/dashboard/embed_mode.js index 22fb42108ce2c..f5b99bf30ca95 100644 --- a/test/functional/apps/dashboard/embed_mode.js +++ b/test/functional/apps/dashboard/embed_mode.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const retry = getService('retry'); diff --git a/test/functional/apps/dashboard/embeddable_rendering.js b/test/functional/apps/dashboard/embeddable_rendering.js index 716d169c490b9..614a66c4f473c 100644 --- a/test/functional/apps/dashboard/embeddable_rendering.js +++ b/test/functional/apps/dashboard/embeddable_rendering.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; /** * This tests both that one of each visualization can be added to a dashboard (as opposed to opening an existing @@ -91,7 +91,8 @@ export default function ({ getService, getPageObjects }) { await dashboardExpect.vegaTextsDoNotExist(['5,000']); }; - describe('dashboard embeddable rendering', function describeIndexTests() { + // FLAKY: https://github.com/elastic/kibana/issues/33504 + describe.skip('dashboard embeddable rendering', function describeIndexTests() { before(async () => { await PageObjects.dashboard.clickNewDashboard(); diff --git a/test/functional/apps/dashboard/empty_dashboard.js b/test/functional/apps/dashboard/empty_dashboard.js index 36f57d48c5100..26745ed61910a 100644 --- a/test/functional/apps/dashboard/empty_dashboard.js +++ b/test/functional/apps/dashboard/empty_dashboard.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const testSubjects = getService('testSubjects'); diff --git a/test/functional/apps/dashboard/full_screen_mode.js b/test/functional/apps/dashboard/full_screen_mode.js index 68bb2f58be8d0..0475c40eff0c4 100644 --- a/test/functional/apps/dashboard/full_screen_mode.js +++ b/test/functional/apps/dashboard/full_screen_mode.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const retry = getService('retry'); diff --git a/test/functional/apps/dashboard/panel_controls.js b/test/functional/apps/dashboard/panel_controls.js index 39f1eca464947..c5c98f191421a 100644 --- a/test/functional/apps/dashboard/panel_controls.js +++ b/test/functional/apps/dashboard/panel_controls.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { PIE_CHART_VIS_NAME } from '../../page_objects/dashboard_page'; import { diff --git a/test/functional/apps/dashboard/panel_expand_toggle.js b/test/functional/apps/dashboard/panel_expand_toggle.js index af74fe6a48290..e61d4f4015a09 100644 --- a/test/functional/apps/dashboard/panel_expand_toggle.js +++ b/test/functional/apps/dashboard/panel_expand_toggle.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const retry = getService('retry'); diff --git a/test/functional/apps/dashboard/time_zones.js b/test/functional/apps/dashboard/time_zones.js index 514b0366d19bb..10f91448c3705 100644 --- a/test/functional/apps/dashboard/time_zones.js +++ b/test/functional/apps/dashboard/time_zones.js @@ -18,7 +18,7 @@ */ import path from 'path'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const pieChart = getService('pieChart'); diff --git a/test/functional/apps/dashboard/view_edit.js b/test/functional/apps/dashboard/view_edit.js index 7851d5320f2e3..edef26dbc2d34 100644 --- a/test/functional/apps/dashboard/view_edit.js +++ b/test/functional/apps/dashboard/view_edit.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const queryBar = getService('queryBar'); diff --git a/test/functional/apps/discover/_discover.js b/test/functional/apps/discover/_discover.js index d4167b5cfae7e..e6c783a801564 100644 --- a/test/functional/apps/discover/_discover.js +++ b/test/functional/apps/discover/_discover.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const log = getService('log'); diff --git a/test/functional/apps/discover/_errors.js b/test/functional/apps/discover/_errors.js index 87cdba3d9ed68..060639d5c49bc 100644 --- a/test/functional/apps/discover/_errors.js +++ b/test/functional/apps/discover/_errors.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const esArchiver = getService('esArchiver'); diff --git a/test/functional/apps/discover/_field_data.js b/test/functional/apps/discover/_field_data.js index d295a502094ab..dc2c1b468f985 100644 --- a/test/functional/apps/discover/_field_data.js +++ b/test/functional/apps/discover/_field_data.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const retry = getService('retry'); diff --git a/test/functional/apps/discover/_inspector.js b/test/functional/apps/discover/_inspector.js index 5b269ef6902d4..6a2144e829920 100644 --- a/test/functional/apps/discover/_inspector.js +++ b/test/functional/apps/discover/_inspector.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const PageObjects = getPageObjects(['common', 'visualize', 'timePicker']); diff --git a/test/functional/apps/discover/_large_string.js b/test/functional/apps/discover/_large_string.js index 9feed7c9202e9..426779bd0c495 100644 --- a/test/functional/apps/discover/_large_string.js +++ b/test/functional/apps/discover/_large_string.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const esArchiver = getService('esArchiver'); diff --git a/test/functional/apps/discover/_shared_links.js b/test/functional/apps/discover/_shared_links.js index bfe90cf17003c..4b85593d1f02c 100644 --- a/test/functional/apps/discover/_shared_links.js +++ b/test/functional/apps/discover/_shared_links.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const retry = getService('retry'); diff --git a/test/functional/apps/discover/_sidebar.js b/test/functional/apps/discover/_sidebar.js index 865b0ea7d71b7..26a47b0a12422 100644 --- a/test/functional/apps/discover/_sidebar.js +++ b/test/functional/apps/discover/_sidebar.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const log = getService('log'); diff --git a/test/functional/apps/discover/_source_filters.js b/test/functional/apps/discover/_source_filters.js index a230c5625ac8d..14ecde383fd44 100644 --- a/test/functional/apps/discover/_source_filters.js +++ b/test/functional/apps/discover/_source_filters.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const log = getService('log'); diff --git a/test/functional/apps/getting_started/_shakespeare.js b/test/functional/apps/getting_started/_shakespeare.js index 4dd7639001104..39bb6acb7494e 100644 --- a/test/functional/apps/getting_started/_shakespeare.js +++ b/test/functional/apps/getting_started/_shakespeare.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const log = getService('log'); diff --git a/test/functional/apps/home/_add_data.js b/test/functional/apps/home/_add_data.js index f6cf02e518260..7b6fa5c1614de 100644 --- a/test/functional/apps/home/_add_data.js +++ b/test/functional/apps/home/_add_data.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const retry = getService('retry'); diff --git a/test/functional/apps/home/_home.js b/test/functional/apps/home/_home.js index 3eaa0c5bdef1c..f4a9b53d89ecb 100644 --- a/test/functional/apps/home/_home.js +++ b/test/functional/apps/home/_home.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { diff --git a/test/functional/apps/home/_navigation.js b/test/functional/apps/home/_navigation.js index c31b3a6100cd2..cc297856e0458 100644 --- a/test/functional/apps/home/_navigation.js +++ b/test/functional/apps/home/_navigation.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { diff --git a/test/functional/apps/home/_sample_data.js b/test/functional/apps/home/_sample_data.js index 700eea39f4613..e77996224094f 100644 --- a/test/functional/apps/home/_sample_data.js +++ b/test/functional/apps/home/_sample_data.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const retry = getService('retry'); diff --git a/test/functional/apps/management/_create_index_pattern_wizard.js b/test/functional/apps/management/_create_index_pattern_wizard.js index 5cde83bed5f99..3539fd975b746 100644 --- a/test/functional/apps/management/_create_index_pattern_wizard.js +++ b/test/functional/apps/management/_create_index_pattern_wizard.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const kibanaServer = getService('kibanaServer'); diff --git a/test/functional/apps/management/_handle_alias.js b/test/functional/apps/management/_handle_alias.js index 7a866a0274bcb..1556897d69387 100644 --- a/test/functional/apps/management/_handle_alias.js +++ b/test/functional/apps/management/_handle_alias.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const esArchiver = getService('esArchiver'); diff --git a/test/functional/apps/management/_handle_version_conflict.js b/test/functional/apps/management/_handle_version_conflict.js index 722e855edf3ac..ce5f968a37115 100644 --- a/test/functional/apps/management/_handle_version_conflict.js +++ b/test/functional/apps/management/_handle_version_conflict.js @@ -27,7 +27,7 @@ */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const esArchiver = getService('esArchiver'); diff --git a/test/functional/apps/management/_import_objects.js b/test/functional/apps/management/_import_objects.js index d7659e6859e77..73e5e7e0cecb3 100644 --- a/test/functional/apps/management/_import_objects.js +++ b/test/functional/apps/management/_import_objects.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import path from 'path'; export default function ({ getService, getPageObjects }) { @@ -41,7 +41,6 @@ export default function ({ getService, getPageObjects }) { it('should import saved objects', async function () { await PageObjects.settings.clickKibanaSavedObjects(); await PageObjects.settings.importFile(path.join(__dirname, 'exports', '_import_objects.json')); - await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.settings.clickImportDone(); await PageObjects.settings.waitUntilSavedObjectsTableIsNotLoading(); const objects = await PageObjects.settings.getSavedObjectsInTable(); @@ -52,7 +51,6 @@ export default function ({ getService, getPageObjects }) { it('should provide dialog to allow the importing of saved objects with index pattern conflicts', async function () { await PageObjects.settings.clickKibanaSavedObjects(); await PageObjects.settings.importFile(path.join(__dirname, 'exports', '_import_objects-conflicts.json')); - await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.settings.associateIndexPattern('d1e4c910-a2e6-11e7-bb30-233be9be6a15', 'logstash-*'); await PageObjects.settings.clickConfirmChanges(); await PageObjects.header.waitUntilLoadingHasFinished(); @@ -70,7 +68,6 @@ export default function ({ getService, getPageObjects }) { // so that we can override the existing visualization. await PageObjects.settings.importFile(path.join(__dirname, 'exports', '_import_objects_exists.json'), false); - await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.settings.associateIndexPattern('logstash-*', 'logstash-*'); await PageObjects.settings.clickConfirmChanges(); @@ -88,7 +85,6 @@ export default function ({ getService, getPageObjects }) { // so that we can be prompted to override the existing visualization. await PageObjects.settings.importFile(path.join(__dirname, 'exports', '_import_objects_exists.json'), false); - await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.settings.associateIndexPattern('logstash-*', 'logstash-*'); await PageObjects.settings.clickConfirmChanges(); @@ -102,13 +98,11 @@ export default function ({ getService, getPageObjects }) { it('should import saved objects linked to saved searches', async function () { await PageObjects.settings.clickKibanaSavedObjects(); await PageObjects.settings.importFile(path.join(__dirname, 'exports', '_import_objects_saved_search.json')); - await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.settings.clickImportDone(); await PageObjects.settings.navigateTo(); await PageObjects.settings.clickKibanaSavedObjects(); await PageObjects.settings.importFile(path.join(__dirname, 'exports', '_import_objects_connected_to_saved_search.json')); - await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.settings.clickImportDone(); await PageObjects.settings.waitUntilSavedObjectsTableIsNotLoading(); @@ -121,7 +115,6 @@ export default function ({ getService, getPageObjects }) { await PageObjects.settings.navigateTo(); await PageObjects.settings.clickKibanaSavedObjects(); await PageObjects.settings.importFile(path.join(__dirname, 'exports', '_import_objects_connected_to_saved_search.json')); - await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.settings.clickImportDone(); await PageObjects.settings.waitUntilSavedObjectsTableIsNotLoading(); @@ -134,8 +127,6 @@ export default function ({ getService, getPageObjects }) { // First, import the saved search await PageObjects.settings.clickKibanaSavedObjects(); await PageObjects.settings.importFile(path.join(__dirname, 'exports', '_import_objects_saved_search.json')); - // Wait for all the saves to happen - await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.settings.clickImportDone(); // Second, we need to delete the index pattern @@ -149,8 +140,6 @@ export default function ({ getService, getPageObjects }) { await PageObjects.settings.navigateTo(); await PageObjects.settings.clickKibanaSavedObjects(); await PageObjects.settings.importFile(path.join(__dirname, 'exports', '_import_objects_connected_to_saved_search.json')); - // Wait for all the saves to happen - await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.settings.clickImportDone(); await PageObjects.settings.waitUntilSavedObjectsTableIsNotLoading(); @@ -163,7 +152,6 @@ export default function ({ getService, getPageObjects }) { // First, import the objects await PageObjects.settings.clickKibanaSavedObjects(); await PageObjects.settings.importFile(path.join(__dirname, 'exports', '_import_objects_with_index_patterns.json')); - await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.settings.clickImportDone(); // Wait for all the saves to happen await PageObjects.settings.waitUntilSavedObjectsTableIsNotLoading(); @@ -183,7 +171,6 @@ export default function ({ getService, getPageObjects }) { // Then, import the objects await PageObjects.settings.clickKibanaSavedObjects(); await PageObjects.settings.importFile(path.join(__dirname, 'exports', '_import_objects_with_index_patterns.json')); - await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.settings.clickImportDone(); // Wait for all the saves to happen await PageObjects.settings.waitUntilSavedObjectsTableIsNotLoading(); diff --git a/test/functional/apps/management/_index_pattern_create_delete.js b/test/functional/apps/management/_index_pattern_create_delete.js index 251a17ec1bfdc..b49bdd5bf738f 100644 --- a/test/functional/apps/management/_index_pattern_create_delete.js +++ b/test/functional/apps/management/_index_pattern_create_delete.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const kibanaServer = getService('kibanaServer'); diff --git a/test/functional/apps/management/_index_pattern_filter.js b/test/functional/apps/management/_index_pattern_filter.js index a27d52d75b35f..0985639ac3c97 100644 --- a/test/functional/apps/management/_index_pattern_filter.js +++ b/test/functional/apps/management/_index_pattern_filter.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const kibanaServer = getService('kibanaServer'); diff --git a/test/functional/apps/management/_index_pattern_popularity.js b/test/functional/apps/management/_index_pattern_popularity.js index 32ee0a8934c48..72f368c9c714b 100644 --- a/test/functional/apps/management/_index_pattern_popularity.js +++ b/test/functional/apps/management/_index_pattern_popularity.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const kibanaServer = getService('kibanaServer'); diff --git a/test/functional/apps/management/_index_pattern_results_sort.js b/test/functional/apps/management/_index_pattern_results_sort.js index f8cfb55db0014..d834ad0c1dfd4 100644 --- a/test/functional/apps/management/_index_pattern_results_sort.js +++ b/test/functional/apps/management/_index_pattern_results_sort.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const kibanaServer = getService('kibanaServer'); diff --git a/test/functional/apps/management/_kibana_settings.js b/test/functional/apps/management/_kibana_settings.js index 08cdfa3494e81..084523e006157 100644 --- a/test/functional/apps/management/_kibana_settings.js +++ b/test/functional/apps/management/_kibana_settings.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const kibanaServer = getService('kibanaServer'); diff --git a/test/functional/apps/management/_mgmt_import_saved_objects.js b/test/functional/apps/management/_mgmt_import_saved_objects.js index e2bfd89f07544..973e394078c40 100644 --- a/test/functional/apps/management/_mgmt_import_saved_objects.js +++ b/test/functional/apps/management/_mgmt_import_saved_objects.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import path from 'path'; export default function ({ getService, getPageObjects }) { @@ -41,7 +41,6 @@ export default function ({ getService, getPageObjects }) { await PageObjects.settings.clickKibanaSavedObjects(); await PageObjects.settings.importFile(path.join(__dirname, 'exports', 'mgmt_import_objects.json')); - await PageObjects.header.waitUntilLoadingHasFinished(); await PageObjects.settings.associateIndexPattern('4c3f3c30-ac94-11e8-a651-614b2788174a', 'logstash-*'); await PageObjects.settings.clickConfirmChanges(); await PageObjects.settings.clickImportDone(); diff --git a/test/functional/apps/management/_scripted_fields.js b/test/functional/apps/management/_scripted_fields.js index 86e7ab7b51a30..a3077e965dd4c 100644 --- a/test/functional/apps/management/_scripted_fields.js +++ b/test/functional/apps/management/_scripted_fields.js @@ -29,7 +29,7 @@ // 3. Filter in Discover by the scripted field // 4. Visualize with aggregation on the scripted field by clicking discover.clickFieldListItemVisualize -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const kibanaServer = getService('kibanaServer'); diff --git a/test/functional/apps/management/_scripted_fields_filter.js b/test/functional/apps/management/_scripted_fields_filter.js index 21be262e1809b..8783e5a10c195 100644 --- a/test/functional/apps/management/_scripted_fields_filter.js +++ b/test/functional/apps/management/_scripted_fields_filter.js @@ -18,7 +18,7 @@ */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const kibanaServer = getService('kibanaServer'); diff --git a/test/functional/apps/management/_scripted_fields_preview.js b/test/functional/apps/management/_scripted_fields_preview.js index 093d242ba3681..f6f2de7c793d1 100644 --- a/test/functional/apps/management/_scripted_fields_preview.js +++ b/test/functional/apps/management/_scripted_fields_preview.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const browser = getService('browser'); diff --git a/test/functional/apps/management/_test_huge_fields.js b/test/functional/apps/management/_test_huge_fields.js index 3fde7937a769d..57b65c33055db 100644 --- a/test/functional/apps/management/_test_huge_fields.js +++ b/test/functional/apps/management/_test_huge_fields.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const esArchiver = getService('esArchiver'); diff --git a/test/functional/apps/status_page/index.js b/test/functional/apps/status_page/index.js index 52d26cd9f3a45..34f2df287dd6b 100644 --- a/test/functional/apps/status_page/index.js +++ b/test/functional/apps/status_page/index.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const retry = getService('retry'); diff --git a/test/functional/apps/timelion/_expression_typeahead.js b/test/functional/apps/timelion/_expression_typeahead.js index aca178a906a86..7cc0740823f3c 100644 --- a/test/functional/apps/timelion/_expression_typeahead.js +++ b/test/functional/apps/timelion/_expression_typeahead.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getPageObjects }) { const PageObjects = getPageObjects(['common', 'timelion', 'settings', 'timePicker']); diff --git a/test/functional/apps/visualize/_area_chart.js b/test/functional/apps/visualize/_area_chart.js index 1fffbc2759355..1799a72e5eb11 100644 --- a/test/functional/apps/visualize/_area_chart.js +++ b/test/functional/apps/visualize/_area_chart.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const log = getService('log'); diff --git a/test/functional/apps/visualize/_chart_types.js b/test/functional/apps/visualize/_chart_types.js index 0912e1536e87a..596c3001285f3 100644 --- a/test/functional/apps/visualize/_chart_types.js +++ b/test/functional/apps/visualize/_chart_types.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const log = getService('log'); diff --git a/test/functional/apps/visualize/_data_table.js b/test/functional/apps/visualize/_data_table.js index 16942dc26e57e..02fa7dd62711c 100644 --- a/test/functional/apps/visualize/_data_table.js +++ b/test/functional/apps/visualize/_data_table.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const log = getService('log'); diff --git a/test/functional/apps/visualize/_data_table_nontimeindex.js b/test/functional/apps/visualize/_data_table_nontimeindex.js index eeb58c197c0b5..102b70ca8a6bc 100644 --- a/test/functional/apps/visualize/_data_table_nontimeindex.js +++ b/test/functional/apps/visualize/_data_table_nontimeindex.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const log = getService('log'); diff --git a/test/functional/apps/visualize/_embedding_chart.js b/test/functional/apps/visualize/_embedding_chart.js index b6caa77d32406..0b59699d47755 100644 --- a/test/functional/apps/visualize/_embedding_chart.js +++ b/test/functional/apps/visualize/_embedding_chart.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const filterBar = getService('filterBar'); diff --git a/test/functional/apps/visualize/_experimental_vis.js b/test/functional/apps/visualize/_experimental_vis.js index 6cce432fd2c31..386185cd9fcc5 100644 --- a/test/functional/apps/visualize/_experimental_vis.js +++ b/test/functional/apps/visualize/_experimental_vis.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default ({ getService, getPageObjects }) => { const log = getService('log'); diff --git a/test/functional/apps/visualize/_gauge_chart.js b/test/functional/apps/visualize/_gauge_chart.js index 080f3eaf52eb6..d58a2cab872bb 100644 --- a/test/functional/apps/visualize/_gauge_chart.js +++ b/test/functional/apps/visualize/_gauge_chart.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const log = getService('log'); diff --git a/test/functional/apps/visualize/_heatmap_chart.js b/test/functional/apps/visualize/_heatmap_chart.js index 795cfbe0e0763..075585b4216f4 100644 --- a/test/functional/apps/visualize/_heatmap_chart.js +++ b/test/functional/apps/visualize/_heatmap_chart.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const log = getService('log'); diff --git a/test/functional/apps/visualize/_histogram_request_start.js b/test/functional/apps/visualize/_histogram_request_start.js index 95eda5003e7f5..e1642c1383fbe 100644 --- a/test/functional/apps/visualize/_histogram_request_start.js +++ b/test/functional/apps/visualize/_histogram_request_start.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const log = getService('log'); diff --git a/test/functional/apps/visualize/_input_control_vis.js b/test/functional/apps/visualize/_input_control_vis.js index 8afdaccf42320..a10c0284b3e7f 100644 --- a/test/functional/apps/visualize/_input_control_vis.js +++ b/test/functional/apps/visualize/_input_control_vis.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const filterBar = getService('filterBar'); diff --git a/test/functional/apps/visualize/_lab_mode.js b/test/functional/apps/visualize/_lab_mode.js index d45d9cc636622..68440c68e358a 100644 --- a/test/functional/apps/visualize/_lab_mode.js +++ b/test/functional/apps/visualize/_lab_mode.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const log = getService('log'); diff --git a/test/functional/apps/visualize/_line_chart.js b/test/functional/apps/visualize/_line_chart.js index 350168006227f..e291e58780bd3 100644 --- a/test/functional/apps/visualize/_line_chart.js +++ b/test/functional/apps/visualize/_line_chart.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const log = getService('log'); diff --git a/test/functional/apps/visualize/_linked_saved_searches.js b/test/functional/apps/visualize/_linked_saved_searches.js index 9a80126f5447c..5343873e9e0a5 100644 --- a/test/functional/apps/visualize/_linked_saved_searches.js +++ b/test/functional/apps/visualize/_linked_saved_searches.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const filterBar = getService('filterBar'); diff --git a/test/functional/apps/visualize/_markdown_vis.js b/test/functional/apps/visualize/_markdown_vis.js index 7d6ee24083c49..4fca691153b36 100644 --- a/test/functional/apps/visualize/_markdown_vis.js +++ b/test/functional/apps/visualize/_markdown_vis.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getPageObjects, getService }) { const PageObjects = getPageObjects(['common', 'visualize', 'header']); diff --git a/test/functional/apps/visualize/_metric_chart.js b/test/functional/apps/visualize/_metric_chart.js index fbece9f724814..9046935285534 100644 --- a/test/functional/apps/visualize/_metric_chart.js +++ b/test/functional/apps/visualize/_metric_chart.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const log = getService('log'); diff --git a/test/functional/apps/visualize/_pie_chart.js b/test/functional/apps/visualize/_pie_chart.js index 853cabef206f4..583f8328a29ec 100644 --- a/test/functional/apps/visualize/_pie_chart.js +++ b/test/functional/apps/visualize/_pie_chart.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const log = getService('log'); diff --git a/test/functional/apps/visualize/_point_series_options.js b/test/functional/apps/visualize/_point_series_options.js index 5d5729e75cafb..8e01b87309a07 100644 --- a/test/functional/apps/visualize/_point_series_options.js +++ b/test/functional/apps/visualize/_point_series_options.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const log = getService('log'); diff --git a/test/functional/apps/visualize/_region_map.js b/test/functional/apps/visualize/_region_map.js index f724e0029fd7e..053e1bafdbe64 100644 --- a/test/functional/apps/visualize/_region_map.js +++ b/test/functional/apps/visualize/_region_map.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { diff --git a/test/functional/apps/visualize/_shared_item.js b/test/functional/apps/visualize/_shared_item.js index 85861f21a69d5..9fe38be15a741 100644 --- a/test/functional/apps/visualize/_shared_item.js +++ b/test/functional/apps/visualize/_shared_item.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const log = getService('log'); diff --git a/test/functional/apps/visualize/_tag_cloud.js b/test/functional/apps/visualize/_tag_cloud.js index 693e435e810b4..116c5d10019e8 100644 --- a/test/functional/apps/visualize/_tag_cloud.js +++ b/test/functional/apps/visualize/_tag_cloud.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const filterBar = getService('filterBar'); diff --git a/test/functional/apps/visualize/_tile_map.js b/test/functional/apps/visualize/_tile_map.js index a739ae857717f..7d097214c3389 100644 --- a/test/functional/apps/visualize/_tile_map.js +++ b/test/functional/apps/visualize/_tile_map.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const log = getService('log'); diff --git a/test/functional/apps/visualize/_tsvb_chart.ts b/test/functional/apps/visualize/_tsvb_chart.ts index 6cb5ab6807f51..8018c69bdec20 100644 --- a/test/functional/apps/visualize/_tsvb_chart.ts +++ b/test/functional/apps/visualize/_tsvb_chart.ts @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; // tslint:disable-next-line:no-default-export diff --git a/test/functional/apps/visualize/_tsvb_markdown.ts b/test/functional/apps/visualize/_tsvb_markdown.ts index 55a5f6f79dc2b..3e62eba78a528 100644 --- a/test/functional/apps/visualize/_tsvb_markdown.ts +++ b/test/functional/apps/visualize/_tsvb_markdown.ts @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; // tslint:disable-next-line:no-default-export diff --git a/test/functional/apps/visualize/_vega_chart.js b/test/functional/apps/visualize/_vega_chart.js index 1e7fe5b2fce2f..186318ebe6325 100644 --- a/test/functional/apps/visualize/_vega_chart.js +++ b/test/functional/apps/visualize/_vega_chart.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const PageObjects = getPageObjects(['common', 'header', 'timePicker', 'visualize']); diff --git a/test/functional/apps/visualize/_vertical_bar_chart.js b/test/functional/apps/visualize/_vertical_bar_chart.js index b5e7bd122560d..54cda5a9ed8b6 100644 --- a/test/functional/apps/visualize/_vertical_bar_chart.js +++ b/test/functional/apps/visualize/_vertical_bar_chart.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const log = getService('log'); diff --git a/test/functional/apps/visualize/_vertical_bar_chart_nontimeindex.js b/test/functional/apps/visualize/_vertical_bar_chart_nontimeindex.js index 992521094fe71..e845742036e80 100644 --- a/test/functional/apps/visualize/_vertical_bar_chart_nontimeindex.js +++ b/test/functional/apps/visualize/_vertical_bar_chart_nontimeindex.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const log = getService('log'); diff --git a/test/functional/apps/visualize/_visualize_listing.js b/test/functional/apps/visualize/_visualize_listing.js index 016514c70fad6..fda15510b4691 100644 --- a/test/functional/apps/visualize/_visualize_listing.js +++ b/test/functional/apps/visualize/_visualize_listing.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getPageObjects }) { const PageObjects = getPageObjects(['visualize', 'header', 'common']); diff --git a/test/functional/page_objects/common_page.js b/test/functional/page_objects/common_page.js index 9962aa2049431..90a8689cfb514 100644 --- a/test/functional/page_objects/common_page.js +++ b/test/functional/page_objects/common_page.js @@ -18,7 +18,7 @@ */ import { delay } from 'bluebird'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import getUrl from '../../../src/test_utils/get_url'; diff --git a/test/functional/page_objects/discover_page.js b/test/functional/page_objects/discover_page.js index 531fd9f984a0b..502dbf5de17cb 100644 --- a/test/functional/page_objects/discover_page.js +++ b/test/functional/page_objects/discover_page.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export function DiscoverPageProvider({ getService, getPageObjects }) { const log = getService('log'); diff --git a/test/functional/page_objects/home_page.js b/test/functional/page_objects/home_page.js index 7c0d2f7faba63..008a3dff69c0f 100644 --- a/test/functional/page_objects/home_page.js +++ b/test/functional/page_objects/home_page.js @@ -60,9 +60,9 @@ export function HomePageProvider({ getService }) { async _waitForSampleDataLoadingAction(id) { const sampleDataCard = await testSubjects.find(`sampleDataSetCard${id}`); await retry.try(async () => { - // waitForDeletedByClassName needs to be inside retry because it will timeout at least once + // waitForDeletedByCssSelector needs to be inside retry because it will timeout at least once // before action is complete - await sampleDataCard.waitForDeletedByClassName('euiLoadingSpinner'); + await sampleDataCard.waitForDeletedByCssSelector('.euiLoadingSpinner'); }); } diff --git a/test/functional/page_objects/settings_page.js b/test/functional/page_objects/settings_page.js index fa2be9eb9f28e..2e728db3b388d 100644 --- a/test/functional/page_objects/settings_page.js +++ b/test/functional/page_objects/settings_page.js @@ -18,7 +18,7 @@ */ import { map as mapAsync } from 'bluebird'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; export function SettingsPageProvider({ getService, getPageObjects }) { const log = getService('log'); @@ -555,6 +555,9 @@ export function SettingsPageProvider({ getService, getPageObjects }) { } await testSubjects.click('importSavedObjectsImportBtn'); log.debug(`done importing the file`); + + // Wait for all the saves to happen + await PageObjects.header.waitUntilLoadingHasFinished(); } async clickImportDone() { diff --git a/test/functional/page_objects/share_page.js b/test/functional/page_objects/share_page.js index 777482b55771b..b9be3faae640b 100644 --- a/test/functional/page_objects/share_page.js +++ b/test/functional/page_objects/share_page.js @@ -56,7 +56,7 @@ export function SharePageProvider({ getService, getPageObjects }) { async checkShortenUrl() { const shareForm = await testSubjects.find('shareUrlForm'); await PageObjects.visualize.checkCheckbox('useShortUrl'); - await shareForm.waitForDeletedByClassName('euiLoadingSpinner'); + await shareForm.waitForDeletedByCssSelector('.euiLoadingSpinner'); } async exportAsSavedObject() { diff --git a/test/functional/page_objects/visualize_page.js b/test/functional/page_objects/visualize_page.js index d7506442aabc8..94f951bd793c1 100644 --- a/test/functional/page_objects/visualize_page.js +++ b/test/functional/page_objects/visualize_page.js @@ -19,7 +19,7 @@ import { VisualizeConstants } from '../../../src/legacy/core_plugins/kibana/public/visualize/visualize_constants'; import Bluebird from 'bluebird'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; export function VisualizePageProvider({ getService, getPageObjects, updateBaselines }) { const browser = getService('browser'); @@ -34,6 +34,7 @@ export function VisualizePageProvider({ getService, getPageObjects, updateBaseli const globalNav = getService('globalNav'); const PageObjects = getPageObjects(['common', 'header']); const defaultFindTimeout = config.get('timeouts.find'); + const comboBox = getService('comboBox'); class VisualizePage { @@ -431,19 +432,14 @@ export function VisualizePageProvider({ getService, getPageObjects, updateBaseli } async selectAggregation(myString, groupName = 'buckets', childAggregationType = null) { - const selector = ` + const comboBoxElement = await find.byCssSelector(` [group-name="${groupName}"] vis-editor-agg-params:not(.ng-hide) ${childAggregationType ? `vis-editor-agg-params[group-name="'${childAggregationType}'"]:not(.ng-hide)` : ''} - .agg-select - `; + [data-test-subj="defaultEditorAggSelect"] + `); - await retry.try(async () => { - await find.clickByCssSelector(selector); - const input = await find.byCssSelector(`${selector} input.ui-select-search`); - await input.type(myString); - await input.pressKeys(browser.keys.RETURN); - }); + await comboBox.setElement(comboBoxElement, myString); await PageObjects.common.sleep(500); } @@ -481,13 +477,12 @@ export function VisualizePageProvider({ getService, getPageObjects, updateBaseli // So to modify a metric or aggregation tests need to keep track of the // order they are added. await this.toggleOpenEditor(index); - const aggSelect = await find - .byCssSelector(`#visAggEditorParams${index} div [data-test-subj="visEditorAggSelect"] div span[aria-label="Select box activate"]`); - // open agg selection list - await aggSelect.click(); + // select our agg - const aggItem = await find.byCssSelector(`[data-test-subj="${agg}"]`); - await aggItem.click(); + const aggSelect = await find + .byCssSelector(`#visAggEditorParams${index} [data-test-subj="defaultEditorAggSelect"]`); + await comboBox.setElement(aggSelect, agg); + const fieldSelect = await find .byCssSelector(`#visAggEditorParams${index} > [agg-param="agg.type.params[0]"] > div > div > div.ui-select-match > span`); // open field selection list diff --git a/test/functional/services/combo_box.js b/test/functional/services/combo_box.js index b60556bacfd94..297e0ee6abaaf 100644 --- a/test/functional/services/combo_box.js +++ b/test/functional/services/combo_box.js @@ -36,7 +36,20 @@ export function ComboBoxProvider({ getService }) { log.debug(`comboBox.setElement, value: ${value}`); await this._filterOptionsList(comboBoxElement, value); await this.openOptionsList(comboBoxElement); - await find.clickByCssSelector('.euiComboBoxOption'); + + if (value !== undefined) { + const options = await find.allByCssSelector(`.euiComboBoxOption[title^="${value.toString().trim()}"]`); + + if (options.length > 0) { + await options[0].click(); + } else { + // if it doesn't find the item which text starts with value, it will choose the first option + await find.clickByCssSelector('.euiComboBoxOption'); + } + } else { + await find.clickByCssSelector('.euiComboBoxOption'); + } + await this.closeOptionsList(comboBoxElement); } @@ -56,7 +69,7 @@ export function ComboBoxProvider({ getService }) { } async _waitForOptionsListLoading(comboBoxElement) { - await comboBoxElement.waitForDeletedByClassName('euiLoadingSpinner'); + await comboBoxElement.waitForDeletedByCssSelector('.euiLoadingSpinner'); } async getOptionsList(comboBoxSelector) { diff --git a/test/functional/services/dashboard/add_panel.js b/test/functional/services/dashboard/add_panel.js index 7f3cbf564ce94..79067b98ac2f7 100644 --- a/test/functional/services/dashboard/add_panel.js +++ b/test/functional/services/dashboard/add_panel.js @@ -104,9 +104,7 @@ export function DashboardAddPanelProvider({ getService, getPageObjects }) { } async waitForListLoading() { - await retry.waitFor('dashboard add panel loading to complete', async () => { - return !(await testSubjects.exists('savedObjectFinderLoadingIndicator')); - }); + await testSubjects.waitForDeleted('savedObjectFinderLoadingIndicator'); } async closeAddPanel() { @@ -148,15 +146,7 @@ export function DashboardAddPanelProvider({ getService, getPageObjects }) { } async addSavedSearch(searchName) { - log.debug(`addSavedSearch(${searchName})`); - - await this.ensureAddPanelIsShowing(); - await this.toggleFilter('search'); - await this.filterEmbeddableNames(searchName); - - await testSubjects.click(`savedObjectTitle${searchName.split(' ').join('-')}`); - await testSubjects.exists('addObjectToDashboardSuccess'); - await this.closeAddPanel(); + return this.addEmbeddable(searchName, 'search'); } async addSavedSearches(searches) { @@ -176,14 +166,18 @@ export function DashboardAddPanelProvider({ getService, getPageObjects }) { } async addVisualization(vizName) { - log.debug(`DashboardAddPanel.addVisualization(${vizName})`); + return this.addEmbeddable(vizName, 'visualization'); + } + + async addEmbeddable(embeddableName, embeddableType) { + log.debug(`DashboardAddPanel.addEmbeddable, name: ${embeddableName}, type: ${embeddableType}`); await this.ensureAddPanelIsShowing(); - await this.toggleFilter('visualization'); - await this.filterEmbeddableNames(`"${vizName.replace('-', ' ')}"`); - await testSubjects.click(`savedObjectTitle${vizName.split(' ').join('-')}`); + await this.toggleFilter(embeddableType); + await this.filterEmbeddableNames(`"${embeddableName.replace('-', ' ')}"`); + await testSubjects.click(`savedObjectTitle${embeddableName.split(' ').join('-')}`); await testSubjects.exists('addObjectToDashboardSuccess'); await this.closeAddPanel(); - return vizName; + return embeddableName; } async filterEmbeddableNames(name) { diff --git a/test/functional/services/dashboard/expectations.js b/test/functional/services/dashboard/expectations.js index e8f85251eefa9..cd610e8a5f02d 100644 --- a/test/functional/services/dashboard/expectations.js +++ b/test/functional/services/dashboard/expectations.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export function DashboardExpectProvider({ getService, getPageObjects }) { const log = getService('log'); diff --git a/test/functional/services/find.js b/test/functional/services/find.js index f16765fd03f7e..16802b5f27078 100644 --- a/test/functional/services/find.js +++ b/test/functional/services/find.js @@ -309,12 +309,14 @@ export async function FindProvider({ getService }) { } async waitForDeletedByCssSelector(selector, timeout = defaultFindTimeout) { log.debug(`Find.waitForDeletedByCssSelector('${selector}') with timeout=${timeout}`); + await this._withTimeout(1000); await driver.wait(async () => { const found = await driver.findElements(By.css(selector)); return found.length === 0; }, timeout, `The element ${selector} was still present when it should have disappeared.`); + await this._withTimeout(defaultFindTimeout); } async waitForAttributeToChange(selector, attribute, value) { diff --git a/test/functional/services/inspector.js b/test/functional/services/inspector.js index eb0de451b2400..8a3c54b6556a7 100644 --- a/test/functional/services/inspector.js +++ b/test/functional/services/inspector.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export function InspectorProvider({ getService }) { const log = getService('log'); diff --git a/test/functional/services/lib/web_element_wrapper/scroll_into_view_if_necessary.js b/test/functional/services/lib/web_element_wrapper/scroll_into_view_if_necessary.js index e135294ab95f4..75a690871c534 100644 --- a/test/functional/services/lib/web_element_wrapper/scroll_into_view_if_necessary.js +++ b/test/functional/services/lib/web_element_wrapper/scroll_into_view_if_necessary.js @@ -1,4 +1,4 @@ -/* eslint-disable @kbn/license-header/require-license-header */ +/* eslint-disable @kbn/eslint/require-license-header */ /** * @notice diff --git a/test/functional/services/lib/web_element_wrapper/web_element_wrapper.js b/test/functional/services/lib/web_element_wrapper/web_element_wrapper.js index 8e96c3af0cc9b..be9c88fda1aa1 100644 --- a/test/functional/services/lib/web_element_wrapper/web_element_wrapper.js +++ b/test/functional/services/lib/web_element_wrapper/web_element_wrapper.js @@ -389,22 +389,20 @@ export class WebElementWrapper { } /** - * Waits for all elements inside this element matching the given CSS class name to be destroyed. + * Waits for all elements inside this element matching the given CSS selector to be destroyed. * * @param {string} className * @return {Promise} */ - async waitForDeletedByClassName(className) { - await this._driver.wait(() => { - return this._webElement.findElements(this._By.className(className)).then((children) => { - if (children.length <= 0) { - return true; - } - return false; - }); + async waitForDeletedByCssSelector(selector) { + await this._driver.manage().setTimeouts({ implicit: 1000 }); + await this._driver.wait(async () => { + const found = await this._webElement.findElements(this._By.css(selector)); + return found.length === 0; }, this._defaultFindTimeout, - `The element with ${className} className was still present when it should have disappeared.`); + `The element with ${selector} selector was still present after ${this._defaultFindTimeout} sec.`); + await this._driver.manage().setTimeouts({ implicit: this._defaultFindTimeout }); } /** diff --git a/test/functional/services/remote/__tests__/remote_default_window_size.js b/test/functional/services/remote/__tests__/remote_default_window_size.js index ffa66bcc7c892..c5ef5fcc3d035 100644 --- a/test/functional/services/remote/__tests__/remote_default_window_size.js +++ b/test/functional/services/remote/__tests__/remote_default_window_size.js @@ -19,7 +19,7 @@ import { fork } from 'child_process'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; const FTR_SCRIPT = require.resolve('../../../../../scripts/functional_test_runner'); const CONFIG_PATH = require.resolve('./fixtures/several_nested_window_size_changes/config.js'); diff --git a/test/functional/services/snapshots.js b/test/functional/services/snapshots.js index b19149a8a1af0..131be48dd3b1b 100644 --- a/test/functional/services/snapshots.js +++ b/test/functional/services/snapshots.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { dirname, resolve } from 'path'; import { writeFile, readFileSync } from 'fs'; import { fromNode as fcb, promisify } from 'bluebird'; diff --git a/test/functional/services/visualizations/pie_chart.js b/test/functional/services/visualizations/pie_chart.js index c5d0d68dec399..cad3f4a589b44 100644 --- a/test/functional/services/visualizations/pie_chart.js +++ b/test/functional/services/visualizations/pie_chart.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export function PieChartProvider({ getService }) { const log = getService('log'); diff --git a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/package.json b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/package.json index 55adf625481e4..ce2d0111c50bb 100644 --- a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/package.json +++ b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/package.json @@ -7,7 +7,7 @@ }, "license": "Apache-2.0", "dependencies": { - "@elastic/eui": "9.4.0", + "@elastic/eui": "9.7.1", "react": "^16.8.0", "react-dom": "^16.8.0" } diff --git a/test/interpreter_functional/test_suites/run_pipeline/basic.js b/test/interpreter_functional/test_suites/run_pipeline/basic.js index d1ca3240fef19..183fb8e2f1db1 100644 --- a/test/interpreter_functional/test_suites/run_pipeline/basic.js +++ b/test/interpreter_functional/test_suites/run_pipeline/basic.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { expectExpressionProvider } from './helpers'; // this file showcases how to use testing utilities defined in helpers.js together with the kbn_tp_run_pipeline diff --git a/test/interpreter_functional/test_suites/run_pipeline/helpers.js b/test/interpreter_functional/test_suites/run_pipeline/helpers.js index 8d8f65bd8d8e6..aacdf1f615bd7 100644 --- a/test/interpreter_functional/test_suites/run_pipeline/helpers.js +++ b/test/interpreter_functional/test_suites/run_pipeline/helpers.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; // helper for testing interpreter expressions export const expectExpressionProvider = ({ getService, updateBaselines }) => { diff --git a/test/plugin_functional/plugins/kbn_tp_custom_visualizations/package.json b/test/plugin_functional/plugins/kbn_tp_custom_visualizations/package.json index 181865ed3ac52..d1491583bc0d5 100644 --- a/test/plugin_functional/plugins/kbn_tp_custom_visualizations/package.json +++ b/test/plugin_functional/plugins/kbn_tp_custom_visualizations/package.json @@ -7,7 +7,7 @@ }, "license": "Apache-2.0", "dependencies": { - "@elastic/eui": "9.4.0", + "@elastic/eui": "9.7.1", "react": "^16.8.0" } } diff --git a/test/plugin_functional/plugins/kbn_tp_sample_panel_action/index.js b/test/plugin_functional/plugins/kbn_tp_sample_panel_action/index.ts similarity index 75% rename from test/plugin_functional/plugins/kbn_tp_sample_panel_action/index.js rename to test/plugin_functional/plugins/kbn_tp_sample_panel_action/index.ts index c4aaaa857cecd..dd069010e0742 100644 --- a/test/plugin_functional/plugins/kbn_tp_sample_panel_action/index.js +++ b/test/plugin_functional/plugins/kbn_tp_sample_panel_action/index.ts @@ -17,8 +17,15 @@ * under the License. */ -function samplePanelAction(kibana) { +import { resolve } from 'path'; + +// TODO: use something better once https://github.com/elastic/kibana/issues/26555 is +// figured out. +type KibanaPlugin = any; + +function samplePanelAction(kibana: KibanaPlugin) { return new kibana.Plugin({ + publicDir: resolve(__dirname, './public'), uiExports: { contextMenuActions: [ 'plugins/kbn_tp_sample_panel_action/sample_panel_action', @@ -28,9 +35,6 @@ function samplePanelAction(kibana) { }); } -module.exports = function (kibana) { - return [ - samplePanelAction(kibana), - ]; +module.exports = (kibana: KibanaPlugin) => { + return [samplePanelAction(kibana)]; }; - diff --git a/test/plugin_functional/plugins/kbn_tp_sample_panel_action/package.json b/test/plugin_functional/plugins/kbn_tp_sample_panel_action/package.json index ae68ac4f5c543..dad6a74d14362 100644 --- a/test/plugin_functional/plugins/kbn_tp_sample_panel_action/package.json +++ b/test/plugin_functional/plugins/kbn_tp_sample_panel_action/package.json @@ -1,13 +1,22 @@ { "name": "kbn_tp_sample_panel_action", "version": "1.0.0", + "main":"target/test/plugin_functional/plugins/kbn_tp_sample_panel_action", "kibana": { "version": "kibana", "templateVersion": "1.0.0" }, "license": "Apache-2.0", "dependencies": { - "@elastic/eui": "9.4.0", + "@elastic/eui": "9.7.1", "react": "^16.8.0" + }, + "scripts": { + "kbn": "node ../../../../scripts/kbn.js", + "build": "rm -rf './target' && tsc" + }, + "devDependencies": { + "@kbn/plugin-helpers" : "9.0.2", + "typescript": "^3.3.3333" } } diff --git a/test/plugin_functional/plugins/kbn_tp_sample_panel_action/public/sample_panel_action.js b/test/plugin_functional/plugins/kbn_tp_sample_panel_action/public/sample_panel_action.tsx similarity index 93% rename from test/plugin_functional/plugins/kbn_tp_sample_panel_action/public/sample_panel_action.js rename to test/plugin_functional/plugins/kbn_tp_sample_panel_action/public/sample_panel_action.tsx index 1310ff027e35e..41c867b5526d5 100644 --- a/test/plugin_functional/plugins/kbn_tp_sample_panel_action/public/sample_panel_action.js +++ b/test/plugin_functional/plugins/kbn_tp_sample_panel_action/public/sample_panel_action.tsx @@ -23,6 +23,7 @@ import { openFlyout } from 'ui/flyout'; import { ContextMenuAction, ContextMenuActionsRegistryProvider, + PanelActionAPI, } from 'ui/embeddable'; class SamplePanelAction extends ContextMenuAction { @@ -33,7 +34,10 @@ class SamplePanelAction extends ContextMenuAction { parentPanelId: 'mainMenu', }); } - onClick({ embeddable }) { + public onClick = ({ embeddable }: PanelActionAPI) => { + if (!embeddable) { + return; + } openFlyout( @@ -47,9 +51,9 @@ class SamplePanelAction extends ContextMenuAction { , { 'data-test-subj': 'samplePanelActionFlyout', - }, + } ); - } + }; } ContextMenuActionsRegistryProvider.register(() => new SamplePanelAction()); diff --git a/test/plugin_functional/plugins/kbn_tp_sample_panel_action/public/sample_panel_link.js b/test/plugin_functional/plugins/kbn_tp_sample_panel_action/public/sample_panel_link.ts similarity index 90% rename from test/plugin_functional/plugins/kbn_tp_sample_panel_action/public/sample_panel_link.js rename to test/plugin_functional/plugins/kbn_tp_sample_panel_action/public/sample_panel_link.ts index 0b99b7eadb3c7..7092c783125d9 100644 --- a/test/plugin_functional/plugins/kbn_tp_sample_panel_action/public/sample_panel_link.js +++ b/test/plugin_functional/plugins/kbn_tp_sample_panel_action/public/sample_panel_link.ts @@ -16,10 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { - ContextMenuAction, - ContextMenuActionsRegistryProvider, -} from 'ui/embeddable'; +import { ContextMenuAction, ContextMenuActionsRegistryProvider } from 'ui/embeddable'; class SamplePanelLink extends ContextMenuAction { constructor() { @@ -29,9 +26,10 @@ class SamplePanelLink extends ContextMenuAction { parentPanelId: 'mainMenu', }); } - getHref() { + + public getHref = () => { return 'https://example.com/kibana/test'; - } + }; } ContextMenuActionsRegistryProvider.register(() => new SamplePanelLink()); diff --git a/test/plugin_functional/plugins/kbn_tp_sample_panel_action/tsconfig.json b/test/plugin_functional/plugins/kbn_tp_sample_panel_action/tsconfig.json new file mode 100644 index 0000000000000..aba7203377aff --- /dev/null +++ b/test/plugin_functional/plugins/kbn_tp_sample_panel_action/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "outDir": "./target", + "skipLibCheck": true + }, + "include": [ + "index.ts", + "public/**/*.ts", + "public/**/*.tsx", + "../../../../typings/**/*", + ], + "exclude": [] +} \ No newline at end of file diff --git a/test/plugin_functional/plugins/kbn_tp_visualize_embedding/package.json b/test/plugin_functional/plugins/kbn_tp_visualize_embedding/package.json index 6286abc45f06f..9051a0e79c857 100644 --- a/test/plugin_functional/plugins/kbn_tp_visualize_embedding/package.json +++ b/test/plugin_functional/plugins/kbn_tp_visualize_embedding/package.json @@ -7,7 +7,7 @@ }, "license": "Apache-2.0", "dependencies": { - "@elastic/eui": "9.4.0", + "@elastic/eui": "9.7.1", "react": "^16.8.0", "react-dom": "^16.8.0" } diff --git a/test/plugin_functional/test_suites/app_plugins/app_navigation.js b/test/plugin_functional/test_suites/app_plugins/app_navigation.js index 1adcde72e1aa3..a6c5b9542f568 100644 --- a/test/plugin_functional/test_suites/app_plugins/app_navigation.js +++ b/test/plugin_functional/test_suites/app_plugins/app_navigation.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const appsMenu = getService('appsMenu'); diff --git a/test/plugin_functional/test_suites/custom_visualizations/self_changing_vis.js b/test/plugin_functional/test_suites/custom_visualizations/self_changing_vis.js index dee2515f9bd25..74519b8117b6f 100644 --- a/test/plugin_functional/test_suites/custom_visualizations/self_changing_vis.js +++ b/test/plugin_functional/test_suites/custom_visualizations/self_changing_vis.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const testSubjects = getService('testSubjects'); diff --git a/test/plugin_functional/test_suites/embedding_visualizations/embed_by_id.js b/test/plugin_functional/test_suites/embedding_visualizations/embed_by_id.js index bd0866882c1fc..dbcf859906dcc 100644 --- a/test/plugin_functional/test_suites/embedding_visualizations/embed_by_id.js +++ b/test/plugin_functional/test_suites/embedding_visualizations/embed_by_id.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { delay } from 'bluebird'; export default function ({ getService }) { diff --git a/test/plugin_functional/test_suites/panel_actions/panel_actions.js b/test/plugin_functional/test_suites/panel_actions/panel_actions.js index 0202fb1f5d534..d7152e0885157 100644 --- a/test/plugin_functional/test_suites/panel_actions/panel_actions.js +++ b/test/plugin_functional/test_suites/panel_actions/panel_actions.js @@ -17,7 +17,7 @@ * under the License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const dashboardPanelActions = getService('dashboardPanelActions'); diff --git a/test/scripts/jenkins_ci_group.sh b/test/scripts/jenkins_ci_group.sh index c9eec36cdc743..a4bc597316dcb 100755 --- a/test/scripts/jenkins_ci_group.sh +++ b/test/scripts/jenkins_ci_group.sh @@ -22,6 +22,10 @@ export TEST_BROWSER_HEADLESS=1 "$(FORCE_COLOR=0 yarn bin)/grunt" "run:functionalTests_ciGroup${CI_GROUP}"; if [ "$CI_GROUP" == "1" ]; then - "$(FORCE_COLOR=0 yarn bin)/grunt" run:pluginFunctionalTestsRelease; + # build kbn_tp_sample_panel_action + cd test/plugin_functional/plugins/kbn_tp_sample_panel_action; + yarn build; + cd -; + "$(FORCE_COLOR=0 yarn bin)/grunt" run:pluginFunctionalTestsRelease --from=source; "$(FORCE_COLOR=0 yarn bin)/grunt" run:interpreterFunctionalTestsRelease; fi diff --git a/test/tsconfig.json b/test/tsconfig.json index f72d03a94f26b..d620d28f3d1de 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -3,11 +3,14 @@ "compilerOptions": { "types": [ "node", - "mocha", - "@kbn/test/types/expect.js" + "mocha" ] }, "include": [ - "**/*.ts" + "**/*.ts", + "**/*.tsx", + ], + "exclude": [ + "plugin_functional/plugins/**/*" ] } diff --git a/tsconfig.json b/tsconfig.json index 59f963b038b8b..d9750b3f259d3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -53,8 +53,7 @@ "types": [ "node", "jest", - "react", - "@kbn/test/types/expect.js" + "react" ] }, "include": [ diff --git a/tslint.yaml b/tslint.yaml index c914787ec7a68..c6447271a7107 100644 --- a/tslint.yaml +++ b/tslint.yaml @@ -67,3 +67,7 @@ rules: * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ + module-migration: + - true + - from: expect.js + to: '@kbn/expect' diff --git a/x-pack/common/__tests__/poller.js b/x-pack/common/__tests__/poller.js index 681a70c56280e..1e82fcc367286 100644 --- a/x-pack/common/__tests__/poller.js +++ b/x-pack/common/__tests__/poller.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { Poller } from '../poller'; diff --git a/x-pack/dev-tools/jest/create_jest_config.js b/x-pack/dev-tools/jest/create_jest_config.js index bf20e88333787..ad5b2fde1acfe 100644 --- a/x-pack/dev-tools/jest/create_jest_config.js +++ b/x-pack/dev-tools/jest/create_jest_config.js @@ -37,8 +37,7 @@ export function createJestConfig({ '**/*.test.{js,ts,tsx}' ], transform: { - '^.+\\.js$': `${kibanaDirectory}/src/dev/jest/babel_transform.js`, - '^.+\\.tsx?$': `${kibanaDirectory}/src/dev/jest/ts_transform.js`, + '^.+\\.(js|tsx?)$': `${kibanaDirectory}/src/dev/jest/babel_transform.js`, }, transformIgnorePatterns: [ '[/\\\\]node_modules[/\\\\].+\\.js$' diff --git a/x-pack/package.json b/x-pack/package.json index 413b9ad22be2e..f79e9eeaf5658 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -27,6 +27,7 @@ "devDependencies": { "@kbn/dev-utils": "1.0.0", "@kbn/es": "1.0.0", + "@kbn/expect": "1.0.0", "@kbn/plugin-helpers": "9.0.2", "@kbn/test": "1.0.0", "@storybook/addon-actions": "^4.1.7", @@ -43,8 +44,8 @@ "@types/d3-array": "^1.2.1", "@types/d3-scale": "^2.0.0", "@types/d3-shape": "^1.3.1", - "@types/d3-time": "^1.0.7", "@types/d3-time-format": "^2.1.0", + "@types/d3-time": "^1.0.7", "@types/elasticsearch": "^5.0.30", "@types/graphql": "^0.13.1", "@types/history": "^4.6.2", @@ -54,12 +55,13 @@ "@types/jsonwebtoken": "^7.2.7", "@types/lodash": "^3.10.1", "@types/mocha": "^5.2.6", + "@types/object-hash": "^1.2.0", "@types/pngjs": "^3.3.1", "@types/prop-types": "^15.5.3", - "@types/react": "^16.8.0", "@types/react-dom": "^16.8.0", "@types/react-redux": "^6.0.6", "@types/react-router-dom": "^4.3.1", + "@types/react": "^16.8.0", "@types/recompose": "^0.30.2", "@types/reduce-reducers": "^0.1.3", "@types/sinon": "^5.0.1", @@ -73,11 +75,11 @@ "ansi-colors": "^3.0.5", "ansicolors": "0.3.2", "axios": "^0.18.0", - "babel-jest": "^23.6.0", - "babel-plugin-inline-react-svg": "^0.5.4", - "babel-plugin-mock-imports": "^0.0.5", - "babel-plugin-require-context-hook": "^1.0.0", - "babel-plugin-transform-react-remove-prop-types": "^0.4.14", + "babel-jest": "^24.1.0", + "babel-plugin-inline-react-svg": "^1.0.1", + "babel-plugin-mock-imports": "^1.0.1", + "babel-plugin-require-context-hook": "npm:babel-plugin-require-context-hook-babel7@^1.0.0", + "babel-plugin-transform-react-remove-prop-types": "^0.4.24", "chalk": "^2.4.1", "chance": "1.0.10", "checksum": "0.1.1", @@ -90,7 +92,6 @@ "enzyme-adapter-utils": "^1.10.0", "enzyme-to-json": "^3.3.4", "execa": "^1.0.0", - "expect.js": "0.3.1", "fancy-log": "^1.3.2", "fetch-mock": "7.3.0", "graphql-code-generator": "^0.13.0", @@ -115,7 +116,9 @@ "proxyquire": "1.7.11", "react-docgen-typescript-loader": "^3.0.0", "react-docgen-typescript-webpack-plugin": "^1.1.0", + "react-hooks-testing-library": "^0.3.8", "react-test-renderer": "^16.8.0", + "react-testing-library": "^6.0.0", "redux-test-utils": "0.2.2", "rsync": "0.4.0", "run-sequence": "^2.2.1", @@ -128,15 +131,18 @@ "supertest-as-promised": "^4.0.2", "tmp": "0.0.31", "tree-kill": "^1.1.0", - "ts-loader": "^5.2.2", "typescript": "^3.3.3333", "vinyl-fs": "^3.0.2", "xml-crypto": "^0.10.1", "yargs": "4.8.1" }, "dependencies": { + "@babel/core": "^7.3.4", + "@babel/polyfill": "^7.2.5", + "@babel/register": "^7.0.0", + "@babel/runtime": "^7.3.4", "@elastic/datemath": "5.0.2", - "@elastic/eui": "9.5.0", + "@elastic/eui": "9.7.1", "@elastic/node-crypto": "0.1.2", "@elastic/numeral": "2.3.2", "@kbn/babel-preset": "1.0.0", @@ -160,11 +166,6 @@ "apollo-server-errors": "^2.0.2", "apollo-server-hapi": "^1.3.6", "axios": "^0.18.0", - "babel-core": "^6.26.3", - "babel-polyfill": "6.20.0", - "babel-preset-es2015": "^6.24.1", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", "base64-js": "^1.2.1", "bluebird": "3.5.3", "boom": "^7.2.0", @@ -228,6 +229,7 @@ "ngreact": "^0.5.1", "node-fetch": "^2.1.2", "nodemailer": "^4.6.4", + "object-hash": "^1.3.1", "object-path-immutable": "^0.5.3", "oppsy": "^2.0.0", "papaparse": "^4.6.0", diff --git a/x-pack/plugins/__mocks__/ui/chrome.js b/x-pack/plugins/__mocks__/ui/chrome.js index e56124bede6e1..b85d345a68ce3 100644 --- a/x-pack/plugins/__mocks__/ui/chrome.js +++ b/x-pack/plugins/__mocks__/ui/chrome.js @@ -15,10 +15,14 @@ function getUiSettingsClient() { default: throw new Error(`Unexpected config key: ${key}`); } - } + }, }; } +function getBasePath() { + return '/some/base/path'; +} + function addBasePath(path) { return path; } @@ -43,6 +47,7 @@ function getXsrfToken() { export default { getInjected, addBasePath, + getBasePath, getUiSettingsClient, - getXsrfToken + getXsrfToken, }; diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.test.tsx b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.test.tsx index b265efb818f3f..f0ffb072c8338 100644 --- a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.test.tsx +++ b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.test.tsx @@ -7,8 +7,6 @@ import { shallow } from 'enzyme'; import { Location } from 'history'; import React from 'react'; -import { RRRRenderResponse } from 'react-redux-request'; -import { ErrorGroupAPIResponse } from 'x-pack/plugins/apm/server/lib/errors/get_error_group'; import { APMError } from 'x-pack/plugins/apm/typings/es_schemas/ui/APMError'; import { mockMoment } from '../../../../utils/testHelpers'; import { DetailView } from './index'; @@ -31,21 +29,17 @@ describe('DetailView', () => { }); it('should render Discover button', () => { - const errorGroup: RRRRenderResponse = { - args: [], - status: 'SUCCESS', - data: { - occurrencesCount: 10, - error: ({ - '@timestamp': 'myTimestamp', - http: { request: { method: 'GET' } }, - url: { full: 'myUrl' }, - service: { name: 'myService' }, - user: { id: 'myUserId' }, - error: { exception: { handled: true } }, - transaction: { id: 'myTransactionId', sampled: true } - } as unknown) as APMError - } + const errorGroup = { + occurrencesCount: 10, + error: ({ + '@timestamp': 'myTimestamp', + http: { request: { method: 'GET' } }, + url: { full: 'myUrl' }, + service: { name: 'myService' }, + user: { id: 'myUserId' }, + error: { exception: { handled: true } }, + transaction: { id: 'myTransactionId', sampled: true } + } as unknown) as APMError }; const wrapper = shallow( { }); it('should render StickyProperties', () => { - const errorGroup: RRRRenderResponse = { - args: [], - status: 'SUCCESS', - data: { - occurrencesCount: 10, - error: {} as APMError - } + const errorGroup = { + occurrencesCount: 10, + error: {} as APMError }; const wrapper = shallow( { }); it('should render tabs', () => { - const errorGroup: RRRRenderResponse = { - args: [], - status: 'SUCCESS', - data: { - occurrencesCount: 10, - error: ({ - '@timestamp': 'myTimestamp', - service: {}, - user: {} - } as unknown) as APMError - } + const errorGroup = { + occurrencesCount: 10, + error: ({ + '@timestamp': 'myTimestamp', + service: {}, + user: {} + } as unknown) as APMError }; const wrapper = shallow( { }); it('should render TabContent', () => { - const errorGroup: RRRRenderResponse = { - args: [], - status: 'SUCCESS', - data: { - occurrencesCount: 10, - error: ({ - '@timestamp': 'myTimestamp', - context: {} - } as unknown) as APMError - } + const errorGroup = { + occurrencesCount: 10, + error: ({ + '@timestamp': 'myTimestamp', + context: {} + } as unknown) as APMError }; const wrapper = shallow( ; + errorGroup: ErrorGroupAPIResponse; urlParams: IUrlParams; location: Location; } export function DetailView({ errorGroup, urlParams, location }: Props) { - if (errorGroup.status !== STATUS.SUCCESS) { - return null; - } - const { transaction, error, occurrencesCount } = errorGroup.data; + const { transaction, error, occurrencesCount } = errorGroup; if (!error) { return null; diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/view.tsx b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/view.tsx index 170ac689239e2..8b1130a605f11 100644 --- a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/view.tsx +++ b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/view.tsx @@ -20,8 +20,11 @@ import React, { Fragment } from 'react'; import styled from 'styled-components'; import { NOT_AVAILABLE_LABEL } from 'x-pack/plugins/apm/common/i18n'; import { idx } from 'x-pack/plugins/apm/common/idx'; -import { ErrorDistributionRequest } from '../../../store/reactReduxRequest/errorDistribution'; -import { ErrorGroupDetailsRequest } from '../../../store/reactReduxRequest/errorGroup'; +import { useFetcher } from '../../../hooks/useFetcher'; +import { + loadErrorDistribution, + loadErrorGroupDetails +} from '../../../services/rest/apm/error_groups'; import { IUrlParams } from '../../../store/urlParams'; import { fontFamilyCode, fontSizes, px, units } from '../../../style/variables'; // @ts-ignore @@ -64,124 +67,117 @@ interface Props { } export function ErrorGroupDetailsView({ urlParams, location }: Props) { + const { serviceName, start, end, errorGroupId } = urlParams; + + const { data: errorGroupData } = useFetcher( + () => loadErrorGroupDetails({ serviceName, start, end, errorGroupId }), + [serviceName, start, end, errorGroupId] + ); + + const { data: errorDistributionData } = useFetcher( + () => loadErrorDistribution({ serviceName, start, end }), + [serviceName, start, end] + ); + + if (!errorGroupData || !errorDistributionData) { + return null; + } + + // If there are 0 occurrences, show only distribution chart w. empty message + const showDetails = errorGroupData.occurrencesCount !== 0; + const logMessage = idx(errorGroupData, _ => _.error.error.log.message); + const excMessage = idx( + errorGroupData, + _ => _.error.error.exception[0].message + ); + const culprit = idx(errorGroupData, _ => _.error.error.culprit); + const isUnhandled = + idx(errorGroupData, _ => _.error.error.exception[0].handled) === false; + return ( - { - // If there are 0 occurrences, show only distribution chart w. empty message - const showDetails = errorGroup.data.occurrencesCount !== 0; - const logMessage = idx(errorGroup, _ => _.data.error.error.log.message); - const excMessage = idx( - errorGroup, - _ => _.data.error.error.exception[0].message - ); - const culprit = idx(errorGroup, _ => _.data.error.error.culprit); - const isUnhandled = - idx(errorGroup, _ => _.data.error.error.exception[0].handled) === - false; - - return ( -
- - - -

- {i18n.translate( - 'xpack.apm.errorGroupDetails.errorGroupTitle', - { - defaultMessage: 'Error group {errorGroupId}', - values: { - errorGroupId: getShortGroupId(urlParams.errorGroupId) - } - } - )} -

-
-
- {isUnhandled && ( - - +
+ + + +

+ {i18n.translate('xpack.apm.errorGroupDetails.errorGroupTitle', { + defaultMessage: 'Error group {errorGroupId}', + values: { + errorGroupId: getShortGroupId(urlParams.errorGroupId) + } + })} +

+
+
+ {isUnhandled && ( + + + {i18n.translate('xpack.apm.errorGroupDetails.unhandledLabel', { + defaultMessage: 'Unhandled' + })} + + + )} +
+ + + + + + + {showDetails && ( + + + {logMessage && ( + + + {logMessage} + )} - - - - - - - - - - {showDetails && ( - - - {logMessage && ( - - - {logMessage} - - )} - - {excMessage || NOT_AVAILABLE_LABEL} - - {culprit || NOT_AVAILABLE_LABEL} - - - )} - ( - + - - {showDetails && ( - - )} -
- ); - }} - /> + + {excMessage || NOT_AVAILABLE_LABEL} + + {culprit || NOT_AVAILABLE_LABEL} + + + )} + + + + + {showDetails && ( + + )} +
); } diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/List/__test__/List.test.tsx b/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/List/__test__/List.test.tsx index 229ce73fe225b..f850a981923da 100644 --- a/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/List/__test__/List.test.tsx +++ b/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/List/__test__/List.test.tsx @@ -6,13 +6,13 @@ import { mount } from 'enzyme'; import { Location } from 'history'; +import createHistory from 'history/createHashHistory'; +import PropTypes from 'prop-types'; import React from 'react'; import { MemoryRouter } from 'react-router-dom'; -import { - mockMoment, - mountWithRouterAndStore, - toJson -} from '../../../../../utils/testHelpers'; +// @ts-ignore +import { createMockStore } from 'redux-test-utils'; +import { mockMoment, toJson } from '../../../../../utils/testHelpers'; import { ErrorGroupList } from '../index'; import props from './props.json'; @@ -47,3 +47,30 @@ describe('ErrorGroupOverview -> List', () => { expect(toJson(wrapper)).toMatchSnapshot(); }); }); + +export function mountWithRouterAndStore( + Component: React.ReactElement, + storeState = {} +) { + const store = createMockStore(storeState); + const history = createHistory(); + + const options = { + context: { + store, + router: { + history, + route: { + match: { path: '/', url: '/', params: {}, isExact: true }, + location: { pathname: '/', search: '', hash: '', key: '4yyjf5' } + } + } + }, + childContextTypes: { + store: PropTypes.object.isRequired, + router: PropTypes.object.isRequired + } + }; + + return mount(Component, options); +} diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/List/__test__/__snapshots__/List.test.tsx.snap b/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/List/__test__/__snapshots__/List.test.tsx.snap index 0277a64ec5048..7df0a14e89080 100644 --- a/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/List/__test__/__snapshots__/List.test.tsx.snap +++ b/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/List/__test__/__snapshots__/List.test.tsx.snap @@ -23,8 +23,11 @@ exports[`ErrorGroupOverview -> List should render empty state 1`] = `
List should render empty state 1`] = `
List should render with data 1`] = `
List should render with data 1`] = `
= ({ urlParams, location }) => { + const { + serviceName, + start, + end, + errorGroupId, + kuery, + sortField, + sortDirection + } = urlParams; + const { data: errorDistributionData } = useFetcher( + () => + loadErrorDistribution({ serviceName, start, end, errorGroupId, kuery }), + [serviceName, start, end, errorGroupId, kuery] + ); + + const { data: errorGroupListData } = useFetcher( + () => + loadErrorGroupList({ + serviceName, + start, + end, + sortField, + sortDirection, + kuery + }), + [serviceName, start, end, sortField, sortDirection, kuery] + ); + + if (!errorDistributionData || !errorGroupListData) { + return null; + } + return ( - ( - + @@ -59,15 +89,11 @@ const ErrorGroupOverview: React.SFC = ({

Errors

- ( - - )} + items={errorGroupListData} + location={location} />
diff --git a/x-pack/plugins/apm/public/components/app/Main/GlobalFetchIndicator.tsx b/x-pack/plugins/apm/public/components/app/Main/GlobalFetchIndicator.tsx new file mode 100644 index 0000000000000..0cd13009685ad --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/Main/GlobalFetchIndicator.tsx @@ -0,0 +1,57 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { EuiDelayHide, EuiPortal, EuiProgress } from '@elastic/eui'; +import React, { Fragment, useMemo, useReducer } from 'react'; + +export const GlobalFetchContext = React.createContext({ + statuses: {}, + dispatchStatus: (action: Action) => undefined as void +}); + +interface State { + [key: string]: boolean; +} + +interface Action { + isLoading: boolean; + name: string; +} + +function reducer(statuses: State, action: Action) { + return { ...statuses, [action.name]: action.isLoading }; +} + +function getIsAnyLoading(statuses: State) { + return Object.values(statuses).some(isLoading => isLoading); +} + +export function GlobalFetchIndicator({ + children +}: { + children: React.ReactNode; +}) { + const [statuses, dispatchStatus] = useReducer(reducer, {}); + const isLoading = useMemo(() => getIsAnyLoading(statuses), [statuses]); + + return ( + + ( + + + + )} + /> + + + + ); +} diff --git a/x-pack/plugins/apm/public/components/app/Main/GlobalProgress/index.ts b/x-pack/plugins/apm/public/components/app/Main/GlobalProgress/index.ts deleted file mode 100644 index f9a8b4ecb2dd3..0000000000000 --- a/x-pack/plugins/apm/public/components/app/Main/GlobalProgress/index.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { get, some } from 'lodash'; -import { connect } from 'react-redux'; -import { IReduxState } from 'x-pack/plugins/apm/public/store/rootReducer'; -import { STATUS } from '../../../../constants/index'; -import { GlobalProgressView } from './view'; - -function getIsLoading(state: IReduxState) { - return some( - state.reactReduxRequest, - subState => get(subState, 'status') === STATUS.LOADING - ); -} - -function mapStateToProps(state = {} as IReduxState) { - return { - isLoading: getIsLoading(state) - }; -} - -export const GlobalProgress = connect(mapStateToProps)(GlobalProgressView); diff --git a/x-pack/plugins/apm/public/components/app/Main/GlobalProgress/view.tsx b/x-pack/plugins/apm/public/components/app/Main/GlobalProgress/view.tsx deleted file mode 100644 index 77995714eff42..0000000000000 --- a/x-pack/plugins/apm/public/components/app/Main/GlobalProgress/view.tsx +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { EuiDelayHide, EuiPortal, EuiProgress } from '@elastic/eui'; -import React from 'react'; - -interface Props { - isLoading: boolean; -} - -export function GlobalProgressView({ isLoading }: Props) { - return ( - ( - - - - )} - /> - ); -} diff --git a/x-pack/plugins/apm/public/components/app/Main/LicenseCheck/index.tsx b/x-pack/plugins/apm/public/components/app/Main/LicenseCheck/index.tsx index 8db0127fb4a2b..1385096babdef 100644 --- a/x-pack/plugins/apm/public/components/app/Main/LicenseCheck/index.tsx +++ b/x-pack/plugins/apm/public/components/app/Main/LicenseCheck/index.tsx @@ -4,21 +4,31 @@ * you may not use this file except in compliance with the Elastic License. */ import React from 'react'; -import { STATUS } from '../../../../constants/index'; -import { LicenceRequest } from '../../../../store/reactReduxRequest/license'; +import { + FETCH_STATUS, + useFetcher +} from 'x-pack/plugins/apm/public/hooks/useFetcher'; +import { loadLicense } from 'x-pack/plugins/apm/public/services/rest/xpack'; import { InvalidLicenseNotification } from './InvalidLicenseNotification'; -export const LicenseCheck: React.FunctionComponent = ({ children }) => { - return ( - { - const hasValidLicense = licenseData.license.is_active; - if (licenseStatus === STATUS.SUCCESS && !hasValidLicense) { - return ; - } +const initialLicense = { + features: { + watcher: { is_available: false }, + ml: { is_available: false } + }, + license: { is_active: false } +}; +export const LicenseContext = React.createContext(initialLicense); + +export const LicenseCheck: React.FC = ({ children }) => { + const { data = initialLicense, status } = useFetcher(() => loadLicense(), []); + const hasValidLicense = data.license.is_active; + + // if license is invalid show an error message + if (status === FETCH_STATUS.SUCCESS && !hasValidLicense) { + return ; + } - return children; - }} - /> - ); + // render rest of application and pass down license via context + return ; }; diff --git a/x-pack/plugins/apm/public/components/app/Main/index.tsx b/x-pack/plugins/apm/public/components/app/Main/index.tsx index 407d1394f81f8..908a0f0211645 100644 --- a/x-pack/plugins/apm/public/components/app/Main/index.tsx +++ b/x-pack/plugins/apm/public/components/app/Main/index.tsx @@ -10,6 +10,7 @@ import styled from 'styled-components'; import { px, topNavHeight, unit, units } from '../../../style/variables'; // @ts-ignore import ConnectRouterToRedux from '../../shared/ConnectRouterToRedux'; +import { GlobalFetchIndicator } from './GlobalFetchIndicator'; import { LicenseCheck } from './LicenseCheck'; import { routes } from './routeConfig'; import { ScrollToTopOnPathChange } from './ScrollToTopOnPathChange'; @@ -23,17 +24,19 @@ const MainContainer = styled.div` export function Main() { return ( - - - - - - - {routes.map((route, i) => ( - - ))} - - - + + + + + + + + {routes.map((route, i) => ( + + ))} + + + + ); } diff --git a/x-pack/plugins/apm/public/components/app/ServiceDetails/CPUUsageChart.tsx b/x-pack/plugins/apm/public/components/app/ServiceDetails/CPUUsageChart.tsx index 46b3243e8649d..264aae21da89e 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceDetails/CPUUsageChart.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceDetails/CPUUsageChart.tsx @@ -11,11 +11,11 @@ import React from 'react'; import CustomPlot from 'x-pack/plugins/apm/public/components/shared/charts/CustomPlot'; import { HoverXHandlers } from 'x-pack/plugins/apm/public/components/shared/charts/SyncChartGroup'; import { asPercent } from 'x-pack/plugins/apm/public/utils/formatters'; -import { CPUChartAPIResponse } from 'x-pack/plugins/apm/server/lib/metrics/get_cpu_chart_data/transformer'; import { Coordinate } from 'x-pack/plugins/apm/typings/timeseries'; +import { CPUMetricSeries } from '../../../store/selectors/chartSelectors'; interface Props { - data: CPUChartAPIResponse; + data: CPUMetricSeries; hoverXHandlers: HoverXHandlers; } diff --git a/x-pack/plugins/apm/public/components/app/ServiceDetails/MemoryUsageChart.tsx b/x-pack/plugins/apm/public/components/app/ServiceDetails/MemoryUsageChart.tsx index 4f620be40ec88..4356142add4c6 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceDetails/MemoryUsageChart.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceDetails/MemoryUsageChart.tsx @@ -11,11 +11,11 @@ import React from 'react'; import CustomPlot from 'x-pack/plugins/apm/public/components/shared/charts/CustomPlot'; import { HoverXHandlers } from 'x-pack/plugins/apm/public/components/shared/charts/SyncChartGroup'; import { asPercent } from 'x-pack/plugins/apm/public/utils/formatters'; -import { MemoryChartAPIResponse } from 'x-pack/plugins/apm/server/lib/metrics/get_memory_chart_data/transformer'; import { Coordinate } from 'x-pack/plugins/apm/typings/timeseries'; +import { MemoryMetricSeries } from '../../../store/selectors/chartSelectors'; interface Props { - data: MemoryChartAPIResponse; + data: MemoryMetricSeries; hoverXHandlers: HoverXHandlers; } diff --git a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout.tsx b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout.tsx deleted file mode 100644 index aea1ae113c532..0000000000000 --- a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout.tsx +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { - EuiButton, - EuiCallOut, - EuiFlexGroup, - EuiFlexItem, - EuiFlyout, - EuiFlyoutBody, - EuiFlyoutFooter, - EuiFlyoutHeader, - EuiFormRow, - EuiSpacer, - EuiText, - EuiTitle -} from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { Location } from 'history'; -import React, { Component } from 'react'; -import { toastNotifications } from 'ui/notify'; -import { getMlJobId } from 'x-pack/plugins/apm/common/ml_job_constants'; -import { KibanaLink } from 'x-pack/plugins/apm/public/components/shared/Links/KibanaLink'; -import { MLJobLink } from 'x-pack/plugins/apm/public/components/shared/Links/MLJobLink'; -import { startMLJob } from 'x-pack/plugins/apm/public/services/rest/ml'; -import { getAPMIndexPattern } from 'x-pack/plugins/apm/public/services/rest/savedObjects'; -import { MLJobsRequest } from 'x-pack/plugins/apm/public/store/reactReduxRequest/machineLearningJobs'; -import { IUrlParams } from 'x-pack/plugins/apm/public/store/urlParams'; -import { TransactionSelect } from './TransactionSelect'; - -interface FlyoutProps { - isOpen: boolean; - onClose: () => void; - urlParams: IUrlParams; - location: Location; - serviceTransactionTypes: string[]; -} - -interface FlyoutState { - isLoading: boolean; - hasMLJob: boolean; - hasIndexPattern: boolean; - selectedTransactionType?: string; -} - -export class MachineLearningFlyout extends Component { - public state = { - isLoading: false, - hasIndexPattern: false, - hasMLJob: false, - selectedTransactionType: this.props.urlParams.transactionType - }; - public willUnmount = false; - - public componentWillUnmount() { - this.willUnmount = true; - } - - public async componentDidMount() { - const indexPattern = await getAPMIndexPattern(); - if (!this.willUnmount) { - this.setState({ hasIndexPattern: !!indexPattern }); - } - } - - // TODO: This should use `getDerivedStateFromProps` - public componentDidUpdate(prevProps: FlyoutProps) { - if ( - prevProps.urlParams.transactionType !== - this.props.urlParams.transactionType - ) { - this.setState({ - selectedTransactionType: this.props.urlParams.transactionType - }); - } - } - - public createJob = async () => { - this.setState({ isLoading: true }); - try { - const { serviceName, transactionType } = this.props.urlParams; - if (!serviceName || !transactionType) { - throw new Error( - 'Service name and transaction type are required to create this ML job' - ); - } - const res = await startMLJob({ serviceName, transactionType }); - const didSucceed = res.datafeeds[0].success && res.jobs[0].success; - if (!didSucceed) { - throw new Error('Creating ML job failed'); - } - this.addSuccessToast(); - } catch (e) { - this.addErrorToast(); - } - - this.setState({ isLoading: false }); - this.props.onClose(); - }; - - public addErrorToast = () => { - const { urlParams } = this.props; - const { serviceName } = urlParams; - - if (!serviceName) { - return; - } - - toastNotifications.addWarning({ - title: i18n.translate( - 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.jobCreationFailedNotificationTitle', - { - defaultMessage: 'Job creation failed' - } - ), - text: ( -

- {i18n.translate( - 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.jobCreationFailedNotificationText', - { - defaultMessage: - 'Your current license may not allow for creating machine learning jobs, or this job may already exist.' - } - )} -

- ) - }); - }; - - public addSuccessToast = () => { - const { location, urlParams } = this.props; - const { serviceName, transactionType } = urlParams; - - if (!serviceName) { - return; - } - - toastNotifications.addSuccess({ - title: i18n.translate( - 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.jobCreatedNotificationTitle', - { - defaultMessage: 'Job successfully created' - } - ), - text: ( -

- {i18n.translate( - 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.jobCreatedNotificationText', - { - defaultMessage: - 'The analysis is now running for {serviceName} ({transactionType}). It might take a while before results are added to the response times graph.', - values: { - serviceName, - transactionType - } - } - )}{' '} - - {i18n.translate( - 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.jobCreatedNotificationText.viewJobLinkText', - { - defaultMessage: 'View job' - } - )} - -

- ) - }); - }; - - public render() { - const { isOpen, onClose, urlParams, location } = this.props; - const { serviceName, transactionType } = urlParams; - const { isLoading, hasIndexPattern, selectedTransactionType } = this.state; - - if (!isOpen || !serviceName) { - return null; - } - - return ( - { - if (status === 'LOADING') { - return null; - } - - const hasMLJob = data.jobs.some( - job => - job.job_id === getMlJobId(serviceName, selectedTransactionType) - ); - - return ( - - - -

- {i18n.translate( - 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.enableAnomalyDetectionTitle', - { - defaultMessage: 'Enable anomaly detection' - } - )} -

-
- -
- - {hasMLJob && ( -
- -

- {i18n.translate( - 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.callout.jobExistsDescription', - { - defaultMessage: - 'There is currently a job running for {serviceName} ({transactionType}).', - values: { - serviceName, - transactionType - } - } - )}{' '} - - {i18n.translate( - 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.callout.jobExistsDescription.viewJobLinkText', - { - defaultMessage: 'View existing job' - } - )} - -

-
- -
- )} - - {!hasIndexPattern && ( -
- - - {i18n.translate( - 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.callout.noPatternTitle.setupInstructionLinkText', - { - defaultMessage: 'Setup Instructions' - } - )} - - ) - }} - /> - - } - color="warning" - iconType="alert" - /> - -
- )} - - -

- - {i18n.translate( - 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.createMLJobDescription.transactionDurationGraphText', - { - defaultMessage: 'the transaction duration graph' - } - )} - - ) - }} - /> -

-

- - {i18n.translate( - 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.manageMLJobDescription.mlJobsPageLinkText', - { - defaultMessage: - 'Machine Learning jobs management page' - } - )} - - ) - }} - />{' '} - - {i18n.translate( - 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.manageMLJobDescription.noteText', - { - defaultMessage: - 'Note: It might take a few minutes for the job to begin calculating results.' - } - )} - -

-
- - -
- - - - {this.props.serviceTransactionTypes.length > 1 ? ( - - this.setState({ - selectedTransactionType: value - }) - } - /> - ) : null} - - - - - {i18n.translate( - 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.createNewJobButtonLabel', - { - defaultMessage: 'Create new job' - } - )} - - - - - -
- ); - }} - /> - ); - } -} diff --git a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/TransactionSelect.tsx b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout/TransactionSelect.tsx similarity index 100% rename from x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/TransactionSelect.tsx rename to x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout/TransactionSelect.tsx diff --git a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout/index.tsx b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout/index.tsx new file mode 100644 index 0000000000000..0f32fb9c91359 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout/index.tsx @@ -0,0 +1,203 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; +import { Location } from 'history'; +import React, { Component } from 'react'; +import { toastNotifications } from 'ui/notify'; +import { MLJobLink } from 'x-pack/plugins/apm/public/components/shared/Links/MLJobLink'; +import { startMLJob } from 'x-pack/plugins/apm/public/services/rest/ml'; +import { getAPMIndexPattern } from 'x-pack/plugins/apm/public/services/rest/savedObjects'; +import { IUrlParams } from 'x-pack/plugins/apm/public/store/urlParams'; +import { MachineLearningFlyoutView } from './view'; + +interface Props { + isOpen: boolean; + onClose: () => void; + urlParams: IUrlParams; + location: Location; + serviceTransactionTypes: string[]; +} + +interface State { + isCreatingJob: boolean; + hasMLJob: boolean; + hasIndexPattern: boolean; + selectedTransactionType?: string; +} + +export class MachineLearningFlyout extends Component { + public state: State = { + isCreatingJob: false, + hasIndexPattern: false, + hasMLJob: false, + selectedTransactionType: this.props.urlParams.transactionType + }; + public willUnmount = false; + + public componentWillUnmount() { + this.willUnmount = true; + } + + public async componentDidMount() { + const indexPattern = await getAPMIndexPattern(); + if (!this.willUnmount) { + // TODO: this is causing warning from react because setState happens after + // the component has been unmounted - dispite of the checks + this.setState({ hasIndexPattern: !!indexPattern }); + } + } + + // TODO: This should use `getDerivedStateFromProps` + public componentDidUpdate(prevProps: Props) { + if ( + prevProps.urlParams.transactionType !== + this.props.urlParams.transactionType + ) { + this.setState({ + selectedTransactionType: this.props.urlParams.transactionType + }); + } + } + + public onClickCreate = async () => { + this.setState({ isCreatingJob: true }); + try { + const { serviceName, transactionType } = this.props.urlParams; + if (!serviceName || !transactionType) { + throw new Error( + 'Service name and transaction type are required to create this ML job' + ); + } + const res = await startMLJob({ serviceName, transactionType }); + const didSucceed = res.datafeeds[0].success && res.jobs[0].success; + if (!didSucceed) { + throw new Error('Creating ML job failed'); + } + this.addSuccessToast(); + } catch (e) { + this.addErrorToast(); + } + + this.setState({ isCreatingJob: false }); + this.props.onClose(); + }; + + public addErrorToast = () => { + const { urlParams } = this.props; + const { serviceName } = urlParams; + + if (!serviceName) { + return; + } + + toastNotifications.addWarning({ + title: i18n.translate( + 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.jobCreationFailedNotificationTitle', + { + defaultMessage: 'Job creation failed' + } + ), + text: ( +

+ {i18n.translate( + 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.jobCreationFailedNotificationText', + { + defaultMessage: + 'Your current license may not allow for creating machine learning jobs, or this job may already exist.' + } + )} +

+ ) + }); + }; + + public addSuccessToast = () => { + const { location, urlParams } = this.props; + const { serviceName, transactionType } = urlParams; + + if (!serviceName) { + return; + } + + toastNotifications.addSuccess({ + title: i18n.translate( + 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.jobCreatedNotificationTitle', + { + defaultMessage: 'Job successfully created' + } + ), + text: ( +

+ {i18n.translate( + 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.jobCreatedNotificationText', + { + defaultMessage: + 'The analysis is now running for {serviceName} ({transactionType}). It might take a while before results are added to the response times graph.', + values: { + serviceName, + transactionType + } + } + )}{' '} + + {i18n.translate( + 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.jobCreatedNotificationText.viewJobLinkText', + { + defaultMessage: 'View job' + } + )} + +

+ ) + }); + }; + + public onChangeTransaction(value: string) { + this.setState({ + selectedTransactionType: value + }); + } + + public render() { + const { + isOpen, + onClose, + urlParams, + location, + serviceTransactionTypes + } = this.props; + const { serviceName, transactionType } = urlParams; + const { + isCreatingJob, + hasIndexPattern, + selectedTransactionType + } = this.state; + + if (!isOpen || !serviceName) { + return null; + } + + return ( + + ); + } +} diff --git a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout/view.tsx b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout/view.tsx new file mode 100644 index 0000000000000..9a146ae71e548 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout/view.tsx @@ -0,0 +1,252 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + EuiButton, + EuiCallOut, + EuiFlexGroup, + EuiFlexItem, + EuiFlyout, + EuiFlyoutBody, + EuiFlyoutFooter, + EuiFlyoutHeader, + EuiFormRow, + EuiSpacer, + EuiText, + EuiTitle +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { Location } from 'history'; +import React from 'react'; +import { getMlJobId } from 'x-pack/plugins/apm/common/ml_job_constants'; +import { KibanaLink } from 'x-pack/plugins/apm/public/components/shared/Links/KibanaLink'; +import { MLJobLink } from 'x-pack/plugins/apm/public/components/shared/Links/MLJobLink'; +import { + FETCH_STATUS, + useFetcher +} from 'x-pack/plugins/apm/public/hooks/useFetcher'; +import { getMLJob } from 'x-pack/plugins/apm/public/services/rest/ml'; +import { TransactionSelect } from './TransactionSelect'; + +interface Props { + hasIndexPattern: boolean; + isCreatingJob: boolean; + location: Location; + onChangeTransaction: (value: string) => void; + onClickCreate: () => void; + onClose: () => void; + selectedTransactionType?: string; + serviceName: string; + serviceTransactionTypes: string[]; + transactionType?: string; +} + +const INITIAL_DATA = { count: 0, jobs: [] }; +export function MachineLearningFlyoutView({ + hasIndexPattern, + isCreatingJob, + location, + onChangeTransaction, + onClickCreate, + onClose, + selectedTransactionType, + serviceName, + serviceTransactionTypes, + transactionType +}: Props) { + const { data = INITIAL_DATA, status } = useFetcher( + () => getMLJob({ serviceName, transactionType }), + [serviceName, transactionType] + ); + + if (status === FETCH_STATUS.LOADING) { + return null; + } + + const hasMLJob = data.jobs.some( + job => job.job_id === getMlJobId(serviceName, selectedTransactionType) + ); + + return ( + + + +

+ {i18n.translate( + 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.enableAnomalyDetectionTitle', + { + defaultMessage: 'Enable anomaly detection' + } + )} +

+
+ +
+ + {hasMLJob && ( +
+ +

+ {i18n.translate( + 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.callout.jobExistsDescription', + { + defaultMessage: + 'There is currently a job running for {serviceName} ({transactionType}).', + values: { + serviceName, + transactionType + } + } + )}{' '} + + {i18n.translate( + 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.callout.jobExistsDescription.viewJobLinkText', + { + defaultMessage: 'View existing job' + } + )} + +

+
+ +
+ )} + + {!hasIndexPattern && ( +
+ + + {i18n.translate( + 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.callout.noPatternTitle.setupInstructionLinkText', + { + defaultMessage: 'Setup Instructions' + } + )} + + ) + }} + /> + + } + color="warning" + iconType="alert" + /> + +
+ )} + + +

+ + {i18n.translate( + 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.createMLJobDescription.transactionDurationGraphText', + { + defaultMessage: 'the transaction duration graph' + } + )} + + ) + }} + /> +

+

+ + {i18n.translate( + 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.manageMLJobDescription.mlJobsPageLinkText', + { + defaultMessage: 'Machine Learning jobs management page' + } + )} + + ) + }} + />{' '} + + {i18n.translate( + 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.manageMLJobDescription.noteText', + { + defaultMessage: + 'Note: It might take a few minutes for the job to begin calculating results.' + } + )} + +

+
+ + +
+ + + + {serviceTransactionTypes.length > 1 ? ( + + ) : null} + + + + + {i18n.translate( + 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.createNewJobButtonLabel', + { + defaultMessage: 'Create new job' + } + )} + + + + + +
+ ); +} diff --git a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/index.tsx b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/index.tsx index 3e6b8a6f2bac3..b740c0507b10d 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/index.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/index.tsx @@ -4,16 +4,181 @@ * you may not use this file except in compliance with the Elastic License. */ -import { connect } from 'react-redux'; -import { IReduxState } from 'x-pack/plugins/apm/public/store/rootReducer'; -import { selectIsMLAvailable } from 'x-pack/plugins/apm/public/store/selectors/license'; -import { ServiceIntegrationsView } from './view'; - -function mapStateToProps(state = {} as IReduxState) { - return { - mlAvailable: selectIsMLAvailable(state) - }; +import { + EuiButton, + EuiContextMenu, + EuiContextMenuPanelItemDescriptor, + EuiPopover +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { Location } from 'history'; +import { memoize } from 'lodash'; +import React, { Fragment } from 'react'; +import chrome from 'ui/chrome'; +import { IUrlParams } from 'x-pack/plugins/apm/public/store/urlParams'; +import { LicenseContext } from '../../Main/LicenseCheck'; +import { MachineLearningFlyout } from './MachineLearningFlyout'; +import { WatcherFlyout } from './WatcherFlyout'; + +interface Props { + location: Location; + transactionTypes: string[]; + urlParams: IUrlParams; } +interface State { + isPopoverOpen: boolean; + activeFlyout: FlyoutName; +} +type FlyoutName = null | 'ML' | 'Watcher'; + +export class ServiceIntegrations extends React.Component { + public state: State = { isPopoverOpen: false, activeFlyout: null }; -const ServiceIntegrations = connect(mapStateToProps)(ServiceIntegrationsView); -export { ServiceIntegrations }; + public getPanelItems = memoize((mlAvailable: boolean) => { + let panelItems: EuiContextMenuPanelItemDescriptor[] = []; + if (mlAvailable) { + panelItems = panelItems.concat(this.getMLPanelItems()); + } + return panelItems.concat(this.getWatcherPanelItems()); + }); + + public getMLPanelItems = () => { + return [ + { + name: i18n.translate( + 'xpack.apm.serviceDetails.integrationsMenu.enableMLAnomalyDetectionButtonLabel', + { + defaultMessage: 'Enable ML anomaly detection' + } + ), + icon: 'machineLearningApp', + toolTipContent: i18n.translate( + 'xpack.apm.serviceDetails.integrationsMenu.enableMLAnomalyDetectionButtonTooltip', + { + defaultMessage: 'Set up a machine learning job for this service' + } + ), + onClick: () => { + this.closePopover(); + this.openFlyout('ML'); + } + }, + { + name: i18n.translate( + 'xpack.apm.serviceDetails.integrationsMenu.viewMLJobsButtonLabel', + { + defaultMessage: 'View existing ML jobs' + } + ), + icon: 'machineLearningApp', + href: chrome.addBasePath('/app/ml'), + target: '_blank', + onClick: () => this.closePopover() + } + ]; + }; + + public getWatcherPanelItems = () => { + return [ + { + name: i18n.translate( + 'xpack.apm.serviceDetails.integrationsMenu.enableWatcherErrorReportsButtonLabel', + { + defaultMessage: 'Enable watcher error reports' + } + ), + icon: 'watchesApp', + onClick: () => { + this.closePopover(); + this.openFlyout('Watcher'); + } + }, + { + name: i18n.translate( + 'xpack.apm.serviceDetails.integrationsMenu.viewWatchesButtonLabel', + { + defaultMessage: 'View existing watches' + } + ), + icon: 'watchesApp', + href: chrome.addBasePath( + '/app/kibana#/management/elasticsearch/watcher' + ), + target: '_blank', + onClick: () => this.closePopover() + } + ]; + }; + + public openPopover = () => + this.setState({ + isPopoverOpen: true + }); + + public closePopover = () => + this.setState({ + isPopoverOpen: false + }); + + public openFlyout = (name: FlyoutName) => + this.setState({ activeFlyout: name }); + + public closeFlyouts = () => this.setState({ activeFlyout: null }); + + public render() { + const button = ( + + {i18n.translate( + 'xpack.apm.serviceDetails.integrationsMenu.integrationsButtonLabel', + { + defaultMessage: 'Integrations' + } + )} + + ); + + return ( + + {license => ( + + + + + + + + )} + + ); + } +} diff --git a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/view.tsx b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/view.tsx deleted file mode 100644 index c7e60934ddcd1..0000000000000 --- a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/view.tsx +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { - EuiButton, - EuiContextMenu, - EuiContextMenuPanelItemDescriptor, - EuiPopover -} from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { Location } from 'history'; -import { memoize } from 'lodash'; -import React from 'react'; -import chrome from 'ui/chrome'; -import { IUrlParams } from 'x-pack/plugins/apm/public/store/urlParams'; -import { MachineLearningFlyout } from './MachineLearningFlyout'; -import { WatcherFlyout } from './WatcherFlyout'; - -export interface ServiceIntegrationProps { - mlAvailable: boolean; - location: Location; - transactionTypes: string[]; - urlParams: IUrlParams; -} -interface ServiceIntegrationState { - isPopoverOpen: boolean; - activeFlyout: FlyoutName; -} -type FlyoutName = null | 'ML' | 'Watcher'; - -export class ServiceIntegrationsView extends React.Component< - ServiceIntegrationProps, - ServiceIntegrationState -> { - public state = { isPopoverOpen: false, activeFlyout: null }; - - public getPanelItems = memoize((mlAvailable: boolean) => { - let panelItems: EuiContextMenuPanelItemDescriptor[] = []; - if (mlAvailable) { - panelItems = panelItems.concat(this.getMLPanelItems()); - } - return panelItems.concat(this.getWatcherPanelItems()); - }); - - public getMLPanelItems = () => { - return [ - { - name: i18n.translate( - 'xpack.apm.serviceDetails.integrationsMenu.enableMLAnomalyDetectionButtonLabel', - { - defaultMessage: 'Enable ML anomaly detection' - } - ), - icon: 'machineLearningApp', - toolTipContent: i18n.translate( - 'xpack.apm.serviceDetails.integrationsMenu.enableMLAnomalyDetectionButtonTooltip', - { - defaultMessage: 'Set up a machine learning job for this service' - } - ), - onClick: () => { - this.closePopover(); - this.openFlyout('ML'); - } - }, - { - name: i18n.translate( - 'xpack.apm.serviceDetails.integrationsMenu.viewMLJobsButtonLabel', - { - defaultMessage: 'View existing ML jobs' - } - ), - icon: 'machineLearningApp', - href: chrome.addBasePath('/app/ml'), - target: '_blank', - onClick: () => this.closePopover() - } - ]; - }; - - public getWatcherPanelItems = () => { - return [ - { - name: i18n.translate( - 'xpack.apm.serviceDetails.integrationsMenu.enableWatcherErrorReportsButtonLabel', - { - defaultMessage: 'Enable watcher error reports' - } - ), - icon: 'watchesApp', - onClick: () => { - this.closePopover(); - this.openFlyout('Watcher'); - } - }, - { - name: i18n.translate( - 'xpack.apm.serviceDetails.integrationsMenu.viewWatchesButtonLabel', - { - defaultMessage: 'View existing watches' - } - ), - icon: 'watchesApp', - href: chrome.addBasePath( - '/app/kibana#/management/elasticsearch/watcher' - ), - target: '_blank', - onClick: () => this.closePopover() - } - ]; - }; - - public openPopover = () => - this.setState({ - isPopoverOpen: true - }); - - public closePopover = () => - this.setState({ - isPopoverOpen: false - }); - - public openFlyout = (name: FlyoutName) => - this.setState({ activeFlyout: name }); - - public closeFlyouts = () => this.setState({ activeFlyout: null }); - - public render() { - const button = ( - - {i18n.translate( - 'xpack.apm.serviceDetails.integrationsMenu.integrationsButtonLabel', - { - defaultMessage: 'Integrations' - } - )} - - ); - - return ( - - - - - - - - ); - } -} diff --git a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceMetrics.tsx b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceMetrics.tsx index 1ae81b44af12c..8d5a99fdd90a3 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceMetrics.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceMetrics.tsx @@ -17,10 +17,11 @@ import React from 'react'; import { ErrorDistribution } from 'x-pack/plugins/apm/public/components/app/ErrorGroupDetails/Distribution'; import { SyncChartGroup } from 'x-pack/plugins/apm/public/components/shared/charts/SyncChartGroup'; import { TransactionCharts } from 'x-pack/plugins/apm/public/components/shared/charts/TransactionCharts'; -import { ErrorDistributionRequest } from 'x-pack/plugins/apm/public/store/reactReduxRequest/errorDistribution'; -import { MetricsChartDataRequest } from 'x-pack/plugins/apm/public/store/reactReduxRequest/serviceMetricsCharts'; -import { TransactionOverviewChartsRequestForAllTypes } from 'x-pack/plugins/apm/public/store/reactReduxRequest/transactionOverviewCharts'; import { IUrlParams } from 'x-pack/plugins/apm/public/store/urlParams'; +import { useFetcher } from '../../../hooks/useFetcher'; +import { useServiceMetricCharts } from '../../../hooks/useServiceMetricCharts'; +import { useTransactionOverviewCharts } from '../../../hooks/useTransactionOverviewCharts'; +import { loadErrorDistribution } from '../../../services/rest/apm/error_groups'; import { CPUUsageChart } from './CPUUsageChart'; import { MemoryUsageChart } from './MemoryUsageChart'; @@ -30,17 +31,29 @@ interface ServiceMetricsProps { } export function ServiceMetrics({ urlParams, location }: ServiceMetricsProps) { + const { serviceName, start, end, errorGroupId, kuery } = urlParams; + const { data: errorDistributionData } = useFetcher( + () => + loadErrorDistribution({ serviceName, start, end, errorGroupId, kuery }), + [serviceName, start, end, errorGroupId, kuery] + ); + + const { data: transactionOverviewChartsData } = useTransactionOverviewCharts( + urlParams + ); + + const { data: serviceMetricChartData } = useServiceMetricCharts(urlParams); + + if (!errorDistributionData) { + return null; + } + return ( - ( - - )} + location={location} /> @@ -48,18 +61,13 @@ export function ServiceMetrics({ urlParams, location }: ServiceMetricsProps) { - ( - + @@ -68,34 +76,27 @@ export function ServiceMetrics({ urlParams, location }: ServiceMetricsProps) { - { - return ( - ( - - - - - - - - - - - - - )} - /> - ); - }} + ( + + + + + + + + + + + + + )} /> diff --git a/x-pack/plugins/apm/public/components/app/ServiceDetails/view.tsx b/x-pack/plugins/apm/public/components/app/ServiceDetails/view.tsx index 5ae7e3b105633..36789ed3b67fa 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceDetails/view.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceDetails/view.tsx @@ -6,56 +6,57 @@ import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiTitle } from '@elastic/eui'; import { Location } from 'history'; -import React, { Fragment } from 'react'; -import { ServiceDetailsRequest } from 'x-pack/plugins/apm/public/store/reactReduxRequest/serviceDetails'; +import React from 'react'; import { IUrlParams } from 'x-pack/plugins/apm/public/store/urlParams'; +import { useFetcher } from '../../../hooks/useFetcher'; +import { loadServiceDetails } from '../../../services/rest/apm/services'; // @ts-ignore import { FilterBar } from '../../shared/FilterBar'; import { ServiceDetailTabs } from './ServiceDetailTabs'; import { ServiceIntegrations } from './ServiceIntegrations'; -interface ServiceDetailsProps { +interface Props { urlParams: IUrlParams; location: Location; } -export class ServiceDetailsView extends React.Component { - public render() { - const { urlParams, location } = this.props; - return ( - loadServiceDetails({ serviceName, start, end, kuery }), + [serviceName, start, end, kuery] + ); + + if (!serviceDetailsData) { + return null; + } + + return ( + + + + +

{urlParams.serviceName}

+
+
+ + + +
+ + + + + + { - return ( - - - - -

{urlParams.serviceName}

-
-
- - - -
- - - - - - -
- ); - }} + transactionTypes={serviceDetailsData.types} /> - ); - } +
+ ); } diff --git a/x-pack/plugins/apm/public/components/app/ServiceOverview/ServiceList/index.tsx b/x-pack/plugins/apm/public/components/app/ServiceOverview/ServiceList/index.tsx index 0d9dd1ed1381f..8bb29b285e097 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceOverview/ServiceList/index.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceOverview/ServiceList/index.tsx @@ -16,7 +16,7 @@ import { asDecimal, asMillis } from '../../../../utils/formatters'; import { ITableColumn, ManagedTable } from '../../../shared/ManagedTable'; interface Props { - items: IServiceListItem[]; + items?: IServiceListItem[]; noItemsMessage?: React.ReactNode; } diff --git a/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/ServiceOverview.test.js b/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/ServiceOverview.test.js deleted file mode 100644 index 2a6d3f8e5fd2e..0000000000000 --- a/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/ServiceOverview.test.js +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; -import { shallow } from 'enzyme'; -import { ServiceOverview } from '../view'; -import { STATUS } from '../../../../constants'; -import * as apmRestServices from '../../../../services/rest/apm/status_check'; -jest.mock('../../../../services/rest/apm/status_check'); - -describe('Service Overview -> View', () => { - let mockAgentStatus; - let wrapper; - let instance; - - beforeEach(() => { - mockAgentStatus = { - dataFound: true - }; - - apmRestServices.loadAgentStatus = jest.fn(() => - Promise.resolve(mockAgentStatus) - ); - - wrapper = shallow(); - instance = wrapper.instance(); - }); - - it('should render when historical data is found', () => { - expect(wrapper).toMatchSnapshot(); - const List = wrapper - .find('ServiceListRequest') - .props() - .render({}); - expect(List.props).toMatchSnapshot(); - }); - - it('should render when historical data is not found', () => { - wrapper.setState({ historicalDataFound: false }); - expect(wrapper).toMatchSnapshot(); - const List = wrapper - .find('ServiceListRequest') - .props() - .render({}); - expect(List.props).toMatchSnapshot(); - }); - - it('should check for historical data once', () => {}); - - describe('checking for historical data', () => { - it('should set historical data to true if data is found', async () => { - const props = { - serviceList: { - status: STATUS.SUCCESS, - data: [] - } - }; - await instance.checkForHistoricalData(props); - expect(wrapper.state('historicalDataFound')).toEqual(true); - }); - - it('should set historical data state to false if data is NOT found', async () => { - const props = { - serviceList: { - status: STATUS.SUCCESS, - data: [] - } - }; - mockAgentStatus.dataFound = false; - await instance.checkForHistoricalData(props); - expect(wrapper.state('historicalDataFound')).toEqual(false); - }); - }); -}); diff --git a/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/ServiceOverview.test.tsx b/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/ServiceOverview.test.tsx new file mode 100644 index 0000000000000..a82be56866e39 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/ServiceOverview.test.tsx @@ -0,0 +1,132 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { Provider } from 'react-redux'; +import { render, wait, waitForElement } from 'react-testing-library'; +import 'react-testing-library/cleanup-after-each'; +import * as apmRestServices from 'x-pack/plugins/apm/public/services/rest/apm/services'; +// @ts-ignore +import configureStore from 'x-pack/plugins/apm/public/store/config/configureStore'; +import * as statusCheck from '../../../../services/rest/apm/status_check'; +import { ServiceOverview } from '../view'; + +function Comp() { + const store = configureStore(); + + return ( + + + + ); +} + +describe('Service Overview -> View', () => { + afterEach(() => { + jest.resetAllMocks(); + }); + + // Suppress warnings about "act" until async/await syntax is supported: https://github.com/facebook/react/issues/14769 + /* tslint:disable:no-console */ + const originalError = console.error; + beforeAll(() => { + console.error = jest.fn(); + }); + afterAll(() => { + console.error = originalError; + }); + + it('should render services, when list is not empty', async () => { + // mock rest requests + const spy1 = jest + .spyOn(statusCheck, 'loadAgentStatus') + .mockResolvedValue(true); + const spy2 = jest + .spyOn(apmRestServices, 'loadServiceList') + .mockResolvedValue([ + { + serviceName: 'My Python Service', + agentName: 'python', + transactionsPerMinute: 100, + errorsPerMinute: 200, + avgResponseTime: 300 + }, + { + serviceName: 'My Go Service', + agentName: 'go', + transactionsPerMinute: 400, + errorsPerMinute: 500, + avgResponseTime: 600 + } + ]); + + const { container, getByText } = render(); + + // wait for requests to be made + await wait( + () => + expect(spy1).toHaveBeenCalledTimes(1) && + expect(spy2).toHaveBeenCalledTimes(1) + ); + + await waitForElement(() => getByText('My Python Service')); + + expect(container.querySelectorAll('.euiTableRow')).toMatchSnapshot(); + }); + + it('should render getting started message, when list is empty and no historical data is found', async () => { + // mock rest requests + const spy1 = jest + .spyOn(statusCheck, 'loadAgentStatus') + .mockResolvedValue(false); + + const spy2 = jest + .spyOn(apmRestServices, 'loadServiceList') + .mockResolvedValue([]); + + const { container, getByText } = render(); + + // wait for requests to be made + await wait( + () => + expect(spy1).toHaveBeenCalledTimes(1) && + expect(spy2).toHaveBeenCalledTimes(1) + ); + + // wait for elements to be rendered + await waitForElement(() => + getByText( + "Looks like you don't have any APM services installed. Let's add some!" + ) + ); + + expect(container.querySelectorAll('.euiTableRow')).toMatchSnapshot(); + }); + + it('should render empty message, when list is empty and historical data is found', async () => { + // mock rest requests + const spy1 = jest + .spyOn(statusCheck, 'loadAgentStatus') + .mockResolvedValue(true); + const spy2 = jest + .spyOn(apmRestServices, 'loadServiceList') + .mockResolvedValue([]); + + const { container, getByText } = render(); + + // wait for requests to be made + await wait( + () => + expect(spy1).toHaveBeenCalledTimes(1) && + expect(spy2).toHaveBeenCalledTimes(1) + ); + + // wait for elements to be rendered + await waitForElement(() => getByText('No services found')); + + expect(container.querySelectorAll('.euiTableRow')).toMatchSnapshot(); + }); +}); diff --git a/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/__snapshots__/ServiceOverview.test.js.snap b/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/__snapshots__/ServiceOverview.test.js.snap deleted file mode 100644 index a08ba5312ba5c..0000000000000 --- a/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/__snapshots__/ServiceOverview.test.js.snap +++ /dev/null @@ -1,43 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Service Overview -> View should render when historical data is found 1`] = ` - - - -`; - -exports[`Service Overview -> View should render when historical data is found 2`] = ` -Object { - "items": Array [], - "noItemsMessage": , -} -`; - -exports[`Service Overview -> View should render when historical data is not found 1`] = ` - - - -`; - -exports[`Service Overview -> View should render when historical data is not found 2`] = ` -Object { - "items": Array [], - "noItemsMessage": , -} -`; diff --git a/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/__snapshots__/ServiceOverview.test.tsx.snap b/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/__snapshots__/ServiceOverview.test.tsx.snap new file mode 100644 index 0000000000000..b7f431249daf8 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/__snapshots__/ServiceOverview.test.tsx.snap @@ -0,0 +1,296 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Service Overview -> View should render empty message, when list is empty and historical data is found 1`] = ` +NodeList [ + + +
+ +
+ +
+ No services found +
+
+ +
+
+
+ + , +] +`; + +exports[`Service Overview -> View should render getting started message, when list is empty and no historical data is found 1`] = ` +NodeList [ + + +
+ +
+ +
+ Looks like you don't have any APM services installed. Let's add some! +
+
+
+

+ Upgrading from a pre-7.x version? Make sure you've also upgraded + your APM server instance(s) to at least 7.0. +

+

+ You may also have old data that needs to be migrated. + + + Learn more by visiting the Kibana Upgrade Assistant + + . +

+
+ + + + , +] +`; + +exports[`Service Overview -> View should render services, when list is not empty 1`] = ` +NodeList [ + + +
+ Name +
+ + + +
+ Agent +
+
+ go +
+ + +
+ Avg. response time +
+
+ 1 ms +
+ + +
+ Trans. per minute +
+
+ 400.0 tpm +
+ + +
+ Errors per minute +
+
+ 500.0 err. +
+ + , + + +
+ Name +
+ + + +
+ Agent +
+
+ python +
+ + +
+ Avg. response time +
+
+ 0 ms +
+ + +
+ Trans. per minute +
+
+ 100.0 tpm +
+ + +
+ Errors per minute +
+
+ 200.0 err. +
+ + , +] +`; diff --git a/x-pack/plugins/apm/public/components/app/ServiceOverview/index.ts b/x-pack/plugins/apm/public/components/app/ServiceOverview/index.ts index 7e2ec20677c3d..378bf3118886a 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceOverview/index.ts +++ b/x-pack/plugins/apm/public/components/app/ServiceOverview/index.ts @@ -5,14 +5,12 @@ */ import { connect } from 'react-redux'; -import { getServiceList } from 'x-pack/plugins/apm/public/store/reactReduxRequest/serviceList'; import { IReduxState } from 'x-pack/plugins/apm/public/store/rootReducer'; import { getUrlParams } from 'x-pack/plugins/apm/public/store/urlParams'; import { ServiceOverview as View } from './view'; function mapStateToProps(state = {} as IReduxState) { return { - serviceList: getServiceList(state), urlParams: getUrlParams(state) }; } diff --git a/x-pack/plugins/apm/public/components/app/ServiceOverview/view.tsx b/x-pack/plugins/apm/public/components/app/ServiceOverview/view.tsx index 1c11b5deff8b4..3480aae74d5c1 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceOverview/view.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceOverview/view.tsx @@ -5,59 +5,32 @@ */ import { EuiPanel } from '@elastic/eui'; -import React, { Component } from 'react'; -import { RRRRenderResponse } from 'react-redux-request'; +import React from 'react'; import { IUrlParams } from 'x-pack/plugins/apm/public/store/urlParams'; -import { IServiceListItem } from 'x-pack/plugins/apm/server/lib/services/get_services'; +import { useFetcher } from '../../../hooks/useFetcher'; +import { loadServiceList } from '../../../services/rest/apm/services'; import { loadAgentStatus } from '../../../services/rest/apm/status_check'; -import { ServiceListRequest } from '../../../store/reactReduxRequest/serviceList'; import { NoServicesMessage } from './NoServicesMessage'; import { ServiceList } from './ServiceList'; interface Props { urlParams: IUrlParams; - serviceList: RRRRenderResponse; } -interface State { - // any data submitted from APM agents found (not just in the given time range) - historicalDataFound: boolean; -} - -export class ServiceOverview extends Component { - public state = { historicalDataFound: true }; - - public async checkForHistoricalData() { - const result = await loadAgentStatus(); - this.setState({ historicalDataFound: result.dataFound }); - } - - public componentDidMount() { - this.checkForHistoricalData(); - } - - public render() { - const { urlParams } = this.props; - - // Render method here uses this.props.serviceList instead of received "data" from RRR - // to make it easier to test -- mapStateToProps uses the RRR selector so the data - // is the same either way - return ( - - ( - - } - /> - )} - /> - - ); - } +export function ServiceOverview({ urlParams }: Props) { + const { start, end, kuery } = urlParams; + const { data: agentStatus = true } = useFetcher(() => loadAgentStatus(), []); + const { data: serviceListData } = useFetcher( + () => loadServiceList({ start, end, kuery }), + [start, end, kuery] + ); + + return ( + + } + /> + + ); } diff --git a/x-pack/plugins/apm/public/components/app/TraceOverview/TraceList.tsx b/x-pack/plugins/apm/public/components/app/TraceOverview/TraceList.tsx index 06d548ea8661d..b7ac9f63f61cc 100644 --- a/x-pack/plugins/apm/public/components/app/TraceOverview/TraceList.tsx +++ b/x-pack/plugins/apm/public/components/app/TraceOverview/TraceList.tsx @@ -11,6 +11,7 @@ import styled from 'styled-components'; import { ITransactionGroup } from 'x-pack/plugins/apm/server/lib/transaction_groups/transform'; import { fontSizes, truncate } from '../../../style/variables'; import { asMillis } from '../../../utils/formatters'; +import { EmptyMessage } from '../../shared/EmptyMessage'; import { ImpactBar } from '../../shared/ImpactBar'; import { TransactionLink } from '../../shared/Links/TransactionLink'; import { ITableColumn, ManagedTable } from '../../shared/ManagedTable'; @@ -22,7 +23,6 @@ const StyledTransactionLink = styled(TransactionLink)` interface Props { items: ITransactionGroup[]; - noItemsMessage: React.ReactNode; isLoading: boolean; } @@ -88,7 +88,15 @@ const traceListColumns: Array> = [ } ]; -export function TraceList({ items = [], noItemsMessage, isLoading }: Props) { +const noItemsMessage = ( + +); + +export function TraceList({ items = [], isLoading }: Props) { const noItems = isLoading ? null : noItemsMessage; return ( loadTraceList({ start, end, kuery }), + [start, end, kuery] + ); return ( - ) => ( - - } - /> - )} - /> + ); } diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Distribution/index.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/Distribution/index.tsx index 5a5e4977458b8..353332e76e4fe 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Distribution/index.tsx +++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Distribution/index.tsx @@ -52,7 +52,7 @@ export function getFormattedBuckets(buckets: IBucket[], bucketSize: number) { interface Props { location: Location; - distribution: ITransactionDistributionAPIResponse; + distribution?: ITransactionDistributionAPIResponse; urlParams: IUrlParams; } @@ -95,9 +95,45 @@ export class TransactionDistribution extends Component { ); }; + public redirectToTransactionType() { + const { urlParams, location, distribution } = this.props; + + if ( + !distribution || + !distribution.defaultSample || + urlParams.traceId || + urlParams.transactionId + ) { + return; + } + + const { traceId, transactionId } = distribution.defaultSample; + + history.replace({ + ...location, + search: fromQuery({ + ...toQuery(location.search), + traceId, + transactionId + }) + }); + } + + public componentDidMount() { + this.redirectToTransactionType(); + } + + public componentDidUpdate() { + this.redirectToTransactionType(); + } + public render() { const { location, distribution, urlParams } = this.props; + if (!distribution || !urlParams.traceId || !urlParams.transactionId) { + return null; + } + const buckets = getFormattedBuckets( distribution.buckets, distribution.bucketSize @@ -163,7 +199,7 @@ export class TransactionDistribution extends Component { bucketIndex={bucketIndex} onClick={(bucket: IChartPoint) => { if (bucket.sample && bucket.y > 0) { - history.replace({ + history.push({ ...location, search: fromQuery({ ...toQuery(location.search), diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/SpanFlyout/index.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/SpanFlyout/index.tsx index b2ed17d1017a3..c81b4e522068f 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/SpanFlyout/index.tsx +++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/SpanFlyout/index.tsx @@ -57,10 +57,10 @@ export function SpanFlyout({ const codeLanguage = idx(parentTransaction, _ => _.service.language.name); const dbContext = idx(span, _ => _.span.db); const httpContext = idx(span, _ => _.span.http); - const labels = span.labels; - const tags = keys(labels).map(key => ({ + const spanLabels = span.labels; + const labels = keys(spanLabels).map(key => ({ key, - value: get(labels, key) + value: get(spanLabels, key) })); return ( @@ -123,11 +123,11 @@ export function SpanFlyout({ ) }, { - id: 'tags', + id: 'labels', name: i18n.translate( - 'xpack.apm.transactionDetails.spanFlyout.tagsTabLabel', + 'xpack.apm.propertiesTable.tabs.labelsLabel', { - defaultMessage: 'Tags' + defaultMessage: 'Labels' } ), content: ( @@ -144,7 +144,7 @@ export function SpanFlyout({ field: 'value' } ]} - items={tags} + items={labels} /> ) diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers.test.ts b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers.test.ts index e8196261a2a73..067bfd628764b 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers.test.ts +++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers.test.ts @@ -96,13 +96,12 @@ describe('waterfall_helpers', () => { it('should return full waterfall', () => { const entryTransactionId = 'myTransactionId1'; - const errorCountsByTransactionId = { + const errorsPerTransaction = { myTransactionId1: 2, myTransactionId2: 3 }; const waterfall = getWaterfall( - hits, - errorCountsByTransactionId, + { trace: hits, errorsPerTransaction }, entryTransactionId ); expect(waterfall.orderedItems.length).toBe(6); @@ -112,13 +111,12 @@ describe('waterfall_helpers', () => { it('should return partial waterfall', () => { const entryTransactionId = 'myTransactionId2'; - const errorCountsByTransactionId = { + const errorsPerTransaction = { myTransactionId1: 2, myTransactionId2: 3 }; const waterfall = getWaterfall( - hits, - errorCountsByTransactionId, + { trace: hits, errorsPerTransaction }, entryTransactionId ); expect(waterfall.orderedItems.length).toBe(4); @@ -128,13 +126,12 @@ describe('waterfall_helpers', () => { it('getTransactionById', () => { const entryTransactionId = 'myTransactionId1'; - const errorCountsByTransactionId = { + const errorsPerTransaction = { myTransactionId1: 2, myTransactionId2: 3 }; const waterfall = getWaterfall( - hits, - errorCountsByTransactionId, + { trace: hits, errorsPerTransaction }, entryTransactionId ); const transaction = waterfall.getTransactionById('myTransactionId2'); diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers.ts b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers.ts index 6056551d41df1..5e54300427f88 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers.ts +++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers.ts @@ -239,8 +239,7 @@ function createGetTransactionById(itemsById: IWaterfallIndex) { } export function getWaterfall( - trace: TraceAPIResponse['trace'], - errorsPerTransaction: TraceAPIResponse['errorsPerTransaction'], + { trace, errorsPerTransaction }: TraceAPIResponse, entryTransactionId?: Transaction['transaction']['id'] ): IWaterfall { if (isEmpty(trace) || !entryTransactionId) { diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/view.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/view.tsx index 7b9eff0cccf3f..aa5f0ef31224b 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionDetails/view.tsx +++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/view.tsx @@ -7,10 +7,11 @@ import { EuiPanel, EuiSpacer, EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { Location } from 'history'; +import _ from 'lodash'; import React from 'react'; -import { TransactionDetailsChartsRequest } from '../../../store/reactReduxRequest/transactionDetailsCharts'; -import { TransactionDistributionRequest } from '../../../store/reactReduxRequest/transactionDistribution'; -import { WaterfallRequest } from '../../../store/reactReduxRequest/waterfall'; +import { useTransactionDetailsCharts } from '../../../hooks/useTransactionDetailsCharts'; +import { useTransactionDistribution } from '../../../hooks/useTransactionDistribution'; +import { useWaterfall } from '../../../hooks/useWaterfall'; import { IUrlParams } from '../../../store/urlParams'; import { TransactionCharts } from '../../shared/charts/TransactionCharts'; import { EmptyMessage } from '../../shared/EmptyMessage'; @@ -19,12 +20,18 @@ import { TransactionDistribution } from './Distribution'; import { Transaction } from './Transaction'; interface Props { - mlAvailable: boolean; urlParams: IUrlParams; location: Location; } export function TransactionDetailsView({ urlParams, location }: Props) { + const { data: distributionData } = useTransactionDistribution(urlParams); + const { data: transactionDetailsChartsData } = useTransactionDetailsCharts( + urlParams + ); + const { data: waterfall } = useWaterfall(urlParams); + const transaction = waterfall.getTransactionById(urlParams.transactionId); + return (
@@ -32,75 +39,51 @@ export function TransactionDetailsView({ urlParams, location }: Props) { - - - ( - - )} + location={location} /> - ( - - )} + location={location} /> - { - const transaction = waterfall.getTransactionById( - urlParams.transactionId - ); - if (!transaction) { - return ( - - ); - } - return ( - - ); - }} - /> + {!transaction ? ( + + ) : ( + + )}
); } diff --git a/x-pack/plugins/apm/public/components/app/TransactionOverview/__jest__/TransactionOverview.test.js b/x-pack/plugins/apm/public/components/app/TransactionOverview/__jest__/TransactionOverview.test.js deleted file mode 100644 index b68d06d162a59..0000000000000 --- a/x-pack/plugins/apm/public/components/app/TransactionOverview/__jest__/TransactionOverview.test.js +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; -import { shallow } from 'enzyme'; -import { TransactionOverviewView } from '..'; - -jest.mock( - 'ui/chrome', - () => ({ - getBasePath: () => `/some/base/path`, - getInjected: key => { - if (key === 'mlEnabled') { - return true; - } - throw new Error(`inexpected key ${key}`); - }, - getUiSettingsClient: () => { - return { - get: key => { - switch (key) { - case 'timepicker:timeDefaults': - return { from: 'now-15m', to: 'now', mode: 'quick' }; - case 'timepicker:refreshIntervalDefaults': - return { display: 'Off', pause: false, value: 0 }; - default: - throw new Error(`Unexpected config key: ${key}`); - } - } - }; - } - }), - { virtual: true } -); - -const setup = () => { - const props = { - agentName: 'test-agent', - serviceName: 'test-service', - serviceTransactionTypes: ['a', 'b'], - location: {}, - history: { - push: jest.fn() - }, - urlParams: { transactionType: 'test-type', serviceName: 'MyServiceName' } - }; - - const wrapper = shallow(); - return { props, wrapper }; -}; - -describe('TransactionOverviewView', () => { - it('should render null if there is no transaction type in the search string', () => { - const { wrapper } = setup(); - wrapper.setProps({ urlParams: { serviceName: 'MyServiceName' } }); - expect(wrapper).toMatchInlineSnapshot(`""`); - }); - - it('should render with type filter controls', () => { - const { wrapper } = setup(); - expect(wrapper).toMatchSnapshot(); - }); - - it('should render without type filter controls if there is just a single type', () => { - const { wrapper } = setup(); - wrapper.setProps({ - serviceTransactionTypes: ['a'] - }); - expect(wrapper).toMatchSnapshot(); - }); -}); diff --git a/x-pack/plugins/apm/public/components/app/TransactionOverview/__jest__/TransactionOverview.test.tsx b/x-pack/plugins/apm/public/components/app/TransactionOverview/__jest__/TransactionOverview.test.tsx new file mode 100644 index 0000000000000..5c702658dbce3 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/TransactionOverview/__jest__/TransactionOverview.test.tsx @@ -0,0 +1,94 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import createHistory from 'history/createHashHistory'; +import React from 'react'; +import { Provider } from 'react-redux'; +import { Router } from 'react-router-dom'; +import { queryByLabelText, render } from 'react-testing-library'; +// @ts-ignore +import configureStore from 'x-pack/plugins/apm/public/store/config/configureStore'; +import { IUrlParams } from 'x-pack/plugins/apm/public/store/urlParams'; +import { TransactionOverview } from '..'; + +function setup(props: { + urlParams: IUrlParams; + serviceTransactionTypes: string[]; +}) { + const store = configureStore(); + const history = createHistory(); + history.replace = jest.fn(); + + const { container } = render( + + + + + + ); + + return { container, history }; +} + +describe('TransactionOverviewView', () => { + describe('when no transaction type is given', () => { + it('should render null', () => { + const { container } = setup({ + serviceTransactionTypes: ['firstType', 'secondType'], + urlParams: { + serviceName: 'MyServiceName' + } + }); + expect(container).toMatchInlineSnapshot(`
`); + }); + + it('should redirect to first type', () => { + const { history } = setup({ + serviceTransactionTypes: ['firstType', 'secondType'], + urlParams: { + serviceName: 'MyServiceName' + } + }); + expect(history.replace).toHaveBeenCalledWith( + expect.objectContaining({ + pathname: '/MyServiceName/transactions/firstType' + }) + ); + }); + }); + + const FILTER_BY_TYPE_LABEL = 'Filter by type'; + + describe('when transactionType is selected and multiple transaction types are given', () => { + it('should render dropdown with transaction types', () => { + const { container } = setup({ + serviceTransactionTypes: ['firstType', 'secondType'], + urlParams: { + transactionType: 'secondType', + serviceName: 'MyServiceName' + } + }); + + expect( + queryByLabelText(container, FILTER_BY_TYPE_LABEL) + ).toMatchSnapshot(); + }); + }); + + describe('when a transaction type is selected, and there are no other transaction types', () => { + it('should not render a dropdown with transaction types', () => { + const { container } = setup({ + serviceTransactionTypes: ['firstType'], + urlParams: { + transactionType: 'firstType', + serviceName: 'MyServiceName' + } + }); + + expect(queryByLabelText(container, FILTER_BY_TYPE_LABEL)).toBeNull(); + }); + }); +}); diff --git a/x-pack/plugins/apm/public/components/app/TransactionOverview/__jest__/__snapshots__/TransactionOverview.test.js.snap b/x-pack/plugins/apm/public/components/app/TransactionOverview/__jest__/__snapshots__/TransactionOverview.test.js.snap deleted file mode 100644 index d6a37bfaa2078..0000000000000 --- a/x-pack/plugins/apm/public/components/app/TransactionOverview/__jest__/__snapshots__/TransactionOverview.test.js.snap +++ /dev/null @@ -1,115 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`TransactionOverviewView should render with type filter controls 1`] = ` - - - - - - - - -

- Transactions -

-
- - -
-
-`; - -exports[`TransactionOverviewView should render without type filter controls if there is just a single type 1`] = ` - - - - - -

- Transactions -

-
- - -
-
-`; diff --git a/x-pack/plugins/apm/public/components/app/TransactionOverview/__jest__/__snapshots__/TransactionOverview.test.tsx.snap b/x-pack/plugins/apm/public/components/app/TransactionOverview/__jest__/__snapshots__/TransactionOverview.test.tsx.snap new file mode 100644 index 0000000000000..41374c9f8fff8 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/TransactionOverview/__jest__/__snapshots__/TransactionOverview.test.tsx.snap @@ -0,0 +1,19 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`TransactionOverviewView when transactionType is selected and multiple transaction types are given should render dropdown with transaction types 1`] = ` + +`; diff --git a/x-pack/plugins/apm/public/components/app/TransactionOverview/index.tsx b/x-pack/plugins/apm/public/components/app/TransactionOverview/index.tsx index eb462a9f917c6..1aa497fb6e9d3 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionOverview/index.tsx +++ b/x-pack/plugins/apm/public/components/app/TransactionOverview/index.tsx @@ -12,91 +12,120 @@ import { EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { Location } from 'history'; +import { first } from 'lodash'; import React from 'react'; import { RouteComponentProps, withRouter } from 'react-router-dom'; import { TransactionCharts } from 'x-pack/plugins/apm/public/components/shared/charts/TransactionCharts'; import { legacyEncodeURIComponent } from 'x-pack/plugins/apm/public/components/shared/Links/url_helpers'; -import { TransactionListRequest } from 'x-pack/plugins/apm/public/store/reactReduxRequest/transactionList'; -import { TransactionOverviewChartsRequest } from 'x-pack/plugins/apm/public/store/reactReduxRequest/transactionOverviewCharts'; import { IUrlParams } from 'x-pack/plugins/apm/public/store/urlParams'; +import { useTransactionList } from '../../../hooks/useTransactionList'; +import { useTransactionOverviewCharts } from '../../../hooks/useTransactionOverviewCharts'; import { TransactionList } from './List'; +import { useRedirect } from './useRedirect'; interface TransactionOverviewProps extends RouteComponentProps { urlParams: IUrlParams; serviceTransactionTypes: string[]; } -export class TransactionOverviewView extends React.Component< - TransactionOverviewProps -> { - public handleTypeChange = (event: React.ChangeEvent) => { - const { urlParams, history, location } = this.props; - const type = legacyEncodeURIComponent(event.target.value); - history.push({ +function getRedirectLocation({ + urlParams, + location, + serviceTransactionTypes +}: { + location: Location; + urlParams: IUrlParams; + serviceTransactionTypes: string[]; +}) { + const { serviceName, transactionType } = urlParams; + const firstTransactionType = first(serviceTransactionTypes); + if (!transactionType && firstTransactionType) { + return { ...location, - pathname: `/${urlParams.serviceName}/transactions/${type}` - }); - }; + pathname: `/${serviceName}/transactions/${firstTransactionType}` + }; + } +} - public render() { - const { urlParams, serviceTransactionTypes, location } = this.props; - const { serviceName, transactionType } = urlParams; +export function TransactionOverviewView({ + urlParams, + serviceTransactionTypes, + location, + history +}: TransactionOverviewProps) { + const { serviceName, transactionType } = urlParams; - // filtering by type is currently required - if (!serviceName || !transactionType) { - return null; - } + // redirect to first transaction type + useRedirect( + history, + getRedirectLocation({ + urlParams, + location, + serviceTransactionTypes + }) + ); - return ( - - {serviceTransactionTypes.length > 1 ? ( - - ({ - text: `${type}`, - value: type - }))} - value={transactionType} - onChange={this.handleTypeChange} - /> - - ) : null} + const { data: transactionOverviewCharts } = useTransactionOverviewCharts( + urlParams + ); - ( - - )} - /> + const { data: transactionListData } = useTransactionList(urlParams); - + // filtering by type is currently required + if (!serviceName || !transactionType) { + return null; + } - - -

Transactions

-
- - ( - - )} + return ( + + {serviceTransactionTypes.length > 1 ? ( + + ({ + text: `${type}`, + value: type + }))} + value={transactionType} + onChange={event => { + const type = legacyEncodeURIComponent(event.target.value); + history.push({ + ...location, + pathname: `/${urlParams.serviceName}/transactions/${type}` + }); + }} /> -
-
- ); - } + + ) : null} + + + + + + + +

Transactions

+
+ + +
+ + ); } export const TransactionOverview = withRouter(TransactionOverviewView); diff --git a/x-pack/plugins/apm/public/components/app/TransactionOverview/useRedirect.ts b/x-pack/plugins/apm/public/components/app/TransactionOverview/useRedirect.ts new file mode 100644 index 0000000000000..653ea73c1fed8 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/TransactionOverview/useRedirect.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { History, Location } from 'history'; +import { useEffect } from 'react'; + +export function useRedirect(history: History, redirectLocation?: Location) { + useEffect(() => { + if (redirectLocation) { + history.replace(redirectLocation); + } + }); +} diff --git a/x-pack/plugins/apm/public/components/shared/FilterBar/__test__/DatePicker.test.tsx b/x-pack/plugins/apm/public/components/shared/FilterBar/__test__/DatePicker.test.tsx index 2ff953e1fe536..5508bc0b0148a 100644 --- a/x-pack/plugins/apm/public/components/shared/FilterBar/__test__/DatePicker.test.tsx +++ b/x-pack/plugins/apm/public/components/shared/FilterBar/__test__/DatePicker.test.tsx @@ -11,7 +11,7 @@ import { MemoryRouter } from 'react-router-dom'; import { Store } from 'redux'; // @ts-ignore import configureStore from 'x-pack/plugins/apm/public/store/config/configureStore'; -import { mockNow } from 'x-pack/plugins/apm/public/utils/testHelpers'; +import { mockNow, tick } from 'x-pack/plugins/apm/public/utils/testHelpers'; import { DatePicker, DatePickerComponent } from '../DatePicker'; function mountPicker(initialState = {}) { @@ -54,8 +54,6 @@ describe('DatePicker', () => { }); }); - const tick = () => new Promise(resolve => setImmediate(resolve, 0)); - describe('refresh cycle', () => { let nowSpy: jest.Mock; beforeEach(() => { diff --git a/x-pack/plugins/apm/public/components/shared/KueryBar/Typeahead/Suggestion.js b/x-pack/plugins/apm/public/components/shared/KueryBar/Typeahead/Suggestion.js index 618d9db44fa5c..e7c5564851efa 100644 --- a/x-pack/plugins/apm/public/components/shared/KueryBar/Typeahead/Suggestion.js +++ b/x-pack/plugins/apm/public/components/shared/KueryBar/Typeahead/Suggestion.js @@ -113,9 +113,7 @@ function Suggestion(props) { {props.suggestion.text} - + {props.suggestion.description} ); } diff --git a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__test__/DiscoverLinks.integration.test.tsx b/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__test__/DiscoverLinks.integration.test.tsx index ed5c609cb9003..12198b1a870df 100644 --- a/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__test__/DiscoverLinks.integration.test.tsx +++ b/x-pack/plugins/apm/public/components/shared/Links/DiscoverLinks/__test__/DiscoverLinks.integration.test.tsx @@ -15,8 +15,6 @@ import { DiscoverErrorLink } from '../DiscoverErrorLink'; import { DiscoverSpanLink } from '../DiscoverSpanLink'; import { DiscoverTransactionLink } from '../DiscoverTransactionLink'; -// NOTE: jest.mock() is broken in TS test files (b/c of ts-jest, I think) -// but using jest's "spies can be stubbed" feature, this works: jest .spyOn(savedObjects, 'getAPMIndexPattern') .mockReturnValue( diff --git a/x-pack/plugins/apm/public/components/shared/PropertiesTable/__test__/tabConfig.test.tsx b/x-pack/plugins/apm/public/components/shared/PropertiesTable/__test__/tabConfig.test.tsx index 47cffde62612e..61d2fcf026652 100644 --- a/x-pack/plugins/apm/public/components/shared/PropertiesTable/__test__/tabConfig.test.tsx +++ b/x-pack/plugins/apm/public/components/shared/PropertiesTable/__test__/tabConfig.test.tsx @@ -4,18 +4,33 @@ * you may not use this file except in compliance with the Elastic License. */ +jest.mock('../tabConfigConst', () => { + return { + TAB_CONFIG: [ + { + key: 'testProperty', + label: 'testPropertyLabel', + required: false, + presortedKeys: ['name', 'age'] + }, + { + key: 'optionalProperty', + label: 'optionalPropertyLabel', + required: false + }, + { + key: 'requiredProperty', + label: 'requiredPropertyLabel', + required: true + } + ] + }; +}); + import * as propertyConfig from '../tabConfig'; const { getTabsFromObject, sortKeysByConfig } = propertyConfig; describe('tabConfig', () => { - beforeEach(() => { - mockPropertyConfig(); - }); - - afterEach(() => { - unMockPropertyConfig(); - }); - describe('getTabsFromObject', () => { it('should return selected and required keys only', () => { const expectedTabs = [ @@ -64,31 +79,3 @@ describe('tabConfig', () => { }); }); }); - -function mockPropertyConfig() { - // @ts-ignore - propertyConfig.TAB_CONFIG = [ - { - key: 'testProperty', - label: 'testPropertyLabel', - required: false, - presortedKeys: ['name', 'age'] - }, - { - key: 'optionalProperty', - label: 'optionalPropertyLabel', - required: false - }, - { - key: 'requiredProperty', - label: 'requiredPropertyLabel', - required: true - } - ]; -} - -const originalPropertyConfig = propertyConfig.TAB_CONFIG; -function unMockPropertyConfig() { - // @ts-ignore - propertyConfig.TAB_CONFIG = originalPropertyConfig; -} diff --git a/x-pack/plugins/apm/public/components/shared/PropertiesTable/tabConfig.ts b/x-pack/plugins/apm/public/components/shared/PropertiesTable/tabConfig.ts index cb9ce7f8538bc..2648c2875cd84 100644 --- a/x-pack/plugins/apm/public/components/shared/PropertiesTable/tabConfig.ts +++ b/x-pack/plugins/apm/public/components/shared/PropertiesTable/tabConfig.ts @@ -4,28 +4,17 @@ * you may not use this file except in compliance with the Elastic License. */ -import { i18n } from '@kbn/i18n'; import { get, indexBy, uniq } from 'lodash'; import { first, has } from 'lodash'; import { StringMap } from 'x-pack/plugins/apm/typings/common'; import { APMError } from 'x-pack/plugins/apm/typings/es_schemas/ui/APMError'; import { Transaction } from 'x-pack/plugins/apm/typings/es_schemas/ui/Transaction'; - -export type PropertyTabKey = - | keyof Transaction - | keyof APMError - | 'transaction.custom' - | 'error.custom'; - -export interface PropertyTab { - key: PropertyTabKey; - label: string; -} - -interface TabConfig extends PropertyTab { - required: boolean; - presortedKeys: string[]; -} +import { + PropertyTab, + PropertyTabKey, + TAB_CONFIG, + TabConfig +} from './tabConfigConst'; export function getTabsFromObject(obj: Transaction | APMError): PropertyTab[] { return TAB_CONFIG.filter( @@ -53,96 +42,4 @@ export function getCurrentTab( return selectedTab ? selectedTab : first(tabs) || {}; } -export const TAB_CONFIG: TabConfig[] = [ - { - key: 'http', - label: i18n.translate('xpack.apm.propertiesTable.tabs.httpLabel', { - defaultMessage: 'HTTP' - }), - required: false, - presortedKeys: [] - }, - { - key: 'host', - label: i18n.translate('xpack.apm.propertiesTable.tabs.hostLabel', { - defaultMessage: 'Host' - }), - required: false, - presortedKeys: ['hostname', 'architecture', 'platform'] - }, - { - key: 'service', - label: i18n.translate('xpack.apm.propertiesTable.tabs.serviceLabel', { - defaultMessage: 'Service' - }), - required: false, - presortedKeys: ['runtime', 'framework', 'version'] - }, - { - key: 'process', - label: i18n.translate('xpack.apm.propertiesTable.tabs.processLabel', { - defaultMessage: 'Process' - }), - required: false, - presortedKeys: ['pid', 'title', 'args'] - }, - { - key: 'agent', - label: i18n.translate('xpack.apm.propertiesTable.tabs.agentLabel', { - defaultMessage: 'Agent' - }), - required: false, - presortedKeys: [] - }, - { - key: 'url', - label: i18n.translate('xpack.apm.propertiesTable.tabs.urlLabel', { - defaultMessage: 'URL' - }), - required: false, - presortedKeys: [] - }, - { - key: 'container', - label: i18n.translate('xpack.apm.propertiesTable.tabs.containerLabel', { - defaultMessage: 'Container' - }), - required: false, - presortedKeys: [] - }, - { - key: 'user', - label: i18n.translate('xpack.apm.propertiesTable.tabs.userLabel', { - defaultMessage: 'User' - }), - required: true, - presortedKeys: ['id', 'username', 'email'] - }, - { - key: 'labels', - label: i18n.translate('xpack.apm.propertiesTable.tabs.labelsLabel', { - defaultMessage: 'Labels' - }), - required: true, - presortedKeys: [] - }, - { - key: 'transaction.custom', - label: i18n.translate( - 'xpack.apm.propertiesTable.tabs.transactionCustomLabel', - { - defaultMessage: 'Custom' - } - ), - required: false, - presortedKeys: [] - }, - { - key: 'error.custom', - label: i18n.translate('xpack.apm.propertiesTable.tabs.errorCustomLabel', { - defaultMessage: 'Custom' - }), - required: false, - presortedKeys: [] - } -]; +export { TAB_CONFIG, TabConfig, PropertyTab, PropertyTabKey }; diff --git a/x-pack/plugins/apm/public/components/shared/PropertiesTable/tabConfigConst.ts b/x-pack/plugins/apm/public/components/shared/PropertiesTable/tabConfigConst.ts new file mode 100644 index 0000000000000..95c4f6da9f37e --- /dev/null +++ b/x-pack/plugins/apm/public/components/shared/PropertiesTable/tabConfigConst.ts @@ -0,0 +1,119 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; +import { APMError } from 'x-pack/plugins/apm/typings/es_schemas/ui/APMError'; +import { Transaction } from 'x-pack/plugins/apm/typings/es_schemas/ui/Transaction'; + +export type PropertyTabKey = + | keyof Transaction + | keyof APMError + | 'transaction.custom' + | 'error.custom'; + +export interface PropertyTab { + key: PropertyTabKey; + label: string; +} + +export interface TabConfig extends PropertyTab { + required: boolean; + presortedKeys: string[]; +} + +export const TAB_CONFIG: TabConfig[] = [ + { + key: 'http', + label: i18n.translate('xpack.apm.propertiesTable.tabs.httpLabel', { + defaultMessage: 'HTTP' + }), + required: false, + presortedKeys: [] + }, + { + key: 'host', + label: i18n.translate('xpack.apm.propertiesTable.tabs.hostLabel', { + defaultMessage: 'Host' + }), + required: false, + presortedKeys: ['hostname', 'architecture', 'platform'] + }, + { + key: 'service', + label: i18n.translate('xpack.apm.propertiesTable.tabs.serviceLabel', { + defaultMessage: 'Service' + }), + required: false, + presortedKeys: ['runtime', 'framework', 'version'] + }, + { + key: 'process', + label: i18n.translate('xpack.apm.propertiesTable.tabs.processLabel', { + defaultMessage: 'Process' + }), + required: false, + presortedKeys: ['pid', 'title', 'args'] + }, + { + key: 'agent', + label: i18n.translate('xpack.apm.propertiesTable.tabs.agentLabel', { + defaultMessage: 'Agent' + }), + required: false, + presortedKeys: [] + }, + { + key: 'url', + label: i18n.translate('xpack.apm.propertiesTable.tabs.urlLabel', { + defaultMessage: 'URL' + }), + required: false, + presortedKeys: [] + }, + { + key: 'container', + label: i18n.translate('xpack.apm.propertiesTable.tabs.containerLabel', { + defaultMessage: 'Container' + }), + required: false, + presortedKeys: [] + }, + { + key: 'user', + label: i18n.translate('xpack.apm.propertiesTable.tabs.userLabel', { + defaultMessage: 'User' + }), + required: true, + presortedKeys: ['id', 'username', 'email'] + }, + { + key: 'labels', + label: i18n.translate('xpack.apm.propertiesTable.tabs.labelsLabel', { + defaultMessage: 'Labels' + }), + required: true, + presortedKeys: [] + }, + { + key: 'transaction.custom', + label: i18n.translate( + 'xpack.apm.propertiesTable.tabs.transactionCustomLabel', + { + defaultMessage: 'Custom' + } + ), + required: false, + presortedKeys: [] + }, + { + key: 'error.custom', + label: i18n.translate('xpack.apm.propertiesTable.tabs.errorCustomLabel', { + defaultMessage: 'Custom' + }), + required: false, + presortedKeys: [] + } +]; diff --git a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/index.tsx b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/index.tsx index d62122b9137de..74ad7fb66c442 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/index.tsx @@ -4,17 +4,220 @@ * you may not use this file except in compliance with the Elastic License. */ -import { connect } from 'react-redux'; -import { selectHasMLJob } from 'x-pack/plugins/apm/public/store/reactReduxRequest/transactionOverviewCharts'; -import { IReduxState } from 'x-pack/plugins/apm/public/store/rootReducer'; -import { selectIsMLAvailable } from 'x-pack/plugins/apm/public/store/selectors/license'; -import { TransactionChartsView } from './view'; - -const mapStateToProps = (state: IReduxState) => ({ - mlAvailable: selectIsMLAvailable(state), - hasMLJob: selectHasMLJob(state) -}); - -export const TransactionCharts = connect(mapStateToProps)( - TransactionChartsView +import { + EuiFlexGrid, + EuiFlexGroup, + EuiFlexItem, + EuiIconTip, + EuiPanel, + EuiText, + EuiTitle +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { Location } from 'history'; +import React, { Component } from 'react'; +import styled from 'styled-components'; +import { MLJobLink } from 'x-pack/plugins/apm/public/components/shared/Links/MLJobLink'; +import { ITransactionChartData } from 'x-pack/plugins/apm/public/store/selectors/chartSelectors'; +import { IUrlParams } from 'x-pack/plugins/apm/public/store/urlParams'; +import { Coordinate } from 'x-pack/plugins/apm/typings/timeseries'; +import { asInteger, asMillis, tpmUnit } from '../../../../utils/formatters'; +import { LicenseContext } from '../../../app/Main/LicenseCheck'; +// @ts-ignore +import CustomPlot from '../CustomPlot'; +import { SyncChartGroup } from '../SyncChartGroup'; + +interface TransactionChartProps { + charts: ITransactionChartData; + location: Location; + urlParams: IUrlParams; +} + +const ShiftedIconWrapper = styled.span` + padding-right: 5px; + position: relative; + top: -1px; + display: inline-block; +`; + +const ShiftedEuiText = styled(EuiText)` + position: relative; + top: 5px; +`; + +const msTimeUnitLabel = i18n.translate( + 'xpack.apm.metrics.transactionChart.msTimeUnitLabel', + { + defaultMessage: 'ms' + } ); + +export class TransactionCharts extends Component { + public getResponseTimeTickFormatter = (t: number) => { + return this.props.charts.noHits ? `- ${msTimeUnitLabel}` : asMillis(t); + }; + + public getResponseTimeTooltipFormatter = (p: Coordinate) => { + return this.props.charts.noHits || !p + ? `- ${msTimeUnitLabel}` + : asMillis(p.y); + }; + + public getTPMFormatter = (t: number | null) => { + const { urlParams, charts } = this.props; + const unit = tpmUnit(urlParams.transactionType); + return charts.noHits || t === null + ? `- ${unit}` + : `${asInteger(t)} ${unit}`; + }; + + public getTPMTooltipFormatter = (p: Coordinate) => { + return this.getTPMFormatter(p.y); + }; + + public renderMLHeader(mlAvailable: boolean) { + const hasMLJob = this.props.charts.hasMLJob; + if (!mlAvailable || !hasMLJob) { + return null; + } + + const { serviceName, transactionType } = this.props.urlParams; + + if (!serviceName) { + return null; + } + + return ( + + + + = 75.' + } + )} + /> + + + {i18n.translate( + 'xpack.apm.metrics.transactionChart.machineLearningLabel', + { + defaultMessage: 'Machine learning:' + } + )}{' '} + + + View Job + + + + ); + } + + public render() { + const { charts, urlParams } = this.props; + const { noHits, responseTimeSeries, tpmSeries } = charts; + const { transactionType } = urlParams; + + return ( + ( + + + + + + + + {responseTimeLabel(transactionType)} + + + + {license => + this.renderMLHeader(license.features.ml.is_available) + } + + + + + + + + + + + + {tpmLabel(transactionType)} + + + + + + + )} + /> + ); + } +} + +function tpmLabel(type?: string) { + return type === 'request' + ? i18n.translate( + 'xpack.apm.metrics.transactionChart.requestsPerMinuteLabel', + { + defaultMessage: 'Requests per minute' + } + ) + : i18n.translate( + 'xpack.apm.metrics.transactionChart.transactionsPerMinuteLabel', + { + defaultMessage: 'Transactions per minute' + } + ); +} + +function responseTimeLabel(type?: string) { + switch (type) { + case 'page-load': + return i18n.translate( + 'xpack.apm.metrics.transactionChart.pageLoadTimesLabel', + { + defaultMessage: 'Page load times' + } + ); + case 'route-change': + return i18n.translate( + 'xpack.apm.metrics.transactionChart.routeChangeTimesLabel', + { + defaultMessage: 'Route change times' + } + ); + default: + return i18n.translate( + 'xpack.apm.metrics.transactionChart.transactionDurationLabel', + { + defaultMessage: 'Transaction duration' + } + ); + } +} diff --git a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/view.tsx b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/view.tsx deleted file mode 100644 index 1c4d79ed1e990..0000000000000 --- a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/view.tsx +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { - EuiFlexGrid, - EuiFlexGroup, - EuiFlexItem, - EuiIconTip, - EuiPanel, - EuiText, - EuiTitle -} from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { Location } from 'history'; -import React, { Component } from 'react'; -import styled from 'styled-components'; -import { MLJobLink } from 'x-pack/plugins/apm/public/components/shared/Links/MLJobLink'; -import { ITransactionChartData } from 'x-pack/plugins/apm/public/store/selectors/chartSelectors'; -import { IUrlParams } from 'x-pack/plugins/apm/public/store/urlParams'; -import { Coordinate } from 'x-pack/plugins/apm/typings/timeseries'; -import { asInteger, asMillis, tpmUnit } from '../../../../utils/formatters'; -// @ts-ignore -import CustomPlot from '../CustomPlot'; -import { SyncChartGroup } from '../SyncChartGroup'; - -interface TransactionChartProps { - charts: ITransactionChartData; - chartWrapper?: React.ComponentClass | React.SFC; - location: Location; - urlParams: IUrlParams; - mlAvailable: boolean; - hasMLJob: boolean; -} - -const ShiftedIconWrapper = styled.span` - padding-right: 5px; - position: relative; - top: -1px; - display: inline-block; -`; - -const ShiftedEuiText = styled(EuiText)` - position: relative; - top: 5px; -`; - -const msTimeUnitLabel = i18n.translate( - 'xpack.apm.metrics.transactionChart.msTimeUnitLabel', - { - defaultMessage: 'ms' - } -); - -export class TransactionChartsView extends Component { - public getResponseTimeTickFormatter = (t: number) => { - return this.props.charts.noHits ? `- ${msTimeUnitLabel}` : asMillis(t); - }; - - public getResponseTimeTooltipFormatter = (p: Coordinate) => { - return this.props.charts.noHits || !p - ? `- ${msTimeUnitLabel}` - : asMillis(p.y); - }; - - public getTPMFormatter = (t: number | null) => { - const { urlParams, charts } = this.props; - const unit = tpmUnit(urlParams.transactionType); - return charts.noHits || t === null - ? `- ${unit}` - : `${asInteger(t)} ${unit}`; - }; - - public getTPMTooltipFormatter = (p: Coordinate) => { - return this.getTPMFormatter(p.y); - }; - - public renderMLHeader() { - if (!this.props.mlAvailable || !this.props.hasMLJob) { - return null; - } - - const { serviceName, transactionType } = this.props.urlParams; - - if (!serviceName) { - return null; - } - - return ( - - - - = 75.' - } - )} - /> - - - {i18n.translate( - 'xpack.apm.metrics.transactionChart.machineLearningLabel', - { - defaultMessage: 'Machine learning:' - } - )}{' '} - - - View Job - - - - ); - } - - public render() { - const { - charts, - urlParams, - chartWrapper: ChartWrapper = React.Fragment - } = this.props; - const { noHits, responseTimeSeries, tpmSeries } = charts; - const { transactionType } = urlParams; - - return ( - ( - - - - - - - - {responseTimeLabel(transactionType)} - - - {this.renderMLHeader()} - - - - - - - - - - - {tpmLabel(transactionType)} - - - - - - - )} - /> - ); - } -} - -function tpmLabel(type?: string) { - return type === 'request' - ? i18n.translate( - 'xpack.apm.metrics.transactionChart.requestsPerMinuteLabel', - { - defaultMessage: 'Requests per minute' - } - ) - : i18n.translate( - 'xpack.apm.metrics.transactionChart.transactionsPerMinuteLabel', - { - defaultMessage: 'Transactions per minute' - } - ); -} - -function responseTimeLabel(type?: string) { - switch (type) { - case 'page-load': - return i18n.translate( - 'xpack.apm.metrics.transactionChart.pageLoadTimesLabel', - { - defaultMessage: 'Page load times' - } - ); - case 'route-change': - return i18n.translate( - 'xpack.apm.metrics.transactionChart.routeChangeTimesLabel', - { - defaultMessage: 'Route change times' - } - ); - default: - return i18n.translate( - 'xpack.apm.metrics.transactionChart.transactionDurationLabel', - { - defaultMessage: 'Transaction duration' - } - ); - } -} diff --git a/x-pack/plugins/apm/public/hooks/useFetcher.integration.test.tsx b/x-pack/plugins/apm/public/hooks/useFetcher.integration.test.tsx new file mode 100644 index 0000000000000..6d4d0557bc27a --- /dev/null +++ b/x-pack/plugins/apm/public/hooks/useFetcher.integration.test.tsx @@ -0,0 +1,121 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { render } from 'react-testing-library'; +import { delay, tick } from '../utils/testHelpers'; +import { useFetcher } from './useFetcher'; + +// Suppress warnings about "act" until async/await syntax is supported: https://github.com/facebook/react/issues/14769 +/* tslint:disable:no-console */ +const originalError = console.error; +beforeAll(() => { + console.error = jest.fn(); +}); +afterAll(() => { + console.error = originalError; +}); + +async function asyncFn(name: string, ms: number) { + await delay(ms); + return `Hello from ${name}`; +} + +describe('when simulating race condition', () => { + let requestCallOrder: Array<[string, string, number]>; + let renderSpy: jest.Mock; + + beforeEach(async () => { + jest.useFakeTimers(); + jest + .spyOn(window, 'requestAnimationFrame') + .mockImplementation(cb => cb(0) as any); + + renderSpy = jest.fn(); + requestCallOrder = []; + + function MyComponent({ + name, + ms, + renderFn + }: { + name: string; + ms: number; + renderFn: any; + }) { + const { data, status, error } = useFetcher( + async () => { + requestCallOrder.push(['request', name, ms]); + const res = await asyncFn(name, ms); + requestCallOrder.push(['response', name, ms]); + return res; + }, + [name, ms] + ); + renderFn({ data, status, error }); + return null; + } + + const { rerender } = render( + + ); + + rerender(); + }); + + it('should render initially render loading state', async () => { + expect(renderSpy).lastCalledWith({ + data: undefined, + error: undefined, + status: 'loading' + }); + }); + + it('should render "Hello from Peter" after 200ms', async () => { + jest.advanceTimersByTime(200); + await tick(); + + expect(renderSpy).lastCalledWith({ + data: 'Hello from Peter', + error: undefined, + status: 'success' + }); + }); + + it('should render "Hello from Peter" after 600ms', async () => { + jest.advanceTimersByTime(600); + await tick(); + + expect(renderSpy).lastCalledWith({ + data: 'Hello from Peter', + error: undefined, + status: 'success' + }); + }); + + it('should should NOT have rendered "Hello from John" at any point', async () => { + jest.advanceTimersByTime(600); + await tick(); + + expect(renderSpy).not.toHaveBeenCalledWith({ + data: 'Hello from John', + error: undefined, + status: 'success' + }); + }); + + it('should send and receive calls in the right order', async () => { + jest.advanceTimersByTime(600); + await tick(); + + expect(requestCallOrder).toEqual([ + ['request', 'John', 500], + ['request', 'Peter', 100], + ['response', 'Peter', 100], + ['response', 'John', 500] + ]); + }); +}); diff --git a/x-pack/plugins/apm/public/hooks/useFetcher.test.tsx b/x-pack/plugins/apm/public/hooks/useFetcher.test.tsx new file mode 100644 index 0000000000000..87722ce3c0275 --- /dev/null +++ b/x-pack/plugins/apm/public/hooks/useFetcher.test.tsx @@ -0,0 +1,159 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { cleanup, renderHook } from 'react-hooks-testing-library'; +import { delay } from '../utils/testHelpers'; +import { useFetcher } from './useFetcher'; + +afterEach(cleanup); + +// Suppress warnings about "act" until async/await syntax is supported: https://github.com/facebook/react/issues/14769 +/* tslint:disable:no-console */ +const originalError = console.error; +beforeAll(() => { + console.error = jest.fn(); +}); +afterAll(() => { + console.error = originalError; +}); + +describe('useFetcher', () => { + describe('when resolving after 500ms', () => { + let hook: ReturnType; + beforeEach(() => { + jest.useFakeTimers(); + async function fn() { + await delay(500); + return 'response from hook'; + } + hook = renderHook(() => useFetcher(() => fn(), [])); + }); + + it('should initially be empty', async () => { + expect(hook.result.current).toEqual({ + data: undefined, + error: undefined, + status: undefined + }); + }); + + it('should show loading spinner after 100ms', async () => { + jest.advanceTimersByTime(100); + await hook.waitForNextUpdate(); + + expect(hook.result.current).toEqual({ + data: undefined, + error: undefined, + status: 'loading' + }); + }); + + it('should show success after 1 second', async () => { + jest.advanceTimersByTime(1000); + await hook.waitForNextUpdate(); + + expect(hook.result.current).toEqual({ + data: 'response from hook', + error: undefined, + status: 'success' + }); + }); + }); + + describe('when throwing after 500ms', () => { + let hook: ReturnType; + beforeEach(() => { + jest.useFakeTimers(); + async function fn() { + await delay(500); + throw new Error('Something went wrong'); + } + hook = renderHook(() => useFetcher(() => fn(), [])); + }); + + it('should initially be empty', async () => { + expect(hook.result.current).toEqual({ + data: undefined, + error: undefined, + status: undefined + }); + }); + + it('should show loading spinner after 100ms', async () => { + jest.advanceTimersByTime(100); + await hook.waitForNextUpdate(); + + expect(hook.result.current).toEqual({ + data: undefined, + error: undefined, + status: 'loading' + }); + }); + + it('should show error after 1 second', async () => { + jest.advanceTimersByTime(1000); + await hook.waitForNextUpdate(); + + expect(hook.result.current).toEqual({ + data: undefined, + error: expect.any(Error), + status: 'failure' + }); + }); + }); + + describe('when a hook already has data', () => { + it('should show "first response" while loading "second response"', async () => { + jest.useFakeTimers(); + const hook = renderHook( + ({ callback, args }) => useFetcher(callback, args), + { + initialProps: { + callback: async () => 'first response', + args: ['a'] + } + } + ); + await hook.waitForNextUpdate(); + + // assert: first response has loaded and should be rendered + expect(hook.result.current).toEqual({ + data: 'first response', + error: undefined, + status: 'success' + }); + + // act: re-render hook with async callback + hook.rerender({ + callback: async () => { + await delay(500); + return 'second response'; + }, + args: ['b'] + }); + + jest.advanceTimersByTime(100); + await hook.waitForNextUpdate(); + + // assert: while loading new data the previous data should still be rendered + expect(hook.result.current).toEqual({ + data: 'first response', + error: undefined, + status: 'loading' + }); + + jest.advanceTimersByTime(500); + await hook.waitForNextUpdate(); + + // assert: "second response" has loaded and should be rendered + expect(hook.result.current).toEqual({ + data: 'second response', + error: undefined, + status: 'success' + }); + }); + }); +}); diff --git a/x-pack/plugins/apm/public/hooks/useFetcher.tsx b/x-pack/plugins/apm/public/hooks/useFetcher.tsx new file mode 100644 index 0000000000000..6022f8bb75853 --- /dev/null +++ b/x-pack/plugins/apm/public/hooks/useFetcher.tsx @@ -0,0 +1,83 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { useContext, useEffect, useState } from 'react'; +import { GlobalFetchContext } from '../components/app/Main/GlobalFetchIndicator'; + +export enum FETCH_STATUS { + LOADING = 'loading', + SUCCESS = 'success', + FAILURE = 'failure' +} + +// use this in request methods to signal to `useFetch` that all arguments are not yet available +export class MissingArgumentsError extends Error {} + +export function useFetcher( + fn: () => Promise, + useEffectKey: Array +) { + const { dispatchStatus } = useContext(GlobalFetchContext); + const [result, setResult] = useState<{ + data?: Response; + status?: FETCH_STATUS; + error?: Error; + }>({}); + + useEffect(() => { + let didCancel = false; + let didFinish = false; + + // only apply the loading indicator if the promise did not resolve immediately + // the promise will resolve immediately if the value was found in cache + requestAnimationFrame(() => { + if (!didFinish && !didCancel) { + dispatchStatus({ name: fn.name, isLoading: true }); + setResult({ + data: result.data, // preserve data from previous state while loading next state + status: FETCH_STATUS.LOADING, + error: undefined + }); + } + }); + + async function doFetch() { + try { + const data = await fn(); + if (!didCancel) { + dispatchStatus({ name: fn.name, isLoading: false }); + setResult({ + data, + status: FETCH_STATUS.SUCCESS, + error: undefined + }); + } + } catch (e) { + if (e instanceof MissingArgumentsError) { + return; + } + if (!didCancel) { + dispatchStatus({ name: fn.name, isLoading: false }); + setResult({ + data: undefined, + status: FETCH_STATUS.FAILURE, + error: e + }); + } + } + didFinish = true; + } + + doFetch(); + + return () => { + dispatchStatus({ name: fn.name, isLoading: false }); + didCancel = true; + }; + }, useEffectKey); + + return result || {}; +} diff --git a/x-pack/plugins/apm/public/hooks/useServiceMetricCharts.ts b/x-pack/plugins/apm/public/hooks/useServiceMetricCharts.ts new file mode 100644 index 0000000000000..040ac6efa59d8 --- /dev/null +++ b/x-pack/plugins/apm/public/hooks/useServiceMetricCharts.ts @@ -0,0 +1,85 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { useMemo } from 'react'; +import { MetricsChartAPIResponse } from '../../server/lib/metrics/get_all_metrics_chart_data'; +import { MemoryChartAPIResponse } from '../../server/lib/metrics/get_memory_chart_data'; +import { loadMetricsChartDataForService } from '../services/rest/apm/metrics'; +import { + getCPUSeries, + getMemorySeries +} from '../store/selectors/chartSelectors'; +import { IUrlParams } from '../store/urlParams'; +import { useFetcher } from './useFetcher'; + +const memory: MemoryChartAPIResponse = { + series: { + memoryUsedAvg: [], + memoryUsedMax: [] + }, + overallValues: { + memoryUsedAvg: null, + memoryUsedMax: null + }, + totalHits: 0 +}; + +const INITIAL_DATA: MetricsChartAPIResponse = { + memory, + cpu: { + series: { + systemCPUAverage: [], + systemCPUMax: [], + processCPUAverage: [], + processCPUMax: [] + }, + overallValues: { + systemCPUAverage: null, + systemCPUMax: null, + processCPUAverage: null, + processCPUMax: null + }, + totalHits: 0 + } +}; + +export function useServiceMetricCharts(urlParams: IUrlParams) { + const { + serviceName, + transactionType, + start, + end, + transactionName, + kuery + } = urlParams; + + const { data = INITIAL_DATA, error, status } = useFetcher( + () => + loadMetricsChartDataForService({ + serviceName, + transactionName, + transactionType, + start, + end, + kuery + }), + [serviceName, transactionName, transactionType, start, end, kuery] + ); + + const memoizedData = useMemo( + () => ({ + memory: getMemorySeries(urlParams, data.memory), + cpu: getCPUSeries(data.cpu) + }), + [data] + ); + + return { + data: memoizedData, + status, + error + }; +} diff --git a/x-pack/plugins/apm/public/hooks/useTransactionDetailsCharts.ts b/x-pack/plugins/apm/public/hooks/useTransactionDetailsCharts.ts new file mode 100644 index 0000000000000..7a9adfc55035a --- /dev/null +++ b/x-pack/plugins/apm/public/hooks/useTransactionDetailsCharts.ts @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { useMemo } from 'react'; +import { loadTransactionDetailsCharts } from '../services/rest/apm/transaction_groups'; +import { getTransactionCharts } from '../store/selectors/chartSelectors'; +import { IUrlParams } from '../store/urlParams'; +import { useFetcher } from './useFetcher'; + +export function useTransactionDetailsCharts(urlParams: IUrlParams) { + const { + serviceName, + transactionType, + start, + end, + transactionName, + kuery + } = urlParams; + + const { data, error, status } = useFetcher( + () => + loadTransactionDetailsCharts({ + serviceName, + transactionName, + transactionType, + start, + end, + kuery + }), + [serviceName, transactionName, transactionType, start, end, kuery] + ); + + const memoizedData = useMemo(() => getTransactionCharts(urlParams, data), [ + data + ]); + + return { + data: memoizedData, + status, + error + }; +} diff --git a/x-pack/plugins/apm/public/hooks/useTransactionDistribution.ts b/x-pack/plugins/apm/public/hooks/useTransactionDistribution.ts new file mode 100644 index 0000000000000..815d709ebfdb2 --- /dev/null +++ b/x-pack/plugins/apm/public/hooks/useTransactionDistribution.ts @@ -0,0 +1,50 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { loadTransactionDistribution } from '../services/rest/apm/transaction_groups'; +import { IUrlParams } from '../store/urlParams'; +import { useFetcher } from './useFetcher'; + +const INITIAL_DATA = { buckets: [], totalHits: 0, bucketSize: 0 }; + +export function useTransactionDistribution(urlParams: IUrlParams) { + const { + serviceName, + transactionType, + transactionId, + traceId, + start, + end, + transactionName, + kuery + } = urlParams; + + const { data = INITIAL_DATA, status, error } = useFetcher( + () => + loadTransactionDistribution({ + serviceName, + transactionType, + transactionId, + traceId, + start, + end, + transactionName, + kuery + }), + [ + serviceName, + transactionType, + transactionId, + traceId, + start, + end, + transactionName, + kuery + ] + ); + + return { data, status, error }; +} diff --git a/x-pack/plugins/apm/public/hooks/useTransactionList.ts b/x-pack/plugins/apm/public/hooks/useTransactionList.ts new file mode 100644 index 0000000000000..fa04aca4280e0 --- /dev/null +++ b/x-pack/plugins/apm/public/hooks/useTransactionList.ts @@ -0,0 +1,50 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { useMemo } from 'react'; +import { TransactionListAPIResponse } from '../../server/lib/transactions/get_top_transactions'; +import { loadTransactionList } from '../services/rest/apm/transaction_groups'; +import { IUrlParams } from '../store/urlParams'; +import { useFetcher } from './useFetcher'; + +const getRelativeImpact = ( + impact: number, + impactMin: number, + impactMax: number +) => + Math.max( + ((impact - impactMin) / Math.max(impactMax - impactMin, 1)) * 100, + 1 + ); + +function getWithRelativeImpact(items: TransactionListAPIResponse) { + const impacts = items.map(({ impact }) => impact); + const impactMin = Math.min(...impacts); + const impactMax = Math.max(...impacts); + + return items.map(item => { + return { + ...item, + impactRelative: getRelativeImpact(item.impact, impactMin, impactMax) + }; + }); +} + +export function useTransactionList(urlParams: IUrlParams) { + const { serviceName, transactionType, start, end, kuery } = urlParams; + const { data = [], error, status } = useFetcher( + () => + loadTransactionList({ serviceName, start, end, transactionType, kuery }), + [serviceName, start, end, transactionType, kuery] + ); + + const memoizedData = useMemo(() => getWithRelativeImpact(data), [data]); + return { + data: memoizedData, + status, + error + }; +} diff --git a/x-pack/plugins/apm/public/hooks/useTransactionOverviewCharts.ts b/x-pack/plugins/apm/public/hooks/useTransactionOverviewCharts.ts new file mode 100644 index 0000000000000..20779069680cb --- /dev/null +++ b/x-pack/plugins/apm/public/hooks/useTransactionOverviewCharts.ts @@ -0,0 +1,44 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { useMemo } from 'react'; +import { loadTransactionOverviewCharts } from '../services/rest/apm/transaction_groups'; +import { getTransactionCharts } from '../store/selectors/chartSelectors'; +import { IUrlParams } from '../store/urlParams'; +import { useFetcher } from './useFetcher'; + +export function useTransactionOverviewCharts(urlParams: IUrlParams) { + const { + serviceName, + transactionType, + start, + end, + + kuery + } = urlParams; + + const { data, error, status } = useFetcher( + () => + loadTransactionOverviewCharts({ + serviceName, + start, + end, + transactionType, + kuery + }), + [serviceName, start, end, transactionType, kuery] + ); + + const memoizedData = useMemo(() => getTransactionCharts(urlParams, data), [ + data + ]); + + return { + data: memoizedData, + status, + error + }; +} diff --git a/x-pack/plugins/apm/public/hooks/useWaterfall.ts b/x-pack/plugins/apm/public/hooks/useWaterfall.ts new file mode 100644 index 0000000000000..d3b23fa2f156b --- /dev/null +++ b/x-pack/plugins/apm/public/hooks/useWaterfall.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { useMemo } from 'react'; +import { getWaterfall } from '../components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers'; +import { loadTrace } from '../services/rest/apm/traces'; +import { IUrlParams } from '../store/urlParams'; +import { useFetcher } from './useFetcher'; + +const INITIAL_DATA = { trace: [], errorsPerTransaction: {} }; + +export function useWaterfall(urlParams: IUrlParams) { + const { traceId, start, end, transactionId } = urlParams; + const { data = INITIAL_DATA, status, error } = useFetcher( + () => loadTrace({ traceId, start, end }), + [traceId, start, end] + ); + + const waterfall = useMemo(() => getWaterfall(data, transactionId), [ + data, + transactionId + ]); + + return { data: waterfall, status, error }; +} diff --git a/x-pack/plugins/apm/public/index.tsx b/x-pack/plugins/apm/public/index.tsx index 1c7a154ee7f10..3779776c54e0c 100644 --- a/x-pack/plugins/apm/public/index.tsx +++ b/x-pack/plugins/apm/public/index.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { Fragment } from 'react'; +import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; import { Router } from 'react-router-dom'; @@ -18,7 +18,6 @@ import { uiModules } from 'ui/modules'; import 'uiExports/autocompleteProviders'; import { GlobalHelpExtension } from './components/app/GlobalHelpExtension'; import { Main } from './components/app/Main'; -import { GlobalProgress } from './components/app/Main/GlobalProgress'; import { history } from './components/shared/Links/url_helpers'; // @ts-ignore import configureStore from './store/config/configureStore'; @@ -53,12 +52,9 @@ waitForRoot.then(() => { ReactDOM.render( - - - -
- - + +
+ , document.getElementById(REACT_APP_ROOT_ID) diff --git a/x-pack/plugins/apm/public/services/__test__/callApi.test.ts b/x-pack/plugins/apm/public/services/__test__/callApi.test.ts index 0d2183b469821..b28287ab9d630 100644 --- a/x-pack/plugins/apm/public/services/__test__/callApi.test.ts +++ b/x-pack/plugins/apm/public/services/__test__/callApi.test.ts @@ -5,7 +5,8 @@ */ import * as kfetchModule from 'ui/kfetch'; -import { callApi } from '../rest/callApi'; +import { mockNow } from '../../utils/testHelpers'; +import { _clearCache, callApi } from '../rest/callApi'; import { SessionStorageMock } from './SessionStorageMock'; describe('callApi', () => { @@ -21,41 +22,148 @@ describe('callApi', () => { afterEach(() => { kfetchSpy.mockClear(); + _clearCache(); }); - describe('callApi', () => { - describe('apm_debug', () => { - beforeEach(() => { - sessionStorage.setItem('apm_debug', 'true'); + describe('apm_debug', () => { + beforeEach(() => { + sessionStorage.setItem('apm_debug', 'true'); + }); + + it('should add debug param for APM endpoints', async () => { + await callApi({ pathname: `/api/apm/status/server` }); + + expect(kfetchSpy).toHaveBeenCalledWith( + { pathname: '/api/apm/status/server', query: { _debug: true } }, + undefined + ); + }); + + it('should not add debug param for non-APM endpoints', async () => { + await callApi({ pathname: `/api/kibana` }); + + expect(kfetchSpy).toHaveBeenCalledWith( + { pathname: '/api/kibana' }, + undefined + ); + }); + }); + + describe('prependBasePath', () => { + it('should be passed on to kFetch', async () => { + await callApi({ pathname: `/api/kibana` }, { prependBasePath: false }); + + expect(kfetchSpy).toHaveBeenCalledWith( + { pathname: '/api/kibana' }, + { prependBasePath: false } + ); + }); + }); + + describe('cache', () => { + let nowSpy: jest.Mock; + beforeEach(() => { + nowSpy = mockNow('2019'); + }); + + beforeEach(() => { + nowSpy.mockRestore(); + }); + + describe('when the call does not contain start/end params', () => { + it('should not return cached response for identical calls', async () => { + await callApi({ pathname: `/api/kibana`, query: { foo: 'bar' } }); + await callApi({ pathname: `/api/kibana`, query: { foo: 'bar' } }); + await callApi({ pathname: `/api/kibana`, query: { foo: 'bar' } }); + + expect(kfetchSpy).toHaveBeenCalledTimes(3); }); + }); - it('should add debug param for APM endpoints', async () => { - await callApi({ pathname: `/api/apm/status/server` }); + describe('when the call contains start/end params', () => { + it('should return cached response for identical calls', async () => { + await callApi({ + pathname: `/api/kibana`, + query: { start: '2010', end: '2011' } + }); + await callApi({ + pathname: `/api/kibana`, + query: { start: '2010', end: '2011' } + }); + await callApi({ + pathname: `/api/kibana`, + query: { start: '2010', end: '2011' } + }); - expect(kfetchSpy).toHaveBeenCalledWith( - { pathname: '/api/apm/status/server', query: { _debug: true } }, - undefined - ); + expect(kfetchSpy).toHaveBeenCalledTimes(1); }); - it('should not add debug param for non-APM endpoints', async () => { - await callApi({ pathname: `/api/kibana` }); + it('should not return cached response for subsequent calls if arguments change', async () => { + await callApi({ + pathname: `/api/kibana`, + query: { start: '2010', end: '2011', foo: 'bar1' } + }); + await callApi({ + pathname: `/api/kibana`, + query: { start: '2010', end: '2011', foo: 'bar2' } + }); + await callApi({ + pathname: `/api/kibana`, + query: { start: '2010', end: '2011', foo: 'bar3' } + }); - expect(kfetchSpy).toHaveBeenCalledWith( - { pathname: '/api/kibana' }, - undefined - ); + expect(kfetchSpy).toHaveBeenCalledTimes(3); + }); + + it('should not return cached response if `end` is a future timestamp', async () => { + await callApi({ + pathname: `/api/kibana`, + query: { end: '2030' } + }); + await callApi({ + pathname: `/api/kibana`, + query: { end: '2030' } + }); + await callApi({ + pathname: `/api/kibana`, + query: { end: '2030' } + }); + + expect(kfetchSpy).toHaveBeenCalledTimes(3); + }); + + it('should return cached response if calls contain `end` param in the past', async () => { + await callApi({ + pathname: `/api/kibana`, + query: { start: '2009', end: '2010' } + }); + await callApi({ + pathname: `/api/kibana`, + query: { start: '2009', end: '2010' } + }); + await callApi({ + pathname: `/api/kibana`, + query: { start: '2009', end: '2010' } + }); + + expect(kfetchSpy).toHaveBeenCalledTimes(1); }); - }); - describe('prependBasePath', () => { - it('should be passed on to kFetch', async () => { - await callApi({ pathname: `/api/kibana` }, { prependBasePath: false }); + it('should return cached response even if order of properties change', async () => { + await callApi({ + pathname: `/api/kibana`, + query: { end: '2010', start: '2009' } + }); + await callApi({ + pathname: `/api/kibana`, + query: { start: '2009', end: '2010' } + }); + await callApi({ + query: { start: '2009', end: '2010' }, + pathname: `/api/kibana` + }); - expect(kfetchSpy).toHaveBeenCalledWith( - { pathname: '/api/kibana' }, - { prependBasePath: false } - ); + expect(kfetchSpy).toHaveBeenCalledTimes(1); }); }); }); diff --git a/x-pack/plugins/apm/public/services/rest/apm/error_groups.ts b/x-pack/plugins/apm/public/services/rest/apm/error_groups.ts index 0edfaf3495f12..02008a3ceac95 100644 --- a/x-pack/plugins/apm/public/services/rest/apm/error_groups.ts +++ b/x-pack/plugins/apm/public/services/rest/apm/error_groups.ts @@ -7,29 +7,27 @@ import { ErrorDistributionAPIResponse } from 'x-pack/plugins/apm/server/lib/errors/distribution/get_distribution'; import { ErrorGroupAPIResponse } from 'x-pack/plugins/apm/server/lib/errors/get_error_group'; import { ErrorGroupListAPIResponse } from 'x-pack/plugins/apm/server/lib/errors/get_error_groups'; +import { MissingArgumentsError } from '../../../hooks/useFetcher'; import { IUrlParams } from '../../../store/urlParams'; import { callApi } from '../callApi'; import { getEncodedEsQuery } from './apm'; -interface ErrorGroupListParams extends IUrlParams { - size: number; -} - export async function loadErrorGroupList({ serviceName, start, end, kuery, - size, sortField, sortDirection -}: ErrorGroupListParams) { +}: IUrlParams) { + if (!(serviceName && start && end)) { + throw new MissingArgumentsError(); + } return callApi({ pathname: `/api/apm/services/${serviceName}/errors`, query: { start, end, - size, sortField, sortDirection, esFilterQuery: await getEncodedEsQuery(kuery) @@ -44,6 +42,9 @@ export async function loadErrorGroupDetails({ kuery, errorGroupId }: IUrlParams) { + if (!(serviceName && start && end && errorGroupId)) { + throw new MissingArgumentsError(); + } return callApi({ pathname: `/api/apm/services/${serviceName}/errors/${errorGroupId}`, query: { @@ -61,6 +62,10 @@ export async function loadErrorDistribution({ kuery, errorGroupId }: IUrlParams) { + if (!(serviceName && start && end)) { + throw new MissingArgumentsError(); + } + const pathname = errorGroupId ? `/api/apm/services/${serviceName}/errors/${errorGroupId}/distribution` : `/api/apm/services/${serviceName}/errors/distribution`; diff --git a/x-pack/plugins/apm/public/services/rest/apm/metrics.ts b/x-pack/plugins/apm/public/services/rest/apm/metrics.ts index 37c8cf0e918b9..bfeee4c1f289a 100644 --- a/x-pack/plugins/apm/public/services/rest/apm/metrics.ts +++ b/x-pack/plugins/apm/public/services/rest/apm/metrics.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import { MetricsChartAPIResponse } from 'x-pack/plugins/apm/server/lib/metrics/get_all_metrics_chart_data'; import { IUrlParams } from '../../../store/urlParams'; import { callApi } from '../callApi'; import { getEncodedEsQuery } from './apm'; @@ -14,7 +15,7 @@ export async function loadMetricsChartDataForService({ end, kuery }: IUrlParams) { - return callApi({ + return callApi({ pathname: `/api/apm/services/${serviceName}/metrics/charts`, query: { start, diff --git a/x-pack/plugins/apm/public/services/rest/apm/services.ts b/x-pack/plugins/apm/public/services/rest/apm/services.ts index 430d2fa21770b..0af17d58813ad 100644 --- a/x-pack/plugins/apm/public/services/rest/apm/services.ts +++ b/x-pack/plugins/apm/public/services/rest/apm/services.ts @@ -6,11 +6,16 @@ import { ServiceAPIResponse } from 'x-pack/plugins/apm/server/lib/services/get_service'; import { ServiceListAPIResponse } from 'x-pack/plugins/apm/server/lib/services/get_services'; +import { MissingArgumentsError } from '../../../hooks/useFetcher'; import { IUrlParams } from '../../../store/urlParams'; import { callApi } from '../callApi'; import { getEncodedEsQuery } from './apm'; export async function loadServiceList({ start, end, kuery }: IUrlParams) { + if (!(start && end)) { + throw new MissingArgumentsError(); + } + return callApi({ pathname: `/api/apm/services`, query: { @@ -27,6 +32,10 @@ export async function loadServiceDetails({ end, kuery }: IUrlParams) { + if (!(serviceName && start && end)) { + throw new MissingArgumentsError(); + } + return callApi({ pathname: `/api/apm/services/${serviceName}`, query: { diff --git a/x-pack/plugins/apm/public/services/rest/apm/status_check.ts b/x-pack/plugins/apm/public/services/rest/apm/status_check.ts index 30fe628d8e7f4..0c6b660930b41 100644 --- a/x-pack/plugins/apm/public/services/rest/apm/status_check.ts +++ b/x-pack/plugins/apm/public/services/rest/apm/status_check.ts @@ -13,7 +13,9 @@ export async function loadServerStatus() { } export async function loadAgentStatus() { - return callApi<{ dataFound: boolean }>({ + const res = await callApi<{ dataFound: boolean }>({ pathname: `/api/apm/status/agent` }); + + return res.dataFound; } diff --git a/x-pack/plugins/apm/public/services/rest/apm/traces.ts b/x-pack/plugins/apm/public/services/rest/apm/traces.ts index 1a681ecc3ade4..75d2f3af9308b 100644 --- a/x-pack/plugins/apm/public/services/rest/apm/traces.ts +++ b/x-pack/plugins/apm/public/services/rest/apm/traces.ts @@ -6,11 +6,16 @@ import { TraceListAPIResponse } from 'x-pack/plugins/apm/server/lib/traces/get_top_traces'; import { TraceAPIResponse } from 'x-pack/plugins/apm/server/lib/traces/get_trace'; +import { MissingArgumentsError } from '../../../hooks/useFetcher'; import { IUrlParams } from '../../../store/urlParams'; import { callApi } from '../callApi'; import { getEncodedEsQuery } from './apm'; export async function loadTrace({ traceId, start, end }: IUrlParams) { + if (!(traceId && start && end)) { + throw new MissingArgumentsError(); + } + return callApi({ pathname: `/api/apm/traces/${traceId}`, query: { @@ -21,6 +26,10 @@ export async function loadTrace({ traceId, start, end }: IUrlParams) { } export async function loadTraceList({ start, end, kuery }: IUrlParams) { + if (!(start && end)) { + throw new MissingArgumentsError(); + } + return callApi({ pathname: '/api/apm/traces', query: { diff --git a/x-pack/plugins/apm/public/services/rest/apm/transaction_groups.ts b/x-pack/plugins/apm/public/services/rest/apm/transaction_groups.ts index 53025a0daf685..a5be968852334 100644 --- a/x-pack/plugins/apm/public/services/rest/apm/transaction_groups.ts +++ b/x-pack/plugins/apm/public/services/rest/apm/transaction_groups.ts @@ -7,6 +7,7 @@ import { TimeSeriesAPIResponse } from 'x-pack/plugins/apm/server/lib/transactions/charts'; import { ITransactionDistributionAPIResponse } from 'x-pack/plugins/apm/server/lib/transactions/distribution'; import { TransactionListAPIResponse } from 'x-pack/plugins/apm/server/lib/transactions/get_top_transactions'; +import { MissingArgumentsError } from '../../../hooks/useFetcher'; import { IUrlParams } from '../../../store/urlParams'; import { callApi } from '../callApi'; import { getEncodedEsQuery } from './apm'; @@ -16,8 +17,12 @@ export async function loadTransactionList({ start, end, kuery, - transactionType = 'request' + transactionType }: IUrlParams) { + if (!(serviceName && transactionType && start && end)) { + throw new MissingArgumentsError(); + } + return await callApi({ pathname: `/api/apm/services/${serviceName}/transaction_groups/${transactionType}`, query: { @@ -33,11 +38,15 @@ export async function loadTransactionDistribution({ start, end, transactionName, - transactionType = 'request', + transactionType, transactionId, traceId, kuery -}: Required) { +}: IUrlParams) { + if (!(serviceName && transactionName && transactionType && start && end)) { + throw new MissingArgumentsError(); + } + return callApi({ pathname: `/api/apm/services/${serviceName}/transaction_groups/${transactionType}/${encodeURIComponent( transactionName @@ -52,14 +61,18 @@ export async function loadTransactionDistribution({ }); } -export async function loadDetailsCharts({ +export async function loadTransactionDetailsCharts({ serviceName, start, end, kuery, - transactionType = 'request', + transactionType, transactionName -}: Required) { +}: IUrlParams) { + if (!(serviceName && transactionName && transactionType && start && end)) { + throw new MissingArgumentsError(); + } + return callApi({ pathname: `/api/apm/services/${serviceName}/transaction_groups/${transactionType}/${encodeURIComponent( transactionName @@ -72,31 +85,23 @@ export async function loadDetailsCharts({ }); } -export async function loadOverviewCharts({ +export async function loadTransactionOverviewCharts({ serviceName, start, end, kuery, - transactionType = 'request' + transactionType }: IUrlParams) { - return callApi({ - pathname: `/api/apm/services/${serviceName}/transaction_groups/${transactionType}/charts`, - query: { - start, - end, - esFilterQuery: await getEncodedEsQuery(kuery) - } - }); -} + if (!(serviceName && start && end)) { + throw new MissingArgumentsError(); + } + + const pathname = transactionType + ? `/api/apm/services/${serviceName}/transaction_groups/${transactionType}/charts` + : `/api/apm/services/${serviceName}/transaction_groups/charts`; -export async function loadOverviewChartsForAllTypes({ - serviceName, - start, - end, - kuery -}: IUrlParams) { return callApi({ - pathname: `/api/apm/services/${serviceName}/transaction_groups/charts`, + pathname, query: { start, end, diff --git a/x-pack/plugins/apm/public/services/rest/callApi.ts b/x-pack/plugins/apm/public/services/rest/callApi.ts index 26fea4f17e9cb..27842a19a322a 100644 --- a/x-pack/plugins/apm/public/services/rest/callApi.ts +++ b/x-pack/plugins/apm/public/services/rest/callApi.ts @@ -4,7 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import { startsWith } from 'lodash'; +import { FetchOptions } from 'apollo-link-http'; +import { isString, startsWith } from 'lodash'; +import LRU from 'lru-cache'; +import hash from 'object-hash'; import { kfetch, KFetchOptions } from 'ui/kfetch'; import { KFetchKibanaOptions } from 'ui/kfetch/kfetch'; @@ -26,10 +29,49 @@ function fetchOptionsWithDebug(fetchOptions: KFetchOptions) { }; } +const cache = new LRU({ max: 100, maxAge: 1000 * 60 * 60 }); + +export function _clearCache() { + cache.reset(); +} + export async function callApi( fetchOptions: KFetchOptions, options?: KFetchKibanaOptions ): Promise { + const cacheKey = getCacheKey(fetchOptions); + const cacheResponse = cache.get(cacheKey); + if (cacheResponse) { + return cacheResponse; + } + const combinedFetchOptions = fetchOptionsWithDebug(fetchOptions); - return await kfetch(combinedFetchOptions, options); + const res = await kfetch(combinedFetchOptions, options); + + if (isCachable(fetchOptions)) { + cache.set(cacheKey, res); + } + + return res; +} + +// only cache items that has a time range with `start` and `end` params, +// and where `end` is not a timestamp in the future +function isCachable(fetchOptions: KFetchOptions) { + if ( + !(fetchOptions.query && fetchOptions.query.start && fetchOptions.query.end) + ) { + return false; + } + + return ( + isString(fetchOptions.query.end) && + new Date(fetchOptions.query.end).getTime() < Date.now() + ); +} + +// order the options object to make sure that two objects with the same arguments, produce produce the +// same cache key regardless of the order of properties +function getCacheKey(options: FetchOptions) { + return hash(options); } diff --git a/x-pack/plugins/apm/public/store/__jest__/rootReducer.test.ts b/x-pack/plugins/apm/public/store/__jest__/rootReducer.test.ts index 0eb91fc267b47..17c0f941079a9 100644 --- a/x-pack/plugins/apm/public/store/__jest__/rootReducer.test.ts +++ b/x-pack/plugins/apm/public/store/__jest__/rootReducer.test.ts @@ -12,7 +12,6 @@ describe('root reducer', () => { expect(state).toEqual({ location: { hash: '', pathname: '', search: '' }, - reactReduxRequest: {}, urlParams: {} }); }); diff --git a/x-pack/plugins/apm/public/store/reactReduxRequest/__jest__/helpers.test.js b/x-pack/plugins/apm/public/store/reactReduxRequest/__jest__/helpers.test.js deleted file mode 100644 index 5ed1bb04651b1..0000000000000 --- a/x-pack/plugins/apm/public/store/reactReduxRequest/__jest__/helpers.test.js +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { createInitialDataSelector } from '../helpers'; - -describe('createInitialDataSelector', () => { - it('should use initialData when data is missing from state', () => { - const state = {}; - const initialData = { foo: 'bar' }; - const withInitialData = createInitialDataSelector(initialData); - - expect(withInitialData(state)).toBe(withInitialData(state)); - expect(withInitialData(state, initialData)).toEqual({ - data: { foo: 'bar' } - }); - }); - - it('should use data when available', () => { - const state = { data: 'hello' }; - const initialData = { foo: 'bar' }; - const withInitialData = createInitialDataSelector(initialData); - - expect(withInitialData(state)).toBe(withInitialData(state)); - expect(withInitialData(state, initialData)).toEqual({ - data: 'hello' - }); - }); -}); diff --git a/x-pack/plugins/apm/public/store/reactReduxRequest/__jest__/serviceList.test.js b/x-pack/plugins/apm/public/store/reactReduxRequest/__jest__/serviceList.test.js deleted file mode 100644 index b45d3bbc76b1c..0000000000000 --- a/x-pack/plugins/apm/public/store/reactReduxRequest/__jest__/serviceList.test.js +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; -import * as rest from '../../../services/rest/apm/services'; -import { getServiceList, ServiceListRequest } from '../serviceList'; -import { mountWithStore } from '../../../utils/testHelpers'; - -describe('serviceList', () => { - describe('getServiceList', () => { - it('should return default value when empty', () => { - const state = { reactReduxRequest: {}, sorting: { service: {} } }; - expect(getServiceList(state)).toEqual({ data: [] }); - }); - - it('should return serviceList when not empty', () => { - const state = { - reactReduxRequest: { serviceList: { data: [{ foo: 'bar' }] } }, - sorting: { service: {} } - }; - expect(getServiceList(state)).toEqual({ data: [{ foo: 'bar' }] }); - }); - }); - - describe('ServiceListRequest', () => { - let loadSpy; - let renderSpy; - let wrapper; - - beforeEach(() => { - const state = { - reactReduxRequest: { - serviceList: { status: 'my-status', data: [{ foo: 'bar' }] } - }, - sorting: { service: {} } - }; - - loadSpy = jest.spyOn(rest, 'loadServiceList').mockReturnValue(); - renderSpy = jest.fn().mockReturnValue(
rendered
); - - wrapper = mountWithStore( - , - state - ); - }); - - it('should call render method', () => { - expect(renderSpy).toHaveBeenCalledWith({ - data: [{ foo: 'bar' }], - status: 'my-status' - }); - }); - - it('should call "loadServiceList"', () => { - expect(loadSpy).toHaveBeenCalledWith({ - start: 'myStart', - end: 'myEnd' - }); - }); - - it('should render component', () => { - expect(wrapper.html()).toEqual('
rendered
'); - }); - }); -}); diff --git a/x-pack/plugins/apm/public/store/reactReduxRequest/errorDistribution.tsx b/x-pack/plugins/apm/public/store/reactReduxRequest/errorDistribution.tsx deleted file mode 100644 index ef91d06bfad6e..0000000000000 --- a/x-pack/plugins/apm/public/store/reactReduxRequest/errorDistribution.tsx +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; -import { Request, RRRRender } from 'react-redux-request'; -import { ErrorDistributionAPIResponse } from 'x-pack/plugins/apm/server/lib/errors/distribution/get_distribution'; -import { loadErrorDistribution } from '../../services/rest/apm/error_groups'; -import { IReduxState } from '../rootReducer'; -import { IUrlParams } from '../urlParams'; -import { createInitialDataSelector } from './helpers'; - -const ID = 'errorDistribution'; -const INITIAL_DATA: ErrorDistributionAPIResponse = { - buckets: [], - totalHits: 0, - bucketSize: 0 -}; -const withInitialData = createInitialDataSelector(INITIAL_DATA); - -export function getErrorDistribution(state: IReduxState) { - return withInitialData(state.reactReduxRequest[ID]); -} - -export function ErrorDistributionRequest({ - urlParams, - render -}: { - urlParams: IUrlParams; - render: RRRRender; -}) { - const { serviceName, start, end, errorGroupId, kuery } = urlParams; - - if (!(serviceName && start && end)) { - return null; - } - - return ( - - ); -} diff --git a/x-pack/plugins/apm/public/store/reactReduxRequest/errorGroup.tsx b/x-pack/plugins/apm/public/store/reactReduxRequest/errorGroup.tsx deleted file mode 100644 index 37e1983c0a2a8..0000000000000 --- a/x-pack/plugins/apm/public/store/reactReduxRequest/errorGroup.tsx +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; -import { Request, RRRRender } from 'react-redux-request'; -import { ErrorGroupAPIResponse } from 'x-pack/plugins/apm/server/lib/errors/get_error_group'; -import { loadErrorGroupDetails } from '../../services/rest/apm/error_groups'; -import { IReduxState } from '../rootReducer'; -import { IUrlParams } from '../urlParams'; -import { createInitialDataSelector } from './helpers'; - -const ID = 'errorGroupDetails'; -const INITIAL_DATA: ErrorGroupAPIResponse = { occurrencesCount: 0 }; -const withInitialData = createInitialDataSelector(INITIAL_DATA); - -export function getErrorGroupDetails(state: IReduxState) { - return withInitialData(state.reactReduxRequest[ID]); -} - -export function ErrorGroupDetailsRequest({ - urlParams, - render -}: { - urlParams: IUrlParams; - render: RRRRender; -}) { - const { serviceName, errorGroupId, start, end, kuery } = urlParams; - - if (!(serviceName && start && end && errorGroupId)) { - return null; - } - - return ( - - ); -} diff --git a/x-pack/plugins/apm/public/store/reactReduxRequest/errorGroupList.tsx b/x-pack/plugins/apm/public/store/reactReduxRequest/errorGroupList.tsx deleted file mode 100644 index b7c3daf2c38b1..0000000000000 --- a/x-pack/plugins/apm/public/store/reactReduxRequest/errorGroupList.tsx +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; -import { Request, RRRRender } from 'react-redux-request'; -import { ErrorGroupListAPIResponse } from 'x-pack/plugins/apm/server/lib/errors/get_error_groups'; -import { loadErrorGroupList } from '../../services/rest/apm/error_groups'; -import { IReduxState } from '../rootReducer'; -import { IUrlParams } from '../urlParams'; -import { createInitialDataSelector } from './helpers'; - -const ID = 'errorGroupList'; -const INITIAL_DATA: ErrorGroupListAPIResponse = []; -const withInitialData = createInitialDataSelector(INITIAL_DATA); - -export function getErrorGroupList(state: IReduxState) { - return withInitialData(state.reactReduxRequest[ID]); -} - -export function ErrorGroupOverviewRequest({ - urlParams, - render -}: { - urlParams: IUrlParams; - render: RRRRender; -}) { - const { - serviceName, - start, - end, - sortField, - sortDirection, - kuery - } = urlParams; - - if (!(serviceName && start && end)) { - return null; - } - - return ( - - ); -} diff --git a/x-pack/plugins/apm/public/store/reactReduxRequest/helpers.ts b/x-pack/plugins/apm/public/store/reactReduxRequest/helpers.ts deleted file mode 100644 index 7575120cfc45b..0000000000000 --- a/x-pack/plugins/apm/public/store/reactReduxRequest/helpers.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { get } from 'lodash'; -import { createSelector } from 'reselect'; - -export function createInitialDataSelector(initialData: T) { - return createSelector( - state => state, - state => { - const data: T = get(state, 'data') || initialData; - return { ...state, data }; - } - ); -} diff --git a/x-pack/plugins/apm/public/store/reactReduxRequest/license.tsx b/x-pack/plugins/apm/public/store/reactReduxRequest/license.tsx deleted file mode 100644 index a8bc527c50af1..0000000000000 --- a/x-pack/plugins/apm/public/store/reactReduxRequest/license.tsx +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import React from 'react'; -import { Request, RRRRender } from 'react-redux-request'; -import { LicenseApiResponse, loadLicense } from '../../services/rest/xpack'; -import { IReduxState } from '../rootReducer'; -import { createInitialDataSelector } from './helpers'; - -const ID = 'license'; -const INITIAL_DATA = { - features: { - watcher: { is_available: false }, - ml: { is_available: false } - }, - license: { is_active: false } -}; - -const withInitialData = createInitialDataSelector(INITIAL_DATA); - -export function getLicense(state: IReduxState) { - return withInitialData(state.reactReduxRequest[ID]); -} - -export function LicenceRequest({ - render -}: { - render: RRRRender; -}) { - return ( - - ); -} diff --git a/x-pack/plugins/apm/public/store/reactReduxRequest/machineLearningJobs.tsx b/x-pack/plugins/apm/public/store/reactReduxRequest/machineLearningJobs.tsx deleted file mode 100644 index 5fd06b3a56804..0000000000000 --- a/x-pack/plugins/apm/public/store/reactReduxRequest/machineLearningJobs.tsx +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; -import { Request, RRRRender } from 'react-redux-request'; -import { getMLJob, MLJobApiResponse } from '../../services/rest/ml'; -import { IReduxState } from '../rootReducer'; -import { createInitialDataSelector } from './helpers'; - -const INITIAL_DATA = { count: 0, jobs: [] }; -const withInitialData = createInitialDataSelector(INITIAL_DATA); -const ID = 'MLJobs'; - -function selectMlJobs(state: IReduxState) { - return withInitialData(state.reactReduxRequest[ID]); -} - -export function MLJobsRequest({ - serviceName, - transactionType = '*', - render -}: { - serviceName: string; - transactionType?: string; - render: RRRRender; -}) { - return ( - - ); -} diff --git a/x-pack/plugins/apm/public/store/reactReduxRequest/serviceDetails.tsx b/x-pack/plugins/apm/public/store/reactReduxRequest/serviceDetails.tsx deleted file mode 100644 index 274f620c7f933..0000000000000 --- a/x-pack/plugins/apm/public/store/reactReduxRequest/serviceDetails.tsx +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { first, get } from 'lodash'; -import React from 'react'; -import { Request, RRRRender } from 'react-redux-request'; -import { IUrlParams } from 'x-pack/plugins/apm/public/store/urlParams'; -import { ServiceAPIResponse } from 'x-pack/plugins/apm/server/lib/services/get_service'; -import { loadServiceDetails } from '../../services/rest/apm/services'; -import { IReduxState } from '../rootReducer'; -import { createInitialDataSelector } from './helpers'; - -const ID = 'serviceDetails'; -const INITIAL_DATA = { types: [] }; -const withInitialData = createInitialDataSelector(INITIAL_DATA); - -export function getServiceDetails(state: IReduxState) { - return withInitialData(state.reactReduxRequest[ID]); -} - -export function getDefaultTransactionType(state: IReduxState) { - const types: string[] = get(state.reactReduxRequest[ID], 'data.types'); - return first(types); -} - -export function ServiceDetailsRequest({ - urlParams, - render -}: { - urlParams: IUrlParams; - render: RRRRender; -}) { - const { serviceName, start, end, kuery } = urlParams; - - if (!(serviceName && start && end)) { - return null; - } - - return ( - - ); -} diff --git a/x-pack/plugins/apm/public/store/reactReduxRequest/serviceList.tsx b/x-pack/plugins/apm/public/store/reactReduxRequest/serviceList.tsx deleted file mode 100644 index 22ea86e906502..0000000000000 --- a/x-pack/plugins/apm/public/store/reactReduxRequest/serviceList.tsx +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; -import { Request, RRRRender, RRRRenderResponse } from 'react-redux-request'; -import { ServiceListAPIResponse } from 'x-pack/plugins/apm/server/lib/services/get_services'; -import { loadServiceList } from '../../services/rest/apm/services'; -import { IReduxState } from '../rootReducer'; -import { IUrlParams } from '../urlParams'; -import { createInitialDataSelector } from './helpers'; - -const ID = 'serviceList'; -const INITIAL_DATA: ServiceListAPIResponse = []; -const withInitialData = createInitialDataSelector( - INITIAL_DATA -); - -export function getServiceList( - state: IReduxState -): RRRRenderResponse { - return withInitialData(state.reactReduxRequest[ID]); -} - -export function ServiceListRequest({ - urlParams, - render -}: { - urlParams: IUrlParams; - render: RRRRender; -}) { - const { start, end, kuery } = urlParams; - - if (!(start && end)) { - return null; - } - - return ( - - ); -} diff --git a/x-pack/plugins/apm/public/store/reactReduxRequest/serviceMetricsCharts.tsx b/x-pack/plugins/apm/public/store/reactReduxRequest/serviceMetricsCharts.tsx deleted file mode 100644 index 19a0dbdc0327e..0000000000000 --- a/x-pack/plugins/apm/public/store/reactReduxRequest/serviceMetricsCharts.tsx +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; -import { Request, RRRRender, RRRRenderResponse } from 'react-redux-request'; -import { createSelector } from 'reselect'; -import { loadMetricsChartDataForService } from 'x-pack/plugins/apm/public/services/rest/apm/metrics'; -import { IMemoryChartData } from 'x-pack/plugins/apm/public/store/selectors/chartSelectors'; -import { MetricsChartAPIResponse } from 'x-pack/plugins/apm/server/lib/metrics/get_all_metrics_chart_data'; -import { IReduxState } from '../rootReducer'; -import { getCPUSeries, getMemorySeries } from '../selectors/chartSelectors'; -import { getUrlParams, IUrlParams } from '../urlParams'; -import { createInitialDataSelector } from './helpers'; - -const ID = 'metricsChartData'; -const INITIAL_DATA: MetricsChartAPIResponse = { - memory: { - series: { - memoryUsedAvg: [], - memoryUsedMax: [] - }, - overallValues: { - memoryUsedAvg: null, - memoryUsedMax: null - }, - totalHits: 0 - }, - cpu: { - series: { - systemCPUAverage: [], - systemCPUMax: [], - processCPUAverage: [], - processCPUMax: [] - }, - overallValues: { - systemCPUAverage: null, - systemCPUMax: null, - processCPUAverage: null, - processCPUMax: null - }, - totalHits: 0 - } -}; - -type MetricsChartDataSelector = ( - state: IReduxState -) => RRRRenderResponse; - -const withInitialData = createInitialDataSelector( - INITIAL_DATA -); - -const selectMetricsChartData: MetricsChartDataSelector = state => - withInitialData(state.reactReduxRequest[ID]); - -export const selectTransformedMetricsChartData = createSelector( - [getUrlParams, selectMetricsChartData], - (urlParams, response) => ({ - ...response, - data: { - ...response.data, - memory: getMemorySeries(urlParams, response.data.memory), - cpu: getCPUSeries(response.data.cpu) - } - }) -); - -interface Props { - urlParams: IUrlParams; - render: RRRRender; -} - -export function MetricsChartDataRequest({ urlParams, render }: Props) { - const { serviceName, start, end } = urlParams; - - if (!(serviceName && start && end)) { - return null; - } - - return ( - - ); -} diff --git a/x-pack/plugins/apm/public/store/reactReduxRequest/traceList.tsx b/x-pack/plugins/apm/public/store/reactReduxRequest/traceList.tsx deleted file mode 100644 index 6bb98a9a1866a..0000000000000 --- a/x-pack/plugins/apm/public/store/reactReduxRequest/traceList.tsx +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; -import { Request, RRRRender } from 'react-redux-request'; -import { createSelector } from 'reselect'; -import { TraceListAPIResponse } from 'x-pack/plugins/apm/server/lib/traces/get_top_traces'; -import { loadTraceList } from '../../services/rest/apm/traces'; -import { IReduxState } from '../rootReducer'; -import { IUrlParams } from '../urlParams'; -import { createInitialDataSelector } from './helpers'; - -const ID = 'traceList'; -const INITIAL_DATA: TraceListAPIResponse = []; -const withInitialData = createInitialDataSelector(INITIAL_DATA); - -const selectRRR = (state = {} as IReduxState) => state.reactReduxRequest; - -export const selectTraceList = createSelector( - [selectRRR], - reactReduxRequest => { - return withInitialData(reactReduxRequest[ID]); - } -); - -interface Props { - urlParams: IUrlParams; - render: RRRRender; -} - -export function TraceListRequest({ urlParams, render }: Props) { - const { start, end, kuery } = urlParams; - - if (!start || !end) { - return null; - } - - return ( - - ); -} diff --git a/x-pack/plugins/apm/public/store/reactReduxRequest/transactionDetailsCharts.tsx b/x-pack/plugins/apm/public/store/reactReduxRequest/transactionDetailsCharts.tsx deleted file mode 100644 index 50b631d25ecfa..0000000000000 --- a/x-pack/plugins/apm/public/store/reactReduxRequest/transactionDetailsCharts.tsx +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; -import { Request, RRRRender } from 'react-redux-request'; -import { createSelector } from 'reselect'; -import { ITransactionChartData } from 'x-pack/plugins/apm/public/store/selectors/chartSelectors'; -import { TimeSeriesAPIResponse } from 'x-pack/plugins/apm/server/lib/transactions/charts'; -import { loadDetailsCharts } from '../../services/rest/apm/transaction_groups'; -import { IReduxState } from '../rootReducer'; -import { getTransactionCharts } from '../selectors/chartSelectors'; -import { getUrlParams, IUrlParams } from '../urlParams'; - -const ID = 'transactionDetailsCharts'; -const INITIAL_DATA: TimeSeriesAPIResponse = { - apmTimeseries: { - totalHits: 0, - responseTimes: { - avg: [], - p95: [], - p99: [] - }, - tpmBuckets: [], - overallAvgDuration: undefined - }, - anomalyTimeseries: undefined -}; - -export const getTransactionDetailsCharts = createSelector( - getUrlParams, - (state: IReduxState) => state.reactReduxRequest[ID], - (urlParams, detailCharts = {}) => { - return { - ...detailCharts, - data: getTransactionCharts(urlParams, detailCharts.data || INITIAL_DATA) - }; - } -); - -interface Props { - urlParams: IUrlParams; - render: RRRRender; -} - -export function TransactionDetailsChartsRequest({ urlParams, render }: Props) { - const { - serviceName, - start, - end, - transactionType, - transactionName, - kuery - } = urlParams; - - if (!(serviceName && start && end && transactionType && transactionName)) { - return null; - } - - return ( - - ); -} diff --git a/x-pack/plugins/apm/public/store/reactReduxRequest/transactionDistribution.tsx b/x-pack/plugins/apm/public/store/reactReduxRequest/transactionDistribution.tsx deleted file mode 100644 index b4232de6a9db2..0000000000000 --- a/x-pack/plugins/apm/public/store/reactReduxRequest/transactionDistribution.tsx +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; -import { Request, RRRRender, RRRRenderResponse } from 'react-redux-request'; -import { createSelector } from 'reselect'; -import { ITransactionDistributionAPIResponse } from 'x-pack/plugins/apm/server/lib/transactions/distribution'; -import { loadTransactionDistribution } from '../../services/rest/apm/transaction_groups'; -import { IReduxState } from '../rootReducer'; -import { IUrlParams } from '../urlParams'; -import { createInitialDataSelector } from './helpers'; - -const ID = 'transactionDistribution'; -const INITIAL_DATA = { buckets: [], totalHits: 0, bucketSize: 0 }; -const withInitialData = createInitialDataSelector< - ITransactionDistributionAPIResponse ->(INITIAL_DATA); - -export function getTransactionDistribution( - state: IReduxState -): RRRRenderResponse { - return withInitialData(state.reactReduxRequest[ID]); -} - -export const getDefaultDistributionSample = createSelector( - getTransactionDistribution, - distribution => { - const { defaultSample = {} } = distribution.data; - return { - traceId: defaultSample.traceId, - transactionId: defaultSample.transactionId - }; - } -); - -export function TransactionDistributionRequest({ - urlParams, - render -}: { - urlParams: IUrlParams; - render: RRRRender; -}) { - const { - serviceName, - transactionType, - transactionId, - traceId, - start, - end, - transactionName, - kuery - } = urlParams; - - if (!(serviceName && transactionType && start && end && transactionName)) { - return null; - } - - return ( - - ); -} diff --git a/x-pack/plugins/apm/public/store/reactReduxRequest/transactionList.tsx b/x-pack/plugins/apm/public/store/reactReduxRequest/transactionList.tsx deleted file mode 100644 index 246af040be84b..0000000000000 --- a/x-pack/plugins/apm/public/store/reactReduxRequest/transactionList.tsx +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; -import { Request, RRRRender } from 'react-redux-request'; -import { createSelector } from 'reselect'; -import { TransactionListAPIResponse } from 'x-pack/plugins/apm/server/lib/transactions/get_top_transactions'; -import { loadTransactionList } from '../../services/rest/apm/transaction_groups'; -import { IReduxState } from '../rootReducer'; -import { IUrlParams } from '../urlParams'; -import { createInitialDataSelector } from './helpers'; - -const ID = 'transactionList'; -const INITIAL_DATA: TransactionListAPIResponse = []; -const withInitialData = createInitialDataSelector( - INITIAL_DATA -); - -const getRelativeImpact = ( - impact: number, - impactMin: number, - impactMax: number -) => - Math.max( - ((impact - impactMin) / Math.max(impactMax - impactMin, 1)) * 100, - 1 - ); - -function getWithRelativeImpact(items: TransactionListAPIResponse) { - const impacts = items.map(({ impact }) => impact); - const impactMin = Math.min(...impacts); - const impactMax = Math.max(...impacts); - - return items.map(item => { - return { - ...item, - impactRelative: getRelativeImpact(item.impact, impactMin, impactMax) - }; - }); -} - -export const getTransactionList = createSelector( - (state: IReduxState) => withInitialData(state.reactReduxRequest[ID]), - transactionList => { - return { - ...transactionList, - data: getWithRelativeImpact(transactionList.data) - }; - } -); - -export function TransactionListRequest({ - urlParams, - render -}: { - urlParams: IUrlParams; - render: RRRRender; -}) { - const { serviceName, start, end, transactionType, kuery } = urlParams; - - if (!(serviceName && start && end)) { - return null; - } - - return ( - - ); -} diff --git a/x-pack/plugins/apm/public/store/reactReduxRequest/transactionOverviewCharts.tsx b/x-pack/plugins/apm/public/store/reactReduxRequest/transactionOverviewCharts.tsx deleted file mode 100644 index 520ba31e3229b..0000000000000 --- a/x-pack/plugins/apm/public/store/reactReduxRequest/transactionOverviewCharts.tsx +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { get } from 'lodash'; -import React from 'react'; -import { Request, RRRRender } from 'react-redux-request'; -import { createSelector } from 'reselect'; -import { ITransactionChartData } from 'x-pack/plugins/apm/public/store/selectors/chartSelectors'; -import { TimeSeriesAPIResponse } from 'x-pack/plugins/apm/server/lib/transactions/charts'; -import { - loadOverviewCharts, - loadOverviewChartsForAllTypes -} from '../../services/rest/apm/transaction_groups'; -import { IReduxState } from '../rootReducer'; -import { getTransactionCharts } from '../selectors/chartSelectors'; -import { getUrlParams, IUrlParams } from '../urlParams'; - -const ID = 'transactionOverviewCharts'; -const INITIAL_DATA: TimeSeriesAPIResponse = { - apmTimeseries: { - totalHits: 0, - responseTimes: { - avg: [], - p95: [], - p99: [] - }, - tpmBuckets: [], - overallAvgDuration: undefined - }, - anomalyTimeseries: undefined -}; - -const selectChartData = (state: IReduxState) => state.reactReduxRequest[ID]; - -export const getTransactionOverviewCharts = createSelector( - [getUrlParams, selectChartData], - (urlParams, overviewCharts = {}) => { - return { - ...overviewCharts, - data: getTransactionCharts(urlParams, overviewCharts.data || INITIAL_DATA) - }; - } -); - -export const selectHasMLJob = createSelector( - [selectChartData], - chartData => get(chartData, 'data.anomalyTimeseries') !== undefined -); - -interface Props { - urlParams: IUrlParams; - render: RRRRender; -} - -export function TransactionOverviewChartsRequest({ urlParams, render }: Props) { - const { serviceName, start, end, transactionType, kuery } = urlParams; - - if (!(serviceName && start && end)) { - return null; - } - - return ( - - ); -} - -// Ignores transaction type from urlParams and requests charts -// for ALL transaction types within this service -export function TransactionOverviewChartsRequestForAllTypes({ - urlParams, - render -}: Props) { - const { serviceName, start, end, kuery } = urlParams; - - if (!(serviceName && start && end)) { - return null; - } - - return ( - - ); -} diff --git a/x-pack/plugins/apm/public/store/reactReduxRequest/waterfall.tsx b/x-pack/plugins/apm/public/store/reactReduxRequest/waterfall.tsx deleted file mode 100644 index abd7e73702a3d..0000000000000 --- a/x-pack/plugins/apm/public/store/reactReduxRequest/waterfall.tsx +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; -import { Request, RRRRender } from 'react-redux-request'; -import { TraceAPIResponse } from 'x-pack/plugins/apm/server/lib/traces/get_trace'; -import { - getWaterfall, - IWaterfall -} from '../../components/app/TransactionDetails/Transaction/WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers'; -import { loadTrace } from '../../services/rest/apm/traces'; -import { IUrlParams } from '../urlParams'; - -export const ID = 'waterfall'; - -interface Props { - urlParams: IUrlParams; - traceId?: string; - render: RRRRender; -} - -export function WaterfallRequest({ urlParams, render, traceId }: Props) { - const { start, end } = urlParams; - - if (!(traceId && start && end)) { - return null; - } - - return ( - - id={ID} - fn={loadTrace} - args={[{ traceId, start, end }]} - render={({ - args, - data = { trace: [], errorsPerTransaction: {} }, - status - }) => { - const waterfall = getWaterfall( - data.trace, - data.errorsPerTransaction, - urlParams.transactionId - ); - return render({ args, data: waterfall, status }); - }} - /> - ); -} diff --git a/x-pack/plugins/apm/public/store/rootReducer.ts b/x-pack/plugins/apm/public/store/rootReducer.ts index 2395c3f0a6af2..0104e26d15416 100644 --- a/x-pack/plugins/apm/public/store/rootReducer.ts +++ b/x-pack/plugins/apm/public/store/rootReducer.ts @@ -5,20 +5,16 @@ */ import { Location } from 'history'; -import { reducer } from 'react-redux-request'; import { combineReducers } from 'redux'; -import { StringMap } from '../../typings/common'; import { locationReducer } from './location'; import { IUrlParams, urlParamsReducer } from './urlParams'; export interface IReduxState { location: Location; urlParams: IUrlParams; - reactReduxRequest: StringMap; } export const rootReducer = combineReducers({ location: locationReducer, - urlParams: urlParamsReducer, - reactReduxRequest: reducer + urlParams: urlParamsReducer }); diff --git a/x-pack/plugins/apm/public/store/selectors/chartSelectors.ts b/x-pack/plugins/apm/public/store/selectors/chartSelectors.ts index 424fe1515819f..7eedff75a1c28 100644 --- a/x-pack/plugins/apm/public/store/selectors/chartSelectors.ts +++ b/x-pack/plugins/apm/public/store/selectors/chartSelectors.ts @@ -65,13 +65,27 @@ export interface ITransactionChartData { noHits: boolean; tpmSeries: ITpmBucket[] | IEmptySeries[]; responseTimeSeries: TimeSerie[] | IEmptySeries[]; + hasMLJob: boolean; } +const INITIAL_DATA = { + apmTimeseries: { + totalHits: 0, + responseTimes: { + avg: [], + p95: [], + p99: [] + }, + tpmBuckets: [], + overallAvgDuration: undefined + }, + anomalyTimeseries: undefined +}; + export function getTransactionCharts( - urlParams: IUrlParams, - timeseriesResponse: TimeSeriesAPIResponse -) { - const { start, end, transactionType } = urlParams; + { start, end, transactionType }: IUrlParams, + timeseriesResponse: TimeSeriesAPIResponse = INITIAL_DATA +): ITransactionChartData { const { apmTimeseries, anomalyTimeseries } = timeseriesResponse; const noHits = apmTimeseries.totalHits === 0; const tpmSeries = noHits @@ -82,26 +96,22 @@ export function getTransactionCharts( ? getEmptySerie(start, end) : getResponseTimeSeries(apmTimeseries, anomalyTimeseries); - const chartsResult: ITransactionChartData = { + return { noHits, tpmSeries, - responseTimeSeries + responseTimeSeries, + hasMLJob: timeseriesResponse.anomalyTimeseries !== undefined }; - - return chartsResult; } -export interface IMemoryChartData extends MetricsChartAPIResponse { - series: TimeSerie[] | IEmptySeries[]; -} +export type MemoryMetricSeries = ReturnType; export function getMemorySeries( - urlParams: IUrlParams, + { start, end }: IUrlParams, memoryChartResponse: MetricsChartAPIResponse['memory'] ) { - const { start, end } = urlParams; const { series, overallValues, totalHits } = memoryChartResponse; - const seriesList: IMemoryChartData['series'] = + const seriesList = totalHits === 0 ? getEmptySerie(start, end) : [ @@ -132,14 +142,12 @@ export function getMemorySeries( ]; return { - ...memoryChartResponse, + totalHits: memoryChartResponse.totalHits, series: seriesList }; } -export interface ICPUChartData extends MetricsChartAPIResponse { - series: TimeSerie[]; -} +export type CPUMetricSeries = ReturnType; export function getCPUSeries(CPUChartResponse: MetricsChartAPIResponse['cpu']) { const { series, overallValues } = CPUChartResponse; @@ -183,7 +191,7 @@ export function getCPUSeries(CPUChartResponse: MetricsChartAPIResponse['cpu']) { } ]; - return { ...CPUChartResponse, series: seriesList }; + return { totalHits: CPUChartResponse.totalHits, series: seriesList }; } interface TimeSerie { diff --git a/x-pack/plugins/apm/public/store/selectors/license.ts b/x-pack/plugins/apm/public/store/selectors/license.ts deleted file mode 100644 index 24ce0a4953b93..0000000000000 --- a/x-pack/plugins/apm/public/store/selectors/license.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { createSelector } from 'reselect'; -import { getLicense } from 'x-pack/plugins/apm/public/store/reactReduxRequest/license'; - -export const selectIsMLAvailable = createSelector( - [getLicense], - license => - license.data && - license.data.features && - license.data.features.ml && - license.data.features.ml.is_available -); diff --git a/x-pack/plugins/apm/public/store/urlParams.ts b/x-pack/plugins/apm/public/store/urlParams.ts index 270f3c690624b..c9bfeef2ee638 100644 --- a/x-pack/plugins/apm/public/store/urlParams.ts +++ b/x-pack/plugins/apm/public/store/urlParams.ts @@ -7,14 +7,11 @@ import datemath from '@elastic/datemath'; import { Location } from 'history'; import { compact, pick } from 'lodash'; -import { createSelector } from 'reselect'; import { legacyDecodeURIComponent, toQuery } from '../components/shared/Links/url_helpers'; import { LOCATION_UPDATE } from './location'; -import { getDefaultTransactionType } from './reactReduxRequest/serviceDetails'; -import { getDefaultDistributionSample } from './reactReduxRequest/transactionDistribution'; import { IReduxState } from './rootReducer'; // ACTION TYPES @@ -153,16 +150,11 @@ export function toNumber(value?: string) { } } -function toString(str?: string | string[]) { - if ( - str === '' || - str === 'null' || - str === 'undefined' || - Array.isArray(str) - ) { +function toString(value?: string) { + if (value === '' || value === 'null' || value === 'undefined') { return; } - return str; + return value; } export function toBoolean(value?: string) { @@ -211,23 +203,9 @@ export function refreshTimeRange(time: TimeRange): TimeRangeRefreshAction { } // Selectors -export const getUrlParams = createSelector( - (state: IReduxState) => state.urlParams, - getDefaultTransactionType, - getDefaultDistributionSample, - ( - urlParams, - transactionType: string, - { traceId, transactionId } - ): IUrlParams => { - return { - transactionType, - transactionId, - traceId, - ...urlParams - }; - } -); +export function getUrlParams(state: IReduxState) { + return state.urlParams; +} export interface IUrlParams { detailTab?: string; diff --git a/x-pack/plugins/apm/public/utils/testHelpers.tsx b/x-pack/plugins/apm/public/utils/testHelpers.tsx index 845dc7b19dd14..3b720cba6e03d 100644 --- a/x-pack/plugins/apm/public/utils/testHelpers.tsx +++ b/x-pack/plugins/apm/public/utils/testHelpers.tsx @@ -8,11 +8,9 @@ import { mount, ReactWrapper } from 'enzyme'; import enzymeToJson from 'enzyme-to-json'; -import createHistory from 'history/createHashHistory'; import 'jest-styled-components'; import moment from 'moment'; import { Moment } from 'moment-timezone'; -import PropTypes from 'prop-types'; import React from 'react'; import { Provider } from 'react-redux'; import { MemoryRouter } from 'react-router-dom'; @@ -29,51 +27,6 @@ export function toJson(wrapper: ReactWrapper) { }); } -const defaultRoute = { - match: { path: '/', url: '/', params: {}, isExact: true }, - location: { pathname: '/', search: '', hash: '', key: '4yyjf5' } -}; - -export function mountWithRouterAndStore( - Component: React.ReactElement, - storeState = {}, - route = defaultRoute -) { - const store = createMockStore(storeState); - const history = createHistory(); - - const options = { - context: { - store, - router: { - history, - route - } - }, - childContextTypes: { - store: PropTypes.object.isRequired, - router: PropTypes.object.isRequired - } - }; - - return mount(Component, options); -} - -export function mountWithStore(Component: React.ReactElement, storeState = {}) { - const store = createMockStore(storeState); - - const options = { - context: { - store - }, - childContextTypes: { - store: PropTypes.object.isRequired - } - }; - - return mount(Component, options); -} - export function mockMoment() { // avoid timezone issues jest @@ -90,11 +43,6 @@ export function mockMoment() { }); } -// Await this when you need to "flush" promises to immediately resolve or throw in tests -export async function asyncFlush() { - return new Promise(resolve => setTimeout(resolve, 0)); -} - // Useful for getting the rendered href from any kind of link component export async function getRenderedHref( Component: React.FunctionComponent<{}>, @@ -109,7 +57,7 @@ export async function getRenderedHref( ); - await asyncFlush(); + await tick(); return mounted.render().attr('href'); } @@ -118,3 +66,10 @@ export function mockNow(date: string) { const fakeNow = new Date(date).getTime(); return jest.spyOn(Date, 'now').mockReturnValue(fakeNow); } + +export function delay(ms: number) { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +// Await this when you need to "flush" promises to immediately resolve or throw in tests +export const tick = () => new Promise(resolve => setImmediate(resolve, 0)); diff --git a/x-pack/plugins/apm/typings/es_schemas/raw/APMBaseDoc.ts b/x-pack/plugins/apm/typings/es_schemas/raw/APMBaseDoc.ts index 1717156d52cfd..e6cec18e8a0dd 100644 --- a/x-pack/plugins/apm/typings/es_schemas/raw/APMBaseDoc.ts +++ b/x-pack/plugins/apm/typings/es_schemas/raw/APMBaseDoc.ts @@ -6,17 +6,16 @@ // all documents types extend APMBaseDoc and inherit all properties export interface APMBaseDoc { - '@metadata': unknown; '@timestamp': string; agent: { name: string; version: string; }; - observer: unknown; timestamp: { us: number }; parent?: { id: string }; // parent ID is not available on root transactions trace?: { id: string }; labels?: { [key: string]: string | number | boolean; }; + [key: string]: unknown; } diff --git a/x-pack/plugins/apm/typings/react-redux-request.d.ts b/x-pack/plugins/apm/typings/react-redux-request.d.ts deleted file mode 100644 index de49e9dc648a5..0000000000000 --- a/x-pack/plugins/apm/typings/react-redux-request.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -// Everything in here should be moved to http://github.com/sqren/react-redux-request - -declare module 'react-redux-request' { - import React from 'react'; - - // status and args are optional, especially for places that use initial data in a reducer - export interface RRRRenderResponse { - status?: 'SUCCESS' | 'LOADING' | 'FAILURE'; - data: T; - args?: P; - } - - export type RRRRender = ( - res: RRRRenderResponse - ) => React.ReactNode; - - export interface RequestProps { - id: string; - fn: (args: any) => Promise; - selector?: (state: any) => any; - args?: any[]; - render?: RRRRender; - } - - export function reducer(state: any): any; - - export class Request extends React.Component< - RequestProps - > {} -} diff --git a/x-pack/plugins/beats_management/common/return_types.ts b/x-pack/plugins/beats_management/common/return_types.ts new file mode 100644 index 0000000000000..a7125795a5c7d --- /dev/null +++ b/x-pack/plugins/beats_management/common/return_types.ts @@ -0,0 +1,116 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export interface BaseReturnType { + error?: { + message: string; + code?: number; + }; + success: boolean; +} + +export interface ReturnTypeCreate extends BaseReturnType { + item: T; + action: 'created'; +} + +export interface ReturnTypeUpdate extends BaseReturnType { + item: T; + action: 'updated'; +} + +export interface ReturnTypeBulkCreate extends BaseReturnType { + results: Array<{ + item: T; + success: boolean; + action: 'created'; + error?: { + message: string; + code?: number; + }; + }>; +} + +// delete +export interface ReturnTypeDelete extends BaseReturnType { + action: 'deleted'; +} + +export interface ReturnTypeBulkDelete extends BaseReturnType { + results: Array<{ + success: boolean; + action: 'deleted'; + error?: { + message: string; + code?: number; + }; + }>; +} + +// upsert +export interface ReturnTypeUpsert extends BaseReturnType { + item: T; + action: 'created' | 'updated'; +} + +// upsert bulk +export interface ReturnTypeBulkUpsert extends BaseReturnType { + results: Array<{ + success: boolean; + action: 'created' | 'updated'; + error?: { + message: string; + code?: number; + }; + }>; +} + +// list +export interface ReturnTypeList extends BaseReturnType { + list: T[]; + page: number; + total: number; +} + +// get +export interface ReturnTypeGet extends BaseReturnType { + item: T; +} + +export interface ReturnTypeBulkGet extends BaseReturnType { + items: T[]; +} + +// action -- e.g. validate config block. Like ES simulate endpoint +export interface ReturnTypeAction extends BaseReturnType { + result: { + [key: string]: any; + }; +} +// e.g. +// { +// result: { +// username: { valid: true }, +// password: { valid: false, error: 'something' }, +// hosts: [ +// { valid: false }, { valid: true }, +// ] +// } +// } + +// bulk action -- e.g. assign tags to beats +export interface ReturnTypeBulkAction extends BaseReturnType { + results?: Array<{ + success: boolean; + result?: { + [key: string]: any; + }; + error?: { + message: string; + code?: number; + }; + }>; +} diff --git a/x-pack/plugins/beats_management/public/components/autocomplete_field/suggestion_item.tsx b/x-pack/plugins/beats_management/public/components/autocomplete_field/suggestion_item.tsx index 2ab04b4d87157..2b0537e11af92 100644 --- a/x-pack/plugins/beats_management/public/components/autocomplete_field/suggestion_item.tsx +++ b/x-pack/plugins/beats_management/public/components/autocomplete_field/suggestion_item.tsx @@ -36,9 +36,7 @@ export class SuggestionItem extends React.Component { {suggestion.text} - + {suggestion.description} ); } diff --git a/x-pack/plugins/beats_management/public/components/config_list.tsx b/x-pack/plugins/beats_management/public/components/config_list.tsx index ed5c925ef950b..f860188e66800 100644 --- a/x-pack/plugins/beats_management/public/components/config_list.tsx +++ b/x-pack/plugins/beats_management/public/components/config_list.tsx @@ -15,7 +15,7 @@ import { ConfigurationBlock } from '../../common/domain_types'; interface ComponentProps { configs: { error?: string | undefined; - blocks: ConfigurationBlock[]; + list: ConfigurationBlock[]; page: number; total: number; }; @@ -30,7 +30,7 @@ const pagination = { const ConfigListUi: React.SFC = props => ( ; update(id: string, beatData: Partial): Promise; getBeatsWithTag(tagId: string): Promise; getAll(ESQuery?: any): Promise; - removeTagsFromBeats(removals: BeatsTagAssignment[]): Promise; - assignTagsToBeats(assignments: BeatsTagAssignment[]): Promise; + removeTagsFromBeats(removals: BeatsTagAssignment[]): Promise; + assignTagsToBeats(assignments: BeatsTagAssignment[]): Promise; getBeatWithToken(enrollmentToken: string): Promise; } diff --git a/x-pack/plugins/beats_management/public/lib/adapters/beats/memory_beats_adapter.ts b/x-pack/plugins/beats_management/public/lib/adapters/beats/memory_beats_adapter.ts index 21aa092ef8440..319e37e226c9e 100644 --- a/x-pack/plugins/beats_management/public/lib/adapters/beats/memory_beats_adapter.ts +++ b/x-pack/plugins/beats_management/public/lib/adapters/beats/memory_beats_adapter.ts @@ -5,14 +5,9 @@ */ import { omit } from 'lodash'; - import { CMBeat } from '../../../../common/domain_types'; -import { - BeatsRemovalReturn, - BeatsTagAssignment, - CMAssignmentReturn, - CMBeatsAdapter, -} from './adapter_types'; +import { ReturnTypeBulkAction } from '../../../../common/return_types'; +import { BeatsTagAssignment, CMBeatsAdapter } from './adapter_types'; export class MemoryBeatsAdapter implements CMBeatsAdapter { private beatsDB: CMBeat[]; @@ -46,7 +41,9 @@ export class MemoryBeatsAdapter implements CMBeatsAdapter { public async getBeatWithToken(enrollmentToken: string): Promise { return this.beatsDB.map((beat: any) => omit(beat, ['access_token']))[0]; } - public async removeTagsFromBeats(removals: BeatsTagAssignment[]): Promise { + public async removeTagsFromBeats( + removals: BeatsTagAssignment[] + ): Promise { const beatIds = removals.map(r => r.beatId); const response = this.beatsDB @@ -76,7 +73,9 @@ export class MemoryBeatsAdapter implements CMBeatsAdapter { })); } - public async assignTagsToBeats(assignments: BeatsTagAssignment[]): Promise { + public async assignTagsToBeats( + assignments: BeatsTagAssignment[] + ): Promise { const beatIds = assignments.map(r => r.beatId); this.beatsDB diff --git a/x-pack/plugins/beats_management/public/lib/adapters/beats/rest_beats_adapter.ts b/x-pack/plugins/beats_management/public/lib/adapters/beats/rest_beats_adapter.ts index 07a81417ebdd8..4a7f768bd4740 100644 --- a/x-pack/plugins/beats_management/public/lib/adapters/beats/rest_beats_adapter.ts +++ b/x-pack/plugins/beats_management/public/lib/adapters/beats/rest_beats_adapter.ts @@ -5,19 +5,20 @@ */ import { CMBeat } from '../../../../common/domain_types'; -import { RestAPIAdapter } from '../rest_api/adapter_types'; import { - BeatsRemovalReturn, - BeatsTagAssignment, - CMAssignmentReturn, - CMBeatsAdapter, -} from './adapter_types'; + ReturnTypeBulkAction, + ReturnTypeGet, + ReturnTypeList, + ReturnTypeUpdate, +} from '../../../../common/return_types'; +import { RestAPIAdapter } from '../rest_api/adapter_types'; +import { BeatsTagAssignment, CMBeatsAdapter } from './adapter_types'; export class RestBeatsAdapter implements CMBeatsAdapter { constructor(private readonly REST: RestAPIAdapter) {} public async get(id: string): Promise { try { - return await this.REST.get(`/api/beats/agent/${id}`); + return (await this.REST.get>(`/api/beats/agent/${id}`)).item; } catch (e) { return null; } @@ -25,7 +26,9 @@ export class RestBeatsAdapter implements CMBeatsAdapter { public async getBeatWithToken(enrollmentToken: string): Promise { try { - return await this.REST.get(`/api/beats/agent/unknown/${enrollmentToken}`); + return (await this.REST.get>( + `/api/beats/agent/unknown/${enrollmentToken}` + )).item; } catch (e) { return null; } @@ -33,7 +36,8 @@ export class RestBeatsAdapter implements CMBeatsAdapter { public async getAll(ESQuery?: string): Promise { try { - return (await this.REST.get<{ beats: CMBeat[] }>('/api/beats/agents/all', { ESQuery })).beats; + return (await this.REST.get>('/api/beats/agents/all', { ESQuery })) + .list; } catch (e) { return []; } @@ -41,32 +45,30 @@ export class RestBeatsAdapter implements CMBeatsAdapter { public async getBeatsWithTag(tagId: string): Promise { try { - return (await this.REST.get<{ beats: CMBeat[] }>(`/api/beats/agents/tag/${tagId}`)).beats; + return (await this.REST.get>(`/api/beats/agents/tag/${tagId}`)).list; } catch (e) { return []; } } public async update(id: string, beatData: Partial): Promise { - await this.REST.put<{ success: true }>(`/api/beats/agent/${id}`, beatData); + await this.REST.put>(`/api/beats/agent/${id}`, beatData); return true; } - public async removeTagsFromBeats(removals: BeatsTagAssignment[]): Promise { - return (await this.REST.post<{ removals: BeatsRemovalReturn[] }>( - `/api/beats/agents_tags/removals`, - { - removals, - } - )).removals; + public async removeTagsFromBeats( + removals: BeatsTagAssignment[] + ): Promise { + return (await this.REST.post(`/api/beats/agents_tags/removals`, { + removals, + })).results; } - public async assignTagsToBeats(assignments: BeatsTagAssignment[]): Promise { - return (await this.REST.post<{ assignments: CMAssignmentReturn[] }>( - `/api/beats/agents_tags/assignments`, - { - assignments, - } - )).assignments; + public async assignTagsToBeats( + assignments: BeatsTagAssignment[] + ): Promise { + return (await this.REST.post(`/api/beats/agents_tags/assignments`, { + assignments, + })).results; } } diff --git a/x-pack/plugins/beats_management/public/lib/adapters/configuration_blocks/adapter_types.ts b/x-pack/plugins/beats_management/public/lib/adapters/configuration_blocks/adapter_types.ts index fb2b077a7532d..e8e2d5cd6b430 100644 --- a/x-pack/plugins/beats_management/public/lib/adapters/configuration_blocks/adapter_types.ts +++ b/x-pack/plugins/beats_management/public/lib/adapters/configuration_blocks/adapter_types.ts @@ -4,19 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ import { ConfigurationBlock } from '../../../../common/domain_types'; +import { ReturnTypeBulkUpsert, ReturnTypeList } from '../../../../common/return_types'; export interface FrontendConfigBlocksAdapter { - upsert( - blocks: ConfigurationBlock[] - ): Promise>; - getForTags( - tagIds: string[], - page: number - ): Promise<{ - error?: string; - blocks: ConfigurationBlock[]; - page: number; - total: number; - }>; + upsert(blocks: ConfigurationBlock[]): Promise; + getForTags(tagIds: string[], page: number): Promise>; delete(id: string): Promise; } diff --git a/x-pack/plugins/beats_management/public/lib/adapters/configuration_blocks/memory_config_blocks_adapter.ts b/x-pack/plugins/beats_management/public/lib/adapters/configuration_blocks/memory_config_blocks_adapter.ts index ab3489ba9745a..b1405cfbf2e60 100644 --- a/x-pack/plugins/beats_management/public/lib/adapters/configuration_blocks/memory_config_blocks_adapter.ts +++ b/x-pack/plugins/beats_management/public/lib/adapters/configuration_blocks/memory_config_blocks_adapter.ts @@ -5,30 +5,26 @@ */ import { ConfigurationBlock } from '../../../../common/domain_types'; +import { ReturnTypeBulkUpsert, ReturnTypeList } from '../../../../common/return_types'; import { FrontendConfigBlocksAdapter } from './adapter_types'; export class MemoryConfigBlocksAdapter implements FrontendConfigBlocksAdapter { constructor(private db: ConfigurationBlock[]) {} - public async upsert(blocks: ConfigurationBlock[]) { + public async upsert(blocks: ConfigurationBlock[]): Promise { this.db = this.db.concat(blocks); - return blocks.map(() => ({ + return { success: true, - blockID: Math.random() - .toString(36) - .substring(7), - })); + results: blocks.map(() => ({ + success: true, + action: 'created', + })), + } as ReturnTypeBulkUpsert; } - public async getForTags( - tagIds: string[] - ): Promise<{ - error?: string; - blocks: ConfigurationBlock[]; - page: number; - total: number; - }> { + public async getForTags(tagIds: string[]): Promise> { return { - blocks: this.db.filter(block => tagIds.includes(block.tag)), + success: true, + list: this.db.filter(block => tagIds.includes(block.tag)), page: 0, total: this.db.filter(block => tagIds.includes(block.tag)).length, }; diff --git a/x-pack/plugins/beats_management/public/lib/adapters/configuration_blocks/rest_config_blocks_adapter.ts b/x-pack/plugins/beats_management/public/lib/adapters/configuration_blocks/rest_config_blocks_adapter.ts index 65fa77cf6a0ad..be501a5e951ba 100644 --- a/x-pack/plugins/beats_management/public/lib/adapters/configuration_blocks/rest_config_blocks_adapter.ts +++ b/x-pack/plugins/beats_management/public/lib/adapters/configuration_blocks/rest_config_blocks_adapter.ts @@ -5,6 +5,11 @@ */ import { ConfigurationBlock } from '../../../../common/domain_types'; +import { + ReturnTypeBulkDelete, + ReturnTypeBulkUpsert, + ReturnTypeList, +} from '../../../../common/return_types'; import { RestAPIAdapter } from '../rest_api/adapter_types'; import { FrontendConfigBlocksAdapter } from './adapter_types'; @@ -12,29 +17,19 @@ export class RestConfigBlocksAdapter implements FrontendConfigBlocksAdapter { constructor(private readonly REST: RestAPIAdapter) {} public async upsert(blocks: ConfigurationBlock[]) { - const result = await this.REST.put< - Array<{ success?: boolean; blockID?: string; error?: string }> - >(`/api/beats/configurations`, blocks); + const result = await this.REST.put(`/api/beats/configurations`, blocks); return result; } public async getForTags( tagIds: string[], page: number - ): Promise<{ - error?: string; - blocks: ConfigurationBlock[]; - page: number; - total: number; - }> { - return await this.REST.get<{ - error?: string; - blocks: ConfigurationBlock[]; - page: number; - total: number; - }>(`/api/beats/configurations/${tagIds.join(',')}/${page}`); + ): Promise> { + return await this.REST.get>( + `/api/beats/configurations/${tagIds.join(',')}/${page}` + ); } public async delete(id: string): Promise { - return (await this.REST.delete<{ success: boolean }>(`/api/beats/configurations/${id}`)) + return (await this.REST.delete(`/api/beats/configurations/${id}`)) .success; } } diff --git a/x-pack/plugins/beats_management/public/lib/adapters/tags/rest_tags_adapter.ts b/x-pack/plugins/beats_management/public/lib/adapters/tags/rest_tags_adapter.ts index 60e4aa11c6ad1..31c55b9272193 100644 --- a/x-pack/plugins/beats_management/public/lib/adapters/tags/rest_tags_adapter.ts +++ b/x-pack/plugins/beats_management/public/lib/adapters/tags/rest_tags_adapter.ts @@ -6,6 +6,12 @@ import { uniq } from 'lodash'; import { BeatTag, CMBeat } from '../../../../common/domain_types'; +import { + ReturnTypeBulkDelete, + ReturnTypeBulkGet, + ReturnTypeList, + ReturnTypeUpsert, +} from '../../../../common/return_types'; import { RestAPIAdapter } from '../rest_api/adapter_types'; import { CMTagsAdapter } from './adapter_types'; @@ -14,7 +20,9 @@ export class RestTagsAdapter implements CMTagsAdapter { public async getTagsWithIds(tagIds: string[]): Promise { try { - return await this.REST.get(`/api/beats/tags/${uniq(tagIds).join(',')}`); + return (await this.REST.get>( + `/api/beats/tags/${uniq(tagIds).join(',')}` + )).items; } catch (e) { return []; } @@ -22,20 +30,20 @@ export class RestTagsAdapter implements CMTagsAdapter { public async getAll(ESQuery: string): Promise { try { - return await this.REST.get(`/api/beats/tags`, { ESQuery }); + return (await this.REST.get>(`/api/beats/tags`, { ESQuery })).list; } catch (e) { return []; } } public async delete(tagIds: string[]): Promise { - return (await this.REST.delete<{ success: boolean }>( + return (await this.REST.delete( `/api/beats/tags/${uniq(tagIds).join(',')}` )).success; } public async upsertTag(tag: BeatTag): Promise { - const response = await this.REST.put<{ success: boolean }>(`/api/beats/tag/${tag.id}`, { + const response = await this.REST.put>(`/api/beats/tag/${tag.id}`, { color: tag.color, name: tag.name, }); @@ -45,9 +53,9 @@ export class RestTagsAdapter implements CMTagsAdapter { public async getAssignable(beats: CMBeat[]) { try { - return await this.REST.get( + return (await this.REST.get>( `/api/beats/tags/assignable/${beats.map(beat => beat.id).join(',')}` - ); + )).items; } catch (e) { return []; } diff --git a/x-pack/plugins/beats_management/public/lib/adapters/tokens/rest_tokens_adapter.ts b/x-pack/plugins/beats_management/public/lib/adapters/tokens/rest_tokens_adapter.ts index 78895c8abc73c..8274764e759ab 100644 --- a/x-pack/plugins/beats_management/public/lib/adapters/tokens/rest_tokens_adapter.ts +++ b/x-pack/plugins/beats_management/public/lib/adapters/tokens/rest_tokens_adapter.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import { ReturnTypeBulkCreate } from '../../../../common/return_types'; import { RestAPIAdapter } from '../rest_api/adapter_types'; import { CMTokensAdapter } from './adapter_types'; @@ -11,9 +12,12 @@ export class RestTokensAdapter implements CMTokensAdapter { constructor(private readonly REST: RestAPIAdapter) {} public async createEnrollmentTokens(numTokens: number = 1): Promise { - const tokens = (await this.REST.post<{ tokens: string[] }>('/api/beats/enrollment_tokens', { - num_tokens: numTokens, - })).tokens; - return tokens; + const results = (await this.REST.post>( + '/api/beats/enrollment_tokens', + { + num_tokens: numTokens, + } + )).results; + return results.map(result => result.item); } } diff --git a/x-pack/plugins/beats_management/public/lib/beats.ts b/x-pack/plugins/beats_management/public/lib/beats.ts index 01ed52a3d303c..5432a39953b84 100644 --- a/x-pack/plugins/beats_management/public/lib/beats.ts +++ b/x-pack/plugins/beats_management/public/lib/beats.ts @@ -4,13 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ +import { ReturnTypeBulkAction } from '../../common/return_types'; import { CMBeat } from './../../common/domain_types'; -import { - BeatsRemovalReturn, - BeatsTagAssignment, - CMAssignmentReturn, - CMBeatsAdapter, -} from './adapters/beats/adapter_types'; +import { BeatsTagAssignment, CMBeatsAdapter } from './adapters/beats/adapter_types'; import { ElasticsearchLib } from './elasticsearch'; export class BeatsLib { @@ -56,14 +52,14 @@ export class BeatsLib { /** unassign tags from beats using an array of tags and beats */ public removeTagsFromBeats = async ( removals: BeatsTagAssignment[] - ): Promise => { + ): Promise => { return await this.adapter.removeTagsFromBeats(removals); }; /** assign tags from beats using an array of tags and beats */ public assignTagsToBeats = async ( assignments: BeatsTagAssignment[] - ): Promise => { + ): Promise => { return await this.adapter.assignTagsToBeats(assignments); }; } diff --git a/x-pack/plugins/beats_management/public/lib/configuration_blocks.ts b/x-pack/plugins/beats_management/public/lib/configuration_blocks.ts index 0dee85e32e63a..c3b21b5df5175 100644 --- a/x-pack/plugins/beats_management/public/lib/configuration_blocks.ts +++ b/x-pack/plugins/beats_management/public/lib/configuration_blocks.ts @@ -23,7 +23,7 @@ export class ConfigBlocksLib { public getForTags = async (tagIds: string[], page: number) => { const result = await this.adapter.getForTags(tagIds, page); - result.blocks = this.jsonConfigToUserYaml(result.blocks); + result.list = this.jsonConfigToUserYaml(result.list); return result; }; diff --git a/x-pack/plugins/beats_management/public/pages/beat/details.tsx b/x-pack/plugins/beats_management/public/pages/beat/details.tsx index b7cffa261c8c4..9b3707b1661f4 100644 --- a/x-pack/plugins/beats_management/public/pages/beat/details.tsx +++ b/x-pack/plugins/beats_management/public/pages/beat/details.tsx @@ -60,7 +60,7 @@ class BeatDetailPageUi extends React.PureComponent { ); this.setState({ - configuration_blocks: blocksResult.blocks, + configuration_blocks: blocksResult.list, tags, }); } diff --git a/x-pack/plugins/beats_management/public/pages/tag/create.tsx b/x-pack/plugins/beats_management/public/pages/tag/create.tsx index 9db3b0adaded7..94b5ac955c165 100644 --- a/x-pack/plugins/beats_management/public/pages/tag/create.tsx +++ b/x-pack/plugins/beats_management/public/pages/tag/create.tsx @@ -61,7 +61,7 @@ class TagCreatePageComponent extends React.PureComponent< ({ ...block, tag: this.state.tag.id })) ); - const creationError = createBlocksResponse.reduce( - (err: string, resp: any) => (!err ? (err = resp.error || '') : err), + const creationError = createBlocksResponse.results.reduce( + (err: string, resp) => (!err ? (err = resp.error ? resp.error.message : '') : err), '' ); if (creationError) { diff --git a/x-pack/plugins/beats_management/public/pages/tag/edit.tsx b/x-pack/plugins/beats_management/public/pages/tag/edit.tsx index 5772c9bd45c0c..401f1d64bca8b 100644 --- a/x-pack/plugins/beats_management/public/pages/tag/edit.tsx +++ b/x-pack/plugins/beats_management/public/pages/tag/edit.tsx @@ -22,7 +22,7 @@ interface TagPageState { beatsTags: BeatTag[]; configuration_blocks: { error?: string | undefined; - blocks: ConfigurationBlock[]; + list: ConfigurationBlock[]; page: number; total: number; }; @@ -47,7 +47,7 @@ class TagEditPageComponent extends React.PureComponent< hasConfigurationBlocksTypes: [], }, configuration_blocks: { - blocks: [], + list: [], page: 0, total: 0, }, @@ -160,7 +160,12 @@ class TagEditPageComponent extends React.PureComponent< const blocksResponse = await this.props.libs.configBlocks.getForTags([this.state.tag.id], page); this.setState({ - configuration_blocks: blocksResponse, + configuration_blocks: blocksResponse as { + error?: string | undefined; + list: ConfigurationBlock[]; + page: number; + total: number; + }, }); }; @@ -189,7 +194,7 @@ class TagEditPageComponent extends React.PureComponent< this.props.goTo(`/overview/configuration_tags`); }; private getNumExclusiveConfigurationBlocks = () => - this.state.configuration_blocks.blocks + this.state.configuration_blocks.list .map(({ type }) => UNIQUENESS_ENFORCING_TYPES.some(uniqueType => uniqueType === type)) .reduce((acc, cur) => (cur ? acc + 1 : acc), 0); } diff --git a/x-pack/plugins/beats_management/public/pages/walkthrough/initial/tag.tsx b/x-pack/plugins/beats_management/public/pages/walkthrough/initial/tag.tsx index 88c6ad844dbce..8dc3afeb06c6b 100644 --- a/x-pack/plugins/beats_management/public/pages/walkthrough/initial/tag.tsx +++ b/x-pack/plugins/beats_management/public/pages/walkthrough/initial/tag.tsx @@ -45,10 +45,7 @@ export class InitialTagPage extends Component { { const createBlocksResponse = await this.props.libs.configBlocks.upsert( this.state.configuration_blocks.map(block => ({ ...block, tag: this.state.tag.id })) ); - const creationError = createBlocksResponse.reduce( - (err: string, resp: any) => (!err ? (err = resp.error || '') : err), + const creationError = createBlocksResponse.results.reduce( + (err: string, resp) => (!err ? (err = resp.error ? resp.error.message : '') : err), '' ); if (creationError) { diff --git a/x-pack/plugins/beats_management/readme.md b/x-pack/plugins/beats_management/readme.md index eb29a9fbf5b51..301caad683dd5 100644 --- a/x-pack/plugins/beats_management/readme.md +++ b/x-pack/plugins/beats_management/readme.md @@ -1,29 +1,32 @@ -# Documentation for Beats CM in x-pack kibana +# Beats CM Notes: Falure to have auth enabled in Kibana will make for a broken UI. UI based errors not yet in place -### Run tests +## Testing -``` -node scripts/jest.js plugins/beats --watch -``` +### Unit tests -and for functional... (from x-pack root) +From `~/kibana/x-pack`, run `node scripts/jest.js plugins/beats --watch`. -``` - node scripts/functional_tests --config test/api_integration/config -``` +### API tests -### Run command to fake an enrolling beat (from beats_management dir) +In one shell, from **~/kibana/x-pack**: +`node scripts/functional_tests-server.js` + +In another shell, from **~kibana/x-pack**: +`node ../scripts/functional_test_runner.js --config test/api_integration/config.js`. + +### Manual e2e testing + +- Run this command to fake an enrolling beat (from beats_management dir) ``` node scripts/enroll.js ``` -### Run a command to setup a fake large-scale deployment - -Note: ts-node is required to be installed gloably from NPM/Yarn for this action +- Run a command to setup a fake large-scale deployment + Note: `ts-node` is required to be installed gloably from NPM/Yarn for this action ``` ts-node scripts/fake_env.ts <# of beats> <# of tags per beat> <# of congifs per tag> diff --git a/x-pack/plugins/beats_management/server/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/beats_management/server/lib/adapters/framework/adapter_types.ts index b031878e9181b..b428e21c1fcc8 100644 --- a/x-pack/plugins/beats_management/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/plugins/beats_management/server/lib/adapters/framework/adapter_types.ts @@ -168,6 +168,6 @@ export interface FrameworkRouteOptions< export type FrameworkRouteHandler< RouteRequest extends KibanaServerRequest, RouteResponse extends FrameworkResponse -> = (request: FrameworkRequest, h: ResponseToolkit) => void; +> = (request: FrameworkRequest, h: ResponseToolkit) => Promise; export type FrameworkResponse = Lifecycle.ReturnValue; diff --git a/x-pack/plugins/beats_management/server/lib/beats.ts b/x-pack/plugins/beats_management/server/lib/beats.ts index 195117a6a85f2..4f78cc2a294fd 100644 --- a/x-pack/plugins/beats_management/server/lib/beats.ts +++ b/x-pack/plugins/beats_management/server/lib/beats.ts @@ -82,7 +82,6 @@ export class CMBeatsDomain { } const user = typeof userOrToken === 'string' ? this.framework.internalUser : userOrToken; - await this.adapter.update(user, { ...beat, ...beatData, diff --git a/x-pack/plugins/beats_management/server/lib/framework.ts b/x-pack/plugins/beats_management/server/lib/framework.ts index 63da39bb245b6..6dc345f0cc785 100644 --- a/x-pack/plugins/beats_management/server/lib/framework.ts +++ b/x-pack/plugins/beats_management/server/lib/framework.ts @@ -4,14 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import Boom from 'boom'; +import { ResponseObject, ResponseToolkit } from 'hapi'; import { difference } from 'lodash'; +import { BaseReturnType } from '../../common/return_types'; import { BackendFrameworkAdapter, FrameworkRequest, FrameworkResponse, - FrameworkRouteHandler, - FrameworkRouteOptions, } from './adapters/framework/adapter_types'; export class BackendFrameworkLib { @@ -26,13 +25,18 @@ export class BackendFrameworkLib { public registerRoute< RouteRequest extends FrameworkRequest, RouteResponse extends FrameworkResponse - >(route: FrameworkRouteOptions) { + >(route: { + path: string; + method: string | string[]; + licenseRequired?: string[]; + requiredRoles?: string[]; + handler: (request: FrameworkRequest) => Promise; + config?: {}; + }) { this.adapter.registerRoute({ ...route, - handler: this.wrapRouteWithSecurity( - route.handler, - route.licenseRequired || [], - route.requiredRoles + handler: this.wrapErrors( + this.wrapRouteWithSecurity(route.handler, route.licenseRequired || [], route.requiredRoles) ), }); } @@ -71,25 +75,35 @@ export class BackendFrameworkLib { } private wrapRouteWithSecurity( - handler: FrameworkRouteHandler, + handler: (request: FrameworkRequest) => Promise, requiredLicense: string[], requiredRoles?: string[] - ) { - return async (request: FrameworkRequest, h: any) => { + ): (request: FrameworkRequest) => Promise { + return async (request: FrameworkRequest) => { if ( requiredLicense.length > 0 && (this.license.expired || !requiredLicense.includes(this.license.type)) ) { - return Boom.forbidden( - `Your ${ - this.license.type - } license does not support this API or is expired. Please upgrade your license.` - ); + return { + error: { + message: `Your ${ + this.license.type + } license does not support this API or is expired. Please upgrade your license.`, + code: 403, + }, + success: false, + }; } if (requiredRoles) { if (request.user.kind !== 'authenticated') { - return h.response().code(403); + return { + error: { + message: `Request must be authenticated`, + code: 403, + }, + success: false, + }; } if ( @@ -97,10 +111,67 @@ export class BackendFrameworkLib { !request.user.roles.includes('superuser') && difference(requiredRoles, request.user.roles).length !== 0 ) { - return h.response().code(403); + return { + error: { + message: `Request must be authenticated by a user with one of the following user roles: ${requiredRoles.join( + ',' + )}`, + code: 403, + }, + success: false, + }; + } + } + return await handler(request); + }; + } + private wrapErrors( + handler: (request: FrameworkRequest) => Promise + ): (request: FrameworkRequest, h: ResponseToolkit) => Promise { + return async (request: FrameworkRequest, h: ResponseToolkit) => { + try { + const result = await handler(request); + if (!result.error) { + return h.response(result); } + return h + .response({ + error: result.error, + success: false, + }) + .code(result.error.code || 400); + } catch (err) { + let statusCode = err.statusCode; + + // This is the only known non-status code error in the system, but just in case we have an else + if (!statusCode && (err.message as string).includes('Invalid user type')) { + statusCode = 403; + } else { + statusCode = 500; + } + + if (statusCode === 403) { + return h + .response({ + error: { + message: 'Insufficient user permissions for managing Beats configuration', + code: 403, + }, + success: false, + }) + .code(403); + } + + return h + .response({ + error: { + message: err.message, + code: statusCode, + }, + success: false, + }) + .code(statusCode); } - return await handler(request, h); }; } } diff --git a/x-pack/plugins/beats_management/server/rest_api/__tests__/beats_assignments.test.ts b/x-pack/plugins/beats_management/server/rest_api/__tests__/beats_assignments.test.ts index e427c9b0b1115..73a16da179d2f 100644 --- a/x-pack/plugins/beats_management/server/rest_api/__tests__/beats_assignments.test.ts +++ b/x-pack/plugins/beats_management/server/rest_api/__tests__/beats_assignments.test.ts @@ -33,7 +33,7 @@ describe('assign_tags_to_beats', () => { }); expect(statusCode).toEqual(200); - expect(result.assignments).toEqual([{ status: 200, result: 'updated' }]); + expect(result.results).toEqual([{ success: true, result: { message: 'updated' } }]); }); it('should not re-add an existing tag to a beat', async () => { @@ -52,7 +52,7 @@ describe('assign_tags_to_beats', () => { expect(statusCode).toEqual(200); - expect(result.assignments).toEqual([{ status: 200, result: 'updated' }]); + expect(result.results).toEqual([{ success: true, result: { message: 'updated' } }]); let beat; @@ -81,9 +81,9 @@ describe('assign_tags_to_beats', () => { expect(statusCode).toEqual(200); - expect(result.assignments).toEqual([ - { status: 200, result: 'updated' }, - { status: 200, result: 'updated' }, + expect(result.results).toEqual([ + { success: true, result: { message: 'updated' } }, + { success: true, result: { message: 'updated' } }, ]); let beat; @@ -123,9 +123,9 @@ describe('assign_tags_to_beats', () => { expect(statusCode).toEqual(200); - expect(result.assignments).toEqual([ - { status: 200, result: 'updated' }, - { status: 200, result: 'updated' }, + expect(result.results).toEqual([ + { success: true, result: { message: 'updated' } }, + { success: true, result: { message: 'updated' } }, ]); const beat = await serverLibs.beats.getById( diff --git a/x-pack/plugins/beats_management/server/rest_api/beats/configuration.ts b/x-pack/plugins/beats_management/server/rest_api/beats/configuration.ts index 39bd54fd0b5e5..aceba95461a79 100644 --- a/x-pack/plugins/beats_management/server/rest_api/beats/configuration.ts +++ b/x-pack/plugins/beats_management/server/rest_api/beats/configuration.ts @@ -5,8 +5,9 @@ */ import Joi from 'joi'; import { ConfigurationBlock } from '../../../common/domain_types'; +import { BaseReturnType, ReturnTypeList } from '../../../common/return_types'; +import { FrameworkRequest } from '../../lib/adapters/framework/adapter_types'; import { CMServerLibs } from '../../lib/types'; -import { wrapEsError } from '../../utils/error_wrappers'; export const createGetBeatConfigurationRoute = (libs: CMServerLibs) => ({ method: 'GET', @@ -19,44 +20,43 @@ export const createGetBeatConfigurationRoute = (libs: CMServerLibs) => ({ }, auth: false, }, - handler: async (request: any, h: any) => { + handler: async ( + request: FrameworkRequest + ): Promise> => { const beatId = request.params.beatId; const accessToken = request.headers['kbn-beats-access-token']; let beat; let configurationBlocks: ConfigurationBlock[]; - try { - beat = await libs.beats.getById(libs.framework.internalUser, beatId); - if (beat === null) { - return h.response({ message: `Beat "${beatId}" not found` }).code(404); - } + beat = await libs.beats.getById(libs.framework.internalUser, beatId); + if (beat === null) { + return { error: { message: `Beat "${beatId}" not found`, code: 404 }, success: false }; + } - const isAccessTokenValid = beat.access_token === accessToken; - if (!isAccessTokenValid) { - return h.response({ message: 'Invalid access token' }).code(401); - } + const isAccessTokenValid = beat.access_token === accessToken; + if (!isAccessTokenValid) { + return { error: { message: 'Invalid access token', code: 401 }, success: false }; + } - await libs.beats.update(libs.framework.internalUser, beat.id, { - last_checkin: new Date(), - }); + await libs.beats.update(libs.framework.internalUser, beat.id, { + last_checkin: new Date(), + }); - if (beat.tags) { - const result = await libs.configurationBlocks.getForTags( - libs.framework.internalUser, - beat.tags, - -1 - ); + if (beat.tags) { + const result = await libs.configurationBlocks.getForTags( + libs.framework.internalUser, + beat.tags, + -1 + ); - configurationBlocks = result.blocks; - } else { - configurationBlocks = []; - } - } catch (err) { - return wrapEsError(err); + configurationBlocks = result.blocks; + } else { + configurationBlocks = []; } return { - configuration_blocks: configurationBlocks, + list: configurationBlocks, + success: true, }; }, }); diff --git a/x-pack/plugins/beats_management/server/rest_api/beats/enroll.ts b/x-pack/plugins/beats_management/server/rest_api/beats/enroll.ts index 9f3feb4651bd2..df2d7474ccb4a 100644 --- a/x-pack/plugins/beats_management/server/rest_api/beats/enroll.ts +++ b/x-pack/plugins/beats_management/server/rest_api/beats/enroll.ts @@ -6,9 +6,10 @@ import Joi from 'joi'; import { omit } from 'lodash'; import { REQUIRED_LICENSES } from '../../../common/constants/security'; +import { CMBeat } from '../../../common/domain_types'; +import { BaseReturnType, ReturnTypeCreate } from '../../../common/return_types'; import { FrameworkRequest } from '../../lib/adapters/framework/adapter_types'; import { BeatEnrollmentStatus, CMServerLibs } from '../../lib/types'; -import { wrapEsError } from '../../utils/error_wrappers'; // TODO: write to Kibana audit log file https://github.com/elastic/kibana/issues/26024 export const createBeatEnrollmentRoute = (libs: CMServerLibs) => ({ @@ -31,38 +32,38 @@ export const createBeatEnrollmentRoute = (libs: CMServerLibs) => ({ }).required(), }, }, - handler: async (request: FrameworkRequest, h: any) => { + handler: async ( + request: FrameworkRequest + ): Promise> => { const { beatId } = request.params; const enrollmentToken = request.headers['kbn-beats-enrollment-token']; - try { - const { status, accessToken } = await libs.beats.enrollBeat( - enrollmentToken, - beatId, - request.info.remoteAddress, - omit(request.payload, 'enrollment_token') - ); + const { status, accessToken } = await libs.beats.enrollBeat( + enrollmentToken, + beatId, + request.info.remoteAddress, + omit(request.payload, 'enrollment_token') + ); - switch (status) { - case BeatEnrollmentStatus.ExpiredEnrollmentToken: - return h - .response({ - message: BeatEnrollmentStatus.ExpiredEnrollmentToken, - }) - .code(400); - case BeatEnrollmentStatus.InvalidEnrollmentToken: - return h - .response({ - message: BeatEnrollmentStatus.InvalidEnrollmentToken, - }) - .code(400); - case BeatEnrollmentStatus.Success: - default: - return h.response({ access_token: accessToken }).code(201); - } - } catch (err) { - // FIXME move this to kibana route thing in adapter - return wrapEsError(err); + switch (status) { + case BeatEnrollmentStatus.ExpiredEnrollmentToken: + return { + error: { message: BeatEnrollmentStatus.ExpiredEnrollmentToken, code: 400 }, + success: false, + }; + + case BeatEnrollmentStatus.InvalidEnrollmentToken: + return { + error: { message: BeatEnrollmentStatus.InvalidEnrollmentToken, code: 400 }, + success: false, + }; + case BeatEnrollmentStatus.Success: + default: + return { + item: accessToken, + action: 'created', + success: true, + }; } }, }); diff --git a/x-pack/plugins/beats_management/server/rest_api/beats/events.ts b/x-pack/plugins/beats_management/server/rest_api/beats/events.ts index ff72f24a630c1..65d7e9979b9ca 100644 --- a/x-pack/plugins/beats_management/server/rest_api/beats/events.ts +++ b/x-pack/plugins/beats_management/server/rest_api/beats/events.ts @@ -4,8 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ import Joi from 'joi'; +import { BaseReturnType, ReturnTypeBulkAction } from '../../../common/return_types'; +import { FrameworkRequest } from '../../lib/adapters/framework/adapter_types'; import { CMServerLibs } from '../../lib/types'; -import { wrapEsError } from '../../utils/error_wrappers'; export const beatEventsRoute = (libs: CMServerLibs) => ({ method: 'POST', @@ -18,29 +19,26 @@ export const beatEventsRoute = (libs: CMServerLibs) => ({ }, auth: false, }, - handler: async (request: any, h: any) => { + handler: async (request: FrameworkRequest): Promise => { const beatId = request.params.beatId; const events = request.payload; const accessToken = request.headers['kbn-beats-access-token']; - try { - const beat = await libs.beats.getById(libs.framework.internalUser, beatId); - if (beat === null) { - return h.response({ message: `Beat "${beatId}" not found` }).code(400); - } + const beat = await libs.beats.getById(libs.framework.internalUser, beatId); + if (beat === null) { + return { error: { message: `Beat "${beatId}" not found`, code: 400 }, success: false }; + } - const isAccessTokenValid = beat.access_token === accessToken; - if (!isAccessTokenValid) { - return h.response({ message: 'Invalid access token' }).code(401); - } + const isAccessTokenValid = beat.access_token === accessToken; + if (!isAccessTokenValid) { + return { error: { message: `Invalid access token`, code: 401 }, success: false }; + } - const results = await libs.beatEvents.log(libs.framework.internalUser, beat.id, events); + const results = await libs.beatEvents.log(libs.framework.internalUser, beat.id, events); - return { - response: results, - }; - } catch (err) { - return wrapEsError(err); - } + return { + results, + success: true, + }; }, }); diff --git a/x-pack/plugins/beats_management/server/rest_api/beats/get.ts b/x-pack/plugins/beats_management/server/rest_api/beats/get.ts index 41415521c7bca..874e66bb8a533 100644 --- a/x-pack/plugins/beats_management/server/rest_api/beats/get.ts +++ b/x-pack/plugins/beats_management/server/rest_api/beats/get.ts @@ -5,39 +5,35 @@ */ import { CMBeat } from '../../../common/domain_types'; +import { BaseReturnType, ReturnTypeGet } from '../../../common/return_types'; +import { FrameworkRequest } from '../../lib/adapters/framework/adapter_types'; import { CMServerLibs } from '../../lib/types'; -import { wrapEsError } from '../../utils/error_wrappers'; export const createGetBeatRoute = (libs: CMServerLibs) => ({ method: 'GET', path: '/api/beats/agent/{beatId}/{token?}', requiredRoles: ['beats_admin'], - handler: async (request: any, h: any) => { + handler: async (request: FrameworkRequest): Promise> => { const beatId = request.params.beatId; let beat: CMBeat | null; if (beatId === 'unknown') { - try { - beat = await libs.beats.getByEnrollmentToken(request.user, request.params.token); - if (beat === null) { - return h.response().code(200); - } - } catch (err) { - return wrapEsError(err); + beat = await libs.beats.getByEnrollmentToken(request.user, request.params.token); + if (beat === null) { + return { success: false }; } } else { - try { - beat = await libs.beats.getById(request.user, beatId); - if (beat === null) { - return h.response({ message: 'Beat not found' }).code(404); - } - } catch (err) { - return wrapEsError(err); + beat = await libs.beats.getById(request.user, beatId); + if (beat === null) { + return { error: { message: 'Beat not found', code: 404 }, success: false }; } } delete beat.access_token; - return beat; + return { + item: beat, + success: true, + }; }, }); diff --git a/x-pack/plugins/beats_management/server/rest_api/beats/list.ts b/x-pack/plugins/beats_management/server/rest_api/beats/list.ts index d8f1566607780..74fb98fc877cc 100644 --- a/x-pack/plugins/beats_management/server/rest_api/beats/list.ts +++ b/x-pack/plugins/beats_management/server/rest_api/beats/list.ts @@ -7,9 +7,9 @@ import * as Joi from 'joi'; import { REQUIRED_LICENSES } from '../../../common/constants/security'; import { CMBeat } from '../../../common/domain_types'; +import { ReturnTypeList } from '../../../common/return_types'; import { FrameworkRequest } from '../../lib/adapters/framework/adapter_types'; import { CMServerLibs } from '../../lib/types'; -import { wrapEsError } from '../../utils/error_wrappers'; export const createListAgentsRoute = (libs: CMServerLibs) => ({ method: 'GET', @@ -27,7 +27,7 @@ export const createListAgentsRoute = (libs: CMServerLibs) => ({ ESQuery: Joi.string(), }), }, - handler: async (request: FrameworkRequest) => { + handler: async (request: FrameworkRequest): Promise> => { const listByAndValueParts = request.params.listByAndValue ? request.params.listByAndValue.split('/') : []; @@ -39,27 +39,22 @@ export const createListAgentsRoute = (libs: CMServerLibs) => ({ listByValue = listByAndValueParts[1]; } - try { - let beats: CMBeat[]; + let beats: CMBeat[]; - switch (listBy) { - case 'tag': - beats = await libs.beats.getAllWithTag(request.user, listByValue || ''); - break; + switch (listBy) { + case 'tag': + beats = await libs.beats.getAllWithTag(request.user, listByValue || ''); + break; - default: - beats = await libs.beats.getAll( - request.user, - request.query && request.query.ESQuery ? JSON.parse(request.query.ESQuery) : undefined - ); + default: + beats = await libs.beats.getAll( + request.user, + request.query && request.query.ESQuery ? JSON.parse(request.query.ESQuery) : undefined + ); - break; - } - - return { beats }; - } catch (err) { - // FIXME move this to kibana route thing in adapter - return wrapEsError(err); + break; } + + return { list: beats, success: true, page: -1, total: -1 }; }, }); diff --git a/x-pack/plugins/beats_management/server/rest_api/beats/tag_assignment.ts b/x-pack/plugins/beats_management/server/rest_api/beats/tag_assignment.ts index fb2dbb8737e6c..90ba4056d7c98 100644 --- a/x-pack/plugins/beats_management/server/rest_api/beats/tag_assignment.ts +++ b/x-pack/plugins/beats_management/server/rest_api/beats/tag_assignment.ts @@ -6,10 +6,10 @@ import Joi from 'joi'; import { REQUIRED_LICENSES } from '../../../common/constants/security'; +import { ReturnTypeBulkAction } from '../../../common/return_types'; import { BeatsTagAssignment } from '../../../public/lib/adapters/beats/adapter_types'; import { FrameworkRequest } from '../../lib/adapters/framework/adapter_types'; import { CMServerLibs } from '../../lib/types'; -import { wrapEsError } from '../../utils/error_wrappers'; // TODO: write to Kibana audit log file https://github.com/elastic/kibana/issues/26024 export const createTagAssignmentsRoute = (libs: CMServerLibs) => ({ @@ -29,15 +29,29 @@ export const createTagAssignmentsRoute = (libs: CMServerLibs) => ({ }).required(), }, }, - handler: async (request: FrameworkRequest) => { + handler: async (request: FrameworkRequest): Promise => { const { assignments }: { assignments: BeatsTagAssignment[] } = request.payload; - try { - const response = await libs.beats.assignTagsToBeats(request.user, assignments); - return response; - } catch (err) { - // TODO move this to kibana route thing in adapter - return wrapEsError(err); - } + const response = await libs.beats.assignTagsToBeats(request.user, assignments); + + return { + success: true, + results: response.assignments.map(assignment => ({ + success: assignment.status && assignment.status >= 200 && assignment.status < 300, + error: + !assignment.status || assignment.status >= 300 + ? { + code: assignment.status || 400, + message: assignment.result, + } + : undefined, + result: + assignment.status && assignment.status >= 200 && assignment.status < 300 + ? { + message: assignment.result, + } + : undefined, + })), + } as ReturnTypeBulkAction; }, }); diff --git a/x-pack/plugins/beats_management/server/rest_api/beats/tag_removal.ts b/x-pack/plugins/beats_management/server/rest_api/beats/tag_removal.ts index e56e114a23204..90c8a78552df7 100644 --- a/x-pack/plugins/beats_management/server/rest_api/beats/tag_removal.ts +++ b/x-pack/plugins/beats_management/server/rest_api/beats/tag_removal.ts @@ -6,9 +6,9 @@ import Joi from 'joi'; import { REQUIRED_LICENSES } from '../../../common/constants/security'; +import { ReturnTypeBulkAction } from '../../../common/return_types'; import { FrameworkRequest } from '../../lib/adapters/framework/adapter_types'; import { CMServerLibs } from '../../lib/types'; -import { wrapEsError } from '../../utils/error_wrappers'; // TODO: write to Kibana audit log file https://github.com/elastic/kibana/issues/26024 export const createTagRemovalsRoute = (libs: CMServerLibs) => ({ @@ -28,15 +28,29 @@ export const createTagRemovalsRoute = (libs: CMServerLibs) => ({ }).required(), }, }, - handler: async (request: FrameworkRequest) => { + handler: async (request: FrameworkRequest): Promise => { const { removals } = request.payload; - try { - const response = await libs.beats.removeTagsFromBeats(request.user, removals); - return response; - } catch (err) { - // TODO move this to kibana route thing in adapter - return wrapEsError(err); - } + const response = await libs.beats.removeTagsFromBeats(request.user, removals); + + return { + success: true, + results: response.removals.map(removal => ({ + success: removal.status && removal.status >= 200 && removal.status < 300, + error: + !removal.status || removal.status >= 300 + ? { + code: removal.status || 400, + message: removal.result, + } + : undefined, + result: + removal.status && removal.status >= 200 && removal.status < 300 + ? { + message: removal.result, + } + : undefined, + })), + } as ReturnTypeBulkAction; }, }); diff --git a/x-pack/plugins/beats_management/server/rest_api/beats/update.ts b/x-pack/plugins/beats_management/server/rest_api/beats/update.ts index 9d415a48f0085..9fef5f1594392 100644 --- a/x-pack/plugins/beats_management/server/rest_api/beats/update.ts +++ b/x-pack/plugins/beats_management/server/rest_api/beats/update.ts @@ -5,10 +5,11 @@ */ import Joi from 'joi'; +import { CMBeat } from 'x-pack/plugins/beats_management/common/domain_types'; import { REQUIRED_LICENSES } from '../../../common/constants/security'; -import { FrameworkRequest } from '../../lib/adapters/framework/adapter_types'; +import { BaseReturnType, ReturnTypeUpdate } from '../../../common/return_types'; +import { FrameworkRequest, internalUser } from '../../lib/adapters/framework/adapter_types'; import { CMServerLibs } from '../../lib/types'; -import { wrapEsError } from '../../utils/error_wrappers'; // TODO: write to Kibana audit log file (include who did the verification as well) https://github.com/elastic/kibana/issues/26024 export const createBeatUpdateRoute = (libs: CMServerLibs) => ({ @@ -38,34 +39,54 @@ export const createBeatUpdateRoute = (libs: CMServerLibs) => ({ }), }, }, - handler: async (request: FrameworkRequest, h: any) => { + handler: async ( + request: FrameworkRequest + ): Promise> => { const { beatId } = request.params; const accessToken = request.headers['kbn-beats-access-token']; const remoteAddress = request.info.remoteAddress; const userOrToken = accessToken || request.user; if (request.user.kind === 'unauthenticated' && request.payload.active !== undefined) { - return h - .response({ message: 'access-token is not a valid auth type to change beat status' }) - .code(401); + return { + error: { + message: 'access-token is not a valid auth type to change beat status', + code: 401, + }, + success: false, + }; } - try { - const status = await libs.beats.update(userOrToken, beatId, { - ...request.payload, - host_ip: remoteAddress, - }); + const status = await libs.beats.update(userOrToken, beatId, { + ...request.payload, + host_ip: remoteAddress, + }); - switch (status) { - case 'beat-not-found': - return h.response({ message: 'Beat not found', success: false }).code(404); - case 'invalid-access-token': - return h.response({ message: 'Invalid access token', success: false }).code(401); - } - - return h.response({ success: true }).code(204); - } catch (err) { - return wrapEsError(err); + switch (status) { + case 'beat-not-found': + return { + error: { + message: 'Beat not found', + code: 404, + }, + success: false, + }; + case 'invalid-access-token': + return { + error: { + message: 'Invalid access token', + code: 401, + }, + success: false, + }; } + + const beat = await libs.beats.getById(internalUser, beatId); + + return { + item: beat, + action: 'updated', + success: true, + }; }, }); diff --git a/x-pack/plugins/beats_management/server/rest_api/configurations/delete.ts b/x-pack/plugins/beats_management/server/rest_api/configurations/delete.ts index 31cf998250637..5cd9897be91d0 100644 --- a/x-pack/plugins/beats_management/server/rest_api/configurations/delete.ts +++ b/x-pack/plugins/beats_management/server/rest_api/configurations/delete.ts @@ -5,22 +5,28 @@ */ import { REQUIRED_LICENSES } from '../../../common/constants/security'; +import { ReturnTypeBulkDelete } from '../../../common/return_types'; +import { FrameworkRequest } from '../../lib/adapters/framework/adapter_types'; import { CMServerLibs } from '../../lib/types'; -import { wrapEsError } from '../../utils/error_wrappers'; export const createDeleteConfidurationsRoute = (libs: CMServerLibs) => ({ method: 'DELETE', path: '/api/beats/configurations/{ids}', requiredRoles: ['beats_admin'], licenseRequired: REQUIRED_LICENSES, - handler: async (request: any) => { + handler: async (request: FrameworkRequest): Promise => { const idString: string = request.params.ids; const ids = idString.split(',').filter((id: string) => id.length > 0); - try { - return await libs.configurationBlocks.delete(request.user, ids); - } catch (err) { - return wrapEsError(err); - } + const results = await libs.configurationBlocks.delete(request.user, ids); + + return { + success: true, + results: results.map(result => ({ + success: result.success, + action: 'deleted', + error: result.success ? undefined : { message: result.reason }, + })), + } as ReturnTypeBulkDelete; }, }); diff --git a/x-pack/plugins/beats_management/server/rest_api/configurations/get.ts b/x-pack/plugins/beats_management/server/rest_api/configurations/get.ts index 62982cb31eb36..df534f74239ed 100644 --- a/x-pack/plugins/beats_management/server/rest_api/configurations/get.ts +++ b/x-pack/plugins/beats_management/server/rest_api/configurations/get.ts @@ -5,31 +5,27 @@ */ import { REQUIRED_LICENSES } from '../../../common/constants/security'; +import { ConfigurationBlock } from '../../../common/domain_types'; +import { ReturnTypeList } from '../../../common/return_types'; +import { FrameworkRequest } from '../../lib/adapters/framework/adapter_types'; import { CMServerLibs } from '../../lib/types'; -import { wrapEsError } from '../../utils/error_wrappers'; -import { FrameworkRouteOptions } from './../../lib/adapters/framework/adapter_types'; -export const createGetConfigurationBlocksRoute = (libs: CMServerLibs): FrameworkRouteOptions => ({ +export const createGetConfigurationBlocksRoute = (libs: CMServerLibs) => ({ method: 'GET', path: '/api/beats/configurations/{tagIds}/{page?}', requiredRoles: ['beats_admin'], licenseRequired: REQUIRED_LICENSES, - handler: async (request: any) => { + handler: async (request: FrameworkRequest): Promise> => { const tagIdString: string = request.params.tagIds; const tagIds = tagIdString.split(',').filter((id: string) => id.length > 0); - let tags; - try { - tags = await libs.configurationBlocks.getForTags( - request.user, - tagIds, - parseInt(request.params.page, 10), - 5 - ); - } catch (err) { - return wrapEsError(err); - } + const result = await libs.configurationBlocks.getForTags( + request.user, + tagIds, + parseInt(request.params.page, 10), + 5 + ); - return tags; + return { page: result.page, total: result.total, list: result.blocks, success: true }; }, }); diff --git a/x-pack/plugins/beats_management/server/rest_api/configurations/upsert.ts b/x-pack/plugins/beats_management/server/rest_api/configurations/upsert.ts index 29f9452be2461..67622bbffad56 100644 --- a/x-pack/plugins/beats_management/server/rest_api/configurations/upsert.ts +++ b/x-pack/plugins/beats_management/server/rest_api/configurations/upsert.ts @@ -16,6 +16,7 @@ import { ConfigurationBlock, createConfigurationBlockInterface, } from '../../../common/domain_types'; +import { ReturnTypeBulkUpsert } from '../../../common/return_types'; import { FrameworkRequest } from '../../lib/adapters/framework/adapter_types'; import { CMServerLibs } from '../../lib/types'; @@ -30,16 +31,16 @@ export const upsertConfigurationRoute = (libs: CMServerLibs) => ({ payload: Joi.array().items(Joi.object({}).unknown(true)), }, }, - handler: async (request: FrameworkRequest) => { - const result = request.payload.map(async (block: ConfigurationBlock) => { - const assertData = createConfigurationBlockInterface().decode(block); - if (assertData.isLeft()) { - return { - error: `Error parsing block info, ${PathReporter.report(assertData)[0]}`, - }; - } + handler: async (request: FrameworkRequest): Promise => { + const result = await Promise.all( + request.payload.map(async (block: ConfigurationBlock) => { + const assertData = createConfigurationBlockInterface().decode(block); + if (assertData.isLeft()) { + return { + error: `Error parsing block info, ${PathReporter.report(assertData)[0]}`, + }; + } - try { const { blockID, success, error } = await libs.configurationBlocks.save( request.user, block @@ -49,11 +50,16 @@ export const upsertConfigurationRoute = (libs: CMServerLibs) => ({ } return { success, blockID }; - } catch (err) { - return { success: false, error: err.msg }; - } - }); + }) + ); - return Promise.all(result); + return { + results: result.map(r => ({ + success: r.success as boolean, + // TODO: we need to surface this data, not hard coded + action: 'created' as 'created' | 'updated', + })), + success: true, + }; }, }); diff --git a/x-pack/plugins/beats_management/server/rest_api/tags/assignable.ts b/x-pack/plugins/beats_management/server/rest_api/tags/assignable.ts index 544470467b0d1..5cb4d2c445e41 100644 --- a/x-pack/plugins/beats_management/server/rest_api/tags/assignable.ts +++ b/x-pack/plugins/beats_management/server/rest_api/tags/assignable.ts @@ -7,29 +7,29 @@ import { flatten } from 'lodash'; import { REQUIRED_LICENSES } from '../../../common/constants/security'; import { BeatTag } from '../../../common/domain_types'; +import { ReturnTypeBulkGet } from '../../../common/return_types'; +import { FrameworkRequest } from '../../lib/adapters/framework/adapter_types'; import { CMServerLibs } from '../../lib/types'; -import { wrapEsError } from '../../utils/error_wrappers'; export const createAssignableTagsRoute = (libs: CMServerLibs) => ({ method: 'GET', path: '/api/beats/tags/assignable/{beatIds}', requiredRoles: ['beats_admin'], licenseRequired: REQUIRED_LICENSES, - handler: async (request: any) => { + handler: async (request: FrameworkRequest): Promise> => { const beatIdString: string = request.params.beatIds; const beatIds = beatIdString.split(',').filter((id: string) => id.length > 0); let tags: BeatTag[]; - try { - const beats = await libs.beats.getByIds(request.user, beatIds); - tags = await libs.tags.getNonConflictingTags( - request.user, - flatten(beats.map(beat => beat.tags)) - ); - } catch (err) { - return wrapEsError(err); - } + const beats = await libs.beats.getByIds(request.user, beatIds); + tags = await libs.tags.getNonConflictingTags( + request.user, + flatten(beats.map(beat => beat.tags)) + ); - return tags; + return { + items: tags, + success: true, + }; }, }); diff --git a/x-pack/plugins/beats_management/server/rest_api/tags/delete.ts b/x-pack/plugins/beats_management/server/rest_api/tags/delete.ts index a91b98d43ac6f..ab94d31296936 100644 --- a/x-pack/plugins/beats_management/server/rest_api/tags/delete.ts +++ b/x-pack/plugins/beats_management/server/rest_api/tags/delete.ts @@ -5,25 +5,28 @@ */ import { REQUIRED_LICENSES } from '../../../common/constants/security'; +import { ReturnTypeBulkDelete } from '../../../common/return_types'; +import { FrameworkRequest } from '../../lib/adapters/framework/adapter_types'; import { CMServerLibs } from '../../lib/types'; -import { wrapEsError } from '../../utils/error_wrappers'; export const createDeleteTagsWithIdsRoute = (libs: CMServerLibs) => ({ method: 'DELETE', path: '/api/beats/tags/{tagIds}', requiredRoles: ['beats_admin'], licenseRequired: REQUIRED_LICENSES, - handler: async (request: any) => { + handler: async (request: FrameworkRequest): Promise => { const tagIdString: string = request.params.tagIds; const tagIds = tagIdString.split(',').filter((id: string) => id.length > 0); let success: boolean; - try { - success = await libs.tags.delete(request.user, tagIds); - } catch (err) { - return wrapEsError(err); - } + success = await libs.tags.delete(request.user, tagIds); - return { success }; + return { + results: tagIds.map(() => ({ + success, + action: 'deleted', + })), + success, + } as ReturnTypeBulkDelete; }, }); diff --git a/x-pack/plugins/beats_management/server/rest_api/tags/get.ts b/x-pack/plugins/beats_management/server/rest_api/tags/get.ts index bebda03c565dc..c20c576f4672d 100644 --- a/x-pack/plugins/beats_management/server/rest_api/tags/get.ts +++ b/x-pack/plugins/beats_management/server/rest_api/tags/get.ts @@ -6,26 +6,25 @@ import { REQUIRED_LICENSES } from '../../../common/constants/security'; import { BeatTag } from '../../../common/domain_types'; +import { ReturnTypeBulkGet } from '../../../common/return_types'; +import { FrameworkRequest } from '../../lib/adapters/framework/adapter_types'; import { CMServerLibs } from '../../lib/types'; -import { wrapEsError } from '../../utils/error_wrappers'; -import { FrameworkRouteOptions } from './../../lib/adapters/framework/adapter_types'; -export const createGetTagsWithIdsRoute = (libs: CMServerLibs): FrameworkRouteOptions => ({ +export const createGetTagsWithIdsRoute = (libs: CMServerLibs) => ({ method: 'GET', path: '/api/beats/tags/{tagIds}', requiredRoles: ['beats_admin'], licenseRequired: REQUIRED_LICENSES, - handler: async (request: any) => { + handler: async (request: FrameworkRequest): Promise> => { const tagIdString: string = request.params.tagIds; const tagIds = tagIdString.split(',').filter((id: string) => id.length > 0); let tags: BeatTag[]; - try { - tags = await libs.tags.getWithIds(request.user, tagIds); - } catch (err) { - return wrapEsError(err); - } + tags = await libs.tags.getWithIds(request.user, tagIds); - return tags; + return { + items: tags, + success: true, + }; }, }); diff --git a/x-pack/plugins/beats_management/server/rest_api/tags/list.ts b/x-pack/plugins/beats_management/server/rest_api/tags/list.ts index 2509a230d24dc..749456828a06a 100644 --- a/x-pack/plugins/beats_management/server/rest_api/tags/list.ts +++ b/x-pack/plugins/beats_management/server/rest_api/tags/list.ts @@ -5,10 +5,11 @@ */ import * as Joi from 'joi'; +import { ReturnTypeList } from 'x-pack/plugins/beats_management/common/return_types'; import { REQUIRED_LICENSES } from '../../../common/constants/security'; import { BeatTag } from '../../../common/domain_types'; +import { FrameworkRequest } from '../../lib/adapters/framework/adapter_types'; import { CMServerLibs } from '../../lib/types'; -import { wrapEsError } from '../../utils/error_wrappers'; export const createListTagsRoute = (libs: CMServerLibs) => ({ method: 'GET', @@ -25,17 +26,13 @@ export const createListTagsRoute = (libs: CMServerLibs) => ({ ESQuery: Joi.string(), }), }, - handler: async (request: any) => { + handler: async (request: FrameworkRequest): Promise> => { let tags: BeatTag[]; - try { - tags = await libs.tags.getAll( - request.user, - request.query && request.query.ESQuery ? JSON.parse(request.query.ESQuery) : undefined - ); - } catch (err) { - return wrapEsError(err); - } + tags = await libs.tags.getAll( + request.user, + request.query && request.query.ESQuery ? JSON.parse(request.query.ESQuery) : undefined + ); - return tags; + return { list: tags, success: true, page: -1, total: -1 }; }, }); diff --git a/x-pack/plugins/beats_management/server/rest_api/tags/set.ts b/x-pack/plugins/beats_management/server/rest_api/tags/set.ts index 5c35d478c9014..adf26124b581b 100644 --- a/x-pack/plugins/beats_management/server/rest_api/tags/set.ts +++ b/x-pack/plugins/beats_management/server/rest_api/tags/set.ts @@ -6,10 +6,11 @@ import Joi from 'joi'; import { get } from 'lodash'; +import { BeatTag } from 'x-pack/plugins/beats_management/common/domain_types'; import { REQUIRED_LICENSES } from '../../../common/constants'; +import { ReturnTypeUpsert } from '../../../common/return_types'; import { FrameworkRequest } from '../../lib/adapters/framework/adapter_types'; import { CMServerLibs } from '../../lib/types'; -import { wrapEsError } from '../../utils/error_wrappers'; // TODO: write to Kibana audit log file export const createSetTagRoute = (libs: CMServerLibs) => ({ @@ -28,7 +29,7 @@ export const createSetTagRoute = (libs: CMServerLibs) => ({ }), }, }, - handler: async (request: FrameworkRequest) => { + handler: async (request: FrameworkRequest): Promise> => { const defaultConfig = { id: request.params.tagId, name: request.params.tagId, @@ -37,13 +38,10 @@ export const createSetTagRoute = (libs: CMServerLibs) => ({ }; const config = { ...defaultConfig, ...get(request, 'payload', {}) }; - try { - const id = await libs.tags.upsertTag(request.user, config); + const id = await libs.tags.upsertTag(request.user, config); + const tag = await libs.tags.getWithIds(request.user, [id]); - return { success: true, id }; - } catch (err) { - // TODO move this to kibana route thing in adapter - return wrapEsError(err); - } + // TODO the action needs to be surfaced + return { success: true, item: tag[0], action: 'created' }; }, }); diff --git a/x-pack/plugins/beats_management/server/rest_api/tokens/create.ts b/x-pack/plugins/beats_management/server/rest_api/tokens/create.ts index ce3ce504226a7..9de44447a0a01 100644 --- a/x-pack/plugins/beats_management/server/rest_api/tokens/create.ts +++ b/x-pack/plugins/beats_management/server/rest_api/tokens/create.ts @@ -4,10 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import Boom from 'boom'; import Joi from 'joi'; import { get } from 'lodash'; import { REQUIRED_LICENSES } from '../../../common/constants/security'; +import { BaseReturnType, ReturnTypeBulkCreate } from '../../../common/return_types'; import { FrameworkRequest } from '../../lib/adapters/framework/adapter_types'; import { CMServerLibs } from '../../lib/types'; @@ -28,15 +28,30 @@ export const createTokensRoute = (libs: CMServerLibs) => ({ }).allow(null), }, }, - handler: async (request: FrameworkRequest) => { + handler: async ( + request: FrameworkRequest + ): Promise> => { const numTokens = get(request, 'payload.num_tokens', DEFAULT_NUM_TOKENS); try { const tokens = await libs.tokens.createEnrollmentTokens(request.user, numTokens); - return { tokens }; + return { + results: tokens.map(token => ({ + item: token, + success: true, + action: 'created', + })), + success: true, + }; } catch (err) { libs.framework.log(err.message); - return Boom.internal(); + return { + error: { + message: 'An error occured, please check your Kibana logs', + code: 500, + }, + success: false, + }; } }, }); diff --git a/x-pack/plugins/beats_management/server/utils/error_wrappers/wrap_es_error.test.ts b/x-pack/plugins/beats_management/server/utils/error_wrappers/wrap_es_error.test.ts deleted file mode 100644 index e7fb1c2adda21..0000000000000 --- a/x-pack/plugins/beats_management/server/utils/error_wrappers/wrap_es_error.test.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { wrapEsError } from './wrap_es_error'; - -describe('wrap_es_error', () => { - describe('#wrapEsError', () => { - let originalError: any; - beforeEach(() => { - originalError = new Error('I am an error'); - originalError.statusCode = 404; - }); - - it('should return a Boom object', () => { - const wrappedError = wrapEsError(originalError); - - expect(wrappedError.isBoom).toEqual(true); - }); - - it('should return the correct Boom object', () => { - const wrappedError = wrapEsError(originalError); - - expect(wrappedError.output.statusCode).toEqual(originalError.statusCode); - expect(wrappedError.output.payload.message).toEqual(originalError.message); - }); - - it('should return invalid permissions message for 403 errors', () => { - const securityError = new Error('I am an error'); - // @ts-ignore - securityError.statusCode = 403; - const wrappedError = wrapEsError(securityError); - - expect(wrappedError.isBoom).toEqual(true); - expect(wrappedError.message).toEqual( - 'Insufficient user permissions for managing Beats configuration' - ); - }); - }); -}); diff --git a/x-pack/plugins/beats_management/server/utils/error_wrappers/wrap_es_error.ts b/x-pack/plugins/beats_management/server/utils/error_wrappers/wrap_es_error.ts deleted file mode 100644 index 16c35fad7d63b..0000000000000 --- a/x-pack/plugins/beats_management/server/utils/error_wrappers/wrap_es_error.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -// @ts-ignore -import Boom from 'boom'; - -/** - * Wraps ES errors into a Boom error response and returns it - * This also handles the permissions issue gracefully - * - * @param err Object ES error - * @return Object Boom error response - */ -export function wrapEsError(err: any) { - const statusCode = err.statusCode; - if (statusCode === 403) { - return Boom.forbidden('Insufficient user permissions for managing Beats configuration'); - } - - return Boom.boomify(err, { statusCode: err.statusCode }); -} diff --git a/x-pack/plugins/canvas/.storybook/webpack.config.js b/x-pack/plugins/canvas/.storybook/webpack.config.js index b52a4020c5923..39e33c9613e44 100644 --- a/x-pack/plugins/canvas/.storybook/webpack.config.js +++ b/x-pack/plugins/canvas/.storybook/webpack.config.js @@ -17,7 +17,7 @@ module.exports = (_baseConfig, _env, config) => { include: /\.storybook/, loaders: 'babel-loader', options: { - presets: [require.resolve('babel-preset-react')], + presets: [require.resolve('@babel/preset-react')], }, }, ); diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/__tests__/markdown.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/__tests__/markdown.js index d4ea050951c9a..e1b0fe770cd3d 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/__tests__/markdown.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/__tests__/markdown.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { markdown } from '../markdown'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { testTable } from '../../common/__tests__/fixtures/test_tables'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/all.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/all.js index 90558c26d5c87..3cde6599d3da2 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/all.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/all.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { all } from '../all'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/alterColumn.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/alterColumn.js index a9ad20c05c6f3..e4487b5bb4ca0 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/alterColumn.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/alterColumn.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { alterColumn } from '../alterColumn'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { emptyTable, testTable } from './fixtures/test_tables'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/any.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/any.js index bc67aa377e49d..5c5b35fa36163 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/any.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/any.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { any } from '../any'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/as.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/as.js index 82a8d29742279..9da489fc9e4f9 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/as.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/as.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { asFn } from '../as'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/axis_config.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/axis_config.js index 1e4bbccb8ae38..06f7bca305980 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/axis_config.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/axis_config.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { axisConfig } from '../axisConfig'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { testTable } from '../__tests__/fixtures/test_tables'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/case.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/case.js index c5fd1f14e79db..37aaa96a7fa16 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/case.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/case.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { caseFn } from '../case'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/clear.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/clear.js index fc6ca6c813d28..80f3b6a4f257b 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/clear.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/clear.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { clear } from '../clear'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { testTable } from './fixtures/test_tables'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/columns.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/columns.js index ca1e647cbe9e7..f4be4920c5737 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/columns.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/columns.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { columns } from '../columns'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { emptyTable, testTable } from './fixtures/test_tables'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/compare.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/compare.js index 2bd31f5d69ffc..26e7b83258b35 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/compare.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/compare.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { compare } from '../compare'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/container_style.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/container_style.js index 7daef98b0929c..77a9bef72d3e8 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/container_style.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/container_style.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { containerStyle } from '../containerStyle'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { elasticLogo } from '../../../lib/elastic_logo'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/context.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/context.js index da162dc9150b1..7d3ce308d6796 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/context.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/context.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { context } from '../context'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { testTable, emptyTable } from './fixtures/test_tables'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/csv.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/csv.js index 8f79cab5577af..03bd7669063bc 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/csv.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/csv.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { csv } from '../csv'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/date.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/date.js index 94b6e7eb4f674..7f79f7cbc4638 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/date.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/date.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { date } from '../date'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/do.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/do.js index 000e614a35c98..6cb6af5405c2a 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/do.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/do.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { doFn } from '../do'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/dropdown_control.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/dropdown_control.js index 437e55a197c40..0c977759b18a7 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/dropdown_control.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/dropdown_control.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { dropdownControl } from '../dropdownControl'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { testTable } from './fixtures/test_tables'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/eq.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/eq.js index a419dd98f3ffa..1e03c73cbcf20 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/eq.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/eq.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { eq } from '../eq'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/exactly.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/exactly.js index e9f37efd15c26..444befdcd0ffc 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/exactly.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/exactly.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { exactly } from '../exactly'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { emptyFilter } from './fixtures/test_filters'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/filterrows.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/filterrows.js index baa7096cb6324..6ab8fd58f27eb 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/filterrows.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/filterrows.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { filterrows } from '../filterrows'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { testTable } from './fixtures/test_tables'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/font.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/font.js index 0bd5871b03ad1..0848d7361b684 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/font.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/font.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { openSans } from '../../../../common/lib/fonts'; import { font } from '../font'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/formatdate.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/formatdate.js index d9f9169079044..bcbd5f4b5ecad 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/formatdate.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/formatdate.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { formatdate } from '../formatdate'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/formatnumber.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/formatnumber.js index b0d8a7df62f1f..c0e10f3080028 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/formatnumber.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/formatnumber.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { formatnumber } from '../formatnumber'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/getCell.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/getCell.js index 7b73dbec4df08..f780aadb4032a 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/getCell.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/getCell.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getCell } from '../getCell'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { emptyTable, testTable } from './fixtures/test_tables'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/get_flot_axis_config.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/get_flot_axis_config.js index 2a1fca38f2685..0e309f667ac8f 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/get_flot_axis_config.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/get_flot_axis_config.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getFlotAxisConfig } from '../plot/get_flot_axis_config'; import { xAxisConfig, yAxisConfig, hideAxis } from './fixtures/test_styles'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/get_font_spec.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/get_font_spec.js index 4f2fb67cd938f..91555ee0382f8 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/get_font_spec.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/get_font_spec.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { defaultSpec, getFontSpec } from '../plot/get_font_spec'; import { fontStyle } from './fixtures/test_styles'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/get_tick_hash.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/get_tick_hash.js index 02412862d9512..7ca21c792003d 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/get_tick_hash.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/get_tick_hash.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getTickHash } from '../plot/get_tick_hash'; describe('getTickHash', () => { diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/gt.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/gt.js index ca490aa88fec7..7f0e259a5211f 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/gt.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/gt.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { gt } from '../gt'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/gte.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/gte.js index ba4f0f7a3f9b1..a6d88b2d839a7 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/gte.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/gte.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { gte } from '../gte'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/head.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/head.js index d9cd5a0743764..2822eb39ae47e 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/head.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/head.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { head } from '../head'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { emptyTable, testTable } from './fixtures/test_tables'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/if.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/if.js index aee9efc5203c2..4c95af2c40bc6 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/if.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/if.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { ifFn } from '../if'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/image.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/image.js index 304d970882bf4..0d1c80665f570 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/image.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/image.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { image } from '../image'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { elasticLogo } from '../../../lib/elastic_logo'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/lt.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/lt.js index 3597bd3805d6e..abc0f6e66641c 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/lt.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/lt.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { lt } from '../lt'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/lte.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/lte.js index e800b72c13ff5..3eeadbb62b272 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/lte.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/lte.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { lte } from '../lte'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/mapColumn.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/mapColumn.js index 87db17cf8b312..bdcdf39625549 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/mapColumn.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/mapColumn.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { mapColumn } from '../mapColumn'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { testTable, emptyTable } from './fixtures/test_tables'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/math.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/math.js index f290cce865153..da5069764927c 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/math.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/math.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { math } from '../math'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { emptyTable, testTable } from './fixtures/test_tables'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/metric.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/metric.js index 587e7fbf1f8b0..f59b0c7bf52a0 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/metric.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/metric.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { metric } from '../metric'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { fontStyle } from './fixtures/test_styles'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/neq.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/neq.js index 3d2ca7b90017c..c4abc22249dc0 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/neq.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/neq.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { neq } from '../neq'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/palette.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/palette.js index ecb3ed8b2bbd0..d3f828cfbcf0b 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/palette.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/palette.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { palette } from '../palette'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { palettes } from '../../../../common/lib/palettes'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/pie.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/pie.js index 2048b6763fb25..d51c718ca4ce7 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/pie.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/pie.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { pie } from '../pie'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { testPie } from './fixtures/test_pointseries'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/plot.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/plot.js index 3d6c62419ef48..fadf847135a4e 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/plot.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/plot.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { plot } from '../plot'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { testPlot } from './fixtures/test_pointseries'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/ply.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/ply.js index 54e33de91a47b..b22ac6df0ed37 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/ply.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/ply.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { ply } from '../ply'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { testTable } from './fixtures/test_tables'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/progress.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/progress.js index 61df4292e0254..70ff9d2c6a280 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/progress.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/progress.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { progress } from '../progress'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { fontStyle } from './fixtures/test_styles'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/render.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/render.js index 720242418e0a5..c29df283fdc1d 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/render.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/render.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { render } from '../render'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { testTable } from './fixtures/test_tables'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/repeat_image.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/repeat_image.js index 0a18b7d25071e..65d17cf2d6387 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/repeat_image.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/repeat_image.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { repeatImage } from '../repeatImage'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { elasticOutline } from '../../../lib/elastic_outline'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/replace.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/replace.js index 55fcbf10d7fd7..3eea71fb1cdbd 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/replace.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/replace.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { replace } from '../replace'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/reveal_image.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/reveal_image.js index 3a3707e7c0b72..8f33f831c8346 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/reveal_image.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/reveal_image.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { revealImage } from '../revealImage'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { elasticOutline } from '../../../lib/elastic_outline'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/rounddate.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/rounddate.js index ab66ef05f4f2b..6f4402d5234f4 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/rounddate.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/rounddate.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { rounddate } from '../rounddate'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/rowCount.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/rowCount.js index c50f39f7b3084..350ffca635d85 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/rowCount.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/rowCount.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { rowCount } from '../rowCount'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { emptyTable, testTable } from './fixtures/test_tables'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/series_style.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/series_style.js index a0de476435949..9130f0d34e452 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/series_style.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/series_style.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { seriesStyle } from '../seriesStyle'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/series_style_to_flot.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/series_style_to_flot.js index adb6b48b9b28b..e84c9fc6e6e69 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/series_style_to_flot.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/series_style_to_flot.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { seriesStyleToFlot } from '../plot/series_style_to_flot'; describe('seriesStyleToFlot', () => { diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/sort.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/sort.js index 9940be856ec91..3c927cde9ccd6 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/sort.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/sort.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { sort } from '../sort'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { testTable } from './fixtures/test_tables'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/staticColumn.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/staticColumn.js index 01d00a3b74bf9..d34a2fe4c3e42 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/staticColumn.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/staticColumn.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { staticColumn } from '../staticColumn'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { testTable, emptyTable } from './fixtures/test_tables'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/string.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/string.js index 7961d0553644d..5fd11273df7fd 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/string.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/string.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { string } from '../string'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/switch.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/switch.js index 769b0ae8c5579..8a7b52ae87a81 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/switch.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/switch.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { switchFn } from '../switch'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/table.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/table.js index 0980f4b124f49..4ba2b3149e064 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/table.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/table.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { table } from '../table'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { testTable } from './fixtures/test_tables'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/tail.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/tail.js index 2e2148237df3d..05e1b2e8f91d6 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/tail.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/tail.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { tail } from '../tail'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; import { emptyTable, testTable } from './fixtures/test_tables'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/timefilter.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/timefilter.js index 70a3a007b889c..76bc2ee9ed0ff 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/timefilter.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/timefilter.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { timefilter } from '../timefilter'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/timefilter_control.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/timefilter_control.js index 1341f961412da..e46c9c0f19810 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/timefilter_control.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/__tests__/timefilter_control.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { timefilterControl } from '../timefilterControl'; import { functionWrapper } from '../../../../__tests__/helpers/function_wrapper'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/server/__tests__/demodata.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/server/__tests__/demodata.js index 1871bc560b795..1892029395a7c 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/server/__tests__/demodata.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/server/__tests__/demodata.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { demodata } from '../demodata'; const nullFilter = { diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/server/__tests__/get_expression_type.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/server/__tests__/get_expression_type.js index f22daa0a8cf51..3e621145e0685 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/server/__tests__/get_expression_type.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/server/__tests__/get_expression_type.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getExpressionType } from '../pointseries/lib/get_expression_type'; import { emptyTable, testTable } from '../../common/__tests__/fixtures/test_tables'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/server/__tests__/get_field_names.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/server/__tests__/get_field_names.js index 9b3f9990d1122..2cf9693a5f159 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/server/__tests__/get_field_names.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/server/__tests__/get_field_names.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { parse } from 'tinymath'; import { getFieldNames } from '../pointseries/lib/get_field_names'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/server/__tests__/is_column_reference.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/server/__tests__/is_column_reference.js index 10951e73b301d..8e8a760be9a26 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/server/__tests__/is_column_reference.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/server/__tests__/is_column_reference.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { isColumnReference } from '../pointseries/lib/is_column_reference'; describe('isColumnReference', () => { diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/server/__tests__/pointseries.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/server/__tests__/pointseries.js index c2c7fb8f4a477..f8e7c7f650b66 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/server/__tests__/pointseries.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/server/__tests__/pointseries.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { pointseries } from '../pointseries'; import { emptyTable, testTable } from '../../common/__tests__/fixtures/test_tables'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/datacolumn/__tests__/get_form_object.js b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/datacolumn/__tests__/get_form_object.js index cf1ae0ea37afc..dbc129094acff 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/datacolumn/__tests__/get_form_object.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/datacolumn/__tests__/get_form_object.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getFormObject } from '../get_form_object'; describe('getFormObject', () => { diff --git a/x-pack/plugins/canvas/canvas_plugin_src/uis/views/progress.js b/x-pack/plugins/canvas/canvas_plugin_src/uis/views/progress.js index bd929a32232d4..6b9831d06d597 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/uis/views/progress.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/uis/views/progress.js @@ -15,6 +15,8 @@ export const progress = () => ({ args: [ { name: 'shape', + displayName: 'Shape', + help: 'Shape of the progress indicator', argType: 'select', options: { choices: Object.keys(shapes).map(key => ({ diff --git a/x-pack/plugins/canvas/common/lib/__tests__/autocomplete.js b/x-pack/plugins/canvas/common/lib/__tests__/autocomplete.js index 72d79adf2a030..58d689c029f6a 100644 --- a/x-pack/plugins/canvas/common/lib/__tests__/autocomplete.js +++ b/x-pack/plugins/canvas/common/lib/__tests__/autocomplete.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { functionSpecs } from '../../../__tests__/fixtures/function_specs'; import { getAutocompleteSuggestions } from '../autocomplete'; diff --git a/x-pack/plugins/canvas/common/lib/__tests__/find_in_object.js b/x-pack/plugins/canvas/common/lib/__tests__/find_in_object.js index b07cd4563a124..f3fa5ebb81a14 100644 --- a/x-pack/plugins/canvas/common/lib/__tests__/find_in_object.js +++ b/x-pack/plugins/canvas/common/lib/__tests__/find_in_object.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { findInObject } from '../find_in_object'; const findMe = { diff --git a/x-pack/plugins/canvas/common/lib/__tests__/get_colors_from_palette.js b/x-pack/plugins/canvas/common/lib/__tests__/get_colors_from_palette.js index 79824edc2e2f7..e397bda763f1a 100644 --- a/x-pack/plugins/canvas/common/lib/__tests__/get_colors_from_palette.js +++ b/x-pack/plugins/canvas/common/lib/__tests__/get_colors_from_palette.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getColorsFromPalette } from '../../lib/get_colors_from_palette'; import { grayscalePalette, diff --git a/x-pack/plugins/canvas/common/lib/__tests__/get_field_type.js b/x-pack/plugins/canvas/common/lib/__tests__/get_field_type.js index cb8f7f68a796c..974880e74e328 100644 --- a/x-pack/plugins/canvas/common/lib/__tests__/get_field_type.js +++ b/x-pack/plugins/canvas/common/lib/__tests__/get_field_type.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getFieldType } from '../get_field_type'; import { emptyTable, diff --git a/x-pack/plugins/canvas/common/lib/__tests__/get_legend_config.js b/x-pack/plugins/canvas/common/lib/__tests__/get_legend_config.js index cca2cd73d0faf..ba43db7a83677 100644 --- a/x-pack/plugins/canvas/common/lib/__tests__/get_legend_config.js +++ b/x-pack/plugins/canvas/common/lib/__tests__/get_legend_config.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getLegendConfig } from '../get_legend_config'; describe('getLegendConfig', () => { diff --git a/x-pack/plugins/canvas/common/lib/__tests__/httpurl.js b/x-pack/plugins/canvas/common/lib/__tests__/httpurl.js index 5d7397ed87a50..cefe2530a01f9 100644 --- a/x-pack/plugins/canvas/common/lib/__tests__/httpurl.js +++ b/x-pack/plugins/canvas/common/lib/__tests__/httpurl.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { isValidHttpUrl } from '../httpurl'; describe('httpurl.isValidHttpUrl', () => { diff --git a/x-pack/plugins/canvas/common/lib/__tests__/latest_change.js b/x-pack/plugins/canvas/common/lib/__tests__/latest_change.js index cc5c246b2c074..f3678267540bf 100644 --- a/x-pack/plugins/canvas/common/lib/__tests__/latest_change.js +++ b/x-pack/plugins/canvas/common/lib/__tests__/latest_change.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { latestChange } from '../latest_change'; describe('latestChange', () => { diff --git a/x-pack/plugins/canvas/common/lib/__tests__/pivot_object_array.js b/x-pack/plugins/canvas/common/lib/__tests__/pivot_object_array.js index 58173c4c5a872..1ef875feacdc6 100644 --- a/x-pack/plugins/canvas/common/lib/__tests__/pivot_object_array.js +++ b/x-pack/plugins/canvas/common/lib/__tests__/pivot_object_array.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { pivotObjectArray } from '../pivot_object_array'; describe('pivotObjectArray', () => { diff --git a/x-pack/plugins/canvas/common/lib/__tests__/unquote_string.js b/x-pack/plugins/canvas/common/lib/__tests__/unquote_string.js index 465338816f155..52fcabf5ae7e0 100644 --- a/x-pack/plugins/canvas/common/lib/__tests__/unquote_string.js +++ b/x-pack/plugins/canvas/common/lib/__tests__/unquote_string.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { unquoteString } from '../unquote_string'; describe('unquoteString', () => { diff --git a/x-pack/plugins/canvas/public/components/download/__tests__/download.js b/x-pack/plugins/canvas/public/components/download/__tests__/download.js index 36c3a199e6fc6..6697730b0db60 100644 --- a/x-pack/plugins/canvas/public/components/download/__tests__/download.js +++ b/x-pack/plugins/canvas/public/components/download/__tests__/download.js @@ -5,7 +5,7 @@ */ import React from 'react'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { render } from 'enzyme'; import { Download } from '../'; diff --git a/x-pack/plugins/canvas/public/components/font_picker/__snapshots__/font_picker.examples.storyshot b/x-pack/plugins/canvas/public/components/font_picker/__snapshots__/font_picker.examples.storyshot index e8544c1863df3..c7a5afedda7ee 100644 --- a/x-pack/plugins/canvas/public/components/font_picker/__snapshots__/font_picker.examples.storyshot +++ b/x-pack/plugins/canvas/public/components/font_picker/__snapshots__/font_picker.examples.storyshot @@ -3,8 +3,11 @@ exports[`Storyshots components/FontPicker default 1`] = `
{ }; }; +// eslint-disable-next-line const getRootElementId = (lookup, id) => { if (!lookup.has(id)) { return null; diff --git a/x-pack/plugins/canvas/public/functions/__tests__/asset.js b/x-pack/plugins/canvas/public/functions/__tests__/asset.js index ea9f1d051ca61..208af754e9105 100644 --- a/x-pack/plugins/canvas/public/functions/__tests__/asset.js +++ b/x-pack/plugins/canvas/public/functions/__tests__/asset.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { functionWrapper } from '../../../__tests__/helpers/function_wrapper'; import { asset } from '../asset'; diff --git a/x-pack/plugins/canvas/public/lib/__tests__/clipboard.js b/x-pack/plugins/canvas/public/lib/__tests__/clipboard.js index d940701c2e71d..c616a76d0dcc3 100644 --- a/x-pack/plugins/canvas/public/lib/__tests__/clipboard.js +++ b/x-pack/plugins/canvas/public/lib/__tests__/clipboard.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { setClipboardData, getClipboardData } from '../clipboard'; import { elements } from '../../../__tests__/fixtures/workpads'; diff --git a/x-pack/plugins/canvas/public/lib/__tests__/history_provider.js b/x-pack/plugins/canvas/public/lib/__tests__/history_provider.js index 68c45d0eb7e4b..756dd4e36e759 100644 --- a/x-pack/plugins/canvas/public/lib/__tests__/history_provider.js +++ b/x-pack/plugins/canvas/public/lib/__tests__/history_provider.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import lzString from 'lz-string'; import { historyProvider } from '../history_provider'; diff --git a/x-pack/plugins/canvas/public/lib/__tests__/modify_path.js b/x-pack/plugins/canvas/public/lib/__tests__/modify_path.js index c5d84e74a3e07..75454890f9717 100644 --- a/x-pack/plugins/canvas/public/lib/__tests__/modify_path.js +++ b/x-pack/plugins/canvas/public/lib/__tests__/modify_path.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { prepend, append } from '../modify_path'; describe('modify paths', () => { diff --git a/x-pack/plugins/canvas/public/lib/__tests__/resolved_arg.js b/x-pack/plugins/canvas/public/lib/__tests__/resolved_arg.js index 24665a11c50f5..9e582ddd1858b 100644 --- a/x-pack/plugins/canvas/public/lib/__tests__/resolved_arg.js +++ b/x-pack/plugins/canvas/public/lib/__tests__/resolved_arg.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getState, getValue, getError } from '../resolved_arg'; describe('resolved arg helper', () => { diff --git a/x-pack/plugins/canvas/public/lib/aeroelastic/layout_functions.js b/x-pack/plugins/canvas/public/lib/aeroelastic/layout_functions.js index 6e93f9eb5fb4b..d62fbe21fa0f0 100644 --- a/x-pack/plugins/canvas/public/lib/aeroelastic/layout_functions.js +++ b/x-pack/plugins/canvas/public/lib/aeroelastic/layout_functions.js @@ -436,6 +436,7 @@ export const applyLocalTransforms = (shapes, transformIntents) => { return shapes.map(shapeApplyLocalTransforms(transformIntents)); }; +// eslint-disable-next-line const getUpstreamTransforms = (shapes, shape) => shape.parent ? getUpstreamTransforms(shapes, shapes.find(s => s.id === shape.parent)).concat([ diff --git a/x-pack/plugins/canvas/public/state/actions/__tests__/elements.get_sibling_context.js b/x-pack/plugins/canvas/public/state/actions/__tests__/elements.get_sibling_context.js index a1e5418b0daf7..198ccb2ffc381 100644 --- a/x-pack/plugins/canvas/public/state/actions/__tests__/elements.get_sibling_context.js +++ b/x-pack/plugins/canvas/public/state/actions/__tests__/elements.get_sibling_context.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getSiblingContext } from '../elements'; const state = { diff --git a/x-pack/plugins/canvas/public/state/reducers/__tests__/elements.js b/x-pack/plugins/canvas/public/state/reducers/__tests__/elements.js index 0a5db91198966..e1f7509325a7a 100644 --- a/x-pack/plugins/canvas/public/state/reducers/__tests__/elements.js +++ b/x-pack/plugins/canvas/public/state/reducers/__tests__/elements.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { get } from 'lodash'; import { elementsReducer } from '../elements'; import { actionCreator } from './fixtures/action_creator'; diff --git a/x-pack/plugins/canvas/public/state/reducers/__tests__/resolved_args.js b/x-pack/plugins/canvas/public/state/reducers/__tests__/resolved_args.js index 7b8bc923a20c1..ef52a80b8960c 100644 --- a/x-pack/plugins/canvas/public/state/reducers/__tests__/resolved_args.js +++ b/x-pack/plugins/canvas/public/state/reducers/__tests__/resolved_args.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import * as actions from '../../actions/resolved_args'; import { flushContextAfterIndex } from '../../actions/elements'; import { resolvedArgsReducer } from '../resolved_args'; diff --git a/x-pack/plugins/canvas/public/state/reducers/elements.js b/x-pack/plugins/canvas/public/state/reducers/elements.js index cc62a202a9882..f4d4fe65cf448 100644 --- a/x-pack/plugins/canvas/public/state/reducers/elements.js +++ b/x-pack/plugins/canvas/public/state/reducers/elements.js @@ -36,11 +36,7 @@ function assignNodeProperties(workpadState, pageId, nodeId, props) { return workpadState; } - // remove any AST value from the element caused by https://github.com/elastic/kibana-canvas/issues/260 - // TODO: remove this after a bit of time - const cleanWorkpadState = del(workpadState, nodesPath.concat([nodeIndex, 'ast'])); - - return assign(cleanWorkpadState, nodesPath.concat(nodeIndex), props); + return assign(workpadState, nodesPath.concat(nodeIndex), props); } function moveNodeLayer(workpadState, pageId, nodeId, movement, location) { diff --git a/x-pack/plugins/canvas/public/state/selectors/__tests__/resolved_args.js b/x-pack/plugins/canvas/public/state/selectors/__tests__/resolved_args.js index 6fa3b4e35db0c..3157201927854 100644 --- a/x-pack/plugins/canvas/public/state/selectors/__tests__/resolved_args.js +++ b/x-pack/plugins/canvas/public/state/selectors/__tests__/resolved_args.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import * as selector from '../resolved_args'; describe('resolved args selector', () => { diff --git a/x-pack/plugins/canvas/public/state/selectors/__tests__/workpad.js b/x-pack/plugins/canvas/public/state/selectors/__tests__/workpad.js index f1ff31874935b..5cfdf726dd258 100644 --- a/x-pack/plugins/canvas/public/state/selectors/__tests__/workpad.js +++ b/x-pack/plugins/canvas/public/state/selectors/__tests__/workpad.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import * as selector from '../workpad'; describe('workpad selectors', () => { diff --git a/x-pack/plugins/canvas/public/style/main.scss b/x-pack/plugins/canvas/public/style/main.scss index 0130a2fbe77c0..ca22b3648a4da 100644 --- a/x-pack/plugins/canvas/public/style/main.scss +++ b/x-pack/plugins/canvas/public/style/main.scss @@ -14,6 +14,7 @@ } .canvasCheckered { + background-color: $euiColorGhost; background-image: linear-gradient(45deg, #ddd 25%, transparent 25%), linear-gradient(-45deg, #ddd 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #ddd 75%), diff --git a/x-pack/plugins/canvas/server/usage/__tests__/collector.handle_response.js b/x-pack/plugins/canvas/server/usage/__tests__/collector.handle_response.js index 06c12ca614936..edb90f90612a2 100644 --- a/x-pack/plugins/canvas/server/usage/__tests__/collector.handle_response.js +++ b/x-pack/plugins/canvas/server/usage/__tests__/collector.handle_response.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { handleResponse } from '../collector'; import { workpads } from '../../../__tests__/fixtures/workpads'; diff --git a/x-pack/plugins/canvas/tasks/helpers/babelhook.js b/x-pack/plugins/canvas/tasks/helpers/babelhook.js index 4a48d09449b20..dea18db918fcd 100644 --- a/x-pack/plugins/canvas/tasks/helpers/babelhook.js +++ b/x-pack/plugins/canvas/tasks/helpers/babelhook.js @@ -5,7 +5,7 @@ */ const { resolve } = require('path'); -const register = require('babel-register'); +const register = require('@babel/register'); const options = { babelrc: false, presets: [require.resolve('@kbn/babel-preset/node_preset')], diff --git a/x-pack/plugins/cross_cluster_replication/__jest__/client_integration/auto_follow_pattern_list.test.js b/x-pack/plugins/cross_cluster_replication/__jest__/client_integration/auto_follow_pattern_list.test.js new file mode 100644 index 0000000000000..502512ab0dd56 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/__jest__/client_integration/auto_follow_pattern_list.test.js @@ -0,0 +1,334 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import sinon from 'sinon'; + +import { initTestBed, registerHttpRequestMockHelpers, nextTick, getRandomString, findTestSubject } from './test_helpers'; +import { AutoFollowPatternList } from '../../public/app/sections/home/auto_follow_pattern_list'; +import { getAutoFollowPatternClientMock } from '../../fixtures/auto_follow_pattern'; + +jest.mock('ui/chrome', () => ({ + addBasePath: () => 'api/cross_cluster_replication', + breadcrumbs: { set: () => {} }, +})); + +jest.mock('ui/index_patterns', () => { + const { INDEX_PATTERN_ILLEGAL_CHARACTERS_VISIBLE } = require.requireActual('../../../../../src/legacy/ui/public/index_patterns/constants'); // eslint-disable-line max-len + return { INDEX_PATTERN_ILLEGAL_CHARACTERS_VISIBLE }; +}); + +describe('', () => { + let server; + let find; + let exists; + let component; + let getMetadataFromEuiTable; + let getUserActions; + let tableCellsValues; + let rows; + let setLoadAutoFollowPatternsResponse; + let setDeleteAutoFollowPatternResponse; + let setAutoFollowStatsResponse; + + beforeEach(() => { + server = sinon.fakeServer.create(); + server.respondImmediately = true; + + // Register helpers to mock Http Requests + ({ + setLoadAutoFollowPatternsResponse, + setDeleteAutoFollowPatternResponse, + setAutoFollowStatsResponse + } = registerHttpRequestMockHelpers(server)); + + // Set "default" mock responses by not providing any arguments + setLoadAutoFollowPatternsResponse(); + setDeleteAutoFollowPatternResponse(); + setAutoFollowStatsResponse(); + }); + + describe('on component mount', () => { + beforeEach(async () => { + ({ exists } = initTestBed(AutoFollowPatternList)); + }); + + test('should show a loading indicator on component', async () => { + expect(exists('ccrAutoFollowPatternLoading')).toBe(true); + }); + }); + + describe('when there are no auto-follow patterns', () => { + beforeEach(async () => { + ({ exists, component } = initTestBed(AutoFollowPatternList)); + + await nextTick(); // We need to wait next tick for the mock server response to comes in + component.update(); + }); + + test('should display an empty prompt', async () => { + expect(exists('ccrAutoFollowPatternEmptyPrompt')).toBe(true); + }); + + test('should have a button to create a follower index', async () => { + expect(exists('ccrCreateAutoFollowPatternButton')).toBe(true); + }); + }); + + describe('when there are auto-follow patterns', async () => { + // For deterministic tests, we need to make sure that autoFollowPattern1 comes before autoFollowPattern2 + // in the table list that is rendered. As the table orders alphabetically by index name + // we prefix the random name to make sure that autoFollowPattern1 comes before autoFollowPattern2 + const testPrefix = 'prefix_'; + const testSuffix = '_suffix'; + + const autoFollowPattern1 = getAutoFollowPatternClientMock({ + name: `a${getRandomString()}`, + followIndexPattern: `${testPrefix}{{leader_index}}${testSuffix}` + }); + const autoFollowPattern2 = getAutoFollowPatternClientMock({ + name: `b${getRandomString()}`, + followIndexPattern: '{{leader_index}}' // no prefix nor suffix + }); + const autoFollowPatterns = [autoFollowPattern1, autoFollowPattern2]; + + let selectAutoFollowPatternAt; + let clickBulkDeleteButton; + let clickConfirmModalDeleteAutoFollowPattern; + let clickRowActionButtonAt; + let clickAutoFollowPatternAt; + + beforeEach(async () => { + setLoadAutoFollowPatternsResponse({ patterns: autoFollowPatterns }); + + // Mount the component + ({ + find, + exists, + component, + getMetadataFromEuiTable, + getUserActions, + } = initTestBed(AutoFollowPatternList)); + + await nextTick(); // Make sure that the Http request is fulfilled + component.update(); + + ({ + selectAutoFollowPatternAt, + clickBulkDeleteButton, + clickConfirmModalDeleteAutoFollowPattern, + clickRowActionButtonAt, + clickAutoFollowPatternAt, + } = getUserActions('autoFollowPatternList')); + + // Read the index list table + ({ tableCellsValues, rows } = getMetadataFromEuiTable('ccrAutoFollowPatternListTable')); + }); + + afterEach(async () => { + // The updates are not all synchronouse + // We need to wait for all the updates to ran before unmounting our component + await nextTick(100); + }); + + test('should not display the empty prompt', () => { + expect(exists('ccrFollowerIndexEmptyPrompt')).toBe(false); + }); + + test('should have a button to create an auto-follow pattern', () => { + expect(exists('ccrCreateAutoFollowPatternButton')).toBe(true); + }); + + test('should list the auto-follow patterns in the table', () => { + expect(tableCellsValues.length).toEqual(autoFollowPatterns.length); + expect(tableCellsValues).toEqual([ + [ '', // Empty because the first column is the checkbox to select row + autoFollowPattern1.name, + autoFollowPattern1.remoteCluster, + autoFollowPattern1.leaderIndexPatterns.join(', '), + testPrefix, + testSuffix, + '' // Empty because the last column is for the "actions" on the resource + ], [ '', + autoFollowPattern2.name, + autoFollowPattern2.remoteCluster, + autoFollowPattern2.leaderIndexPatterns.join(', '), + '', // no prefix + '', // no suffix + '' ] + ]); + }); + + describe('bulk delete button', () => { + test('should be visible when an auto-follow pattern is selected', () => { + expect(exists('ccrAutoFollowPatternListBulkDeleteActionButton')).toBe(false); + + selectAutoFollowPatternAt(0); + + expect(exists('ccrAutoFollowPatternListBulkDeleteActionButton')).toBe(true); + }); + + test('should update the button label according to the number of patterns selected', () => { + selectAutoFollowPatternAt(0); // 1 auto-follow pattern selected + expect(find('ccrAutoFollowPatternListBulkDeleteActionButton').text()).toEqual('Delete auto-follow pattern'); + + selectAutoFollowPatternAt(1); // 2 auto-follow patterns selected + expect(find('ccrAutoFollowPatternListBulkDeleteActionButton').text()).toEqual('Delete auto-follow patterns'); + }); + + test('should open a confirmation modal when clicking the delete button', () => { + expect(exists('ccrAutoFollowPatternDeleteConfirmationModal')).toBe(false); + + selectAutoFollowPatternAt(0); + clickBulkDeleteButton(); + + expect(exists('ccrAutoFollowPatternDeleteConfirmationModal')).toBe(true); + }); + + test('should remove the auto-follow pattern from the table after delete is complete', async () => { + // Make sure that we have our 2 auto-follow patterns in the table + expect(rows.length).toBe(2); + + // We wil delete the *first* auto-follow pattern in the table + setDeleteAutoFollowPatternResponse({ itemsDeleted: [autoFollowPattern1.name] }); + + selectAutoFollowPatternAt(0); + clickBulkDeleteButton(); + clickConfirmModalDeleteAutoFollowPattern(); + + await nextTick(); + component.update(); + + ({ rows } = getMetadataFromEuiTable('ccrAutoFollowPatternListTable')); + + expect(rows.length).toBe(1); + expect(rows[0].columns[1].value).toEqual(autoFollowPattern2.name); + }); + }); + + describe('table row actions', () => { + test('should have a "delete" and an "edit" action button on each row', () => { + const indexLastColumn = rows[0].columns.length - 1; + const tableCellActions = rows[0].columns[indexLastColumn].reactWrapper; + + const deleteButton = findTestSubject(tableCellActions, 'ccrAutoFollowPatternListDeleteActionButton'); + const editButton = findTestSubject(tableCellActions, 'ccrAutoFollowPatternListEditActionButton'); + + expect(deleteButton.length).toBe(1); + expect(editButton.length).toBe(1); + }); + + test('should open a confirmation modal when clicking on "delete" button', async () => { + expect(exists('ccrAutoFollowPatternDeleteConfirmationModal')).toBe(false); + + clickRowActionButtonAt(0, 'delete'); + + expect(exists('ccrAutoFollowPatternDeleteConfirmationModal')).toBe(true); + }); + }); + + describe('detail panel', () => { + test('should open a detail panel when clicking on a follower index', () => { + expect(exists('ccrAutoFollowPatternDetailsFlyout')).toBe(false); + + clickAutoFollowPatternAt(0); + + expect(exists('ccrAutoFollowPatternDetailsFlyout')).toBe(true); + }); + + test('should set the title the index that has been selected', () => { + clickAutoFollowPatternAt(0); // Open the detail panel + expect(find('autoFollowPatternDetailsFlyoutTitle').text()).toEqual(autoFollowPattern1.name); + }); + + test('should have a "settings" section', () => { + clickAutoFollowPatternAt(0); + expect(find('ccrAutoFollowPatternDetailPanelSettingsSection').find('h3').text()).toEqual('Settings'); + expect(exists('ccrAutoFollowPatternDetailPanelSettingsValues')).toBe(true); + }); + + test('should set the correct follower index settings values', () => { + clickAutoFollowPatternAt(0); + + expect(find('ccrAutoFollowPatternDetailRemoteCluster').text()).toEqual(autoFollowPattern1.remoteCluster); + expect(find('ccrAutoFollowPatternDetailLeaderIndexPatterns').text()).toEqual(autoFollowPattern1.leaderIndexPatterns.join(', ')); + expect(find('ccrAutoFollowPatternDetailPatternPrefix').text()).toEqual(testPrefix); + expect(find('ccrAutoFollowPatternDetailPatternSuffix').text()).toEqual(testSuffix); + }); + + test('should have a default value when there are no prefix or no suffix', () => { + clickAutoFollowPatternAt(1); // Does not have prefix and suffix + + expect(find('ccrAutoFollowPatternDetailPatternPrefix').text()).toEqual('No prefix'); + expect(find('ccrAutoFollowPatternDetailPatternSuffix').text()).toEqual('No suffix'); + }); + + test('should show a preview of the indices that might be generated by the auto-follow pattern', () => { + clickAutoFollowPatternAt(0); + const detailPanel = find('ccrAutoFollowPatternDetailsFlyout'); + const indicesPreview = findTestSubject(detailPanel, 'ccrAutoFollowPatternIndexPreview'); + + expect(exists('ccrAutoFollowPatternDetailPanelIndicesPreviewSection')).toBe(true); + expect(indicesPreview.length).toBe(3); + }); + + test('should have a link to view the indices in Index Management', () => { + clickAutoFollowPatternAt(0); + expect(exists('ccrAutoFollowPatternDetailsViewIndexManagementButton')).toBe(true); + expect(find('ccrAutoFollowPatternDetailsViewIndexManagementButton').text()).toBe('View your follower indices in Index Management'); + }); + + test('should have a "close", "delete" and "edit" button in the footer', () => { + clickAutoFollowPatternAt(0); + expect(exists('ccrAutoFollowPatternDetailsFlyoutCloseButton')).toBe(true); + expect(exists('ccrAutoFollowPatternDetailsDeleteActionButton')).toBe(true); + expect(exists('ccrAutoFollowPatternDetailsEditActionButton')).toBe(true); + }); + + test('should close the detail panel when clicking the "close" button', () => { + clickAutoFollowPatternAt(0); // open the detail panel + expect(exists('ccrAutoFollowPatternDetailsFlyout')).toBe(true); + + find('ccrAutoFollowPatternDetailsFlyoutCloseButton').simulate('click'); // close the detail panel + + expect(exists('ccrAutoFollowPatternDetailsFlyout')).toBe(false); + }); + + test('should open a confirmation modal when clicking the "delete" button', () => { + clickAutoFollowPatternAt(0); + expect(exists('ccrAutoFollowPatternDeleteConfirmationModal')).toBe(false); + + find('ccrAutoFollowPatternDetailsDeleteActionButton').simulate('click'); + + expect(exists('ccrAutoFollowPatternDeleteConfirmationModal')).toBe(true); + }); + + test('should display the recent errors', async () => { + const message = 'bar'; + const recentAutoFollowErrors = [{ + leaderIndex: `${autoFollowPattern1.name}:my-leader-test`, + autoFollowException: { type: 'exception', reason: message } + }, { + leaderIndex: `${autoFollowPattern2.name}:my-leader-test`, + autoFollowException: { type: 'exception', reason: message } + }]; + setAutoFollowStatsResponse({ recentAutoFollowErrors }); + + clickAutoFollowPatternAt(0); + expect(exists('ccrAutoFollowPatternDetailErrors')).toBe(false); + + // We select the other auto-follow pattern because the stats are fetched + // each time we change the auto-follow pattern selection + clickAutoFollowPatternAt(1); + await nextTick(); + component.update(); + + expect(exists('ccrAutoFollowPatternDetailErrors')).toBe(true); + expect(exists('ccrAutoFollowPatternDetailsTitleErrors')).toBe(true); + expect(find('ccrAutoFollowPatternDetailRecentError').map(error => error.text())).toEqual([message]); + }); + }); + }); +}); diff --git a/x-pack/plugins/cross_cluster_replication/__jest__/client_integration/follower_indices_list.test.js b/x-pack/plugins/cross_cluster_replication/__jest__/client_integration/follower_indices_list.test.js new file mode 100644 index 0000000000000..4b48b37a0c193 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/__jest__/client_integration/follower_indices_list.test.js @@ -0,0 +1,348 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import sinon from 'sinon'; + +import { initTestBed, registerHttpRequestMockHelpers, nextTick, getRandomString } from './test_helpers'; +import { FollowerIndicesList } from '../../public/app/sections/home/follower_indices_list'; +import { getFollowerIndexMock } from '../../fixtures/follower_index'; + +jest.mock('ui/chrome', () => ({ + addBasePath: () => 'api/cross_cluster_replication', + breadcrumbs: { set: () => {} }, +})); + +jest.mock('ui/index_patterns', () => { + const { INDEX_PATTERN_ILLEGAL_CHARACTERS_VISIBLE } = require.requireActual('../../../../../src/legacy/ui/public/index_patterns/constants'); // eslint-disable-line max-len + return { INDEX_PATTERN_ILLEGAL_CHARACTERS_VISIBLE }; +}); + +describe('', () => { + let server; + let find; + let exists; + let component; + let getMetadataFromEuiTable; + let getUserActions; + let tableCellsValues; + let setLoadFollowerIndicesResponse; + + beforeEach(() => { + server = sinon.fakeServer.create(); + server.respondImmediately = true; + + // Register helpers to mock Http Requests + ({ setLoadFollowerIndicesResponse } = registerHttpRequestMockHelpers(server)); + + // Set "default" mock responses by not providing any arguments + setLoadFollowerIndicesResponse(); + }); + + describe('on component mount', () => { + beforeEach(async () => { + ({ exists } = initTestBed(FollowerIndicesList)); + }); + + test('should show a loading indicator on component', async () => { + expect(exists('ccrFollowerIndexLoading')).toBe(true); + }); + }); + + describe('when there are no follower indices', () => { + beforeEach(async () => { + ({ exists, component } = initTestBed(FollowerIndicesList)); + + await nextTick(); // We need to wait next tick for the mock server response to comes in + component.update(); + }); + + test('should display an empty prompt', async () => { + expect(exists('ccrFollowerIndexEmptyPrompt')).toBe(true); + }); + + test('should have a button to create a follower index', async () => { + expect(exists('ccrFollowerIndexEmptyPromptCreateButton')).toBe(true); + }); + }); + + describe('when there are follower indices', async () => { + // For deterministic tests, we need to make sure that index1 comes before index2 + // in the table list that is rendered. As the table orders alphabetically by index name + // we prefix the random name to make sure that index1 name comes before index2. + const index1 = getFollowerIndexMock({ name: `a${getRandomString()}` }); + const index2 = getFollowerIndexMock({ name: `b${getRandomString()}`, status: 'paused' }); + + const followerIndices = [index1, index2]; + + let selectFollowerIndexAt; + let openContextMenu; + let openTableRowContextMenuAt; + let clickContextMenuButtonAt; + let clickFollowerIndexAt; + + beforeEach(async () => { + setLoadFollowerIndicesResponse({ indices: followerIndices }); + + // Mount the component + ({ + find, + exists, + component, + getMetadataFromEuiTable, + getUserActions, + } = initTestBed(FollowerIndicesList)); + + await nextTick(); // Make sure that the Http request is fulfilled + component.update(); + + ({ + selectFollowerIndexAt, + openContextMenu, + openTableRowContextMenuAt, + clickContextMenuButtonAt, + clickFollowerIndexAt, + } = getUserActions('followerIndicesList')); + + // Read the index list table + ({ tableCellsValues } = getMetadataFromEuiTable('ccrFollowerIndexListTable')); + }); + + afterEach(async () => { + // The updates are not all synchronouse + // We need to wait for all the updates to ran before unmounting our component + await nextTick(100); + }); + + test('should not display the empty prompt', () => { + expect(exists('ccrFollowerIndexEmptyPrompt')).toBe(false); + }); + + test('should have a button to create a follower index', () => { + expect(exists('ccrCreateFollowerIndexButton')).toBe(true); + }); + + test('should list the follower indices in the table', () => { + expect(tableCellsValues.length).toEqual(followerIndices.length); + expect(tableCellsValues).toEqual([ + [ '', // Empty because the first column is the checkbox to select row + index1.name, + 'Active', + index1.remoteCluster, + index1.leaderIndex, + '' // Empty because the last column is for the "actions" on the resource + ], [ '', + index2.name, + 'Paused', + index2.remoteCluster, + index2.leaderIndex, + '' ] + ]); + }); + + describe('action menu', () => { + test('should be visible when a follower index is selected', () => { + expect(exists('ccrFollowerIndexListContextMenuButton')).toBe(false); + + selectFollowerIndexAt(0); + + expect(exists('ccrFollowerIndexListContextMenuButton')).toBe(true); + }); + + test('should have a "pause", "edit" and "unfollow" action when the follower index is active', async () => { + selectFollowerIndexAt(0); + openContextMenu(); + + const contextMenu = find('followerIndexActionContextMenu'); + + expect(contextMenu.length).toBeTruthy(); + const contextMenuButtons = contextMenu.find('button'); + const buttonsLabel = contextMenuButtons.map(btn => btn.text()); + + expect(buttonsLabel).toEqual([ + 'Pause replication', + 'Edit follower index', + 'Unfollow leader index' + ]); + }); + + test('should have a "resume", "edit" and "unfollow" action when the follower index is active', async () => { + selectFollowerIndexAt(1); // Select the second follower that is "paused" + openContextMenu(); + + const contextMenu = find('followerIndexActionContextMenu'); + + const contextMenuButtons = contextMenu.find('button'); + const buttonsLabel = contextMenuButtons.map(btn => btn.text()); + expect(buttonsLabel).toEqual([ + 'Resume replication', + 'Edit follower index', + 'Unfollow leader index' + ]); + }); + + test('should open a confirmation modal when clicking on "pause replication"', () => { + expect(exists('ccrFollowerIndexPauseReplicationConfirmationModal')).toBe(false); + + selectFollowerIndexAt(0); + openContextMenu(); + clickContextMenuButtonAt(0); // first button is the "pause" action + + expect(exists('ccrFollowerIndexPauseReplicationConfirmationModal')).toBe(true); + }); + + test('should open a confirmation modal when clicking on "unfollow leader index"', () => { + expect(exists('ccrFollowerIndexUnfollowLeaderConfirmationModal')).toBe(false); + + selectFollowerIndexAt(0); + openContextMenu(); + clickContextMenuButtonAt(2); // third button is the "unfollow" action + + expect(exists('ccrFollowerIndexUnfollowLeaderConfirmationModal')).toBe(true); + }); + }); + + describe('table row action menu', () => { + test('should open a context menu when clicking on the button of each row', async () => { + expect(component.find('.euiContextMenuPanel').length).toBe(0); + + openTableRowContextMenuAt(0); + + expect(component.find('.euiContextMenuPanel').length).toBe(1); + }); + + test('should have the "pause", "edit" and "unfollow" options in the row context menu', async () => { + openTableRowContextMenuAt(0); + + const buttonLabels = component + .find('.euiContextMenuPanel') + .find('.euiContextMenuItem') + .map(button => button.text()); + + expect(buttonLabels).toEqual([ + 'Pause replication', + 'Edit follower index', + 'Unfollow leader index' + ]); + }); + + test('should have the "resume", "edit" and "unfollow" options in the row context menu', async () => { + // We open the context menu of the second row (index 1) as followerIndices[1].status is "paused" + openTableRowContextMenuAt(1); + + const buttonLabels = component + .find('.euiContextMenuPanel') + .find('.euiContextMenuItem') + .map(button => button.text()); + + expect(buttonLabels).toEqual([ + 'Resume replication', + 'Edit follower index', + 'Unfollow leader index' + ]); + }); + + test('should open a confirmation modal when clicking on "pause replication"', async () => { + expect(exists('ccrFollowerIndexPauseReplicationConfirmationModal')).toBe(false); + + openTableRowContextMenuAt(0); + find('ccrFollowerIndexListPauseActionButton').simulate('click'); + + expect(exists('ccrFollowerIndexPauseReplicationConfirmationModal')).toBe(true); + }); + + test('should open a confirmation modal when clicking on "resume"', async () => { + expect(exists('ccrFollowerIndexResumeReplicationConfirmationModal')).toBe(false); + + openTableRowContextMenuAt(1); // open the second row context menu, as it is a "paused" follower index + find('ccrFollowerIndexListResumeActionButton').simulate('click'); + + expect(exists('ccrFollowerIndexResumeReplicationConfirmationModal')).toBe(true); + }); + + test('should open a confirmation modal when clicking on "unfollow leader index"', () => { + expect(exists('ccrFollowerIndexUnfollowLeaderConfirmationModal')).toBe(false); + + openTableRowContextMenuAt(0); + find('ccrFollowerIndexListUnfollowActionButton').simulate('click'); + + expect(exists('ccrFollowerIndexUnfollowLeaderConfirmationModal')).toBe(true); + }); + }); + + describe('detail panel', () => { + test('should open a detail panel when clicking on a follower index', () => { + expect(exists('ccrFollowerIndexDetailsFlyout')).toBe(false); + + clickFollowerIndexAt(0); + + expect(exists('ccrFollowerIndexDetailsFlyout')).toBe(true); + }); + + test('should set the title the index that has been selected', () => { + clickFollowerIndexAt(0); // Open the detail panel + expect(find('followerIndexDetailsFlyoutTitle').text()).toEqual(index1.name); + }); + + test('should have a "settings" section', () => { + clickFollowerIndexAt(0); + expect(find('ccrFollowerIndexDetailPanelSettingsSection').find('h3').text()).toEqual('Settings'); + expect(exists('ccrFollowerIndexDetailPanelSettingsValues')).toBe(true); + }); + + test('should set the correct follower index settings values', () => { + const mapSettingsToFollowerIndexProp = { + Status: 'status', + RemoteCluster: 'remoteCluster', + LeaderIndex: 'leaderIndex', + MaxReadReqOpCount: 'maxReadRequestOperationCount', + MaxOutstandingReadReq: 'maxOutstandingReadRequests', + MaxReadReqSize: 'maxReadRequestSize', + MaxWriteReqOpCount: 'maxWriteRequestOperationCount', + MaxWriteReqSize: 'maxWriteRequestSize', + MaxOutstandingWriteReq: 'maxOutstandingWriteRequests', + MaxWriteBufferCount: 'maxWriteBufferCount', + MaxWriteBufferSize: 'maxWriteBufferSize', + MaxRetryDelay: 'maxRetryDelay', + ReadPollTimeout: 'readPollTimeout' + }; + + clickFollowerIndexAt(0); + + Object.entries(mapSettingsToFollowerIndexProp).forEach(([setting, prop]) => { + const wrapper = find(`ccrFollowerIndexDetail${setting}`); + + if (!wrapper.length) { + throw new Error(`Could not find description for setting "${setting}"`); + } + + expect(wrapper.text()).toEqual(index1[prop].toString()); + }); + }); + + test('should not have settings values for a "paused" follower index', () => { + clickFollowerIndexAt(1); // the second follower index is paused + expect(exists('ccrFollowerIndexDetailPanelSettingsValues')).toBe(false); + expect(find('ccrFollowerIndexDetailPanelSettingsSection').text()).toContain('paused follower index does not have settings'); + }); + + test('should have a section to render the follower index shards stats', () => { + clickFollowerIndexAt(0); + expect(exists('ccrFollowerIndexDetailPanelShardsStatsSection')).toBe(true); + }); + + test('should render a EuiCodeEditor for each shards stats', () => { + clickFollowerIndexAt(0); + + const codeEditors = component.find(`EuiCodeEditor`); + + expect(codeEditors.length).toBe(index1.shards.length); + codeEditors.forEach((codeEditor, i) => { + expect(JSON.parse(codeEditor.props().value)).toEqual(index1.shards[i]); + }); + }); + }); + }); +}); diff --git a/x-pack/plugins/cross_cluster_replication/__jest__/client_integration/home.test.js b/x-pack/plugins/cross_cluster_replication/__jest__/client_integration/home.test.js new file mode 100644 index 0000000000000..b8056e2625342 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/__jest__/client_integration/home.test.js @@ -0,0 +1,89 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import sinon from 'sinon'; + +import { initTestBed, registerHttpRequestMockHelpers, nextTick } from './test_helpers'; +import { CrossClusterReplicationHome } from '../../public/app/sections/home/home'; +import { BASE_PATH } from '../../common/constants'; +import routing from '../../public/app/services/routing'; + +jest.mock('ui/chrome', () => ({ + addBasePath: () => 'api/cross_cluster_replication', + breadcrumbs: { set: () => {} }, +})); + +jest.mock('ui/index_patterns', () => { + const { INDEX_PATTERN_ILLEGAL_CHARACTERS_VISIBLE } = require.requireActual('../../../../../src/legacy/ui/public/index_patterns/constants'); // eslint-disable-line max-len + return { INDEX_PATTERN_ILLEGAL_CHARACTERS_VISIBLE }; +}); + +const testBedOptions = { + memoryRouter: { + initialEntries: [`${BASE_PATH}/follower_indices`], + componentRoutePath: `${BASE_PATH}/:section`, + onRouter: (router) => routing.reactRouter = router + } +}; + +describe('', () => { + let server; + let find; + let exists; + let component; + + beforeEach(() => { + server = sinon.fakeServer.create(); + server.respondImmediately = true; + + // Register helpers to mock Http Requests + const { setLoadFollowerIndicesResponse } = registerHttpRequestMockHelpers(server); + + // Set "default" mock responses by not providing any arguments + setLoadFollowerIndicesResponse(); + }); + + describe('on component mount', () => { + beforeEach(async () => { + ({ exists, find, component } = initTestBed(CrossClusterReplicationHome, undefined, testBedOptions)); + }); + + test('should set the correct an app title', () => { + expect(exists('ccrAppTitle')).toBe(true); + expect(find('ccrAppTitle').text()).toEqual('Cross-Cluster Replication'); + }); + + test('should have 2 tabs to switch between "Follower indices" & "Auto-follow patterns"', () => { + expect(exists('ccrFollowerIndicesTab')).toBe(true); + expect(find('ccrFollowerIndicesTab').text()).toEqual('Follower indices'); + + expect(exists('ccrAutoFollowPatternsTab')).toBe(true); + expect(find('ccrAutoFollowPatternsTab').text()).toEqual('Auto-follow patterns'); + }); + + test('should set the default selected tab to "Follower indices"', () => { + expect(component.find('.euiTab-isSelected').text()).toBe('Follower indices'); + + // Verify that the component is rendered + expect(component.find('FollowerIndicesList').length).toBe(1); + }); + }); + + describe('section change', () => { + test('should change to auto-follow pattern', async () => { + const autoFollowPatternsTab = find('ccrAutoFollowPatternsTab'); + + autoFollowPatternsTab.simulate('click'); + await nextTick(); + component.update(); + + expect(component.find('.euiTab-isSelected').text()).toBe('Auto-follow patterns'); + + // Verify that the component is rendered + expect(component.find('AutoFollowPatternList').length).toBe(1); + }); + }); +}); diff --git a/x-pack/plugins/cross_cluster_replication/__jest__/client_integration/test_helpers.js b/x-pack/plugins/cross_cluster_replication/__jest__/client_integration/test_helpers.js new file mode 100644 index 0000000000000..ba0cdb0a67169 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/__jest__/client_integration/test_helpers.js @@ -0,0 +1,194 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import axios from 'axios'; + +import { registerTestBed, findTestSubject } from '../../../../test_utils'; +import { ccrStore } from '../../public/app/store'; +import { setHttpClient } from '../../public/app/services/api'; +import routing from '../../public/app/services/routing'; + +// Mock React router +const reactRouter = { + history: { + push: () => {}, + createHref: (location) => location.pathname, + location: '' + } +}; + +routing.reactRouter = reactRouter; +// Mock Angular $q +const $q = { defer: () => ({ resolve() {} }) }; +// axios has a $http like interface so using it to simulate $http +setHttpClient(axios.create(), $q); + +const initUserActions = ({ getMetadataFromEuiTable, find }) => (section) => { + const userActions = { + // Follower indices user actions + followerIndicesList() { + const { rows } = getMetadataFromEuiTable('ccrFollowerIndexListTable'); + + const selectFollowerIndexAt = (index = 0) => { + const row = rows[index]; + const checkBox = row.reactWrapper.find('input').hostNodes(); + checkBox.simulate('change', { target: { checked: true } }); + }; + + const openContextMenu = () => { + find('ccrFollowerIndexListContextMenuButton').simulate('click'); + }; + + const clickContextMenuButtonAt = (index = 0) => { + const contextMenu = find('followerIndexActionContextMenu'); + contextMenu.find('button').at(index).simulate('click'); + }; + + const openTableRowContextMenuAt = (index = 0) => { + const actionsColumnIndex = rows[0].columns.length - 1; // Actions are in the last column + const actionsTableCell = rows[index].columns[actionsColumnIndex]; + const button = actionsTableCell.reactWrapper.find('button'); + if (!button.length) { + throw new Error(`No button to open context menu were found on Follower index list table row ${index}`); + } + button.simulate('click'); + }; + + const clickFollowerIndexAt = (index = 0) => { + const followerIndexLink = findTestSubject(rows[index].reactWrapper, 'ccrFollowerIndexListFollowerIndexLink'); + followerIndexLink.simulate('click'); + }; + + return { + selectFollowerIndexAt, + openContextMenu, + clickContextMenuButtonAt, + openTableRowContextMenuAt, + clickFollowerIndexAt, + }; + }, + // Auto-follow patterns user actions + autoFollowPatternList() { + const { rows } = getMetadataFromEuiTable('ccrAutoFollowPatternListTable'); + + const selectAutoFollowPatternAt = (index = 0) => { + const row = rows[index]; + const checkBox = row.reactWrapper.find('input').hostNodes(); + checkBox.simulate('change', { target: { checked: true } }); + }; + + const clickBulkDeleteButton = () => { + find('ccrAutoFollowPatternListBulkDeleteActionButton').simulate('click'); + }; + + const clickConfirmModalDeleteAutoFollowPattern = () => { + const modal = find('ccrAutoFollowPatternDeleteConfirmationModal'); + findTestSubject(modal, 'confirmModalConfirmButton').simulate('click'); + }; + + const clickRowActionButtonAt = (index = 0, action = 'delete') => { + const indexLastColumn = rows[index].columns.length - 1; + const tableCellActions = rows[index].columns[indexLastColumn].reactWrapper; + + let button; + if (action === 'delete') { + button = findTestSubject(tableCellActions, 'ccrAutoFollowPatternListDeleteActionButton'); + } else if (action === 'edit') { + findTestSubject(tableCellActions, 'ccrAutoFollowPatternListEditActionButton'); + } + + if (!button) { + throw new Error(`Button for action "${action}" not found.`); + } + + button.simulate('click'); + }; + + const clickAutoFollowPatternAt = (index = 0) => { + const autoFollowPatternLink = findTestSubject(rows[index].reactWrapper, 'ccrAutoFollowPatternListPatternLink'); + autoFollowPatternLink.simulate('click'); + }; + + return { + selectAutoFollowPatternAt, + clickBulkDeleteButton, + clickConfirmModalDeleteAutoFollowPattern, + clickRowActionButtonAt, + clickAutoFollowPatternAt + }; + } + }; + + return userActions[section](); +}; + +export { nextTick, getRandomString, findTestSubject } from '../../../../test_utils'; + +export const initTestBed = (component, props = {}, options) => { + const testBed = registerTestBed(component, {}, ccrStore)(props, options); + const getUserActions = initUserActions(testBed); + + return { + ...testBed, + getUserActions, + }; +}; + +export const registerHttpRequestMockHelpers = server => { + const mockResponse = (defaultResponse, response) => ([ + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify({ ...defaultResponse, ...response }), + ]); + + const setLoadFollowerIndicesResponse = (response) => { + const defaultResponse = { indices: [] }; + + server.respondWith('GET', 'api/cross_cluster_replication/follower_indices', + mockResponse(defaultResponse, response)); + }; + + const setLoadAutoFollowPatternsResponse = (response) => { + const defaultResponse = { patterns: [] }; + + server.respondWith('GET', 'api/cross_cluster_replication/auto_follow_patterns', + mockResponse(defaultResponse, response) + ); + }; + + const setDeleteAutoFollowPatternResponse = (response) => { + const defaultResponse = { errors: [], itemsDeleted: [] }; + + server.respondWith('DELETE', /api\/cross_cluster_replication\/auto_follow_patterns/, + mockResponse(defaultResponse, response) + ); + }; + + const setAutoFollowStatsResponse = (response) => { + const defaultResponse = { + numberOfFailedFollowIndices: 0, + numberOfFailedRemoteClusterStateRequests: 0, + numberOfSuccessfulFollowIndices: 0, + recentAutoFollowErrors: [], + autoFollowedClusters: [{ + clusterName: 'new-york', + timeSinceLastCheckMillis: 13746, + lastSeenMetadataVersion: 22 + }] + }; + + server.respondWith('GET', 'api/cross_cluster_replication/stats/auto_follow', + mockResponse(defaultResponse, response) + ); + }; + + return { + setLoadFollowerIndicesResponse, + setLoadAutoFollowPatternsResponse, + setDeleteAutoFollowPatternResponse, + setAutoFollowStatsResponse, + }; +}; diff --git a/x-pack/plugins/cross_cluster_replication/fixtures/auto_follow_pattern.js b/x-pack/plugins/cross_cluster_replication/fixtures/auto_follow_pattern.js index 187b91b66ea73..cfedad5c1c072 100644 --- a/x-pack/plugins/cross_cluster_replication/fixtures/auto_follow_pattern.js +++ b/x-pack/plugins/cross_cluster_replication/fixtures/auto_follow_pattern.js @@ -4,14 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -const Chance = require('chance'); // eslint-disable-line import/no-extraneous-dependencies -const chance = new Chance(); +import { getRandomString } from '../../../test_utils'; export const getAutoFollowPatternMock = ( - name = chance.string(), - remoteCluster = chance.string(), - leaderIndexPatterns = [chance.string()], - followIndexPattern = chance.string() + name = getRandomString(), + remoteCluster = getRandomString(), + leaderIndexPatterns = [getRandomString()], + followIndexPattern = getRandomString() ) => ({ name, pattern: { @@ -33,3 +32,18 @@ export const getAutoFollowPatternListMock = (total = 3) => { return list; }; + +// ----------------- +// Client test mock +// ----------------- +export const getAutoFollowPatternClientMock = ({ + name = getRandomString(), + remoteCluster = getRandomString(), + leaderIndexPatterns = [`${getRandomString()}-*`], + followIndexPattern = getRandomString() +}) => ({ + name, + remoteCluster, + leaderIndexPatterns, + followIndexPattern, +}); diff --git a/x-pack/plugins/cross_cluster_replication/fixtures/follower_index.js b/x-pack/plugins/cross_cluster_replication/fixtures/follower_index.js index ef888f8929a26..e873c1a394f44 100644 --- a/x-pack/plugins/cross_cluster_replication/fixtures/follower_index.js +++ b/x-pack/plugins/cross_cluster_replication/fixtures/follower_index.js @@ -6,6 +6,63 @@ const Chance = require('chance'); // eslint-disable-line import/no-extraneous-dependencies const chance = new Chance(); +import { getRandomString } from '../../../test_utils'; + +const serializeShard = ({ + id, + remoteCluster, + leaderIndex, + leaderGlobalCheckpoint, + leaderMaxSequenceNum, + followerGlobalCheckpoint, + followerMaxSequenceNum, + lastRequestedSequenceNum, + outstandingReadRequestsCount, + outstandingWriteRequestsCount, + writeBufferOperationsCount, + writeBufferSizeBytes, + followerMappingVersion, + followerSettingsVersion, + totalReadTimeMs, + totalReadRemoteExecTimeMs, + successfulReadRequestCount, + failedReadRequestsCount, + operationsReadCount, + bytesReadCount, + totalWriteTimeMs, + successfulWriteRequestsCount, + failedWriteRequestsCount, + operationsWrittenCount, + readExceptions, + timeSinceLastReadMs, +}) => ({ + shard_id: id, + remote_cluster: remoteCluster, + leader_index: leaderIndex, + leader_global_checkpoint: leaderGlobalCheckpoint, + leader_max_seq_no: leaderMaxSequenceNum, + follower_global_checkpoint: followerGlobalCheckpoint, + follower_max_seq_no: followerMaxSequenceNum, + last_requested_seq_no: lastRequestedSequenceNum, + outstanding_read_requests: outstandingReadRequestsCount, + outstanding_write_requests: outstandingWriteRequestsCount, + write_buffer_operation_count: writeBufferOperationsCount, + write_buffer_size_in_bytes: writeBufferSizeBytes, + follower_mapping_version: followerMappingVersion, + follower_settings_version: followerSettingsVersion, + total_read_time_millis: totalReadTimeMs, + total_read_remote_exec_time_millis: totalReadRemoteExecTimeMs, + successful_read_requests: successfulReadRequestCount, + failed_read_requests: failedReadRequestsCount, + operations_read: operationsReadCount, + bytes_read: bytesReadCount, + total_write_time_millis: totalWriteTimeMs, + successful_write_requests: successfulWriteRequestsCount, + failed_write_requests: failedWriteRequestsCount, + operations_written: operationsWrittenCount, + read_exceptions: readExceptions, + time_since_last_read_millis: timeSinceLastReadMs, +}); export const getFollowerIndexStatsMock = ( name = chance.string(), @@ -37,68 +94,10 @@ export const getFollowerIndexStatsMock = ( readExceptions: [ chance.string() ], timeSinceLastReadMs: chance.integer(), }] -) => { - const serializeShard = ({ - id, - remoteCluster, - leaderIndex, - leaderGlobalCheckpoint, - leaderMaxSequenceNum, - followerGlobalCheckpoint, - followerMaxSequenceNum, - lastRequestedSequenceNum, - outstandingReadRequestsCount, - outstandingWriteRequestsCount, - writeBufferOperationsCount, - writeBufferSizeBytes, - followerMappingVersion, - followerSettingsVersion, - totalReadTimeMs, - totalReadRemoteExecTimeMs, - successfulReadRequestCount, - failedReadRequestsCount, - operationsReadCount, - bytesReadCount, - totalWriteTimeMs, - successfulWriteRequestsCount, - failedWriteRequestsCount, - operationsWrittenCount, - readExceptions, - timeSinceLastReadMs, - }) => ({ - shard_id: id, - remote_cluster: remoteCluster, - leader_index: leaderIndex, - leader_global_checkpoint: leaderGlobalCheckpoint, - leader_max_seq_no: leaderMaxSequenceNum, - follower_global_checkpoint: followerGlobalCheckpoint, - follower_max_seq_no: followerMaxSequenceNum, - last_requested_seq_no: lastRequestedSequenceNum, - outstanding_read_requests: outstandingReadRequestsCount, - outstanding_write_requests: outstandingWriteRequestsCount, - write_buffer_operation_count: writeBufferOperationsCount, - write_buffer_size_in_bytes: writeBufferSizeBytes, - follower_mapping_version: followerMappingVersion, - follower_settings_version: followerSettingsVersion, - total_read_time_millis: totalReadTimeMs, - total_read_remote_exec_time_millis: totalReadRemoteExecTimeMs, - successful_read_requests: successfulReadRequestCount, - failed_read_requests: failedReadRequestsCount, - operations_read: operationsReadCount, - bytes_read: bytesReadCount, - total_write_time_millis: totalWriteTimeMs, - successful_write_requests: successfulWriteRequestsCount, - failed_write_requests: failedWriteRequestsCount, - operations_written: operationsWrittenCount, - read_exceptions: readExceptions, - time_since_last_read_millis: timeSinceLastReadMs, - }); - - return { - index: name, - shards: shards.map(serializeShard), - }; -}; +) => ({ + index: name, + shards: shards.map(serializeShard), +}); export const getFollowerIndexListStatsMock = (total = 3, names) => { const list = { @@ -157,3 +156,57 @@ export const getFollowerIndexListInfoMock = (total = 3) => { return list; }; + +// ----------------- +// Client test mock +// ----------------- + +export const getFollowerIndexMock = ({ + name = getRandomString(), + remoteCluster = getRandomString(), + leaderIndex = getRandomString(), + status = 'Active' +} = {}) => ({ + name, + remoteCluster, + leaderIndex, + status, + maxReadRequestOperationCount: chance.integer(), + maxOutstandingReadRequests: chance.integer(), + maxReadRequestSize: getRandomString({ length: 5 }), + maxWriteRequestOperationCount: chance.integer(), + maxWriteRequestSize: '9223372036854775807b', + maxOutstandingWriteRequests: chance.integer(), + maxWriteBufferCount: chance.integer(), + maxWriteBufferSize: getRandomString({ length: 5 }), + maxRetryDelay: getRandomString({ length: 5 }), + readPollTimeout: getRandomString({ length: 5 }), + shards: [{ + id: 0, + remoteCluster: remoteCluster, + leaderIndex: leaderIndex, + leaderGlobalCheckpoint: chance.integer(), + leaderMaxSequenceNum: chance.integer(), + followerGlobalCheckpoint: chance.integer(), + followerMaxSequenceNum: chance.integer(), + lastRequestedSequenceNum: chance.integer(), + outstandingReadRequestsCount: chance.integer(), + outstandingWriteRequestsCount: chance.integer(), + writeBufferOperationsCount: chance.integer(), + writeBufferSizeBytes: chance.integer(), + followerMappingVersion: chance.integer(), + followerSettingsVersion: chance.integer(), + totalReadTimeMs: chance.integer(), + totalReadRemoteExecTimeMs: chance.integer(), + successfulReadRequestCount: chance.integer(), + failedReadRequestsCount: chance.integer(), + operationsReadCount: chance.integer(), + bytesReadCount: chance.integer(), + totalWriteTimeMs: chance.integer(), + successfulWriteRequestsCount: chance.integer(), + failedWriteRequestsCount: chance.integer(), + operationsWrittenCount: chance.integer(), + readExceptions: [], + timeSinceLastReadMs: chance.integer(), + }] +}); diff --git a/x-pack/plugins/cross_cluster_replication/public/app/app.js b/x-pack/plugins/cross_cluster_replication/public/app/app.js index 781b5040b2b66..d07712727aa77 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/app.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/app.js @@ -95,7 +95,7 @@ export class App extends Component { // This error isn't an HTTP error, so let the fatal error screen tell the user something // unexpected happened. fatalError(error, i18n.translate('xpack.crossClusterReplication.app.checkPermissionsFatalErrorTitle', { - defaultMessage: 'Cross Cluster Replication app', + defaultMessage: 'Cross-Cluster Replication app', })); } } @@ -196,7 +196,7 @@ export class App extends Component {

{!isSingle && ( diff --git a/x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_indices_preview.js b/x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_indices_preview.js index 3e41cb9bdcefd..c76c13c44d51f 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_indices_preview.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_indices_preview.js @@ -36,7 +36,7 @@ export const AutoFollowPatternIndicesPreview = ({ prefix, suffix, leaderIndexPat />

- { ); expect(wrapper).toMatchInlineSnapshot(` - { ); expect(wrapper).toMatchInlineSnapshot(` - ({ + create: jest.fn().mockReturnValue(mockClient), +})); diff --git a/x-pack/plugins/upgrade_assistant/public/components/tabs/checkup/deprecations/reindex/polling_service.test.ts b/x-pack/plugins/upgrade_assistant/public/components/tabs/checkup/deprecations/reindex/polling_service.test.ts index f15927c0d6a3b..9f47f51bc8cde 100644 --- a/x-pack/plugins/upgrade_assistant/public/components/tabs/checkup/deprecations/reindex/polling_service.test.ts +++ b/x-pack/plugins/upgrade_assistant/public/components/tabs/checkup/deprecations/reindex/polling_service.test.ts @@ -4,25 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ReindexStatus, ReindexStep } from '../../../../../../common/types'; - -const mockClient = { - post: jest.fn().mockResolvedValue({ - lastCompletedStep: ReindexStep.created, - status: ReindexStatus.inProgress, - }), - get: jest.fn().mockResolvedValue({ - status: 200, - data: { - warnings: [], - reindexOp: null, - }, - }), -}; -jest.mock('axios', () => ({ - create: jest.fn().mockReturnValue(mockClient), -})); +import { mockClient } from './polling_service.test.mocks'; +import { ReindexStatus, ReindexStep } from '../../../../../../common/types'; import { ReindexPollingService } from './polling_service'; describe('ReindexPollingService', () => { diff --git a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/worker.ts b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/worker.ts index 9d37fec650b70..1b19db8a378ef 100644 --- a/x-pack/plugins/upgrade_assistant/server/lib/reindexing/worker.ts +++ b/x-pack/plugins/upgrade_assistant/server/lib/reindexing/worker.ts @@ -7,7 +7,7 @@ import { CallCluster, CallClusterWithRequest } from 'src/legacy/core_plugins/ela import { Request, Server } from 'src/legacy/server/kbn_server'; import { SavedObjectsClient } from 'src/legacy/server/saved_objects'; -import moment = require('moment'); +import moment from 'moment'; import { XPackInfo } from 'x-pack/plugins/xpack_main/server/lib/xpack_info'; import { ReindexSavedObject, ReindexStatus } from '../../../common/types'; import { CredentialStore } from './credential_store'; diff --git a/x-pack/plugins/uptime/public/components/functional/__tests__/__snapshots__/monitor_charts.test.tsx.snap b/x-pack/plugins/uptime/public/components/functional/__tests__/__snapshots__/monitor_charts.test.tsx.snap index f854c6f76b2d8..66b72b4029fdc 100644 --- a/x-pack/plugins/uptime/public/components/functional/__tests__/__snapshots__/monitor_charts.test.tsx.snap +++ b/x-pack/plugins/uptime/public/components/functional/__tests__/__snapshots__/monitor_charts.test.tsx.snap @@ -29,7 +29,6 @@ exports[`MonitorCharts component renders the component without errors 1`] = ` } > - { const component = shallowWithIntl( ); expect(component).toMatchSnapshot(); diff --git a/x-pack/plugins/uptime/public/components/functional/empty_state/__tests__/__snapshots__/empty_state.test.tsx.snap b/x-pack/plugins/uptime/public/components/functional/empty_state/__tests__/__snapshots__/empty_state.test.tsx.snap index 4bd055eab879f..512529d27691c 100644 --- a/x-pack/plugins/uptime/public/components/functional/empty_state/__tests__/__snapshots__/empty_state.test.tsx.snap +++ b/x-pack/plugins/uptime/public/components/functional/empty_state/__tests__/__snapshots__/empty_state.test.tsx.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`EmptyState component doesn't render child components when count is falsey 1`] = ` - - - - + + `; exports[`EmptyState component renders child components when count is truthy 1`] = ` @@ -268,7 +268,7 @@ exports[`EmptyState component renders child components when count is truthy 1`] `; exports[`EmptyState component renders empty state with appropriate base path 1`] = ` - - - - + + `; exports[`EmptyState component renders message while loading 1`] = ` - - + - - + + `; exports[`EmptyState component renders the message when an error occurs 1`] = ` - - - - + + `; diff --git a/x-pack/plugins/uptime/public/components/functional/monitor_charts.tsx b/x-pack/plugins/uptime/public/components/functional/monitor_charts.tsx index 334a32054f7ad..a60d1034f474c 100644 --- a/x-pack/plugins/uptime/public/components/functional/monitor_charts.tsx +++ b/x-pack/plugins/uptime/public/components/functional/monitor_charts.tsx @@ -29,24 +29,20 @@ import { convertMicrosecondsToMilliseconds as microsToMillis } from '../../lib/h interface MonitorChartsProps { checkDomainLimits: number[]; - crosshairLocation: number; danger: string; durationDomainLimits: number[]; monitorChartData: MonitorChart; primary: string; secondary: string; - updateCrosshairLocation: (crosshairLocation: number) => void; } export const MonitorCharts = ({ checkDomainLimits, - crosshairLocation, danger, durationDomainLimits, monitorChartData: { durationArea, durationLine, status }, primary, secondary, - updateCrosshairLocation, }: MonitorChartsProps) => ( @@ -60,7 +56,6 @@ export const MonitorCharts = ({ /> - { - constructor(props: Props) { - super(props); - this.state = { crosshairLocation: 0 }; - } +export const MonitorChartsQuery = ({ + colors: { primary, secondary, danger }, + dateRangeStart, + dateRangeEnd, + monitorId, + autorefreshIsPaused, + autorefreshInterval, +}: Props) => { + return ( + + {({ loading, error, data }) => { + if (loading) { + return i18n.translate('xpack.uptime.monitorCharts.loadingMessage', { + defaultMessage: 'Loading…', + }); + } + if (error) { + return i18n.translate('xpack.uptime.monitorCharts.errorMessage', { + values: { message: error.message }, + defaultMessage: 'Error {message}', + }); + } - public render() { - const { - colors: { primary, secondary, danger }, - dateRangeStart, - dateRangeEnd, - monitorId, - autorefreshIsPaused, - autorefreshInterval, - } = this.props; - return ( - - {({ loading, error, data }) => { - if (loading) { - return i18n.translate('xpack.uptime.monitorCharts.loadingMessage', { - defaultMessage: 'Loading…', - }); - } - if (error) { - return i18n.translate('xpack.uptime.monitorCharts.errorMessage', { - values: { message: error.message }, - defaultMessage: 'Error {message}', - }); - } + const { + monitorChartsData, + monitorChartsData: { durationMaxValue, statusMaxCount }, + }: { monitorChartsData: MonitorChart } = data; - const { - monitorChartsData, - monitorChartsData: { durationMaxValue, statusMaxCount }, - }: { monitorChartsData: MonitorChart } = data; + const durationMax = microsToMillis(durationMaxValue); + // These limits provide domain sizes for the charts + const checkDomainLimits = [0, statusMaxCount]; + const durationDomainLimits = [0, durationMax ? durationMax : 0]; - const durationMax = microsToMillis(durationMaxValue); - // These limits provide domain sizes for the charts - const checkDomainLimits = [0, statusMaxCount]; - const durationDomainLimits = [0, durationMax ? durationMax : 0]; - - return ( - - ); - }} - - ); - } - private updateCrosshairLocation = (crosshairLocation: number) => - this.setState({ crosshairLocation }); -} + return ( + + ); + }} + + ); +}; diff --git a/x-pack/plugins/uptime/scripts/infer_graphql_types.js b/x-pack/plugins/uptime/scripts/infer_graphql_types.js index c4b87c9ea9339..b821fbde4084e 100644 --- a/x-pack/plugins/uptime/scripts/infer_graphql_types.js +++ b/x-pack/plugins/uptime/scripts/infer_graphql_types.js @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +require('../../../../src/setup_node_env'); + const { resolve } = require('path'); // eslint-disable-next-line import/no-extraneous-dependencies, import/no-unresolved const { generate } = require('graphql-code-generator'); @@ -20,7 +22,6 @@ async function main() { config: CONFIG_PATH, out: OUTPUT_INTROSPECTION_PATH, overwrite: true, - require: ['ts-node/register'], schema: SCHEMA_PATH, template: 'graphql-codegen-introspection-template', }, diff --git a/x-pack/plugins/watcher/__tests__/plugin_definition.js b/x-pack/plugins/watcher/__tests__/plugin_definition.js index eb0c2d011eb6a..c95d5aba8bbc5 100644 --- a/x-pack/plugins/watcher/__tests__/plugin_definition.js +++ b/x-pack/plugins/watcher/__tests__/plugin_definition.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { pluginDefinition } from '../plugin_definition'; describe ('pluginDefinition', () => { diff --git a/x-pack/plugins/watcher/common/lib/get_action_type/__tests__/get_action_type.js b/x-pack/plugins/watcher/common/lib/get_action_type/__tests__/get_action_type.js index 3ee5a1d75b4b4..7b2fd7bd84062 100644 --- a/x-pack/plugins/watcher/common/lib/get_action_type/__tests__/get_action_type.js +++ b/x-pack/plugins/watcher/common/lib/get_action_type/__tests__/get_action_type.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getActionType } from '../get_action_type'; import { ACTION_TYPES } from '../../../../common/constants'; diff --git a/x-pack/plugins/watcher/common/lib/get_moment/__tests__/get_moment.js b/x-pack/plugins/watcher/common/lib/get_moment/__tests__/get_moment.js index 69ccd634ec6e7..a90099f465ccd 100644 --- a/x-pack/plugins/watcher/common/lib/get_moment/__tests__/get_moment.js +++ b/x-pack/plugins/watcher/common/lib/get_moment/__tests__/get_moment.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getMoment } from '../get_moment'; describe('get_moment', () => { diff --git a/x-pack/plugins/watcher/public/components/duration_select/duration_select.js b/x-pack/plugins/watcher/public/components/duration_select/duration_select.js index 3b2c1cf2ee6d7..9fab3504ac638 100644 --- a/x-pack/plugins/watcher/public/components/duration_select/duration_select.js +++ b/x-pack/plugins/watcher/public/components/duration_select/duration_select.js @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import 'ui/fancy_forms'; import { uiModules } from 'ui/modules'; import { InitAfterBindingsWorkaround } from 'ui/compat'; import { TIME_UNITS } from 'plugins/watcher/constants'; diff --git a/x-pack/plugins/watcher/public/components/expression_builder/components/expression_item/expression_item.js b/x-pack/plugins/watcher/public/components/expression_builder/components/expression_item/expression_item.js index 24337a58d7c18..895a26280dbeb 100644 --- a/x-pack/plugins/watcher/public/components/expression_builder/components/expression_item/expression_item.js +++ b/x-pack/plugins/watcher/public/components/expression_builder/components/expression_item/expression_item.js @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import 'ui/fancy_forms'; import { uiModules } from 'ui/modules'; import { keyMap } from 'ui/utils/key_map'; import template from './expression_item.html'; diff --git a/x-pack/plugins/watcher/public/components/json_editor/json_editor.js b/x-pack/plugins/watcher/public/components/json_editor/json_editor.js index dc78985ab47ca..812bdaeb8a41e 100644 --- a/x-pack/plugins/watcher/public/components/json_editor/json_editor.js +++ b/x-pack/plugins/watcher/public/components/json_editor/json_editor.js @@ -6,6 +6,7 @@ import { uiModules } from 'ui/modules'; import template from './json_editor.html'; +import 'ui/directives/json_input'; import 'ace'; const app = uiModules.get('xpack/watcher'); diff --git a/x-pack/plugins/watcher/public/components/watch_actions/components/watch_action/watch_action.js b/x-pack/plugins/watcher/public/components/watch_actions/components/watch_action/watch_action.js index feb49b152dd16..021d4a5ef7e17 100644 --- a/x-pack/plugins/watcher/public/components/watch_actions/components/watch_action/watch_action.js +++ b/x-pack/plugins/watcher/public/components/watch_actions/components/watch_action/watch_action.js @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import 'ui/fancy_forms'; import { uiModules } from 'ui/modules'; import template from './watch_action.html'; import angular from 'angular'; diff --git a/x-pack/plugins/watcher/public/components/watch_history_item_detail/watch_history_item_detail.js b/x-pack/plugins/watcher/public/components/watch_history_item_detail/watch_history_item_detail.js index 4c2ad500ee0bb..e3e3218745d83 100644 --- a/x-pack/plugins/watcher/public/components/watch_history_item_detail/watch_history_item_detail.js +++ b/x-pack/plugins/watcher/public/components/watch_history_item_detail/watch_history_item_detail.js @@ -5,6 +5,7 @@ */ import { uiModules } from 'ui/modules'; +import 'ui/directives/json_input'; import template from './watch_history_item_detail.html'; import 'ace'; diff --git a/x-pack/plugins/watcher/public/lib/sortable_boolean/__tests__/sortable_boolean.js b/x-pack/plugins/watcher/public/lib/sortable_boolean/__tests__/sortable_boolean.js index ba32ba27f53d1..b51130c836459 100644 --- a/x-pack/plugins/watcher/public/lib/sortable_boolean/__tests__/sortable_boolean.js +++ b/x-pack/plugins/watcher/public/lib/sortable_boolean/__tests__/sortable_boolean.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { sortableBoolean } from '../sortable_boolean'; describe('sortable_boolean', () => { diff --git a/x-pack/plugins/watcher/server/lib/check_license/__tests__/check_license.js b/x-pack/plugins/watcher/server/lib/check_license/__tests__/check_license.js index fe410e498b91a..3dc2eced25a8e 100644 --- a/x-pack/plugins/watcher/server/lib/check_license/__tests__/check_license.js +++ b/x-pack/plugins/watcher/server/lib/check_license/__tests__/check_license.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { set } from 'lodash'; import { checkLicense } from '../check_license'; diff --git a/x-pack/plugins/watcher/server/lib/error_wrappers/__tests__/wrap_custom_error.js b/x-pack/plugins/watcher/server/lib/error_wrappers/__tests__/wrap_custom_error.js index 443744ccb0cc8..f9c102be7a1ff 100644 --- a/x-pack/plugins/watcher/server/lib/error_wrappers/__tests__/wrap_custom_error.js +++ b/x-pack/plugins/watcher/server/lib/error_wrappers/__tests__/wrap_custom_error.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { wrapCustomError } from '../wrap_custom_error'; describe('wrap_custom_error', () => { diff --git a/x-pack/plugins/watcher/server/lib/error_wrappers/__tests__/wrap_es_error.js b/x-pack/plugins/watcher/server/lib/error_wrappers/__tests__/wrap_es_error.js index 394c182140000..467cc4fcdae1f 100644 --- a/x-pack/plugins/watcher/server/lib/error_wrappers/__tests__/wrap_es_error.js +++ b/x-pack/plugins/watcher/server/lib/error_wrappers/__tests__/wrap_es_error.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { wrapEsError } from '../wrap_es_error'; describe('wrap_es_error', () => { diff --git a/x-pack/plugins/watcher/server/lib/error_wrappers/__tests__/wrap_unknown_error.js b/x-pack/plugins/watcher/server/lib/error_wrappers/__tests__/wrap_unknown_error.js index 6d6a336417bef..85e0b2b3033ad 100644 --- a/x-pack/plugins/watcher/server/lib/error_wrappers/__tests__/wrap_unknown_error.js +++ b/x-pack/plugins/watcher/server/lib/error_wrappers/__tests__/wrap_unknown_error.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { wrapUnknownError } from '../wrap_unknown_error'; describe('wrap_unknown_error', () => { diff --git a/x-pack/plugins/watcher/server/lib/fetch_all_from_scroll/__tests__/fetch_all_from_scroll.js b/x-pack/plugins/watcher/server/lib/fetch_all_from_scroll/__tests__/fetch_all_from_scroll.js index 582c021892d42..5e532b68e2bcc 100644 --- a/x-pack/plugins/watcher/server/lib/fetch_all_from_scroll/__tests__/fetch_all_from_scroll.js +++ b/x-pack/plugins/watcher/server/lib/fetch_all_from_scroll/__tests__/fetch_all_from_scroll.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { fetchAllFromScroll } from '../fetch_all_from_scroll'; import { set } from 'lodash'; diff --git a/x-pack/plugins/watcher/server/lib/is_es_error_factory/__tests__/is_es_error_factory.js b/x-pack/plugins/watcher/server/lib/is_es_error_factory/__tests__/is_es_error_factory.js index d50ff9480d3e4..76fdf7b36c3d0 100644 --- a/x-pack/plugins/watcher/server/lib/is_es_error_factory/__tests__/is_es_error_factory.js +++ b/x-pack/plugins/watcher/server/lib/is_es_error_factory/__tests__/is_es_error_factory.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { isEsErrorFactory } from '../is_es_error_factory'; import { set } from 'lodash'; diff --git a/x-pack/plugins/watcher/server/lib/license_pre_routing_factory/__tests__/license_pre_routing_factory.js b/x-pack/plugins/watcher/server/lib/license_pre_routing_factory/__tests__/license_pre_routing_factory.js index 359b3fb2ce6f4..24cbaae2b2b67 100644 --- a/x-pack/plugins/watcher/server/lib/license_pre_routing_factory/__tests__/license_pre_routing_factory.js +++ b/x-pack/plugins/watcher/server/lib/license_pre_routing_factory/__tests__/license_pre_routing_factory.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { licensePreRoutingFactory } from '../license_pre_routing_factory'; describe('license_pre_routing_factory', () => { diff --git a/x-pack/plugins/watcher/server/models/action_status/__tests__/action_status.js b/x-pack/plugins/watcher/server/models/action_status/__tests__/action_status.js index b30d29af611d7..911c960efdab5 100644 --- a/x-pack/plugins/watcher/server/models/action_status/__tests__/action_status.js +++ b/x-pack/plugins/watcher/server/models/action_status/__tests__/action_status.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { ActionStatus } from '../action_status'; import { ACTION_STATES } from '../../../../common/constants'; import moment from 'moment'; diff --git a/x-pack/plugins/watcher/server/models/execute_details/__tests__/execute_details.js b/x-pack/plugins/watcher/server/models/execute_details/__tests__/execute_details.js index bdd4a13eb8e37..00937bbc6204c 100644 --- a/x-pack/plugins/watcher/server/models/execute_details/__tests__/execute_details.js +++ b/x-pack/plugins/watcher/server/models/execute_details/__tests__/execute_details.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { ExecuteDetails } from '../execute_details'; describe('execute_details', () => { diff --git a/x-pack/plugins/watcher/server/models/fields/__tests__/fields.js b/x-pack/plugins/watcher/server/models/fields/__tests__/fields.js index 9588c51a2ad4f..5c872ff56749c 100644 --- a/x-pack/plugins/watcher/server/models/fields/__tests__/fields.js +++ b/x-pack/plugins/watcher/server/models/fields/__tests__/fields.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { find } from 'lodash'; import { Fields } from '../fields'; diff --git a/x-pack/plugins/watcher/server/models/settings/__tests__/settings.js b/x-pack/plugins/watcher/server/models/settings/__tests__/settings.js index 6c34467ef8629..7add7a0e0564e 100644 --- a/x-pack/plugins/watcher/server/models/settings/__tests__/settings.js +++ b/x-pack/plugins/watcher/server/models/settings/__tests__/settings.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { Settings } from '../settings'; describe('settings module', () => { diff --git a/x-pack/plugins/watcher/server/models/watch/__tests__/base_watch.js b/x-pack/plugins/watcher/server/models/watch/__tests__/base_watch.js index 9740874cb92ac..fbbbd52c7987b 100644 --- a/x-pack/plugins/watcher/server/models/watch/__tests__/base_watch.js +++ b/x-pack/plugins/watcher/server/models/watch/__tests__/base_watch.js @@ -5,7 +5,7 @@ */ import proxyquire from 'proxyquire'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; const actionFromUpstreamJSONMock = sinon.stub(); diff --git a/x-pack/plugins/watcher/server/models/watch/__tests__/json_watch.js b/x-pack/plugins/watcher/server/models/watch/__tests__/json_watch.js index e4b258d51cfe5..a38b10afcd28f 100644 --- a/x-pack/plugins/watcher/server/models/watch/__tests__/json_watch.js +++ b/x-pack/plugins/watcher/server/models/watch/__tests__/json_watch.js @@ -5,7 +5,7 @@ */ import { pick } from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import proxyquire from 'proxyquire'; diff --git a/x-pack/plugins/watcher/server/models/watch/__tests__/monitoring_watch.js b/x-pack/plugins/watcher/server/models/watch/__tests__/monitoring_watch.js index c580d8c8f7768..44e457476815d 100644 --- a/x-pack/plugins/watcher/server/models/watch/__tests__/monitoring_watch.js +++ b/x-pack/plugins/watcher/server/models/watch/__tests__/monitoring_watch.js @@ -5,7 +5,7 @@ */ import { pick } from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import proxyquire from 'proxyquire'; diff --git a/x-pack/plugins/watcher/server/models/watch/__tests__/threshold_watch.js b/x-pack/plugins/watcher/server/models/watch/__tests__/threshold_watch.js index 635d23734b968..a93280d5c6aa8 100644 --- a/x-pack/plugins/watcher/server/models/watch/__tests__/threshold_watch.js +++ b/x-pack/plugins/watcher/server/models/watch/__tests__/threshold_watch.js @@ -5,7 +5,7 @@ */ import { pick } from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import proxyquire from 'proxyquire'; import { COMPARATORS, SORT_ORDERS } from '../../../../common/constants'; diff --git a/x-pack/plugins/watcher/server/models/watch/__tests__/watch.js b/x-pack/plugins/watcher/server/models/watch/__tests__/watch.js index ac186b3846579..14d5005b13e04 100644 --- a/x-pack/plugins/watcher/server/models/watch/__tests__/watch.js +++ b/x-pack/plugins/watcher/server/models/watch/__tests__/watch.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import proxyquire from 'proxyquire'; import { WATCH_TYPES } from '../../../../common/constants'; diff --git a/x-pack/plugins/watcher/server/models/watch/threshold_watch/__tests__/format_visualize_data.js b/x-pack/plugins/watcher/server/models/watch/threshold_watch/__tests__/format_visualize_data.js index 41c84f1750a5e..04239ab6e1b5f 100644 --- a/x-pack/plugins/watcher/server/models/watch/threshold_watch/__tests__/format_visualize_data.js +++ b/x-pack/plugins/watcher/server/models/watch/threshold_watch/__tests__/format_visualize_data.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { AGG_TYPES } from '../../../../../common/constants'; import { formatVisualizeData } from '../format_visualize_data'; diff --git a/x-pack/plugins/watcher/server/models/watch_history_item/__tests__/watch_history_item.js b/x-pack/plugins/watcher/server/models/watch_history_item/__tests__/watch_history_item.js index 2d13243f8a6d3..a22609db226e5 100644 --- a/x-pack/plugins/watcher/server/models/watch_history_item/__tests__/watch_history_item.js +++ b/x-pack/plugins/watcher/server/models/watch_history_item/__tests__/watch_history_item.js @@ -5,7 +5,7 @@ */ import moment from 'moment'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { WatchHistoryItem } from '../watch_history_item'; describe('watch_history_item', () => { diff --git a/x-pack/plugins/watcher/server/models/watch_status/__tests__/watch_status.js b/x-pack/plugins/watcher/server/models/watch_status/__tests__/watch_status.js index 4b1649ab4c1e0..e29c8dd2a529e 100644 --- a/x-pack/plugins/watcher/server/models/watch_status/__tests__/watch_status.js +++ b/x-pack/plugins/watcher/server/models/watch_status/__tests__/watch_status.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { WatchStatus } from '../watch_status'; import { ACTION_STATES, WATCH_STATES, WATCH_STATE_COMMENTS } from '../../../../common/constants'; import moment from 'moment'; diff --git a/x-pack/plugins/xpack_main/public/hacks/__tests__/fetch_telemetry.js b/x-pack/plugins/xpack_main/public/hacks/__tests__/fetch_telemetry.js index 903abf4d202db..1dfeefdd295ec 100644 --- a/x-pack/plugins/xpack_main/public/hacks/__tests__/fetch_telemetry.js +++ b/x-pack/plugins/xpack_main/public/hacks/__tests__/fetch_telemetry.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { fetchTelemetry } from '../fetch_telemetry'; diff --git a/x-pack/plugins/xpack_main/public/hacks/welcome_banner/__tests__/click_banner.js b/x-pack/plugins/xpack_main/public/hacks/welcome_banner/__tests__/click_banner.js index 3a1e528e3fc41..d77c77cf53356 100644 --- a/x-pack/plugins/xpack_main/public/hacks/welcome_banner/__tests__/click_banner.js +++ b/x-pack/plugins/xpack_main/public/hacks/welcome_banner/__tests__/click_banner.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { uiModules } from 'ui/modules'; diff --git a/x-pack/plugins/xpack_main/public/hacks/welcome_banner/__tests__/handle_old_settings.js b/x-pack/plugins/xpack_main/public/hacks/welcome_banner/__tests__/handle_old_settings.js index 3ceb31cb2eb30..ab17b0080463d 100644 --- a/x-pack/plugins/xpack_main/public/hacks/welcome_banner/__tests__/handle_old_settings.js +++ b/x-pack/plugins/xpack_main/public/hacks/welcome_banner/__tests__/handle_old_settings.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { CONFIG_TELEMETRY } from '../../../../common/constants'; diff --git a/x-pack/plugins/xpack_main/public/hacks/welcome_banner/__tests__/render_banner.js b/x-pack/plugins/xpack_main/public/hacks/welcome_banner/__tests__/render_banner.js index de8c690c1a391..0ba0a21b6413b 100644 --- a/x-pack/plugins/xpack_main/public/hacks/welcome_banner/__tests__/render_banner.js +++ b/x-pack/plugins/xpack_main/public/hacks/welcome_banner/__tests__/render_banner.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { renderBanner } from '../render_banner'; diff --git a/x-pack/plugins/xpack_main/public/hacks/welcome_banner/__tests__/should_show_banner.js b/x-pack/plugins/xpack_main/public/hacks/welcome_banner/__tests__/should_show_banner.js index ed9d3e79a0c59..e78d69f25ecb3 100644 --- a/x-pack/plugins/xpack_main/public/hacks/welcome_banner/__tests__/should_show_banner.js +++ b/x-pack/plugins/xpack_main/public/hacks/welcome_banner/__tests__/should_show_banner.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { CONFIG_TELEMETRY } from '../../../../common/constants'; diff --git a/x-pack/plugins/xpack_main/public/services/__tests__/xpack_info.js b/x-pack/plugins/xpack_main/public/services/__tests__/xpack_info.js index 70eb4925fe1a7..a6ee8cb0c8d6a 100644 --- a/x-pack/plugins/xpack_main/public/services/__tests__/xpack_info.js +++ b/x-pack/plugins/xpack_main/public/services/__tests__/xpack_info.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { XPackInfoProvider } from 'plugins/xpack_main/services/xpack_info'; import { MockWindowProvider } from './_mock_window'; diff --git a/x-pack/plugins/xpack_main/public/services/__tests__/xpack_info_signature.js b/x-pack/plugins/xpack_main/public/services/__tests__/xpack_info_signature.js index 47db141d610d4..980d8f649f1d4 100644 --- a/x-pack/plugins/xpack_main/public/services/__tests__/xpack_info_signature.js +++ b/x-pack/plugins/xpack_main/public/services/__tests__/xpack_info_signature.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ngMock from 'ng_mock'; import { XPackInfoSignatureProvider } from 'plugins/xpack_main/services/xpack_info_signature'; import { MockWindowProvider } from './_mock_window'; diff --git a/x-pack/plugins/xpack_main/server/lib/__tests__/call_cluster_factory.js b/x-pack/plugins/xpack_main/server/lib/__tests__/call_cluster_factory.js index 9c7f17a9e507b..9251829f07608 100644 --- a/x-pack/plugins/xpack_main/server/lib/__tests__/call_cluster_factory.js +++ b/x-pack/plugins/xpack_main/server/lib/__tests__/call_cluster_factory.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { callClusterFactory } from '../call_cluster_factory'; diff --git a/x-pack/plugins/xpack_main/server/lib/__tests__/inject_xpack_info_signature.js b/x-pack/plugins/xpack_main/server/lib/__tests__/inject_xpack_info_signature.js index c044636a2c93a..c0f52b1cb7f1f 100644 --- a/x-pack/plugins/xpack_main/server/lib/__tests__/inject_xpack_info_signature.js +++ b/x-pack/plugins/xpack_main/server/lib/__tests__/inject_xpack_info_signature.js @@ -5,7 +5,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { injectXPackInfoSignature } from '../inject_xpack_info_signature'; describe('injectXPackInfoSignature()', () => { diff --git a/x-pack/plugins/xpack_main/server/lib/__tests__/replace_injected_vars.js b/x-pack/plugins/xpack_main/server/lib/__tests__/replace_injected_vars.js index 863f07725ad29..26bce06adaaba 100644 --- a/x-pack/plugins/xpack_main/server/lib/__tests__/replace_injected_vars.js +++ b/x-pack/plugins/xpack_main/server/lib/__tests__/replace_injected_vars.js @@ -5,7 +5,7 @@ */ import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { replaceInjectedVars } from '../replace_injected_vars'; diff --git a/x-pack/plugins/xpack_main/server/lib/__tests__/xpack_info.js b/x-pack/plugins/xpack_main/server/lib/__tests__/xpack_info.js index 8cb75f3cb642b..88ba3d6003277 100644 --- a/x-pack/plugins/xpack_main/server/lib/__tests__/xpack_info.js +++ b/x-pack/plugins/xpack_main/server/lib/__tests__/xpack_info.js @@ -5,7 +5,7 @@ */ import { createHash } from 'crypto'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { XPackInfo } from '../xpack_info'; diff --git a/x-pack/plugins/xpack_main/server/lib/file_integrity.test.mocks.ts b/x-pack/plugins/xpack_main/server/lib/file_integrity.test.mocks.ts new file mode 100644 index 0000000000000..36f76516e188b --- /dev/null +++ b/x-pack/plugins/xpack_main/server/lib/file_integrity.test.mocks.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { Readable } from 'stream'; + +jest.doMock('fs', () => ({ + createReadStream(filepath: string): Readable { + if (filepath === 'ERROR') { + throw new Error('MOCK ERROR - Invalid Path'); + } + const readableStream = new Readable(); + const streamData = filepath.split(''); + let cursor = 0; + + readableStream._read = function(size) { + const current = streamData[cursor++]; + if (typeof current === 'undefined') { + return this.push(null); + } + this.push(current); + }; + + return readableStream; + }, +})); diff --git a/x-pack/plugins/xpack_main/server/lib/file_integrity.test.ts b/x-pack/plugins/xpack_main/server/lib/file_integrity.test.ts index 5e554cd77d849..668b0d0c21088 100644 --- a/x-pack/plugins/xpack_main/server/lib/file_integrity.test.ts +++ b/x-pack/plugins/xpack_main/server/lib/file_integrity.test.ts @@ -4,28 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Readable } from 'stream'; - -jest.mock('fs', () => ({ - createReadStream(filepath: string): Readable { - if (filepath === 'ERROR') { - throw new Error('MOCK ERROR - Invalid Path'); - } - const readableStream = new Readable(); - const streamData = filepath.split(''); - let cursor = 0; - - readableStream._read = function(size) { - const current = streamData[cursor++]; - if (typeof current === 'undefined') { - return this.push(null); - } - this.push(current); - }; - - return readableStream; - }, -})); +import './file_integrity.test.mocks'; import { getIntegrityHash, getIntegrityHashes } from './file_integrity'; diff --git a/x-pack/plugins/xpack_main/server/lib/telemetry/local/__tests__/get_cluster_info.js b/x-pack/plugins/xpack_main/server/lib/telemetry/local/__tests__/get_cluster_info.js index 2331c8b01bce8..863556b70df45 100644 --- a/x-pack/plugins/xpack_main/server/lib/telemetry/local/__tests__/get_cluster_info.js +++ b/x-pack/plugins/xpack_main/server/lib/telemetry/local/__tests__/get_cluster_info.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { getClusterInfo } from '../get_cluster_info'; diff --git a/x-pack/plugins/xpack_main/server/lib/telemetry/local/__tests__/get_cluster_stats.js b/x-pack/plugins/xpack_main/server/lib/telemetry/local/__tests__/get_cluster_stats.js index 6e3bc59928a21..ce4620d34601a 100644 --- a/x-pack/plugins/xpack_main/server/lib/telemetry/local/__tests__/get_cluster_stats.js +++ b/x-pack/plugins/xpack_main/server/lib/telemetry/local/__tests__/get_cluster_stats.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { TIMEOUT } from '../constants'; diff --git a/x-pack/plugins/xpack_main/server/lib/telemetry/local/__tests__/get_local_stats.js b/x-pack/plugins/xpack_main/server/lib/telemetry/local/__tests__/get_local_stats.js index 03056f8c9e26b..153166c4b1f1e 100644 --- a/x-pack/plugins/xpack_main/server/lib/telemetry/local/__tests__/get_local_stats.js +++ b/x-pack/plugins/xpack_main/server/lib/telemetry/local/__tests__/get_local_stats.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { mockGetClusterInfo } from './get_cluster_info'; diff --git a/x-pack/plugins/xpack_main/server/lib/telemetry/local/__tests__/get_xpack.js b/x-pack/plugins/xpack_main/server/lib/telemetry/local/__tests__/get_xpack.js index c4cc1fa249a17..bc9c6981e4410 100644 --- a/x-pack/plugins/xpack_main/server/lib/telemetry/local/__tests__/get_xpack.js +++ b/x-pack/plugins/xpack_main/server/lib/telemetry/local/__tests__/get_xpack.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { TIMEOUT } from '../constants'; diff --git a/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/create_query.js b/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/create_query.js index 7ad932bdef024..2d35c10ea2189 100644 --- a/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/create_query.js +++ b/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/create_query.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { set } from 'lodash'; import { createTypeFilter, createQuery } from '../create_query.js'; diff --git a/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/get_all_stats.js b/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/get_all_stats.js index 3357f27ad6447..fff281a0d87ef 100644 --- a/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/get_all_stats.js +++ b/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/get_all_stats.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { addStackStats, getAllStats, getAllStatsForServer, handleAllStats } from '../get_all_stats'; diff --git a/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/get_beats_stats.js b/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/get_beats_stats.js index 42642b16de4c4..529cd306275b1 100644 --- a/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/get_beats_stats.js +++ b/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/get_beats_stats.js @@ -6,7 +6,7 @@ import { fetchBeatsStats, processResults } from '../get_beats_stats'; import sinon from 'sinon'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import beatsStatsResultSet from './fixtures/beats_stats_results'; const getBaseOptions = () => ({ diff --git a/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/get_cluster_uuids.js b/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/get_cluster_uuids.js index 6ec260f8f4f4c..e3153670ac58f 100644 --- a/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/get_cluster_uuids.js +++ b/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/get_cluster_uuids.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { getClusterUuids, fetchClusterUuids, handleClusterUuidsResponse } from '../get_cluster_uuids'; diff --git a/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/get_es_stats.js b/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/get_es_stats.js index 5005037bd641b..6f13a1e1bdf75 100644 --- a/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/get_es_stats.js +++ b/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/get_es_stats.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { fetchElasticsearchStats, getElasticsearchStats, handleElasticsearchStats } from '../get_es_stats'; diff --git a/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/get_high_level_stats.js b/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/get_high_level_stats.js index a071837a163f2..be86130f2452e 100644 --- a/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/get_high_level_stats.js +++ b/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/get_high_level_stats.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { fetchHighLevelStats, getHighLevelStats, handleHighLevelStatsResponse } from '../get_high_level_stats'; diff --git a/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/get_kibana_stats.js b/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/get_kibana_stats.js index 4811f825ed7bb..4d0ad95c919c8 100644 --- a/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/get_kibana_stats.js +++ b/x-pack/plugins/xpack_main/server/lib/telemetry/monitoring/__tests__/get_kibana_stats.js @@ -5,7 +5,7 @@ */ import { getUsageStats, combineStats, rollUpTotals } from '../get_kibana_stats'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; describe('Get Kibana Stats', () => { describe('Make a map of usage stats for each cluster', () => { diff --git a/x-pack/plugins/xpack_main/server/routes/api/v1/__tests__/xpack_info.js b/x-pack/plugins/xpack_main/server/routes/api/v1/__tests__/xpack_info.js index 9e095a12dad78..178564e4578fb 100644 --- a/x-pack/plugins/xpack_main/server/routes/api/v1/__tests__/xpack_info.js +++ b/x-pack/plugins/xpack_main/server/routes/api/v1/__tests__/xpack_info.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { xpackInfoRoute } from '../xpack_info'; diff --git a/x-pack/plugins/xpack_main/server/routes/api/v1/telemetry/__tests__/telemetry.js b/x-pack/plugins/xpack_main/server/routes/api/v1/telemetry/__tests__/telemetry.js index a16d9187e2ca4..1d657df734fe6 100644 --- a/x-pack/plugins/xpack_main/server/routes/api/v1/telemetry/__tests__/telemetry.js +++ b/x-pack/plugins/xpack_main/server/routes/api/v1/telemetry/__tests__/telemetry.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import sinon from 'sinon'; import { getTelemetry } from '../telemetry'; diff --git a/x-pack/server/lib/__tests__/key_case_converter.js b/x-pack/server/lib/__tests__/key_case_converter.js index 78a627ffc8553..b5f4515844d15 100644 --- a/x-pack/server/lib/__tests__/key_case_converter.js +++ b/x-pack/server/lib/__tests__/key_case_converter.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { convertKeysToSnakeCaseDeep, convertKeysToCamelCaseDeep } from '../key_case_converter'; describe('key_case_converter', () => { diff --git a/x-pack/server/lib/__tests__/kibana_state.js b/x-pack/server/lib/__tests__/kibana_state.js index 3b0b8f8a2ea2d..f0576701c980a 100644 --- a/x-pack/server/lib/__tests__/kibana_state.js +++ b/x-pack/server/lib/__tests__/kibana_state.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import rison from 'rison-node'; import { parseKibanaState } from '../parse_kibana_state'; diff --git a/x-pack/server/lib/__tests__/mirror_plugin_status.js b/x-pack/server/lib/__tests__/mirror_plugin_status.js index 4383932141543..745c69b7a3d70 100644 --- a/x-pack/server/lib/__tests__/mirror_plugin_status.js +++ b/x-pack/server/lib/__tests__/mirror_plugin_status.js @@ -5,7 +5,7 @@ */ import EventEmitter from 'events'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { mirrorPluginStatus } from '../mirror_plugin_status'; describe('mirror_plugin_status', () => { diff --git a/x-pack/server/lib/create_router/error_wrappers/__tests__/wrap_custom_error.js b/x-pack/server/lib/create_router/error_wrappers/__tests__/wrap_custom_error.js index 443744ccb0cc8..f9c102be7a1ff 100644 --- a/x-pack/server/lib/create_router/error_wrappers/__tests__/wrap_custom_error.js +++ b/x-pack/server/lib/create_router/error_wrappers/__tests__/wrap_custom_error.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { wrapCustomError } from '../wrap_custom_error'; describe('wrap_custom_error', () => { diff --git a/x-pack/server/lib/create_router/error_wrappers/__tests__/wrap_es_error.js b/x-pack/server/lib/create_router/error_wrappers/__tests__/wrap_es_error.js index 394c182140000..467cc4fcdae1f 100644 --- a/x-pack/server/lib/create_router/error_wrappers/__tests__/wrap_es_error.js +++ b/x-pack/server/lib/create_router/error_wrappers/__tests__/wrap_es_error.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { wrapEsError } from '../wrap_es_error'; describe('wrap_es_error', () => { diff --git a/x-pack/server/lib/create_router/error_wrappers/__tests__/wrap_unknown_error.js b/x-pack/server/lib/create_router/error_wrappers/__tests__/wrap_unknown_error.js index 6d6a336417bef..85e0b2b3033ad 100644 --- a/x-pack/server/lib/create_router/error_wrappers/__tests__/wrap_unknown_error.js +++ b/x-pack/server/lib/create_router/error_wrappers/__tests__/wrap_unknown_error.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { wrapUnknownError } from '../wrap_unknown_error'; describe('wrap_unknown_error', () => { diff --git a/x-pack/server/lib/create_router/is_es_error_factory/__tests__/is_es_error_factory.js b/x-pack/server/lib/create_router/is_es_error_factory/__tests__/is_es_error_factory.js index d50ff9480d3e4..76fdf7b36c3d0 100644 --- a/x-pack/server/lib/create_router/is_es_error_factory/__tests__/is_es_error_factory.js +++ b/x-pack/server/lib/create_router/is_es_error_factory/__tests__/is_es_error_factory.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { isEsErrorFactory } from '../is_es_error_factory'; import { set } from 'lodash'; diff --git a/x-pack/server/lib/create_router/license_pre_routing_factory/__tests__/license_pre_routing_factory.js b/x-pack/server/lib/create_router/license_pre_routing_factory/__tests__/license_pre_routing_factory.js index 5192181d37767..cbb0ca1d6076a 100644 --- a/x-pack/server/lib/create_router/license_pre_routing_factory/__tests__/license_pre_routing_factory.js +++ b/x-pack/server/lib/create_router/license_pre_routing_factory/__tests__/license_pre_routing_factory.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { licensePreRoutingFactory } from '../license_pre_routing_factory'; import { LICENSE_STATUS_INVALID, LICENSE_STATUS_VALID } from '../../../../../common/constants'; diff --git a/x-pack/tasks/build.js b/x-pack/tasks/build.js index 82ccc9c75bd6f..59033bb40c7d3 100644 --- a/x-pack/tasks/build.js +++ b/x-pack/tasks/build.js @@ -34,7 +34,7 @@ export default (gulp, { buildTarget }) => { // As result of it, we need to move the transpiled js files for the correct folder // and in the end deleting the generated outDir from the intermediateBuildDirectory. // - //# TODO: This might be able to go away with the upgrade to babel 7 + //# TODO: This might be able to go away as soon as we upgrade the x-pack build to use babel7 await moveFiles( gulp, resolve(buildRoot, 'x-pack/build/plugin/kibana/x-pack/**/!(*.test).js'), diff --git a/x-pack/test/api_integration/apis/beats/assign_tags_to_beats.js b/x-pack/test/api_integration/apis/beats/assign_tags_to_beats.js index a1268eea645eb..e407bc75bdc39 100644 --- a/x-pack/test/api_integration/apis/beats/assign_tags_to_beats.js +++ b/x-pack/test/api_integration/apis/beats/assign_tags_to_beats.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { ES_INDEX_NAME } from './constants'; export default function ({ getService }) { @@ -28,7 +28,7 @@ export default function ({ getService }) { }) .expect(200); - expect(apiResponse.assignments).to.eql([{ status: 200, result: 'updated' }]); + expect(apiResponse.results).to.eql([{ success: true, result: { message: 'updated' } }]); const esResponse = await es.get({ index: ES_INDEX_NAME, @@ -63,7 +63,7 @@ export default function ({ getService }) { }) .expect(200); - expect(apiResponse.assignments).to.eql([{ status: 200, result: 'updated' }]); + expect(apiResponse.results).to.eql([{ success: true, result: { message: 'updated' } }]); // After adding the existing tag esResponse = await es.get({ @@ -87,9 +87,9 @@ export default function ({ getService }) { }) .expect(200); - expect(apiResponse.assignments).to.eql([ - { status: 200, result: 'updated' }, - { status: 200, result: 'updated' }, + expect(apiResponse.results).to.eql([ + { success: true, result: { message: 'updated' } }, + { success: true, result: { message: 'updated' } }, ]); let esResponse; @@ -126,9 +126,9 @@ export default function ({ getService }) { }) .expect(200); - expect(apiResponse.assignments).to.eql([ - { status: 200, result: 'updated' }, - { status: 200, result: 'updated' }, + expect(apiResponse.results).to.eql([ + { success: true, result: { message: 'updated' } }, + { success: true, result: { message: 'updated' } }, ]); const esResponse = await es.get({ @@ -152,9 +152,9 @@ export default function ({ getService }) { }) .expect(200); - expect(apiResponse.assignments).to.eql([ - { status: 200, result: 'updated' }, - { status: 200, result: 'updated' }, + expect(apiResponse.results).to.eql([ + { success: true, result: { message: 'updated' } }, + { success: true, result: { message: 'updated' } }, ]); let esResponse; @@ -190,8 +190,8 @@ export default function ({ getService }) { }) .expect(200); - expect(apiResponse.assignments).to.eql([ - { status: 404, result: `Beat ${nonExistentBeatId} not found` }, + expect(apiResponse.results).to.eql([ + { success: false, error: { code: 404, message: `Beat ${nonExistentBeatId} not found` } }, ]); }); @@ -206,8 +206,8 @@ export default function ({ getService }) { }) .expect(200); - expect(apiResponse.assignments).to.eql([ - { status: 404, result: `Tag ${nonExistentTag} not found` }, + expect(apiResponse.results).to.eql([ + { success: false, error: { code: 404, message: `Tag ${nonExistentTag} not found` } }, ]); const esResponse = await es.get({ @@ -231,8 +231,14 @@ export default function ({ getService }) { }) .expect(200); - expect(apiResponse.assignments).to.eql([ - { status: 404, result: `Beat ${nonExistentBeatId} and tag ${nonExistentTag} not found` }, + expect(apiResponse.results).to.eql([ + { + success: false, + error: { + code: 404, + message: `Beat ${nonExistentBeatId} and tag ${nonExistentTag} not found`, + }, + }, ]); const esResponse = await es.get({ diff --git a/x-pack/test/api_integration/apis/beats/create_enrollment_tokens.js b/x-pack/test/api_integration/apis/beats/create_enrollment_tokens.js index ba3d6792367ee..6cd4fdf22bb41 100644 --- a/x-pack/test/api_integration/apis/beats/create_enrollment_tokens.js +++ b/x-pack/test/api_integration/apis/beats/create_enrollment_tokens.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import moment from 'moment'; import { ES_INDEX_NAME } from './constants'; @@ -20,7 +20,7 @@ export default function ({ getService }) { .send() .expect(200); - const tokensFromApi = apiResponse.tokens; + const tokensFromApi = apiResponse.results.map(r => r.item); const esResponse = await es.search({ index: ES_INDEX_NAME, @@ -44,7 +44,7 @@ export default function ({ getService }) { }) .expect(200); - const tokensFromApi = apiResponse.tokens; + const tokensFromApi = apiResponse.results.map(r => r.item); const esResponse = await es.search({ index: ES_INDEX_NAME, diff --git a/x-pack/test/api_integration/apis/beats/enroll_beat.js b/x-pack/test/api_integration/apis/beats/enroll_beat.js index 72933f2950225..b94af7215edf7 100644 --- a/x-pack/test/api_integration/apis/beats/enroll_beat.js +++ b/x-pack/test/api_integration/apis/beats/enroll_beat.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import moment from 'moment'; import { ES_INDEX_NAME } from './constants'; @@ -58,7 +58,7 @@ export default function ({ getService }) { .set('kbn-xsrf', 'xxx') .set('kbn-beats-enrollment-token', validEnrollmentToken) .send(beat) - .expect(201); + .expect(200); const esResponse = await es.get({ index: ES_INDEX_NAME, @@ -75,9 +75,9 @@ export default function ({ getService }) { .set('kbn-xsrf', 'xxx') .set('kbn-beats-enrollment-token', validEnrollmentToken) .send(beat) - .expect(201); + .expect(200); - const accessTokenFromApi = apiResponse.access_token; + const accessTokenFromApi = apiResponse.item; const esResponse = await es.get({ index: ES_INDEX_NAME, @@ -98,7 +98,10 @@ export default function ({ getService }) { .send(beat) .expect(400); - expect(apiResponse).to.eql({ message: 'Invalid enrollment token' }); + expect(apiResponse).to.eql({ + success: false, + error: { code: 400, message: 'Invalid enrollment token' }, + }); }); it('should reject an expired enrollment token', async () => { @@ -128,7 +131,10 @@ export default function ({ getService }) { .send(beat) .expect(400); - expect(apiResponse).to.eql({ message: 'Expired enrollment token' }); + expect(apiResponse).to.eql({ + success: false, + error: { code: 400, message: 'Expired enrollment token' }, + }); }); it('should delete the given enrollment token so it may not be reused', async () => { @@ -137,7 +143,7 @@ export default function ({ getService }) { .set('kbn-xsrf', 'xxx') .set('kbn-beats-enrollment-token', validEnrollmentToken) .send(beat) - .expect(201); + .expect(200); const esResponse = await es.get({ index: ES_INDEX_NAME, @@ -154,7 +160,7 @@ export default function ({ getService }) { .set('kbn-xsrf', 'xxx') .set('kbn-beats-enrollment-token', validEnrollmentToken) .send(beat) - .expect(201); + .expect(200); await es.index({ index: ES_INDEX_NAME, @@ -175,7 +181,7 @@ export default function ({ getService }) { .set('kbn-xsrf', 'xxx') .set('kbn-beats-enrollment-token', validEnrollmentToken) .send(beat) - .expect(201); + .expect(200); }); }); } diff --git a/x-pack/test/api_integration/apis/beats/get_beat.js b/x-pack/test/api_integration/apis/beats/get_beat.js index bb300f5c3e230..07cc056e3af99 100644 --- a/x-pack/test/api_integration/apis/beats/get_beat.js +++ b/x-pack/test/api_integration/apis/beats/get_beat.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { ES_INDEX_NAME } from './constants'; export default function ({ getService }) { @@ -47,7 +47,7 @@ export default function ({ getService }) { ) .expect(200); - const configurationBlocks = apiResponse.configuration_blocks; + const configurationBlocks = apiResponse.list; expect(configurationBlocks).to.be.an(Array); expect(configurationBlocks.length).to.be(0); @@ -64,7 +64,7 @@ export default function ({ getService }) { ) .expect(200); - const configurationBlocks = apiResponse.configuration_blocks; + const configurationBlocks = apiResponse.list; expect(configurationBlocks).to.be.an(Array); expect(configurationBlocks.length).to.be(3); diff --git a/x-pack/test/api_integration/apis/beats/index.js b/x-pack/test/api_integration/apis/beats/index.js index a6552a383dbd8..da47fdbf77fc7 100644 --- a/x-pack/test/api_integration/apis/beats/index.js +++ b/x-pack/test/api_integration/apis/beats/index.js @@ -10,10 +10,11 @@ export default function ({ getService, loadTestFile }) { const es = getService('es'); describe('beats', () => { - const cleanup = () => es.indices.delete({ - index: ES_INDEX_NAME, - ignore: [404] - }); + const cleanup = () => + es.indices.delete({ + index: ES_INDEX_NAME, + ignore: [404], + }); beforeEach(cleanup); diff --git a/x-pack/test/api_integration/apis/beats/list_beats.js b/x-pack/test/api_integration/apis/beats/list_beats.js index b78939b30b62f..76296f352fb14 100644 --- a/x-pack/test/api_integration/apis/beats/list_beats.js +++ b/x-pack/test/api_integration/apis/beats/list_beats.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); @@ -19,7 +19,7 @@ export default function ({ getService }) { it('should return all beats', async () => { const { body: apiResponse } = await supertest.get('/api/beats/agents').expect(200); - const beatsFromApi = apiResponse.beats; + const beatsFromApi = apiResponse.list; expect(beatsFromApi.length).to.be(4); expect(beatsFromApi.filter(beat => beat.hasOwnProperty('verified_on')).length).to.be(1); @@ -29,7 +29,7 @@ export default function ({ getService }) { it('should not return access tokens', async () => { const { body: apiResponse } = await supertest.get('/api/beats/agents').expect(200); - const beatsFromApi = apiResponse.beats; + const beatsFromApi = apiResponse.list; expect(beatsFromApi.length).to.be(4); expect(beatsFromApi.filter(beat => beat.hasOwnProperty('access_token')).length).to.be(0); diff --git a/x-pack/test/api_integration/apis/beats/remove_tags_from_beats.js b/x-pack/test/api_integration/apis/beats/remove_tags_from_beats.js index 1bc0664d6f80e..3e7c6ce8f48ff 100644 --- a/x-pack/test/api_integration/apis/beats/remove_tags_from_beats.js +++ b/x-pack/test/api_integration/apis/beats/remove_tags_from_beats.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { ES_INDEX_NAME } from './constants'; export default function ({ getService }) { @@ -28,7 +28,7 @@ export default function ({ getService }) { }) .expect(200); - expect(apiResponse.removals).to.eql([{ status: 200, result: 'updated' }]); + expect(apiResponse.results).to.eql([{ success: true, result: { message: 'updated' } }]); const esResponse = await es.get({ index: ES_INDEX_NAME, @@ -48,9 +48,9 @@ export default function ({ getService }) { }) .expect(200); - expect(apiResponse.removals).to.eql([ - { status: 200, result: 'updated' }, - { status: 200, result: 'updated' }, + expect(apiResponse.results).to.eql([ + { success: true, result: { message: 'updated' } }, + { success: true, result: { message: 'updated' } }, ]); let esResponse; @@ -84,9 +84,9 @@ export default function ({ getService }) { }) .expect(200); - expect(apiResponse.removals).to.eql([ - { status: 200, result: 'updated' }, - { status: 200, result: 'updated' }, + expect(apiResponse.results).to.eql([ + { success: true, result: { message: 'updated' } }, + { success: true, result: { message: 'updated' } }, ]); const esResponse = await es.get({ @@ -107,9 +107,9 @@ export default function ({ getService }) { }) .expect(200); - expect(apiResponse.removals).to.eql([ - { status: 200, result: 'updated' }, - { status: 200, result: 'updated' }, + expect(apiResponse.results).to.eql([ + { success: true, result: { message: 'updated' } }, + { success: true, result: { message: 'updated' } }, ]); let esResponse; @@ -145,8 +145,8 @@ export default function ({ getService }) { }) .expect(200); - expect(apiResponse.removals).to.eql([ - { status: 404, result: `Beat ${nonExistentBeatId} not found` }, + expect(apiResponse.results).to.eql([ + { success: false, error: { code: 404, message: `Beat ${nonExistentBeatId} not found` } }, ]); }); @@ -161,8 +161,8 @@ export default function ({ getService }) { }) .expect(200); - expect(apiResponse.removals).to.eql([ - { status: 404, result: `Tag ${nonExistentTag} not found` }, + expect(apiResponse.results).to.eql([ + { success: false, error: { code: 404, message: `Tag ${nonExistentTag} not found` } }, ]); const esResponse = await es.get({ @@ -186,8 +186,14 @@ export default function ({ getService }) { }) .expect(200); - expect(apiResponse.removals).to.eql([ - { status: 404, result: `Beat ${nonExistentBeatId} and tag ${nonExistentTag} not found` }, + expect(apiResponse.results).to.eql([ + { + success: false, + error: { + code: 404, + message: `Beat ${nonExistentBeatId} and tag ${nonExistentTag} not found`, + }, + }, ]); const esResponse = await es.get({ diff --git a/x-pack/test/api_integration/apis/beats/set_config.js b/x-pack/test/api_integration/apis/beats/set_config.js index 2c023ecbbf0ae..a4d7d491d4778 100644 --- a/x-pack/test/api_integration/apis/beats/set_config.js +++ b/x-pack/test/api_integration/apis/beats/set_config.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { ES_INDEX_NAME } from './constants'; export default function ({ getService }) { @@ -31,7 +31,7 @@ export default function ({ getService }) { config: { elasticsearch: { hosts: ['localhost:9200'], username: 'foo' } }, }, ]) - .expect(201); + .expect(200); const esResponse = await es.get({ index: ES_INDEX_NAME, id: `tag:${tagId}`, diff --git a/x-pack/test/api_integration/apis/beats/set_tag.js b/x-pack/test/api_integration/apis/beats/set_tag.js index 445f939dd80cd..ee9a601b25096 100644 --- a/x-pack/test/api_integration/apis/beats/set_tag.js +++ b/x-pack/test/api_integration/apis/beats/set_tag.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { ES_INDEX_NAME } from './constants'; export default function ({ getService }) { diff --git a/x-pack/test/api_integration/apis/beats/update_beat.js b/x-pack/test/api_integration/apis/beats/update_beat.js index ba8ed8b9631f8..090668aff925c 100644 --- a/x-pack/test/api_integration/apis/beats/update_beat.js +++ b/x-pack/test/api_integration/apis/beats/update_beat.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { ES_INDEX_NAME } from './constants'; import moment from 'moment'; @@ -25,6 +25,7 @@ export default function ({ getService }) { 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.' + 'eyJjcmVhdGVkIjoiMjAxOC0wNi0zMFQwMzo0MjoxNS4yMzBaIiwiaWF0IjoxNTMwMzMwMTM1fQ.' + 'SSsX2Byyo1B1bGxV8C3G4QldhE5iH87EY_1r21-bwbI'; + const version = chance.integer({ min: 1, max: 10 }) + '.' + @@ -62,9 +63,14 @@ export default function ({ getService }) { await supertest .put(`/api/beats/agent/${beatId}`) .set('kbn-xsrf', 'xxx') - .set('kbn-beats-access-token', validEnrollmentToken) + .set( + 'kbn-beats-access-token', + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.' + + 'eyJjcmVhdGVkIjoiMjAxOC0wNi0zMFQwMzo0MjoxNS4yMzBaIiwiaWF0IjoxNTMwMzMwMTM1fQ.' + + 'SSsX2Byyo1B1bGxV8C3G4QldhE5iH87EY_1r21-bwbI' + ) .send(beat) - .expect(204); + .expect(200); const beatInEs = await es.get({ index: ES_INDEX_NAME, @@ -88,7 +94,7 @@ export default function ({ getService }) { .send(beat) .expect(401); - expect(body.message).to.be('Invalid access token'); + expect(body.error.message).to.be('Invalid access token'); const beatInEs = await es.get({ index: ES_INDEX_NAME, @@ -111,7 +117,7 @@ export default function ({ getService }) { .send(beat) .expect(404); - expect(body.message).to.be('Beat not found'); + expect(body.error.message).to.be('Beat not found'); }); }); } diff --git a/x-pack/test/api_integration/apis/es/has_privileges.js b/x-pack/test/api_integration/apis/es/has_privileges.js index 21283d483ca37..5cbbefd8f2f37 100644 --- a/x-pack/test/api_integration/apis/es/has_privileges.js +++ b/x-pack/test/api_integration/apis/es/has_privileges.js @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; const application = 'has_privileges_test'; diff --git a/x-pack/test/api_integration/apis/es/post_privileges.js b/x-pack/test/api_integration/apis/es/post_privileges.js index bf2266575d3b1..4b1695487f832 100644 --- a/x-pack/test/api_integration/apis/es/post_privileges.js +++ b/x-pack/test/api_integration/apis/es/post_privileges.js @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { diff --git a/x-pack/test/api_integration/apis/infra/log_entries.ts b/x-pack/test/api_integration/apis/infra/log_entries.ts index c2e37e5e578d5..79a39163e235d 100644 --- a/x-pack/test/api_integration/apis/infra/log_entries.ts +++ b/x-pack/test/api_integration/apis/infra/log_entries.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import expect from '@kbn/expect'; import { ascending, pairs } from 'd3-array'; -import expect from 'expect.js'; import gql from 'graphql-tag'; import { InfraTimeKey } from '../../../../plugins/infra/public/graphql/types'; diff --git a/x-pack/test/api_integration/apis/infra/log_item.ts b/x-pack/test/api_integration/apis/infra/log_item.ts index bfdde32fa57ae..798f12477a811 100644 --- a/x-pack/test/api_integration/apis/infra/log_item.ts +++ b/x-pack/test/api_integration/apis/infra/log_item.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { flyoutItemQuery } from '../../../../plugins/infra/public/containers/logs/flyout_item.gql_query'; import { FlyoutItemQuery } from '../../../../plugins/infra/public/graphql/types'; import { KbnTestProvider } from './types'; diff --git a/x-pack/test/api_integration/apis/infra/log_summary.ts b/x-pack/test/api_integration/apis/infra/log_summary.ts index 7530ec3030794..2682987f9c0ba 100644 --- a/x-pack/test/api_integration/apis/infra/log_summary.ts +++ b/x-pack/test/api_integration/apis/infra/log_summary.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import expect from '@kbn/expect'; import { pairs } from 'd3-array'; -import expect from 'expect.js'; import gql from 'graphql-tag'; import { KbnTestProvider } from './types'; diff --git a/x-pack/test/api_integration/apis/infra/logs_without_millis.ts b/x-pack/test/api_integration/apis/infra/logs_without_millis.ts index 94301c7f42789..5e67b82508e92 100644 --- a/x-pack/test/api_integration/apis/infra/logs_without_millis.ts +++ b/x-pack/test/api_integration/apis/infra/logs_without_millis.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import expect from '@kbn/expect'; import { ascending, pairs } from 'd3-array'; -import expect from 'expect.js'; import gql from 'graphql-tag'; import { InfraTimeKey } from '../../../../plugins/infra/public/graphql/types'; diff --git a/x-pack/test/api_integration/apis/infra/metadata.ts b/x-pack/test/api_integration/apis/infra/metadata.ts index 749c31fe2b7a3..76cc2da7b7ad3 100644 --- a/x-pack/test/api_integration/apis/infra/metadata.ts +++ b/x-pack/test/api_integration/apis/infra/metadata.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { metadataQuery } from '../../../../plugins/infra/public/containers/metadata/metadata.gql_query'; import { MetadataQuery } from '../../../../plugins/infra/public/graphql/types'; diff --git a/x-pack/test/api_integration/apis/infra/metrics.ts b/x-pack/test/api_integration/apis/infra/metrics.ts index 52d593789e8e2..6cf3723063d5b 100644 --- a/x-pack/test/api_integration/apis/infra/metrics.ts +++ b/x-pack/test/api_integration/apis/infra/metrics.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { first, last } from 'lodash'; import { metricsQuery } from '../../../../plugins/infra/public/containers/metrics/metrics.gql_query'; diff --git a/x-pack/test/api_integration/apis/infra/sources.ts b/x-pack/test/api_integration/apis/infra/sources.ts index d0002e73d9875..952c1a0dd3baa 100644 --- a/x-pack/test/api_integration/apis/infra/sources.ts +++ b/x-pack/test/api_integration/apis/infra/sources.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import gql from 'graphql-tag'; import { sourceQuery } from '../../../../plugins/infra/public/containers/with_source/query_source.gql_query'; diff --git a/x-pack/test/api_integration/apis/infra/waffle.ts b/x-pack/test/api_integration/apis/infra/waffle.ts index 023bdd4f7bc7a..f7aafc1352029 100644 --- a/x-pack/test/api_integration/apis/infra/waffle.ts +++ b/x-pack/test/api_integration/apis/infra/waffle.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { first, last } from 'lodash'; import { waffleNodesQuery } from '../../../../plugins/infra/public/containers/waffle/waffle_nodes.gql_query'; diff --git a/x-pack/test/api_integration/apis/kibana/kql_telemetry/kql_telemetry.js b/x-pack/test/api_integration/apis/kibana/kql_telemetry/kql_telemetry.js index ab47576cdc239..43f00b920420d 100644 --- a/x-pack/test/api_integration/apis/kibana/kql_telemetry/kql_telemetry.js +++ b/x-pack/test/api_integration/apis/kibana/kql_telemetry/kql_telemetry.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertestNoAuth = getService('supertestWithoutAuth'); diff --git a/x-pack/test/api_integration/apis/kibana/stats/stats.js b/x-pack/test/api_integration/apis/kibana/stats/stats.js index 8672f64cdf2bd..48c720bb57ba9 100644 --- a/x-pack/test/api_integration/apis/kibana/stats/stats.js +++ b/x-pack/test/api_integration/apis/kibana/stats/stats.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertestNoAuth = getService('supertestWithoutAuth'); diff --git a/x-pack/test/api_integration/apis/logstash/cluster/load.js b/x-pack/test/api_integration/apis/logstash/cluster/load.js index 40ff7adcff987..a20c524f0a8f8 100644 --- a/x-pack/test/api_integration/apis/logstash/cluster/load.js +++ b/x-pack/test/api_integration/apis/logstash/cluster/load.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); diff --git a/x-pack/test/api_integration/apis/logstash/pipeline/load.js b/x-pack/test/api_integration/apis/logstash/pipeline/load.js index 8e5c74154d12c..c7b27348a0a11 100644 --- a/x-pack/test/api_integration/apis/logstash/pipeline/load.js +++ b/x-pack/test/api_integration/apis/logstash/pipeline/load.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import pipeline from './fixtures/load'; export default function ({ getService }) { diff --git a/x-pack/test/api_integration/apis/logstash/pipeline/save.js b/x-pack/test/api_integration/apis/logstash/pipeline/save.js index cfcbdf4633d45..73e710c8f9067 100644 --- a/x-pack/test/api_integration/apis/logstash/pipeline/save.js +++ b/x-pack/test/api_integration/apis/logstash/pipeline/save.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); diff --git a/x-pack/test/api_integration/apis/logstash/pipelines/list.js b/x-pack/test/api_integration/apis/logstash/pipelines/list.js index 5c97f5fc933f1..54b2ed0a2b26a 100644 --- a/x-pack/test/api_integration/apis/logstash/pipelines/list.js +++ b/x-pack/test/api_integration/apis/logstash/pipelines/list.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import pipelineList from './fixtures/list'; export default function ({ getService }) { diff --git a/x-pack/test/api_integration/apis/management/cross_cluster_replication/auto_follow_pattern.js b/x-pack/test/api_integration/apis/management/cross_cluster_replication/auto_follow_pattern.js index 8274b3b003ff1..82422e13cd19d 100644 --- a/x-pack/test/api_integration/apis/management/cross_cluster_replication/auto_follow_pattern.js +++ b/x-pack/test/api_integration/apis/management/cross_cluster_replication/auto_follow_pattern.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { API_BASE_PATH } from './constants'; diff --git a/x-pack/test/api_integration/apis/management/cross_cluster_replication/follower_indices.js b/x-pack/test/api_integration/apis/management/cross_cluster_replication/follower_indices.js index aa5269d80f593..f93ab9f4629c3 100644 --- a/x-pack/test/api_integration/apis/management/cross_cluster_replication/follower_indices.js +++ b/x-pack/test/api_integration/apis/management/cross_cluster_replication/follower_indices.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { FOLLOWER_INDEX_ADVANCED_SETTINGS } from '../../../../../plugins/cross_cluster_replication/common/constants'; import { API_BASE_PATH } from './constants'; diff --git a/x-pack/test/api_integration/apis/management/cross_cluster_replication/index.js b/x-pack/test/api_integration/apis/management/cross_cluster_replication/index.js index a033a03d613f9..e1cc6d7cf2c14 100644 --- a/x-pack/test/api_integration/apis/management/cross_cluster_replication/index.js +++ b/x-pack/test/api_integration/apis/management/cross_cluster_replication/index.js @@ -5,7 +5,7 @@ */ export default function ({ loadTestFile }) { - describe('cross cluster replication', () => { + describe('cross-cluster replication', () => { loadTestFile(require.resolve('./auto_follow_pattern')); loadTestFile(require.resolve('./follower_indices')); }); diff --git a/x-pack/test/api_integration/apis/management/remote_clusters/remote_clusters.js b/x-pack/test/api_integration/apis/management/remote_clusters/remote_clusters.js index 45ded44276661..6e4946c465cb0 100644 --- a/x-pack/test/api_integration/apis/management/remote_clusters/remote_clusters.js +++ b/x-pack/test/api_integration/apis/management/remote_clusters/remote_clusters.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { API_BASE_PATH, NODE_SEED } from './constants'; export default function ({ getService }) { diff --git a/x-pack/test/api_integration/apis/management/rollup/index.js b/x-pack/test/api_integration/apis/management/rollup/index.js index ee0641ce4b4bf..45d84ddc6ad5d 100644 --- a/x-pack/test/api_integration/apis/management/rollup/index.js +++ b/x-pack/test/api_integration/apis/management/rollup/index.js @@ -5,7 +5,7 @@ */ export default function ({ loadTestFile }) { - // FLAKY: https://github.com/elastic/kibana/issues/33217 + // FLAKY: https://github.com/elastic/kibana/issues/33282 describe.skip('rollup', () => { loadTestFile(require.resolve('./rollup')); loadTestFile(require.resolve('./index_patterns_extensions')); diff --git a/x-pack/test/api_integration/apis/management/rollup/index_patterns_extensions.js b/x-pack/test/api_integration/apis/management/rollup/index_patterns_extensions.js index 0237a5821380c..25bc503682bc7 100644 --- a/x-pack/test/api_integration/apis/management/rollup/index_patterns_extensions.js +++ b/x-pack/test/api_integration/apis/management/rollup/index_patterns_extensions.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import querystring from 'querystring'; import { registerHelpers } from './rollup.test_helpers'; diff --git a/x-pack/test/api_integration/apis/management/rollup/rollup.js b/x-pack/test/api_integration/apis/management/rollup/rollup.js index f00ea63a60db8..fecaf548709bd 100644 --- a/x-pack/test/api_integration/apis/management/rollup/rollup.js +++ b/x-pack/test/api_integration/apis/management/rollup/rollup.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { API_BASE_PATH, ROLLUP_INDEX_NAME } from './constants'; import { registerHelpers } from './rollup.test_helpers'; @@ -16,6 +16,7 @@ export default function ({ getService }) { const { createIndexWithMappings, getJobPayload, + loadJobs, createJob, deleteJob, startJob, @@ -77,9 +78,7 @@ export default function ({ getService }) { describe('crud', () => { describe('list', () => { it('should return an empty array when there are no jobs', async () => { - const { body } = await supertest - .get(`${API_BASE_PATH}/jobs`) - .expect(200); + const { body } = await loadJobs().expect(200); expect(body).to.eql({ jobs: [] }); }); @@ -117,7 +116,7 @@ export default function ({ getService }) { const payload = getJobPayload(indexName); await createJob(payload); - const { body: { jobs } } = await supertest.get(`${API_BASE_PATH}/jobs`); + const { body: { jobs } } = await loadJobs(); const job = jobs.find(job => job.config.id === payload.job.id); expect(job).not.be(undefined); @@ -193,7 +192,8 @@ export default function ({ getService }) { await createJob(payload); }); - it('should delete a job that was created', async () => { + it('should delete a job that has been stopped', async () => { + await stopJob(jobId); const { body } = await deleteJob(jobId).expect(200); expect(body).to.eql({ success: true }); }); @@ -215,7 +215,7 @@ export default function ({ getService }) { const payload = getJobPayload(indexName); await createJob(payload); - const { body: { jobs } } = await supertest.get(`${API_BASE_PATH}/jobs`); + const { body: { jobs } } = await loadJobs(); job = jobs.find(job => job.config.id === payload.job.id); }); @@ -228,7 +228,7 @@ export default function ({ getService }) { // Fetch the job to make sure it has been started const jobId = job.config.id; - const { body: { jobs } } = await supertest.get(`${API_BASE_PATH}/jobs`); + const { body: { jobs } } = await loadJobs(); job = jobs.find(job => job.config.id === jobId); expect(job.status.job_state).to.eql('started'); }); @@ -255,7 +255,7 @@ export default function ({ getService }) { expect(body).to.eql({ success: true }); // Fetch the job to make sure it has been stopped - const { body: { jobs } } = await supertest.get(`${API_BASE_PATH}/jobs`); + const { body: { jobs } } = await loadJobs(); const job = jobs.find(job => job.config.id === jobId); expect(job.status.job_state).to.eql('stopped'); }); diff --git a/x-pack/test/api_integration/apis/management/rollup/rollup.test_helpers.js b/x-pack/test/api_integration/apis/management/rollup/rollup.test_helpers.js index cee70461a7bd0..3397bef1dbdaa 100644 --- a/x-pack/test/api_integration/apis/management/rollup/rollup.test_helpers.js +++ b/x-pack/test/api_integration/apis/management/rollup/rollup.test_helpers.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { initElasticsearchIndicesHelpers, getRandomString, wait } from './lib'; +import { initElasticsearchIndicesHelpers, getRandomString } from './lib'; import { API_BASE_PATH, ROLLUP_INDEX_NAME, INDEX_TO_ROLLUP_MAPPINGS } from './constants'; const jobsCreated = []; @@ -81,63 +81,21 @@ export const registerHelpers = ({ supertest, es }) => { const jobIds = Array.isArray(ids) ? ids : [ids]; return supertest - .post(`${API_BASE_PATH}/stop`) + .post(`${API_BASE_PATH}/stop?waitForCompletion=true`) .set('kbn-xsrf', 'xxx') .send({ jobIds }); }; const loadJobs = () => supertest.get(`${API_BASE_PATH}/jobs`); - const waitForJobsToStop = (attempt = 0) => ( + const stopAllJobs = () => ( loadJobs() .then(async ({ body: { jobs } }) => { - const jobBeingStopped = jobs.filter(job => job.status.job_state !== 'stopped' && job.status.job_state !== 'started'); + const jobIds = jobs.map(job => job.config.id); - if (!jobBeingStopped.length) { - return; - } - - if (attempt < 3 && jobBeingStopped.length) { - await wait(500); - return waitForJobsToStop(++attempt); - } + await stopJob(jobIds); - throw new Error('Error while waiting for Rollup Jobs to stop'); - })); - - const stopAllJobStarted = (jobIds = jobsStarted, attempt = 0) => ( - stopJob(jobIds) - .then(waitForJobsToStop) - .then(loadJobs) - .then(({ body: { jobs } }) => { - // We make sure that there are no more jobs started - // as trying to delete a job that is started will throw an exception - const jobsStillStarted = jobs.filter(job => job.status.job_state === 'started').map(job => job.config.id); - - if (jobsStillStarted.length && attempt < 3) { - return stopAllJobStarted(jobsStillStarted, ++attempt); - } else if(jobsStillStarted.length) { - throw new Error('Error trying to stop jobs started'); - } - }) - ); - - const deleteJobsCreated = (ids = jobsCreated, attempt = 0) => ( - deleteJob(ids) - .then((response) => { - if (response.status !== 200 && response.status !== 404) { - throw response; - } - }) - .then(loadJobs) - .then(({ body: { jobs } }) => { - if (jobs.length && attempt < 3) { - // There are still some jobs left to delete. - // Call recursively until all rollup jobs are removed. - return deleteJobsCreated(jobs.map(job => job.config.id), ++attempt); - } else if (jobs.length) { - throw new Error('Error trying to delete Jobs created'); - } + return jobIds; }) ); @@ -155,7 +113,7 @@ export const registerHelpers = ({ supertest, es }) => { const cleanUp = () => ( Promise.all([ deleteAllIndices(), - stopAllJobStarted().then(deleteJobsCreated), + stopAllJobs().then(deleteJob), deleteIndicesGeneratedByJobs(), ]).catch(err => { console.log('ERROR cleaning up!'); @@ -166,6 +124,7 @@ export const registerHelpers = ({ supertest, es }) => { return { createIndexWithMappings, getJobPayload, + loadJobs, createJob, deleteJob, startJob, diff --git a/x-pack/test/api_integration/apis/management/rollup/rollup_search.js b/x-pack/test/api_integration/apis/management/rollup/rollup_search.js index 4455ae8db925e..2a38cd563f312 100644 --- a/x-pack/test/api_integration/apis/management/rollup/rollup_search.js +++ b/x-pack/test/api_integration/apis/management/rollup/rollup_search.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { registerHelpers } from './rollup.test_helpers'; import { API_BASE_PATH } from './constants'; diff --git a/x-pack/test/api_integration/apis/maps/migrations.js b/x-pack/test/api_integration/apis/maps/migrations.js index 74fdc46c80b09..0c1193660a1d1 100644 --- a/x-pack/test/api_integration/apis/maps/migrations.js +++ b/x-pack/test/api_integration/apis/maps/migrations.js @@ -5,7 +5,7 @@ */ /* eslint max-len: 0 */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); diff --git a/x-pack/test/api_integration/apis/monitoring/apm/instance.js b/x-pack/test/api_integration/apis/monitoring/apm/instance.js index f66c64f1fc8e2..b01bf6fdbd066 100644 --- a/x-pack/test/api_integration/apis/monitoring/apm/instance.js +++ b/x-pack/test/api_integration/apis/monitoring/apm/instance.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import apmInstanceFixture from './fixtures/instance'; export default function ({ getService }) { diff --git a/x-pack/test/api_integration/apis/monitoring/apm/instances.js b/x-pack/test/api_integration/apis/monitoring/apm/instances.js index 4ad9a666ab5d1..46abe97c1ea06 100644 --- a/x-pack/test/api_integration/apis/monitoring/apm/instances.js +++ b/x-pack/test/api_integration/apis/monitoring/apm/instances.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); diff --git a/x-pack/test/api_integration/apis/monitoring/apm/overview.js b/x-pack/test/api_integration/apis/monitoring/apm/overview.js index 30a5ae8198b2f..bcdb773837051 100644 --- a/x-pack/test/api_integration/apis/monitoring/apm/overview.js +++ b/x-pack/test/api_integration/apis/monitoring/apm/overview.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import apmClusterFixture from './fixtures/cluster'; export default function ({ getService }) { diff --git a/x-pack/test/api_integration/apis/monitoring/beats/detail.js b/x-pack/test/api_integration/apis/monitoring/beats/detail.js index 1af5277b653af..076b1083d9fad 100644 --- a/x-pack/test/api_integration/apis/monitoring/beats/detail.js +++ b/x-pack/test/api_integration/apis/monitoring/beats/detail.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import beatDetailFixture from './fixtures/detail'; export default function ({ getService }) { diff --git a/x-pack/test/api_integration/apis/monitoring/beats/list.js b/x-pack/test/api_integration/apis/monitoring/beats/list.js index 0ec1ae3226c06..b47703cc6ab3d 100644 --- a/x-pack/test/api_integration/apis/monitoring/beats/list.js +++ b/x-pack/test/api_integration/apis/monitoring/beats/list.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); diff --git a/x-pack/test/api_integration/apis/monitoring/beats/overview.js b/x-pack/test/api_integration/apis/monitoring/beats/overview.js index 67978e948c0af..f1634fcfd7294 100644 --- a/x-pack/test/api_integration/apis/monitoring/beats/overview.js +++ b/x-pack/test/api_integration/apis/monitoring/beats/overview.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import beatsClusterFixture from './fixtures/cluster'; export default function ({ getService }) { diff --git a/x-pack/test/api_integration/apis/monitoring/cluster/list.js b/x-pack/test/api_integration/apis/monitoring/cluster/list.js index 2b920e4f2567c..cc130a340dd6a 100644 --- a/x-pack/test/api_integration/apis/monitoring/cluster/list.js +++ b/x-pack/test/api_integration/apis/monitoring/cluster/list.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import multiclusterFixture from './fixtures/multicluster'; export default function ({ getService }) { diff --git a/x-pack/test/api_integration/apis/monitoring/cluster/overview.js b/x-pack/test/api_integration/apis/monitoring/cluster/overview.js index 57be7082d6971..7b9f5087e78c1 100644 --- a/x-pack/test/api_integration/apis/monitoring/cluster/overview.js +++ b/x-pack/test/api_integration/apis/monitoring/cluster/overview.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import overviewFixture from './fixtures/overview'; export default function ({ getService }) { diff --git a/x-pack/test/api_integration/apis/monitoring/common/mappings_exist.js b/x-pack/test/api_integration/apis/monitoring/common/mappings_exist.js index a0f1e3bdb4af3..5dd647b97ac43 100644 --- a/x-pack/test/api_integration/apis/monitoring/common/mappings_exist.js +++ b/x-pack/test/api_integration/apis/monitoring/common/mappings_exist.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { get } from 'lodash'; import * as esMetrics from '../../../../../plugins/monitoring/server/lib/metrics/elasticsearch/metrics'; import * as kibanaMetrics from '../../../../../plugins/monitoring/server/lib/metrics/kibana/metrics'; diff --git a/x-pack/test/api_integration/apis/monitoring/elasticsearch/ccr.js b/x-pack/test/api_integration/apis/monitoring/elasticsearch/ccr.js index 249baa8c27915..8413217cbb781 100644 --- a/x-pack/test/api_integration/apis/monitoring/elasticsearch/ccr.js +++ b/x-pack/test/api_integration/apis/monitoring/elasticsearch/ccr.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ccrFixture from './fixtures/ccr'; export default function ({ getService }) { diff --git a/x-pack/test/api_integration/apis/monitoring/elasticsearch/ccr_shard.js b/x-pack/test/api_integration/apis/monitoring/elasticsearch/ccr_shard.js index e5a2418f215b9..776bee5a3eaf0 100644 --- a/x-pack/test/api_integration/apis/monitoring/elasticsearch/ccr_shard.js +++ b/x-pack/test/api_integration/apis/monitoring/elasticsearch/ccr_shard.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import ccrShardFixture from './fixtures/ccr_shard'; export default function ({ getService }) { diff --git a/x-pack/test/api_integration/apis/monitoring/elasticsearch/index_detail.js b/x-pack/test/api_integration/apis/monitoring/elasticsearch/index_detail.js index b9af7be8154aa..de21b697a7dc5 100644 --- a/x-pack/test/api_integration/apis/monitoring/elasticsearch/index_detail.js +++ b/x-pack/test/api_integration/apis/monitoring/elasticsearch/index_detail.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import indexDetailFixture from './fixtures/index_detail'; import indexDetailAdvancedFixture from './fixtures/index_detail_advanced'; diff --git a/x-pack/test/api_integration/apis/monitoring/elasticsearch/indices.js b/x-pack/test/api_integration/apis/monitoring/elasticsearch/indices.js index 9e4b072796590..085e0354ee3eb 100644 --- a/x-pack/test/api_integration/apis/monitoring/elasticsearch/indices.js +++ b/x-pack/test/api_integration/apis/monitoring/elasticsearch/indices.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import relocatingShardsFixture from './fixtures/indices_shards_relocating'; import relocationShardsAllFixture from './fixtures/indices_shards_relocating_all'; import indicesRedClusterFixture from './fixtures/indices_red_cluster'; diff --git a/x-pack/test/api_integration/apis/monitoring/elasticsearch/node_detail.js b/x-pack/test/api_integration/apis/monitoring/elasticsearch/node_detail.js index 35fc50c14d278..e23b5db8db225 100644 --- a/x-pack/test/api_integration/apis/monitoring/elasticsearch/node_detail.js +++ b/x-pack/test/api_integration/apis/monitoring/elasticsearch/node_detail.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import nodeDetailFixture from './fixtures/node_detail'; export default function ({ getService }) { diff --git a/x-pack/test/api_integration/apis/monitoring/elasticsearch/node_detail_advanced.js b/x-pack/test/api_integration/apis/monitoring/elasticsearch/node_detail_advanced.js index 14911878dfb6d..ec182a1d1b518 100644 --- a/x-pack/test/api_integration/apis/monitoring/elasticsearch/node_detail_advanced.js +++ b/x-pack/test/api_integration/apis/monitoring/elasticsearch/node_detail_advanced.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import nodeDetailFixture from './fixtures/node_detail_advanced'; export default function ({ getService }) { diff --git a/x-pack/test/api_integration/apis/monitoring/elasticsearch/nodes.js b/x-pack/test/api_integration/apis/monitoring/elasticsearch/nodes.js index f1a978a8bdab5..7d3bb23ebfbcf 100644 --- a/x-pack/test/api_integration/apis/monitoring/elasticsearch/nodes.js +++ b/x-pack/test/api_integration/apis/monitoring/elasticsearch/nodes.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import nodesListingFixtureGreen from './fixtures/nodes_listing_green'; import nodesListingFixtureRed from './fixtures/nodes_listing_red'; import nodesListingFixtureCgroup from './fixtures/nodes_listing_cgroup'; diff --git a/x-pack/test/api_integration/apis/monitoring/elasticsearch/overview.js b/x-pack/test/api_integration/apis/monitoring/elasticsearch/overview.js index 170fe101433b4..cc5ab081125ec 100644 --- a/x-pack/test/api_integration/apis/monitoring/elasticsearch/overview.js +++ b/x-pack/test/api_integration/apis/monitoring/elasticsearch/overview.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import overviewFixtureGreenPlatinum from './fixtures/overview_green_platinum'; import overviewFixtureRedPlatinum from './fixtures/overview_red_platinum'; diff --git a/x-pack/test/api_integration/apis/monitoring/elasticsearch_settings/check_cluster.js b/x-pack/test/api_integration/apis/monitoring/elasticsearch_settings/check_cluster.js index 0c17f08ff3368..521d201c9d1d7 100644 --- a/x-pack/test/api_integration/apis/monitoring/elasticsearch_settings/check_cluster.js +++ b/x-pack/test/api_integration/apis/monitoring/elasticsearch_settings/check_cluster.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); diff --git a/x-pack/test/api_integration/apis/monitoring/elasticsearch_settings/check_nodes.js b/x-pack/test/api_integration/apis/monitoring/elasticsearch_settings/check_nodes.js index 0c500610b1ed6..c383a65f4a154 100644 --- a/x-pack/test/api_integration/apis/monitoring/elasticsearch_settings/check_nodes.js +++ b/x-pack/test/api_integration/apis/monitoring/elasticsearch_settings/check_nodes.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); diff --git a/x-pack/test/api_integration/apis/monitoring/elasticsearch_settings/set_collection_enabled.js b/x-pack/test/api_integration/apis/monitoring/elasticsearch_settings/set_collection_enabled.js index 7b5c73f029a44..9b85887311e9c 100644 --- a/x-pack/test/api_integration/apis/monitoring/elasticsearch_settings/set_collection_enabled.js +++ b/x-pack/test/api_integration/apis/monitoring/elasticsearch_settings/set_collection_enabled.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); diff --git a/x-pack/test/api_integration/apis/monitoring/elasticsearch_settings/set_collection_interval.js b/x-pack/test/api_integration/apis/monitoring/elasticsearch_settings/set_collection_interval.js index ac469fb3e8869..a58cc01c38719 100644 --- a/x-pack/test/api_integration/apis/monitoring/elasticsearch_settings/set_collection_interval.js +++ b/x-pack/test/api_integration/apis/monitoring/elasticsearch_settings/set_collection_interval.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); diff --git a/x-pack/test/api_integration/apis/monitoring/kibana/instance.js b/x-pack/test/api_integration/apis/monitoring/kibana/instance.js index e0a67839e2969..e2906e74c5170 100644 --- a/x-pack/test/api_integration/apis/monitoring/kibana/instance.js +++ b/x-pack/test/api_integration/apis/monitoring/kibana/instance.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import instanceFixture from './fixtures/instance'; export default function ({ getService }) { diff --git a/x-pack/test/api_integration/apis/monitoring/kibana/listing.js b/x-pack/test/api_integration/apis/monitoring/kibana/listing.js index 013f20486d9ae..c6db6171d530b 100644 --- a/x-pack/test/api_integration/apis/monitoring/kibana/listing.js +++ b/x-pack/test/api_integration/apis/monitoring/kibana/listing.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import listingFixture from './fixtures/listing'; export default function ({ getService }) { diff --git a/x-pack/test/api_integration/apis/monitoring/kibana/overview.js b/x-pack/test/api_integration/apis/monitoring/kibana/overview.js index c3e3339623443..42c0def5050fa 100644 --- a/x-pack/test/api_integration/apis/monitoring/kibana/overview.js +++ b/x-pack/test/api_integration/apis/monitoring/kibana/overview.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import overviewFixture from './fixtures/overview'; export default function ({ getService }) { diff --git a/x-pack/test/api_integration/apis/monitoring/logstash/node_detail.js b/x-pack/test/api_integration/apis/monitoring/logstash/node_detail.js index bbc385e3ba1c9..92f093e8a3346 100644 --- a/x-pack/test/api_integration/apis/monitoring/logstash/node_detail.js +++ b/x-pack/test/api_integration/apis/monitoring/logstash/node_detail.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import nodeDetailFixture from './fixtures/node_detail'; import nodeDetailAdvancedFixture from './fixtures/node_detail_advanced'; diff --git a/x-pack/test/api_integration/apis/monitoring/logstash/nodes.js b/x-pack/test/api_integration/apis/monitoring/logstash/nodes.js index 7709eaeae0c6b..ddc60e780e863 100644 --- a/x-pack/test/api_integration/apis/monitoring/logstash/nodes.js +++ b/x-pack/test/api_integration/apis/monitoring/logstash/nodes.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import nodesFixture from './fixtures/nodes'; export default function ({ getService }) { diff --git a/x-pack/test/api_integration/apis/monitoring/logstash/overview.js b/x-pack/test/api_integration/apis/monitoring/logstash/overview.js index b5053336f0722..9c432486c4615 100644 --- a/x-pack/test/api_integration/apis/monitoring/logstash/overview.js +++ b/x-pack/test/api_integration/apis/monitoring/logstash/overview.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import overviewFixture from './fixtures/overview.json'; export default function ({ getService }) { diff --git a/x-pack/test/api_integration/apis/monitoring/standalone_cluster/cluster.js b/x-pack/test/api_integration/apis/monitoring/standalone_cluster/cluster.js index ed753e8dea9ad..d9ff5303be654 100644 --- a/x-pack/test/api_integration/apis/monitoring/standalone_cluster/cluster.js +++ b/x-pack/test/api_integration/apis/monitoring/standalone_cluster/cluster.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import clusterFixture from './fixtures/cluster'; export default function ({ getService }) { diff --git a/x-pack/test/api_integration/apis/monitoring/standalone_cluster/clusters.js b/x-pack/test/api_integration/apis/monitoring/standalone_cluster/clusters.js index e4a99127c7bb3..33fcdc6f9b5a9 100644 --- a/x-pack/test/api_integration/apis/monitoring/standalone_cluster/clusters.js +++ b/x-pack/test/api_integration/apis/monitoring/standalone_cluster/clusters.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import clustersFixture from './fixtures/clusters'; export default function ({ getService }) { diff --git a/x-pack/test/api_integration/apis/security/basic_login.js b/x-pack/test/api_integration/apis/security/basic_login.js index add872ee66dd0..39c6c0ef0a135 100644 --- a/x-pack/test/api_integration/apis/security/basic_login.js +++ b/x-pack/test/api_integration/apis/security/basic_login.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import request from 'request'; export default function ({ getService }) { diff --git a/x-pack/test/api_integration/apis/security/roles.js b/x-pack/test/api_integration/apis/security/roles.js index 28e6f517d8e87..46eb56ab5602e 100644 --- a/x-pack/test/api_integration/apis/security/roles.js +++ b/x-pack/test/api_integration/apis/security/roles.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const es = getService('es'); diff --git a/x-pack/test/api_integration/apis/uptime/get_all_pings.js b/x-pack/test/api_integration/apis/uptime/get_all_pings.js index a3cf2774fb022..d2c7cd3b3f5c3 100644 --- a/x-pack/test/api_integration/apis/uptime/get_all_pings.js +++ b/x-pack/test/api_integration/apis/uptime/get_all_pings.js @@ -5,7 +5,7 @@ */ import moment from 'moment'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); diff --git a/x-pack/test/api_integration/apis/uptime/graphql/doc_count.js b/x-pack/test/api_integration/apis/uptime/graphql/doc_count.js index 9935151b36a7e..087697377ce81 100644 --- a/x-pack/test/api_integration/apis/uptime/graphql/doc_count.js +++ b/x-pack/test/api_integration/apis/uptime/graphql/doc_count.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getDocCountQueryString } from '../../../../../plugins/uptime/public/components/queries/empty_state/get_doc_count'; import docCount from './fixtures/doc_count'; diff --git a/x-pack/test/api_integration/apis/uptime/graphql/error_list.js b/x-pack/test/api_integration/apis/uptime/graphql/error_list.js index 3aaf7798d1fae..862cfefec4df0 100644 --- a/x-pack/test/api_integration/apis/uptime/graphql/error_list.js +++ b/x-pack/test/api_integration/apis/uptime/graphql/error_list.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getErrorListQueryString } from '../../../../../plugins/uptime/public/components/queries/error_list/get_error_list'; import errorList from './fixtures/error_list'; import errorListFilteredById from './fixtures/error_list_filtered_by_id'; diff --git a/x-pack/test/api_integration/apis/uptime/graphql/filter_bar.js b/x-pack/test/api_integration/apis/uptime/graphql/filter_bar.js index fdbade1b15909..463b7b9bd9b27 100644 --- a/x-pack/test/api_integration/apis/uptime/graphql/filter_bar.js +++ b/x-pack/test/api_integration/apis/uptime/graphql/filter_bar.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getFilterBarQueryString } from '../../../../../plugins/uptime/public/components/queries/filter_bar/get_filter_bar'; import filterList from './fixtures/filter_list'; diff --git a/x-pack/test/api_integration/apis/uptime/graphql/monitor_charts.js b/x-pack/test/api_integration/apis/uptime/graphql/monitor_charts.js index 26e73fca2d80a..8e761557b1c74 100644 --- a/x-pack/test/api_integration/apis/uptime/graphql/monitor_charts.js +++ b/x-pack/test/api_integration/apis/uptime/graphql/monitor_charts.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getMonitorChartsQueryString } from '../../../../../plugins/uptime/public/components/queries/monitor_charts/get_monitor_charts'; import monitorCharts from './fixtures/monitor_charts'; import monitorChartsEmptySet from './fixtures/monitor_charts_empty_set'; diff --git a/x-pack/test/api_integration/apis/uptime/graphql/monitor_list.js b/x-pack/test/api_integration/apis/uptime/graphql/monitor_list.js index 1720d1c11db02..6e190195f5208 100644 --- a/x-pack/test/api_integration/apis/uptime/graphql/monitor_list.js +++ b/x-pack/test/api_integration/apis/uptime/graphql/monitor_list.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import monitorList from './fixtures/monitor_list'; import monitorListDownFiltered from './fixtures/monitor_list_down_filtered'; import monitorListUpFiltered from './fixtures/monitor_list_up_filtered'; diff --git a/x-pack/test/api_integration/apis/uptime/graphql/monitor_status_bar.js b/x-pack/test/api_integration/apis/uptime/graphql/monitor_status_bar.js index f50e48dafc2d1..15399b058f9b7 100644 --- a/x-pack/test/api_integration/apis/uptime/graphql/monitor_status_bar.js +++ b/x-pack/test/api_integration/apis/uptime/graphql/monitor_status_bar.js @@ -5,7 +5,7 @@ */ import { omit } from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; // eslint-disable-next-line max-len import { getMonitorStatusBarQueryString } from '../../../../../plugins/uptime/public/components/queries/monitor_status_bar/get_monitor_status_bar'; import monitorStatus from './fixtures/monitor_status'; diff --git a/x-pack/test/api_integration/apis/uptime/graphql/ping_list.js b/x-pack/test/api_integration/apis/uptime/graphql/ping_list.js index ea44b03fbe81d..89d974353b7f6 100644 --- a/x-pack/test/api_integration/apis/uptime/graphql/ping_list.js +++ b/x-pack/test/api_integration/apis/uptime/graphql/ping_list.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getPingsQueryString } from '../../../../../plugins/uptime/public/components/queries/ping_list/get_pings'; import pingList from './fixtures/ping_list'; import pingListCount from './fixtures/ping_list_count'; diff --git a/x-pack/test/api_integration/apis/uptime/graphql/snapshot.js b/x-pack/test/api_integration/apis/uptime/graphql/snapshot.js index f1f98733be4e5..4e656e001ac99 100644 --- a/x-pack/test/api_integration/apis/uptime/graphql/snapshot.js +++ b/x-pack/test/api_integration/apis/uptime/graphql/snapshot.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getSnapshotQueryString } from '../../../../../plugins/uptime/public/components/queries/snapshot/get_snapshot'; import snapshot from './fixtures/snapshot'; import snapshotFilteredByDown from './fixtures/snapshot_filtered_by_down'; diff --git a/x-pack/test/api_integration/apis/xpack_main/settings/settings.js b/x-pack/test/api_integration/apis/xpack_main/settings/settings.js index 9f7055c7b8332..3a19aa10e305d 100644 --- a/x-pack/test/api_integration/apis/xpack_main/settings/settings.js +++ b/x-pack/test/api_integration/apis/xpack_main/settings/settings.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); diff --git a/x-pack/test/api_integration/apis/xpack_main/telemetry/telemetry.js b/x-pack/test/api_integration/apis/xpack_main/telemetry/telemetry.js index 08ebc715527bd..3017a35880236 100644 --- a/x-pack/test/api_integration/apis/xpack_main/telemetry/telemetry.js +++ b/x-pack/test/api_integration/apis/xpack_main/telemetry/telemetry.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import multiClusterFixture from './fixtures/multicluster'; import basicClusterFixture from './fixtures/basiccluster'; diff --git a/x-pack/test/api_integration/apis/xpack_main/telemetry/telemetry_local.js b/x-pack/test/api_integration/apis/xpack_main/telemetry/telemetry_local.js index 2ee08c3cdfb8e..93671ccdc5fd8 100644 --- a/x-pack/test/api_integration/apis/xpack_main/telemetry/telemetry_local.js +++ b/x-pack/test/api_integration/apis/xpack_main/telemetry/telemetry_local.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import _ from 'lodash'; /* diff --git a/x-pack/test/functional/apps/canvas/smoke_test.js b/x-pack/test/functional/apps/canvas/smoke_test.js index 45552e1a4067d..b309472f382c6 100644 --- a/x-pack/test/functional/apps/canvas/smoke_test.js +++ b/x-pack/test/functional/apps/canvas/smoke_test.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { parse } from 'url'; export default function canvasSmokeTest({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/dashboard_mode/dashboard_view_mode.js b/x-pack/test/functional/apps/dashboard_mode/dashboard_view_mode.js index 8a70a2c64c5dd..9275a802bfaa7 100644 --- a/x-pack/test/functional/apps/dashboard_mode/dashboard_view_mode.js +++ b/x-pack/test/functional/apps/dashboard_mode/dashboard_view_mode.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const kibanaServer = getService('kibanaServer'); diff --git a/x-pack/test/functional/apps/graph/graph.js b/x-pack/test/functional/apps/graph/graph.js index 655feb529cfad..b7e5e44450973 100644 --- a/x-pack/test/functional/apps/graph/graph.js +++ b/x-pack/test/functional/apps/graph/graph.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; // import { indexBy } from 'lodash'; export default function ({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/logstash/pipeline_create.js b/x-pack/test/functional/apps/logstash/pipeline_create.js index 101f9d3f03876..7c1d1bf13d8e2 100644 --- a/x-pack/test/functional/apps/logstash/pipeline_create.js +++ b/x-pack/test/functional/apps/logstash/pipeline_create.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const browser = getService('browser'); diff --git a/x-pack/test/functional/apps/logstash/pipeline_list.js b/x-pack/test/functional/apps/logstash/pipeline_list.js index 5fd40a0b3a36c..d04f50690368d 100644 --- a/x-pack/test/functional/apps/logstash/pipeline_list.js +++ b/x-pack/test/functional/apps/logstash/pipeline_list.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { omit } from 'lodash'; export default function ({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/maps/add_layer_panel.js b/x-pack/test/functional/apps/maps/add_layer_panel.js index f18ea6fb99719..1bb30477a2a9c 100644 --- a/x-pack/test/functional/apps/maps/add_layer_panel.js +++ b/x-pack/test/functional/apps/maps/add_layer_panel.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getPageObjects }) { const PageObjects = getPageObjects(['maps', 'common']); diff --git a/x-pack/test/functional/apps/maps/embeddable/dashboard.js b/x-pack/test/functional/apps/maps/embeddable/dashboard.js index f7e35bd5ca995..f458c38093e4f 100644 --- a/x-pack/test/functional/apps/maps/embeddable/dashboard.js +++ b/x-pack/test/functional/apps/maps/embeddable/dashboard.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getPageObjects, getService }) { const PageObjects = getPageObjects(['common', 'dashboard', 'maps']); @@ -12,16 +12,24 @@ export default function ({ getPageObjects, getService }) { const filterBar = getService('filterBar'); const dashboardPanelActions = getService('dashboardPanelActions'); const inspector = getService('inspector'); + const testSubjects = getService('testSubjects'); describe('embed in dashboard', () => { before(async () => { await kibanaServer.uiSettings.replace({ - 'defaultIndex': 'c698b940-e149-11e8-a35a-370a8516603a' + 'defaultIndex': 'c698b940-e149-11e8-a35a-370a8516603a', + 'courier:ignoreFilterIfFieldNotInIndex': true }); await PageObjects.common.navigateToApp('dashboard'); await PageObjects.dashboard.loadSavedDashboard('map embeddable example'); }); + after(async () => { + await kibanaServer.uiSettings.replace({ + 'courier:ignoreFilterIfFieldNotInIndex': false + }); + }); + async function getRequestTimestamp() { await inspector.openInspectorRequestsView(); const requestStats = await inspector.getTableData(); @@ -58,11 +66,22 @@ export default function ({ getPageObjects, getService }) { it('should apply new container state (time, query, filters) to embeddable', async () => { await filterBar.selectIndexPattern('logstash-*'); await filterBar.addFilter('machine.os', 'is', 'win 8'); + await filterBar.selectIndexPattern('meta_for_geo_shapes*'); + await filterBar.addFilter('shape_name', 'is', 'alpha'); + await dashboardPanelActions.openInspectorByTitle('geo grid vector grid example'); - const requestStats = await inspector.getTableData(); - const totalHits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits (total)'); + const geoGridRequestStats = await inspector.getTableData(); + const geoGridTotalHits = PageObjects.maps.getInspectorStatRowHit(geoGridRequestStats, 'Hits (total)'); + await inspector.close(); + expect(geoGridTotalHits).to.equal('1'); + + await dashboardPanelActions.openInspectorByTitle('join example'); + await testSubjects.click('inspectorRequestChooser'); + await testSubjects.click('inspectorRequestChoosermeta_for_geo_shapes*.shape_name'); + const joinRequestStats = await inspector.getTableData(); + const joinTotalHits = PageObjects.maps.getInspectorStatRowHit(joinRequestStats, 'Hits (total)'); await inspector.close(); - expect(totalHits).to.equal('1'); + expect(joinTotalHits).to.equal('3'); }); it('should re-fetch query when "refresh" is clicked', async () => { diff --git a/x-pack/test/functional/apps/maps/embeddable/embeddable_state.js b/x-pack/test/functional/apps/maps/embeddable/embeddable_state.js new file mode 100644 index 0000000000000..960d875c6b7b2 --- /dev/null +++ b/x-pack/test/functional/apps/maps/embeddable/embeddable_state.js @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import expect from '@kbn/expect'; + +export default function ({ getPageObjects, getService }) { + const PageObjects = getPageObjects(['common', 'dashboard', 'maps']); + const kibanaServer = getService('kibanaServer'); + const dashboardAddPanel = getService('dashboardAddPanel'); + const DASHBOARD_NAME = 'verify_map_embeddable_state'; + + describe('embeddable state', () => { + + before(async () => { + await kibanaServer.uiSettings.replace({ + 'defaultIndex': 'c698b940-e149-11e8-a35a-370a8516603a' + }); + await PageObjects.common.navigateToApp('dashboard'); + await PageObjects.dashboard.clickNewDashboard(); + await dashboardAddPanel.addEmbeddable('document example', 'map'); + + await PageObjects.maps.setView(0.0, 0.0, 10); + await PageObjects.dashboard.saveDashboard(DASHBOARD_NAME); + await PageObjects.dashboard.loadSavedDashboard(DASHBOARD_NAME); + }); + + it('should render map with center and zoom from embeddable state', async () => { + const { lat, lon, zoom } = await PageObjects.maps.getView(); + expect(Math.round(lat)).to.equal(0); + expect(Math.round(lon)).to.equal(0); + expect(Math.round(zoom)).to.equal(10); + }); + + }); +} diff --git a/x-pack/test/functional/apps/maps/es_geo_grid_source.js b/x-pack/test/functional/apps/maps/es_geo_grid_source.js index a4663256fc340..1ee034d07689c 100644 --- a/x-pack/test/functional/apps/maps/es_geo_grid_source.js +++ b/x-pack/test/functional/apps/maps/es_geo_grid_source.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getPageObjects, getService }) { diff --git a/x-pack/test/functional/apps/maps/es_search_source.js b/x-pack/test/functional/apps/maps/es_search_source.js index c9745ebbecfa2..a5f36157ddc87 100644 --- a/x-pack/test/functional/apps/maps/es_search_source.js +++ b/x-pack/test/functional/apps/maps/es_search_source.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getPageObjects, getService }) { const PageObjects = getPageObjects(['maps']); @@ -73,7 +73,7 @@ export default function ({ getPageObjects, getService }) { expect(beforeQueryRefreshTimestamp).not.to.equal(afterQueryRefreshTimestamp); }); - it('should apply query to fit to bounds', async () => { + it.skip('should apply query to fit to bounds', async () => { // Set view to other side of world so no matching results await PageObjects.maps.setView(-15, -100, 6); await PageObjects.maps.clickFitToBounds('logstash'); @@ -84,6 +84,31 @@ export default function ({ getPageObjects, getService }) { }); }); + describe('layer query', () => { + before(async () => { + await PageObjects.maps.setLayerQuery('logstash', 'machine.os.raw : "ios"'); + }); + + it('should apply layer query to search request', async () => { + await inspector.open(); + await inspector.openInspectorRequestsView(); + const requestStats = await inspector.getTableData(); + const hits = PageObjects.maps.getInspectorStatRowHit(requestStats, 'Hits'); + await inspector.close(); + expect(hits).to.equal('2'); + }); + + it.skip('should apply layer query to fit to bounds', async () => { + // Set view to other side of world so no matching results + await PageObjects.maps.setView(-15, -100, 6); + await PageObjects.maps.clickFitToBounds('logstash'); + const { lat, lon, zoom } = await PageObjects.maps.getView(); + expect(Math.round(lat)).to.equal(42); + expect(Math.round(lon)).to.equal(-102); + expect(Math.round(zoom)).to.equal(5); + }); + }); + describe('filter by extent', () => { it('should handle geo_point filtering with extents that cross antimeridian', async () => { await PageObjects.maps.loadSavedMap('antimeridian points example'); diff --git a/x-pack/test/functional/apps/maps/index.js b/x-pack/test/functional/apps/maps/index.js index d88834de95644..49b8611eff869 100644 --- a/x-pack/test/functional/apps/maps/index.js +++ b/x-pack/test/functional/apps/maps/index.js @@ -41,6 +41,7 @@ export default function ({ loadTestFile, getService }) { loadTestFile(require.resolve('./add_layer_panel')); loadTestFile(require.resolve('./layer_errors')); loadTestFile(require.resolve('./embeddable/dashboard')); + loadTestFile(require.resolve('./embeddable/embeddable_state')); }); }); } diff --git a/x-pack/test/functional/apps/maps/joins.js b/x-pack/test/functional/apps/maps/joins.js index 7976225405993..4eae5e85dbecf 100644 --- a/x-pack/test/functional/apps/maps/joins.js +++ b/x-pack/test/functional/apps/maps/joins.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; const JOIN_PROPERTY_NAME = '__kbnjoin__max_of_prop1_groupby_meta_for_geo_shapes*.shape_name'; const EXPECTED_JOIN_VALUES = { diff --git a/x-pack/test/functional/apps/maps/layer_errors.js b/x-pack/test/functional/apps/maps/layer_errors.js index 532cba839127e..1fe9778a44db3 100644 --- a/x-pack/test/functional/apps/maps/layer_errors.js +++ b/x-pack/test/functional/apps/maps/layer_errors.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getPageObjects }) { diff --git a/x-pack/test/functional/apps/maps/sample_data.js b/x-pack/test/functional/apps/maps/sample_data.js index 7e871d01f9fd8..76ddeab4ae155 100644 --- a/x-pack/test/functional/apps/maps/sample_data.js +++ b/x-pack/test/functional/apps/maps/sample_data.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getPageObjects, getService, updateBaselines }) { const PageObjects = getPageObjects(['common', 'maps', 'header', 'home', 'timePicker']); diff --git a/x-pack/test/functional/apps/maps/saved_object_management.js b/x-pack/test/functional/apps/maps/saved_object_management.js index e093d86ebde8b..a31bc2bdd569c 100644 --- a/x-pack/test/functional/apps/maps/saved_object_management.js +++ b/x-pack/test/functional/apps/maps/saved_object_management.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getPageObjects, getService }) { diff --git a/x-pack/test/functional/apps/monitoring/beats/beat_detail.js b/x-pack/test/functional/apps/monitoring/beats/beat_detail.js index 5ca033549f937..d352579e01160 100644 --- a/x-pack/test/functional/apps/monitoring/beats/beat_detail.js +++ b/x-pack/test/functional/apps/monitoring/beats/beat_detail.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getLifecycleMethods } from '../_get_lifecycle_methods'; export default function ({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/monitoring/beats/cluster.js b/x-pack/test/functional/apps/monitoring/beats/cluster.js index 949feef987851..8ee93066254d5 100644 --- a/x-pack/test/functional/apps/monitoring/beats/cluster.js +++ b/x-pack/test/functional/apps/monitoring/beats/cluster.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getLifecycleMethods } from '../_get_lifecycle_methods'; export default function ({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/monitoring/beats/listing.js b/x-pack/test/functional/apps/monitoring/beats/listing.js index 0a0148aee69c6..700b5d593ecb8 100644 --- a/x-pack/test/functional/apps/monitoring/beats/listing.js +++ b/x-pack/test/functional/apps/monitoring/beats/listing.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getLifecycleMethods } from '../_get_lifecycle_methods'; export default function ({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/monitoring/beats/overview.js b/x-pack/test/functional/apps/monitoring/beats/overview.js index 049ffc963c4f9..1c8b70a462843 100644 --- a/x-pack/test/functional/apps/monitoring/beats/overview.js +++ b/x-pack/test/functional/apps/monitoring/beats/overview.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getLifecycleMethods } from '../_get_lifecycle_methods'; export default function ({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/monitoring/cluster/alerts.js b/x-pack/test/functional/apps/monitoring/cluster/alerts.js index 8cc6b3e5f089e..0a2ffb90c536d 100644 --- a/x-pack/test/functional/apps/monitoring/cluster/alerts.js +++ b/x-pack/test/functional/apps/monitoring/cluster/alerts.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getLifecycleMethods } from '../_get_lifecycle_methods'; const HIGH_ALERT_MESSAGE = 'High severity alert'; diff --git a/x-pack/test/functional/apps/monitoring/cluster/list.js b/x-pack/test/functional/apps/monitoring/cluster/list.js index aa2e8ff8ee045..c3eb509c6eed8 100644 --- a/x-pack/test/functional/apps/monitoring/cluster/list.js +++ b/x-pack/test/functional/apps/monitoring/cluster/list.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getLifecycleMethods } from '../_get_lifecycle_methods'; export default function ({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/monitoring/cluster/overview.js b/x-pack/test/functional/apps/monitoring/cluster/overview.js index bfbd1b69a9e54..8242150e404eb 100644 --- a/x-pack/test/functional/apps/monitoring/cluster/overview.js +++ b/x-pack/test/functional/apps/monitoring/cluster/overview.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getLifecycleMethods } from '../_get_lifecycle_methods'; export default function ({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/monitoring/elasticsearch/index_detail.js b/x-pack/test/functional/apps/monitoring/elasticsearch/index_detail.js index dd0ea8f03ab41..718d4c012989b 100644 --- a/x-pack/test/functional/apps/monitoring/elasticsearch/index_detail.js +++ b/x-pack/test/functional/apps/monitoring/elasticsearch/index_detail.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getLifecycleMethods } from '../_get_lifecycle_methods'; export default function ({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/monitoring/elasticsearch/indices.js b/x-pack/test/functional/apps/monitoring/elasticsearch/indices.js index 2dea5db65598e..fc3669079dbce 100644 --- a/x-pack/test/functional/apps/monitoring/elasticsearch/indices.js +++ b/x-pack/test/functional/apps/monitoring/elasticsearch/indices.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getLifecycleMethods } from '../_get_lifecycle_methods'; export default function ({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/monitoring/elasticsearch/node_detail.js b/x-pack/test/functional/apps/monitoring/elasticsearch/node_detail.js index 1cb6902948a16..46fdd8d3921a3 100644 --- a/x-pack/test/functional/apps/monitoring/elasticsearch/node_detail.js +++ b/x-pack/test/functional/apps/monitoring/elasticsearch/node_detail.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getLifecycleMethods } from '../_get_lifecycle_methods'; export default function ({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/monitoring/elasticsearch/nodes.js b/x-pack/test/functional/apps/monitoring/elasticsearch/nodes.js index f57677411c210..357874d501417 100644 --- a/x-pack/test/functional/apps/monitoring/elasticsearch/nodes.js +++ b/x-pack/test/functional/apps/monitoring/elasticsearch/nodes.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getLifecycleMethods } from '../_get_lifecycle_methods'; export default function ({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/monitoring/elasticsearch/overview.js b/x-pack/test/functional/apps/monitoring/elasticsearch/overview.js index 1597bc6be046d..3f90c6a096e90 100644 --- a/x-pack/test/functional/apps/monitoring/elasticsearch/overview.js +++ b/x-pack/test/functional/apps/monitoring/elasticsearch/overview.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getLifecycleMethods } from '../_get_lifecycle_methods'; export default function ({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/monitoring/elasticsearch/shards.js b/x-pack/test/functional/apps/monitoring/elasticsearch/shards.js index dd106082d033a..e22d160f4faf6 100644 --- a/x-pack/test/functional/apps/monitoring/elasticsearch/shards.js +++ b/x-pack/test/functional/apps/monitoring/elasticsearch/shards.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getLifecycleMethods } from '../_get_lifecycle_methods'; export default function ({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/monitoring/enable_monitoring/index.js b/x-pack/test/functional/apps/monitoring/enable_monitoring/index.js index efb9fecb37445..2cdecc58266a6 100644 --- a/x-pack/test/functional/apps/monitoring/enable_monitoring/index.js +++ b/x-pack/test/functional/apps/monitoring/enable_monitoring/index.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const PageObjects = getPageObjects(['monitoring', 'common', 'header']); diff --git a/x-pack/test/functional/apps/monitoring/kibana/instance.js b/x-pack/test/functional/apps/monitoring/kibana/instance.js index c6f6fb4aaa5c4..33448fc4b206a 100644 --- a/x-pack/test/functional/apps/monitoring/kibana/instance.js +++ b/x-pack/test/functional/apps/monitoring/kibana/instance.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getLifecycleMethods } from '../_get_lifecycle_methods'; export default function ({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/monitoring/kibana/instances.js b/x-pack/test/functional/apps/monitoring/kibana/instances.js index b79f67152b857..28bf108d59f24 100644 --- a/x-pack/test/functional/apps/monitoring/kibana/instances.js +++ b/x-pack/test/functional/apps/monitoring/kibana/instances.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getLifecycleMethods } from '../_get_lifecycle_methods'; export default function ({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/monitoring/kibana/overview.js b/x-pack/test/functional/apps/monitoring/kibana/overview.js index 90a8bebe90215..7282e48fc8a91 100644 --- a/x-pack/test/functional/apps/monitoring/kibana/overview.js +++ b/x-pack/test/functional/apps/monitoring/kibana/overview.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getLifecycleMethods } from '../_get_lifecycle_methods'; export default function ({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/monitoring/logstash/pipelines.js b/x-pack/test/functional/apps/monitoring/logstash/pipelines.js index 613a3d87efe7c..4d2a7dbc68887 100644 --- a/x-pack/test/functional/apps/monitoring/logstash/pipelines.js +++ b/x-pack/test/functional/apps/monitoring/logstash/pipelines.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { getLifecycleMethods } from '../_get_lifecycle_methods'; export default function ({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/rollup_job/rollup_jobs.js b/x-pack/test/functional/apps/rollup_job/rollup_jobs.js index c0012ee04ab71..5546cd9311ef1 100644 --- a/x-pack/test/functional/apps/rollup_job/rollup_jobs.js +++ b/x-pack/test/functional/apps/rollup_job/rollup_jobs.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { indexBy } from 'lodash'; export default function ({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/security/doc_level_security_roles.js b/x-pack/test/functional/apps/security/doc_level_security_roles.js index 2229c8c083650..9ea1e30358ff3 100644 --- a/x-pack/test/functional/apps/security/doc_level_security_roles.js +++ b/x-pack/test/functional/apps/security/doc_level_security_roles.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { indexBy } from 'lodash'; export default function ({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/security/field_level_security.js b/x-pack/test/functional/apps/security/field_level_security.js index eb9fdd2a5084d..4ce68580334a2 100644 --- a/x-pack/test/functional/apps/security/field_level_security.js +++ b/x-pack/test/functional/apps/security/field_level_security.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { indexBy } from 'lodash'; export default function ({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/security/management.js b/x-pack/test/functional/apps/security/management.js index 053f805d4e46c..aa9ae9f1ed48c 100644 --- a/x-pack/test/functional/apps/security/management.js +++ b/x-pack/test/functional/apps/security/management.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { USERS_PATH, EDIT_USERS_PATH, diff --git a/x-pack/test/functional/apps/security/rbac_phase1.js b/x-pack/test/functional/apps/security/rbac_phase1.js index e25dcec464a73..e8c70b0d96445 100644 --- a/x-pack/test/functional/apps/security/rbac_phase1.js +++ b/x-pack/test/functional/apps/security/rbac_phase1.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { indexBy } from 'lodash'; export default function ({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/security/secure_roles_perm.js b/x-pack/test/functional/apps/security/secure_roles_perm.js index 47502e7fc72a4..fb5effa627756 100644 --- a/x-pack/test/functional/apps/security/secure_roles_perm.js +++ b/x-pack/test/functional/apps/security/secure_roles_perm.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { indexBy } from 'lodash'; export default function ({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/security/security.js b/x-pack/test/functional/apps/security/security.js index ba4ee6fb7b29d..38d4d6a393981 100644 --- a/x-pack/test/functional/apps/security/security.js +++ b/x-pack/test/functional/apps/security/security.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export default function ({ getService, getPageObjects }) { const esArchiver = getService('esArchiver'); diff --git a/x-pack/test/functional/apps/security/user_email.js b/x-pack/test/functional/apps/security/user_email.js index 3312171786683..d4828b61053d6 100644 --- a/x-pack/test/functional/apps/security/user_email.js +++ b/x-pack/test/functional/apps/security/user_email.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { indexBy } from 'lodash'; export default function ({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/security/users.js b/x-pack/test/functional/apps/security/users.js index 53c4df274c87e..b8fabf534f6e2 100644 --- a/x-pack/test/functional/apps/security/users.js +++ b/x-pack/test/functional/apps/security/users.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { indexBy } from 'lodash'; export default function ({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/apps/watcher/watcher_test.js b/x-pack/test/functional/apps/watcher/watcher_test.js index 1af7da85036bf..c07ab3b7155d7 100644 --- a/x-pack/test/functional/apps/watcher/watcher_test.js +++ b/x-pack/test/functional/apps/watcher/watcher_test.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { indexBy } from 'lodash'; const watchID = 'watchID'; diff --git a/x-pack/test/functional/config.js b/x-pack/test/functional/config.js index f1cfd20210000..82270b7ac00d5 100644 --- a/x-pack/test/functional/config.js +++ b/x-pack/test/functional/config.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable kibana-custom/no-default-export */ +/* eslint-disable @kbn/eslint/no-default-export */ import { resolve } from 'path'; diff --git a/x-pack/test/functional/page_objects/accountsetting_page.js b/x-pack/test/functional/page_objects/accountsetting_page.js index 90f3bc5bc181b..a49b9544ce7e3 100644 --- a/x-pack/test/functional/page_objects/accountsetting_page.js +++ b/x-pack/test/functional/page_objects/accountsetting_page.js @@ -5,7 +5,7 @@ */ //import { map as mapAsync } from 'bluebird'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; export function AccountSettingProvider({ getService }) { const testSubjects = getService('testSubjects'); diff --git a/x-pack/test/functional/page_objects/gis_page.js b/x-pack/test/functional/page_objects/gis_page.js index 122e6434301a9..bee98a55d59bc 100644 --- a/x-pack/test/functional/page_objects/gis_page.js +++ b/x-pack/test/functional/page_objects/gis_page.js @@ -55,7 +55,7 @@ export function GisPageProvider({ getService, getPageObjects }) { log.debug('Wait for layers to load'); const tableOfContents = await testSubjects.find('mapLayerTOC'); await retry.try(async () => { - await tableOfContents.waitForDeletedByClassName('euiLoadingSpinner'); + await tableOfContents.waitForDeletedByCssSelector('.euiLoadingSpinner'); }); } @@ -170,6 +170,8 @@ export function GisPageProvider({ getService, getPageObjects }) { await testSubjects.setValue('zoomInput', zoom.toString()); await testSubjects.click('submitViewButton'); await this.waitForLayersToLoad(); + // there is no way to wait for canvas been reloaded + await PageObjects.common.sleep(5000); } async getView() { @@ -230,6 +232,19 @@ export function GisPageProvider({ getService, getPageObjects }) { } } + async setLayerQuery(layerName, query) { + await this.openLayerPanel(layerName); + await testSubjects.click('mapLayerPanelOpenFilterEditorButton'); + const filterEditorContainer = await testSubjects.find('mapFilterEditor'); + const queryBarInFilterEditor = await testSubjects.findDescendant('queryInput', filterEditorContainer); + await queryBarInFilterEditor.click(); + const input = await find.activeElement(); + await input.clearValue(); + await input.type(query); + await testSubjects.click('mapFilterEditorSubmitButton'); + await this.waitForLayersToLoad(); + } + async selectVectorSource() { log.debug(`Select vector source`); await testSubjects.click('vectorShapes'); diff --git a/x-pack/test/functional/page_objects/rollup_page.js b/x-pack/test/functional/page_objects/rollup_page.js index b722fd17a4167..44eb762fb7082 100644 --- a/x-pack/test/functional/page_objects/rollup_page.js +++ b/x-pack/test/functional/page_objects/rollup_page.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { map as mapAsync } from 'bluebird'; export function RollupPageProvider({ getService, getPageObjects }) { diff --git a/x-pack/test/functional/page_objects/space_selector_page.js b/x-pack/test/functional/page_objects/space_selector_page.js index 9f7ff9ced6b6d..3be1ae174ce46 100644 --- a/x-pack/test/functional/page_objects/space_selector_page.js +++ b/x-pack/test/functional/page_objects/space_selector_page.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export function SpaceSelectorPageProvider({ getService, getPageObjects }) { const retry = getService('retry'); diff --git a/x-pack/test/functional/page_objects/status_page.js b/x-pack/test/functional/page_objects/status_page.js index 36915dff5dd09..68fc931a9140f 100644 --- a/x-pack/test/functional/page_objects/status_page.js +++ b/x-pack/test/functional/page_objects/status_page.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export function StatusPagePageProvider({ getService, getPageObjects }) { const retry = getService('retry'); diff --git a/x-pack/test/functional/page_objects/upgrade_assistant.js b/x-pack/test/functional/page_objects/upgrade_assistant.js index f0011b76b2ac4..af9d5ea55cec6 100644 --- a/x-pack/test/functional/page_objects/upgrade_assistant.js +++ b/x-pack/test/functional/page_objects/upgrade_assistant.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export function UpgradeAssistantProvider({ getService, getPageObjects }) { const retry = getService('retry'); diff --git a/x-pack/test/functional/services/grok_debugger.js b/x-pack/test/functional/services/grok_debugger.js index c8870e534ce55..48717bee0e3a9 100644 --- a/x-pack/test/functional/services/grok_debugger.js +++ b/x-pack/test/functional/services/grok_debugger.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export function GrokDebuggerProvider({ getService }) { const aceEditor = getService('aceEditor'); diff --git a/x-pack/test/functional/services/monitoring/cluster_overview.js b/x-pack/test/functional/services/monitoring/cluster_overview.js index 25c110ef4d9df..83657bd884965 100644 --- a/x-pack/test/functional/services/monitoring/cluster_overview.js +++ b/x-pack/test/functional/services/monitoring/cluster_overview.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; export function MonitoringClusterOverviewProvider({ getService }) { const testSubjects = getService('testSubjects'); diff --git a/x-pack/test/functional/services/pipeline_editor.js b/x-pack/test/functional/services/pipeline_editor.js index ad7b5e7d0147f..804fdf27158fe 100644 --- a/x-pack/test/functional/services/pipeline_editor.js +++ b/x-pack/test/functional/services/pipeline_editor.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { props as propsAsync } from 'bluebird'; export function PipelineEditorProvider({ getService }) { diff --git a/x-pack/test/plugin_api_integration/plugins/task_manager/package.json b/x-pack/test/plugin_api_integration/plugins/task_manager/package.json index ede03a08a2721..ec63c512e9cd7 100644 --- a/x-pack/test/plugin_api_integration/plugins/task_manager/package.json +++ b/x-pack/test/plugin_api_integration/plugins/task_manager/package.json @@ -1,4 +1,12 @@ { "name": "sample_task_plugin", - "version": "kibana" + "version": "1.0.0", + "kibana": { + "version": "kibana", + "templateVersion": "1.0.0" + }, + "license": "Apache-2.0", + "dependencies": { + "joi": "^13.5.2" + } } diff --git a/x-pack/test/plugin_api_integration/test_suites/task_manager/task_manager_integration.js b/x-pack/test/plugin_api_integration/test_suites/task_manager/task_manager_integration.js index 0d3180902d550..4bfae4c24a882 100644 --- a/x-pack/test/plugin_api_integration/test_suites/task_manager/task_manager_integration.js +++ b/x-pack/test/plugin_api_integration/test_suites/task_manager/task_manager_integration.js @@ -5,7 +5,7 @@ */ import _ from 'lodash'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import url from 'url'; import supertestAsPromised from 'supertest-as-promised'; diff --git a/x-pack/test/reporting/api/usage.js b/x-pack/test/reporting/api/usage.js index 0e5004e9c956e..1b70ab9e4547f 100644 --- a/x-pack/test/reporting/api/usage.js +++ b/x-pack/test/reporting/api/usage.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import * as GenerationUrls from './generation_urls'; export default function ({ getService }) { diff --git a/x-pack/test/reporting/functional/reporting.js b/x-pack/test/reporting/functional/reporting.js index 33f064388aa6c..4e1b51ae058e5 100644 --- a/x-pack/test/reporting/functional/reporting.js +++ b/x-pack/test/reporting/functional/reporting.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import path from 'path'; import mkdirp from 'mkdirp'; import fs from 'fs'; diff --git a/x-pack/test/reporting/services/reporting_api.js b/x-pack/test/reporting/services/reporting_api.js index 0c66a77a65fe2..8feb7a70803e2 100644 --- a/x-pack/test/reporting/services/reporting_api.js +++ b/x-pack/test/reporting/services/reporting_api.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { indexTimestamp } from '../../../plugins/reporting/server/lib/esqueue/helpers/index_timestamp'; function removeWhitespace(str) { diff --git a/x-pack/test/saml_api_integration/apis/security/saml_login.js b/x-pack/test/saml_api_integration/apis/security/saml_login.js index fe6f2bf07db02..ca89b36c0c34d 100644 --- a/x-pack/test/saml_api_integration/apis/security/saml_login.js +++ b/x-pack/test/saml_api_integration/apis/security/saml_login.js @@ -8,7 +8,7 @@ import querystring from 'querystring'; import url from 'url'; import { delay } from 'bluebird'; import { getLogoutRequest, getSAMLRequestId, getSAMLResponse } from '../../fixtures/saml_tools'; -import expect from 'expect.js'; +import expect from '@kbn/expect'; import request from 'request'; export default function ({ getService }) { @@ -333,7 +333,7 @@ export default function ({ getService }) { expect(apiResponse.body).to.eql({ error: 'Bad Request', - message: 'invalid_grant', + message: 'Both access and refresh tokens are expired.', statusCode: 400 }); }); @@ -390,7 +390,7 @@ export default function ({ getService }) { expect(apiResponse.body).to.eql({ error: 'Bad Request', - message: 'invalid_grant', + message: 'Both access and refresh tokens are expired.', statusCode: 400 }); }); @@ -417,7 +417,7 @@ export default function ({ getService }) { expect(apiResponse.body).to.eql({ error: 'Bad Request', - message: 'invalid_grant', + message: 'Both access and refresh tokens are expired.', statusCode: 400 }); }); @@ -502,5 +502,54 @@ export default function ({ getService }) { .expect(200); }); }); + + describe('API access with missing access token document.', () => { + let sessionCookie; + + beforeEach(async () => { + const handshakeResponse = await supertest.get('/abc/xyz') + .expect(302); + + const handshakeCookie = request.cookie(handshakeResponse.headers['set-cookie'][0]); + const samlRequestId = await getSAMLRequestId(handshakeResponse.headers.location); + + const samlAuthenticationResponse = await supertest.post('/api/security/v1/saml') + .set('kbn-xsrf', 'xxx') + .set('Cookie', handshakeCookie.cookieString()) + .send({ SAMLResponse: await createSAMLResponse({ inResponseTo: samlRequestId }) }, {}) + .expect(302); + + sessionCookie = request.cookie(samlAuthenticationResponse.headers['set-cookie'][0]); + }); + + it('should properly set cookie and start new SAML handshake', async function () { + // Let's delete tokens from `.security` index directly to simulate the case when + // Elasticsearch automatically removes access/refresh token document from the index + // after some period of time. + const esResponse = await getService('es').deleteByQuery({ + index: '.security', + q: 'doc_type:token', + refresh: true, + }); + expect(esResponse).to.have.property('deleted').greaterThan(0); + + const handshakeResponse = await supertest.get('/abc/xyz/handshake?one=two three') + .set('Cookie', sessionCookie.cookieString()) + .expect(302); + + const cookies = handshakeResponse.headers['set-cookie']; + expect(cookies).to.have.length(1); + + const handshakeCookie = request.cookie(cookies[0]); + expect(handshakeCookie.key).to.be('sid'); + expect(handshakeCookie.value).to.not.be.empty(); + expect(handshakeCookie.path).to.be('/'); + expect(handshakeCookie.httpOnly).to.be(true); + + const redirectURL = url.parse(handshakeResponse.headers.location, true /* parseQueryString */); + expect(redirectURL.href.startsWith(`https://elastic.co/sso/saml`)).to.be(true); + expect(redirectURL.query.SAMLRequest).to.not.be.empty(); + }); + }); }); } diff --git a/x-pack/test/saml_api_integration/config.js b/x-pack/test/saml_api_integration/config.js index 2a9e0fe314a00..4ac092d7f09d1 100644 --- a/x-pack/test/saml_api_integration/config.js +++ b/x-pack/test/saml_api_integration/config.js @@ -18,6 +18,7 @@ export default async function ({ readConfigFile }) { servers: xPackAPITestsConfig.get('servers'), services: { chance: kibanaAPITestsConfig.get('services.chance'), + es: kibanaAPITestsConfig.get('services.es'), supertestWithoutAuth: xPackAPITestsConfig.get('services.supertestWithoutAuth'), }, junit: { diff --git a/x-pack/test/saved_object_api_integration/common/services/es.js b/x-pack/test/saved_object_api_integration/common/services/es.js index f5ef3be4b4bde..af188ca5e3971 100644 --- a/x-pack/test/saved_object_api_integration/common/services/es.js +++ b/x-pack/test/saved_object_api_integration/common/services/es.js @@ -8,9 +8,8 @@ import { format as formatUrl } from 'url'; import elasticsearch from 'elasticsearch'; import shieldPlugin from '../../../../server/lib/esjs_shield_plugin'; -import { TestInvoker } from '../lib/types'; -export function EsProvider({ getService }: TestInvoker) { +export function EsProvider({ getService }) { const config = getService('config'); return new elasticsearch.Client({ diff --git a/x-pack/test/saved_object_api_integration/common/suites/bulk_create.ts b/x-pack/test/saved_object_api_integration/common/suites/bulk_create.ts index 82099fe4bd304..b0390af36017a 100644 --- a/x-pack/test/saved_object_api_integration/common/suites/bulk_create.ts +++ b/x-pack/test/saved_object_api_integration/common/suites/bulk_create.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { SuperTest } from 'supertest'; import { DEFAULT_SPACE_ID } from '../../../../plugins/spaces/common/constants'; import { getIdPrefix, getUrlPrefix } from '../lib/space_test_utils'; diff --git a/x-pack/test/saved_object_api_integration/common/suites/bulk_get.ts b/x-pack/test/saved_object_api_integration/common/suites/bulk_get.ts index e82ea7b856a8c..a0e0d21f942dd 100644 --- a/x-pack/test/saved_object_api_integration/common/suites/bulk_get.ts +++ b/x-pack/test/saved_object_api_integration/common/suites/bulk_get.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { SuperTest } from 'supertest'; import { DEFAULT_SPACE_ID } from '../../../../plugins/spaces/common/constants'; import { getIdPrefix, getUrlPrefix } from '../lib/space_test_utils'; diff --git a/x-pack/test/saved_object_api_integration/common/suites/create.ts b/x-pack/test/saved_object_api_integration/common/suites/create.ts index 9a8de7d7f3bd9..8dc73a7b31e4c 100644 --- a/x-pack/test/saved_object_api_integration/common/suites/create.ts +++ b/x-pack/test/saved_object_api_integration/common/suites/create.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { SuperTest } from 'supertest'; import { DEFAULT_SPACE_ID } from '../../../../plugins/spaces/common/constants'; import { getUrlPrefix } from '../lib/space_test_utils'; diff --git a/x-pack/test/saved_object_api_integration/common/suites/delete.ts b/x-pack/test/saved_object_api_integration/common/suites/delete.ts index 5e4068f5b795c..229ef4e625baa 100644 --- a/x-pack/test/saved_object_api_integration/common/suites/delete.ts +++ b/x-pack/test/saved_object_api_integration/common/suites/delete.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { SuperTest } from 'supertest'; import { DEFAULT_SPACE_ID } from '../../../../plugins/spaces/common/constants'; import { getIdPrefix, getUrlPrefix } from '../lib/space_test_utils'; diff --git a/x-pack/test/saved_object_api_integration/common/suites/export.ts b/x-pack/test/saved_object_api_integration/common/suites/export.ts index 1b55245a210c6..58ebf31e5daec 100644 --- a/x-pack/test/saved_object_api_integration/common/suites/export.ts +++ b/x-pack/test/saved_object_api_integration/common/suites/export.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { SuperTest } from 'supertest'; import { DEFAULT_SPACE_ID } from '../../../../plugins/spaces/common/constants'; import { getIdPrefix, getUrlPrefix } from '../lib/space_test_utils'; diff --git a/x-pack/test/saved_object_api_integration/common/suites/find.ts b/x-pack/test/saved_object_api_integration/common/suites/find.ts index d71a56a79a41b..c89380de2de6d 100644 --- a/x-pack/test/saved_object_api_integration/common/suites/find.ts +++ b/x-pack/test/saved_object_api_integration/common/suites/find.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { SuperTest } from 'supertest'; import { DEFAULT_SPACE_ID } from '../../../../plugins/spaces/common/constants'; import { getIdPrefix, getUrlPrefix } from '../lib/space_test_utils'; @@ -68,6 +68,7 @@ export function findTestSuiteFactory(esArchiver: any, supertest: SuperTest) name: 'My favorite global object', }, references: [], + updated_at: '2017-09-21T18:59:16.270Z', }, ], }); @@ -100,7 +101,17 @@ export function findTestSuiteFactory(esArchiver: any, supertest: SuperTest) attributes: { title: 'Count of requests', }, - references: [], + migrationVersion: { + visualization: '7.0.0', + }, + references: [ + { + id: `${getIdPrefix(spaceId)}91200a00-9efd-11e7-acb3-3dab96693fab`, + name: 'kibanaSavedObjectMeta.searchSourceJSON.index', + type: 'index-pattern', + }, + ], + updated_at: '2017-09-21T18:51:23.794Z', }, ], }); diff --git a/x-pack/test/saved_object_api_integration/common/suites/get.ts b/x-pack/test/saved_object_api_integration/common/suites/get.ts index 1cc36b411c61a..c178a2389986d 100644 --- a/x-pack/test/saved_object_api_integration/common/suites/get.ts +++ b/x-pack/test/saved_object_api_integration/common/suites/get.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { SuperTest } from 'supertest'; import { DEFAULT_SPACE_ID } from '../../../../plugins/spaces/common/constants'; import { getIdPrefix, getUrlPrefix } from '../lib/space_test_utils'; diff --git a/x-pack/test/saved_object_api_integration/common/suites/import.ts b/x-pack/test/saved_object_api_integration/common/suites/import.ts index 9f45044031e5a..816b68d3eed3f 100644 --- a/x-pack/test/saved_object_api_integration/common/suites/import.ts +++ b/x-pack/test/saved_object_api_integration/common/suites/import.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { SuperTest } from 'supertest'; import { DEFAULT_SPACE_ID } from '../../../../plugins/spaces/common/constants'; import { getIdPrefix, getUrlPrefix } from '../lib/space_test_utils'; diff --git a/x-pack/test/saved_object_api_integration/common/suites/resolve_import_errors.ts b/x-pack/test/saved_object_api_integration/common/suites/resolve_import_errors.ts index c13a5bf15afe6..0a06ca064beee 100644 --- a/x-pack/test/saved_object_api_integration/common/suites/resolve_import_errors.ts +++ b/x-pack/test/saved_object_api_integration/common/suites/resolve_import_errors.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { SuperTest } from 'supertest'; import { DEFAULT_SPACE_ID } from '../../../../plugins/spaces/common/constants'; import { getIdPrefix, getUrlPrefix } from '../lib/space_test_utils'; diff --git a/x-pack/test/saved_object_api_integration/common/suites/update.ts b/x-pack/test/saved_object_api_integration/common/suites/update.ts index 7fa534e142b3d..e292daa13d122 100644 --- a/x-pack/test/saved_object_api_integration/common/suites/update.ts +++ b/x-pack/test/saved_object_api_integration/common/suites/update.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { SuperTest } from 'supertest'; import { DEFAULT_SPACE_ID } from '../../../../plugins/spaces/common/constants'; import { getIdPrefix, getUrlPrefix } from '../lib/space_test_utils'; diff --git a/x-pack/test/saved_object_api_integration/spaces_only/apis/bulk_create.ts b/x-pack/test/saved_object_api_integration/spaces_only/apis/bulk_create.ts index cf794079a42ea..efbc14060c9f2 100644 --- a/x-pack/test/saved_object_api_integration/spaces_only/apis/bulk_create.ts +++ b/x-pack/test/saved_object_api_integration/spaces_only/apis/bulk_create.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { SPACES } from '../../common/lib/spaces'; import { TestInvoker } from '../../common/lib/types'; import { bulkCreateTestSuiteFactory } from '../../common/suites/bulk_create'; diff --git a/x-pack/test/saved_object_api_integration/spaces_only/apis/create.ts b/x-pack/test/saved_object_api_integration/spaces_only/apis/create.ts index 129023130e716..0c29292f293cb 100644 --- a/x-pack/test/saved_object_api_integration/spaces_only/apis/create.ts +++ b/x-pack/test/saved_object_api_integration/spaces_only/apis/create.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { SPACES } from '../../common/lib/spaces'; import { TestInvoker } from '../../common/lib/types'; import { createTestSuiteFactory } from '../../common/suites/create'; diff --git a/x-pack/test/spaces_api_integration/common/suites/create.ts b/x-pack/test/spaces_api_integration/common/suites/create.ts index 4a8b2bc5c9e8d..6af5afc2530c7 100644 --- a/x-pack/test/spaces_api_integration/common/suites/create.ts +++ b/x-pack/test/spaces_api_integration/common/suites/create.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { SuperTest } from 'supertest'; import { getUrlPrefix } from '../lib/space_test_utils'; import { DescribeFn, TestDefinitionAuthentication } from '../lib/types'; diff --git a/x-pack/test/spaces_api_integration/common/suites/delete.ts b/x-pack/test/spaces_api_integration/common/suites/delete.ts index 4ebd26190f9de..2cf2d9388665a 100644 --- a/x-pack/test/spaces_api_integration/common/suites/delete.ts +++ b/x-pack/test/spaces_api_integration/common/suites/delete.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { SuperTest } from 'supertest'; import { getUrlPrefix } from '../lib/space_test_utils'; import { DescribeFn, TestDefinitionAuthentication } from '../lib/types'; diff --git a/x-pack/test/spaces_api_integration/common/suites/get.ts b/x-pack/test/spaces_api_integration/common/suites/get.ts index dd9e686de75a1..06fda9313f7a2 100644 --- a/x-pack/test/spaces_api_integration/common/suites/get.ts +++ b/x-pack/test/spaces_api_integration/common/suites/get.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { SuperAgent } from 'superagent'; import { getUrlPrefix } from '../lib/space_test_utils'; import { DescribeFn, TestDefinitionAuthentication } from '../lib/types'; diff --git a/x-pack/test/spaces_api_integration/common/suites/get_all.ts b/x-pack/test/spaces_api_integration/common/suites/get_all.ts index 175fcc8f8bfb8..64acb60308c41 100644 --- a/x-pack/test/spaces_api_integration/common/suites/get_all.ts +++ b/x-pack/test/spaces_api_integration/common/suites/get_all.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { SuperTest } from 'supertest'; import { getUrlPrefix } from '../lib/space_test_utils'; import { DescribeFn, TestDefinitionAuthentication } from '../lib/types'; diff --git a/x-pack/test/spaces_api_integration/common/suites/select.ts b/x-pack/test/spaces_api_integration/common/suites/select.ts index b9f67d9f0596a..489dc9f26529b 100644 --- a/x-pack/test/spaces_api_integration/common/suites/select.ts +++ b/x-pack/test/spaces_api_integration/common/suites/select.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { SuperTest } from 'supertest'; import { DEFAULT_SPACE_ID } from '../../../../plugins/spaces/common/constants'; import { getUrlPrefix } from '../lib/space_test_utils'; diff --git a/x-pack/test/spaces_api_integration/common/suites/update.ts b/x-pack/test/spaces_api_integration/common/suites/update.ts index a0cb1a9441730..88297df311334 100644 --- a/x-pack/test/spaces_api_integration/common/suites/update.ts +++ b/x-pack/test/spaces_api_integration/common/suites/update.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { SuperTest } from 'supertest'; import { getUrlPrefix } from '../lib/space_test_utils'; import { DescribeFn, TestDefinitionAuthentication } from '../lib/types'; diff --git a/x-pack/test/token_api_integration/auth/session.js b/x-pack/test/token_api_integration/auth/session.js index 953873a615f53..ad7750f46ec29 100644 --- a/x-pack/test/token_api_integration/auth/session.js +++ b/x-pack/test/token_api_integration/auth/session.js @@ -5,6 +5,7 @@ */ import request from 'request'; +import expect from '@kbn/expect'; const delay = ms => new Promise(resolve => setTimeout(() => resolve(), ms)); @@ -122,5 +123,36 @@ export default function ({ getService }) { .expect(200); }); }); + + describe('API access with missing access token document.', () => { + let sessionCookie; + beforeEach(async () => sessionCookie = await createSessionCookie()); + + it('should clear cookie and redirect to login', async function () { + // Let's delete tokens from `.security` index directly to simulate the case when + // Elasticsearch automatically removes access/refresh token document from the index + // after some period of time. + const esResponse = await getService('es').deleteByQuery({ + index: '.security', + q: 'doc_type:token', + refresh: true, + }); + expect(esResponse).to.have.property('deleted').greaterThan(0); + + const response = await supertest.get('/abc/xyz/') + .set('Cookie', sessionCookie.cookieString()) + .expect('location', '/login?next=%2Fabc%2Fxyz%2F') + .expect(302); + + const cookies = response.headers['set-cookie']; + expect(cookies).to.have.length(1); + + const cookie = request.cookie(cookies[0]); + expect(cookie.key).to.be('sid'); + expect(cookie.value).to.be.empty(); + expect(cookie.path).to.be('/'); + expect(cookie.httpOnly).to.be(true); + }); + }); }); } diff --git a/x-pack/test/tsconfig.json b/x-pack/test/tsconfig.json index 2e9fc43a6aa62..a22ce122b1766 100644 --- a/x-pack/test/tsconfig.json +++ b/x-pack/test/tsconfig.json @@ -2,7 +2,6 @@ "extends": "../tsconfig.json", "compilerOptions": { "types": [ - "@kbn/test/types/expect.js", "mocha", "node" ] diff --git a/x-pack/test/upgrade_assistant_integration/upgrade_assistant/reindexing.js b/x-pack/test/upgrade_assistant_integration/upgrade_assistant/reindexing.js index 56f1171de944d..ae48c38a23fe6 100644 --- a/x-pack/test/upgrade_assistant_integration/upgrade_assistant/reindexing.js +++ b/x-pack/test/upgrade_assistant_integration/upgrade_assistant/reindexing.js @@ -5,7 +5,7 @@ */ -import expect from 'expect.js'; +import expect from '@kbn/expect'; import { ReindexStatus, REINDEX_OP_TYPE } from '../../../plugins/upgrade_assistant/common/types'; diff --git a/x-pack/test_utils/index.js b/x-pack/test_utils/index.js index 47e0c732ab135..7eca11c3f559b 100644 --- a/x-pack/test_utils/index.js +++ b/x-pack/test_utils/index.js @@ -5,4 +5,5 @@ */ export { registerTestBed } from './testbed'; -export { getRandomString } from './lib'; +export { getRandomString, nextTick } from './lib'; +export { findTestSubject } from '@elastic/eui/lib/test'; diff --git a/x-pack/test_utils/jest/config.integration.js b/x-pack/test_utils/jest/config.integration.js index 9b3a764855128..242942594d985 100644 --- a/x-pack/test_utils/jest/config.integration.js +++ b/x-pack/test_utils/jest/config.integration.js @@ -19,4 +19,7 @@ export default { 'default', ['/../src/dev/jest/junit_reporter.js', { reportName: 'Jest Integration Tests' }], ], + setupFilesAfterEnv: [ + '/../src/dev/jest/setup/after_env.integration.js' + ] }; diff --git a/x-pack/test_utils/jest/config.js b/x-pack/test_utils/jest/config.js index 014c3793c585d..e460c705f293c 100644 --- a/x-pack/test_utils/jest/config.js +++ b/x-pack/test_utils/jest/config.js @@ -31,11 +31,6 @@ export default { coverageReporters: [ 'html', ], - globals: { - 'ts-jest': { - skipBabel: true, - }, - }, moduleFileExtensions: [ 'js', 'json', @@ -55,8 +50,7 @@ export default { 'integration_tests/' ], transform: { - '^.+\\.js$': '/../src/dev/jest/babel_transform.js', - '^.+\\.tsx?$': '/../src/dev/jest/ts_transform.js', + '^.+\\.(js|tsx?)$': '/../src/dev/jest/babel_transform.js', '^.+\\.txt?$': 'jest-raw-loader', '^.+\\.html?$': 'jest-raw-loader', }, diff --git a/x-pack/test_utils/lib/index.js b/x-pack/test_utils/lib/index.js index e78e377157355..49c8ada6806b0 100644 --- a/x-pack/test_utils/lib/index.js +++ b/x-pack/test_utils/lib/index.js @@ -6,3 +6,4 @@ export { getRandomString } from './strings'; +export { nextTick } from './utils'; diff --git a/x-pack/test_utils/lib/strings.js b/x-pack/test_utils/lib/strings.js index 1c88ecf1a636a..f4ea808062edf 100644 --- a/x-pack/test_utils/lib/strings.js +++ b/x-pack/test_utils/lib/strings.js @@ -9,4 +9,4 @@ import Chance from 'chance'; const chance = new Chance(); const CHARS_POOL = 'abcdefghijklmnopqrstuvwxyz'; -export const getRandomString = () => `${chance.string({ pool: CHARS_POOL })}-${Date.now()}`; +export const getRandomString = (options = {}) => `${chance.string({ pool: CHARS_POOL, ...options })}-${Date.now()}`; diff --git a/x-pack/plugins/security/server/lib/errors.js b/x-pack/test_utils/lib/utils.js similarity index 66% rename from x-pack/plugins/security/server/lib/errors.js rename to x-pack/test_utils/lib/utils.js index 0f8a0f0d8c0a9..85ab84d96cba3 100644 --- a/x-pack/plugins/security/server/lib/errors.js +++ b/x-pack/test_utils/lib/utils.js @@ -4,8 +4,5 @@ * you may not use this file except in compliance with the Elastic License. */ -import { boomify } from 'boom'; -export function wrapError(error) { - return boomify(error, { statusCode: error.status }); -} +export const nextTick = (time = 0) => new Promise((resolve) => setTimeout(resolve, time)); diff --git a/x-pack/test_utils/testbed/testbed.js b/x-pack/test_utils/testbed/testbed.js index 03477d46ab465..30bd82c710d87 100644 --- a/x-pack/test_utils/testbed/testbed.js +++ b/x-pack/test_utils/testbed/testbed.js @@ -4,20 +4,75 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; +import React, { Component } from 'react'; +import { MemoryRouter, Route } from 'react-router-dom'; +import PropTypes from 'prop-types'; import { Provider } from 'react-redux'; import { mountWithIntl } from '../enzyme_helpers'; -import { findTestSubject as findTestSubjectHelper } from '@elastic/eui/lib/test'; +import { findTestSubject as findTestSubjectHelper } from '../index'; const registerTestSubjExists = component => (testSubject, count = 1) => findTestSubjectHelper(component, testSubject).length === count; -export const registerTestBed = (Component, defaultProps, store = {}) => (props) => { +const defaultOptions = { + memoryRouter: { + wrapRoute: true, + }, +}; + +const withRoute = (WrappedComponent, componentRoutePath = '/', onRouter = () => {}) => { + return class extends Component { + static contextTypes = { + router: PropTypes.object + }; + + componentDidMount() { + const { router } = this.context; + onRouter(router); + } + + render() { + return ( + } + /> + ); + } + }; +}; + + +/** + * Register a testBed for a React component to be tested inside a Redux provider + * + * @param {React.SFC} Component A react component to test + * @param {object} defaultProps Props to initialize the component with + * @param {object} store The Redux store to initialize the Redux Provider with + * + * @returns {object} with the following properties: + * + * - component The component wrapped by the Redux provider + * - exists() Method to check if a test subject exists in the mounted component + * - find() Method to find a test subject in the mounted componenet + * - setProp() Method to update the props on the wrapped component + * - getFormErrorsMessages() Method that will find all the "".euiFormErrorText" from eui and return their text + * - getMetadataFromEuiTable() Method that will extract the table rows and column + their values from an Eui tablle component + * - form.setInput() Method to update a form input value + * - form.selectCheckBox() Method to select a form checkbox + */ +export const registerTestBed = (Component, defaultProps, store = {}) => (props, options = defaultOptions) => { + const Comp = options.memoryRouter.wrapRoute === false + ? Component + : withRoute(Component, options.memoryRouter.componentRoutePath, options.memoryRouter.onRouter); + const component = mountWithIntl( - + + + ); @@ -63,7 +118,13 @@ export const registerTestBed = (Component, defaultProps, store = {}) => (props) * @param {ReactWrapper} table enzyme react wrapper of the EuiBasicTable */ const getMetadataFromEuiTable = (tableTestSubject) => { - const rows = find(tableTestSubject) + const table = find(tableTestSubject); + + if (!table.length) { + throw new Error(`Eui Table "${tableTestSubject}" not found.`); + } + + const rows = table .find('tr') .slice(1) // we remove the first row as it is the table header .map(row => ({ diff --git a/x-pack/tsconfig.json b/x-pack/tsconfig.json index dd3ab033718b8..979d0737d03a9 100644 --- a/x-pack/tsconfig.json +++ b/x-pack/tsconfig.json @@ -32,8 +32,7 @@ }, "types": [ "node", - "jest", - "@kbn/test/types/expect.js" + "jest" ] } } diff --git a/yarn.lock b/yarn.lock index 6236beffd0ab7..ca116a43bfc9f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -35,7 +35,7 @@ esutils "^2.0.2" js-tokens "^3.0.0" -"@babel/core@^7.1.0", "@babel/core@^7.3.4": +"@babel/core@7.3.4", "@babel/core@^7.1.0", "@babel/core@^7.3.4": version "7.3.4" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.3.4.tgz#921a5a13746c21e32445bf0798680e9d11a6530b" integrity sha512-jRsuseXBo9pN197KnDwhhaaBzyZr2oIcLHHTt2oDdQrej5Qp57dCCJafWx5ivU8/alEYDpssYqv1MUqcxwQlrA== @@ -259,7 +259,7 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.3", "@babel/parser@^7.2.2", "@babel/parser@^7.3.4": +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.1.3", "@babel/parser@^7.2.2", "@babel/parser@^7.3.4": version "7.3.4" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.3.4.tgz#a43357e4bbf4b92a437fb9e465c192848287f27c" integrity sha512-tXZCqWtlOOP4wgCp6RjRvLmfuhnqTLy9VHwRochJBCP2nDm27JnnuFEnXFASVyQNHk36jD1tAammsCEEqgscIQ== @@ -596,6 +596,16 @@ resolve "^1.8.1" semver "^5.5.1" +"@babel/plugin-transform-runtime@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.3.4.tgz#57805ac8c1798d102ecd75c03b024a5b3ea9b431" + integrity sha512-PaoARuztAdd5MgeVjAxnIDAIUet5KpogqaefQvPOmPYCxYoaPhautxDh3aO8a4xHsKgT/b9gSxR0BKK1MIewPA== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + resolve "^1.8.1" + semver "^5.5.1" + "@babel/plugin-transform-shorthand-properties@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz#6333aee2f8d6ee7e28615457298934a3b46198f0" @@ -650,6 +660,14 @@ "@babel/helper-regex" "^7.0.0" regexpu-core "^4.1.3" +"@babel/polyfill@7.2.5", "@babel/polyfill@^7.2.5": + version "7.2.5" + resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.2.5.tgz#6c54b964f71ad27edddc567d065e57e87ed7fa7d" + integrity sha512-8Y/t3MWThtMLYr0YNC/Q76tqN1w30+b0uQMeFUYauG2UGTR19zyUtFrAzT23zNtBxPp+LbE5E/nwV/q/r3y6ug== + dependencies: + core-js "^2.5.7" + regenerator-runtime "^0.12.0" + "@babel/preset-env@^7.1.0", "@babel/preset-env@^7.3.4": version "7.3.4" resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.3.4.tgz#887cf38b6d23c82f19b5135298bdb160062e33e1" @@ -726,6 +744,19 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-typescript" "^7.3.2" +"@babel/register@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.0.0.tgz#fa634bae1bfa429f60615b754fc1f1d745edd827" + integrity sha512-f/+CRmaCe7rVEvcvPvxeA8j5aJhHC3aJie7YuqcMDhUOuyWLA7J/aNrTaHIzoWPEhpHA54mec4Mm8fv8KBlv3g== + dependencies: + core-js "^2.5.7" + find-cache-dir "^1.0.0" + home-or-tmp "^3.0.0" + lodash "^4.17.10" + mkdirp "^0.5.1" + pirates "^4.0.0" + source-map-support "^0.5.9" + "@babel/runtime@7.0.0-beta.54": version "7.0.0-beta.54" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0-beta.54.tgz#39ebb42723fe7ca4b3e1b00e967e80138d47cadf" @@ -741,6 +772,20 @@ dependencies: regenerator-runtime "^0.12.0" +"@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4": + version "7.3.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.3.4.tgz#73d12ba819e365fcf7fd152aed56d6df97d21c83" + integrity sha512-IvfvnMdSaLBateu0jfsYIpZTxAc2cKEXEMiezGGN75QcBcecDUKd3PgLAncT0oOgxKy8dd8hrJKj9MfzgfZd6g== + dependencies: + regenerator-runtime "^0.12.0" + +"@babel/runtime@^7.4.2": + version "7.4.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.4.2.tgz#f5ab6897320f16decd855eed70b705908a313fe8" + integrity sha512-7Bl2rALb7HpvXFL7TETNzKSAeBVCPHELzc0C//9FCxN8nsiueWSJBqaF+2oIJScyILStASR/Cx5WMkXGYTiJFA== + dependencies: + regenerator-runtime "^0.13.2" + "@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.1.2", "@babel/template@^7.2.2": version "7.2.2" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.2.2.tgz#005b3fdf0ed96e88041330379e0da9a708eb2907" @@ -796,36 +841,10 @@ tabbable "^1.1.0" uuid "^3.1.0" -"@elastic/eui@9.4.0": - version "9.4.0" - resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-9.4.0.tgz#e5f83c612674fc6f59e990f557e563be1409d25e" - integrity sha512-cQnsU3UeQ1s6F427vY53lzlh7mvNoPmIvPL24B5jH3JYaWULhIL1xSJXJgDSOSdrdHCxkXDD9Q8Y7256x4Xf4Q== - dependencies: - "@types/lodash" "^4.14.116" - "@types/numeral" "^0.0.25" - classnames "^2.2.5" - core-js "^2.5.1" - highlight.js "^9.12.0" - html "^1.0.0" - keymirror "^0.1.1" - lodash "^4.17.11" - numeral "^2.0.6" - prop-types "^15.6.0" - react-ace "^5.5.0" - react-color "^2.13.8" - react-focus-lock "^1.17.7" - react-input-autosize "^2.2.1" - react-is "~16.3.0" - react-virtualized "^9.18.5" - react-vis "1.10.2" - resize-observer-polyfill "^1.5.0" - tabbable "^1.1.0" - uuid "^3.1.0" - -"@elastic/eui@9.5.0": - version "9.5.0" - resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-9.5.0.tgz#233b4722b0cd2506793472ec1c6b97640a365229" - integrity sha512-LXtCNJxdbH6+ajb1x0/AvEAnpdNMQzlDubj+yqP8XShNiNBPMa3M7Hzdb5iSPJ4TL/EPuGrUQbMPx4aZNKLc1g== +"@elastic/eui@9.7.1": + version "9.7.1" + resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-9.7.1.tgz#817b5018303a2c6160011e201a8d21fca2f3e47b" + integrity sha512-yYTnW1jqv586M8dD4TxTa/9wkj84gJuHeDh9F13z7XGeZ/clUN0XP43Y5Jzv80Q3M80VlEuTpABYMGpPqBAw8w== dependencies: "@types/lodash" "^4.14.116" "@types/numeral" "^0.0.25" @@ -1045,6 +1064,14 @@ normalize-path "^2.0.1" through2 "^2.0.3" +"@jest/types@^24.5.0": + version "24.5.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.5.0.tgz#feee214a4d0167b0ca447284e95a57aa10b3ee95" + integrity sha512-kN7RFzNMf2R8UDadPOl6ReyI+MT8xfqRuAnuVL+i4gwjv/zubdDK+EDeLHYwq1j0CSSR2W/MmgaRlMZJzXdmVA== + dependencies: + "@types/istanbul-lib-coverage" "^1.1.0" + "@types/yargs" "^12.0.9" + "@mapbox/geojson-area@0.2.2": version "0.2.2" resolved "https://registry.yarnpkg.com/@mapbox/geojson-area/-/geojson-area-0.2.2.tgz#18d7814aa36bf23fbbcc379f8e26a22927debf10" @@ -1131,6 +1158,11 @@ dependencies: url-pattern "^1.0.3" +"@sheerun/mutationobserver-shim@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.2.tgz#8013f2af54a2b7d735f71560ff360d3a8176a87b" + integrity sha512-vTCdPp/T/Q3oSqwHmZ5Kpa9oI7iLtGl3RQaA/NyLHikvcrPxACkkKVr/XzkSPJWXHRhKGzVvb0urJsbMlRxi1Q== + "@sindresorhus/is@^0.7.0": version "0.7.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" @@ -1580,45 +1612,45 @@ resolved "https://registry.yarnpkg.com/@types/async/-/async-2.0.49.tgz#92e33d13f74c895cb9a7f38ba97db8431ed14bc0" integrity sha512-Benr3i5odUkvpFkOpzGqrltGdbSs+EVCkEBGXbuR7uT0VzhXKIkhem6PDzHdx5EonA+rfbB3QvP6aDOw5+zp5Q== -"@types/babel-core@^6.25.5": - version "6.25.5" - resolved "https://registry.yarnpkg.com/@types/babel-core/-/babel-core-6.25.5.tgz#7598b1287c2cb5a8e9150d60e4d4a8f2dbe29982" - integrity sha512-pecvyMrc46zY0AFYXVZWNmm/gekr7f32OBYCd9baOiIpOTFtNN0ormeWpJaG7p+MEzncUvNtJdYql94dZYZGsw== - dependencies: - "@types/babel-generator" "*" - "@types/babel-template" "*" - "@types/babel-traverse" "*" - "@types/babel-types" "*" - "@types/babylon" "*" +"@types/babel-types@*", "@types/babel-types@^7.0.0": + version "7.0.4" + resolved "https://registry.yarnpkg.com/@types/babel-types/-/babel-types-7.0.4.tgz#bfd5b0d0d1ba13e351dff65b6e52783b816826c8" + integrity sha512-WiZhq3SVJHFRgRYLXvpf65XnV6ipVHhnNaNvE8yCimejrGglkg38kEj0JcizqwSHxmPSjcTlig/6JouxLGEhGw== -"@types/babel-generator@*": - version "6.25.2" - resolved "https://registry.yarnpkg.com/@types/babel-generator/-/babel-generator-6.25.2.tgz#fa13653ec2d34a4037be9c34dec32ae75bea04cc" - integrity sha512-W7PQkeDlYOqJblfNeqZARwj4W8nO+ZhQQZksU8+wbaKuHeUdIVUAdREO/Qb0FfNr3CY5Sq1gNtqsyFeZfS3iSw== +"@types/babel__core@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.0.tgz#710f2487dda4dcfd010ca6abb2b4dc7394365c51" + integrity sha512-wJTeJRt7BToFx3USrCDs2BhEi4ijBInTQjOIukj6a/5tEkwpFMVZ+1ppgmE+Q/FQyc5P/VWUbx7I9NELrKruHA== dependencies: - "@types/babel-types" "*" + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" -"@types/babel-template@*": - version "6.25.1" - resolved "https://registry.yarnpkg.com/@types/babel-template/-/babel-template-6.25.1.tgz#03e23a893c16bab2ec00200ab51feccf488cae78" - integrity sha512-teJYxh35PbBaf9OY6YwLSQ7pRiWRnHCHmlqwfVSfexOsqHUf6hpNZ4FG9PfgnpBM1VRzRJVQF3SqqOtkcNrBZQ== +"@types/babel__generator@*": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.0.2.tgz#d2112a6b21fad600d7674274293c85dce0cb47fc" + integrity sha512-NHcOfab3Zw4q5sEE2COkpfXjoE7o+PmqD9DQW4koUT3roNxwziUdXGnRndMat/LJNUtePwn1TlP4do3uoe3KZQ== dependencies: - "@types/babel-types" "*" - "@types/babylon" "*" + "@babel/types" "^7.0.0" -"@types/babel-traverse@*": - version "6.25.4" - resolved "https://registry.yarnpkg.com/@types/babel-traverse/-/babel-traverse-6.25.4.tgz#269af6a25c80419b635c8fa29ae42b0d5ce2418c" - integrity sha512-+/670NaZE7qPvdh8EtGds32/2uHFKE5JeS+7ePH6nGwF8Wj8r671/RkTiJQP2k22nFntWEb9xQ11MFj7xEqI0g== +"@types/babel__template@*": + version "7.0.2" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.0.2.tgz#4ff63d6b52eddac1de7b975a5223ed32ecea9307" + integrity sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg== dependencies: - "@types/babel-types" "*" + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" -"@types/babel-types@*", "@types/babel-types@^7.0.0": - version "7.0.4" - resolved "https://registry.yarnpkg.com/@types/babel-types/-/babel-types-7.0.4.tgz#bfd5b0d0d1ba13e351dff65b6e52783b816826c8" - integrity sha512-WiZhq3SVJHFRgRYLXvpf65XnV6ipVHhnNaNvE8yCimejrGglkg38kEj0JcizqwSHxmPSjcTlig/6JouxLGEhGw== +"@types/babel__traverse@*": + version "7.0.6" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.0.6.tgz#328dd1a8fc4cfe3c8458be9477b219ea158fd7b2" + integrity sha512-XYVgHF2sQ0YblLRMLNPB3CkFMewzFmlDsH/TneZFHUXDlABQgh88uOxuez7ZcXxayLFrqLwtDH1t+FmlFwNZxw== + dependencies: + "@babel/types" "^7.3.0" -"@types/babylon@*", "@types/babylon@6.16.3", "@types/babylon@^6.16.2": +"@types/babylon@6.16.3", "@types/babylon@^6.16.2": version "6.16.3" resolved "https://registry.yarnpkg.com/@types/babylon/-/babylon-6.16.3.tgz#c2937813a89fcb5e79a00062fc4a8b143e7237bb" integrity sha512-lyJ8sW1PbY3uwuvpOBZ9zMYKshMnQpXmeDHh8dj9j2nJm/xrW0FgB5gLSYOArj5X0IfaXnmhFoJnhS4KbqIMug== @@ -1790,10 +1822,10 @@ "@types/cheerio" "*" "@types/react" "*" -"@types/eslint@^4.16.2": - version "4.16.2" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-4.16.2.tgz#30f4f026019eb78a6ef12f276b75cd16ea2afb27" - integrity sha512-gCqhoFlyLic8Ux1OQt9cjlPbXk/dS7zPpofazBkie6SWCl+e1IEZBgLqyakm27nh0/uSZYW2TqkBusV9fLmztw== +"@types/eslint@^4.16.6": + version "4.16.6" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-4.16.6.tgz#96d4ecddbea618ab0b55eaf0dffedf387129b06c" + integrity sha512-GL7tGJig55FeclpOytU7nCCqtR143jBoC7AUdH0DO9xBSIFiNNUFCY/S3KNWsHeQJuU3hjw/OC1+kRTFNXqUZQ== dependencies: "@types/estree" "*" "@types/json-schema" "*" @@ -1934,6 +1966,11 @@ dependencies: "@types/node" "*" +"@types/istanbul-lib-coverage@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.0.tgz#2cc2ca41051498382b43157c8227fea60363f94a" + integrity sha512-ohkhb9LehJy+PA40rDtGAji61NCgdtKLAlFoYp4cnuuQEswwdK3vz9SOIkkyc3wrk8dzjphQApNs56yyXLStaQ== + "@types/jest-diff@*": version "20.0.1" resolved "https://registry.yarnpkg.com/@types/jest-diff/-/jest-diff-20.0.1.tgz#35cc15b9c4f30a18ef21852e255fdb02f6d59b89" @@ -2034,6 +2071,11 @@ resolved "https://registry.yarnpkg.com/@types/loglevel/-/loglevel-1.5.3.tgz#adfce55383edc5998a2170ad581b3e23d6adb5b8" integrity sha512-TzzIZihV+y9kxSg5xJMkyIkaoGkXi50isZTtGHObNHRqAAwjGNjSCNPI7AUAv0tZUKTq9f2cdkCUd/2JVZUTrA== +"@types/lru-cache@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.0.tgz#57f228f2b80c046b4a1bd5cac031f81f207f4f03" + integrity sha512-RaE0B+14ToE4l6UqdarKPnXwVDuigfFv+5j9Dze/Nqr23yyuqdNvzcZi3xB+3Agvi5R4EOgAksfv3lXX4vBt9w== + "@types/mime-db@*": version "1.27.0" resolved "https://registry.yarnpkg.com/@types/mime-db/-/mime-db-1.27.0.tgz#9bc014a1fd1fdf47649c1a54c6dd7966b8284792" @@ -2102,6 +2144,11 @@ resolved "https://registry.yarnpkg.com/@types/numeral/-/numeral-0.0.25.tgz#b6f55062827a4787fe4ab151cf3412a468e65271" integrity sha512-ShHzHkYD+Ldw3eyttptCpUhF1/mkInWwasQkCNXZHOsJMJ/UMa8wXrxSrTJaVk0r4pLK/VnESVM0wFsfQzNEKQ== +"@types/object-hash@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@types/object-hash/-/object-hash-1.2.0.tgz#d65904331bd0b05c7d5ece75f9ddfdbe82affd30" + integrity sha512-0JKYQRatHdzijO/ni7JV5eHUJWaMRpGvwiABk8U5iAk5Corm0yLNEfYGNkZWYc+wCyCKKpg0+TsZIvP8AymIYA== + "@types/opn@^5.1.0": version "5.1.0" resolved "https://registry.yarnpkg.com/@types/opn/-/opn-5.1.0.tgz#bff7bc371677f4bdbb37884400e03fd81f743927" @@ -2183,6 +2230,13 @@ dependencies: "@types/react" "*" +"@types/react-grid-layout@^0.16.7": + version "0.16.7" + resolved "https://registry.yarnpkg.com/@types/react-grid-layout/-/react-grid-layout-0.16.7.tgz#53d5f5034deb0c60e25a0fa578141e9a0982011f" + integrity sha512-A3tW9xySd03KGONkp8gP4+QRLuT1Mcx++m0hO0nZIM4H/Qwz8GsiDv+9okbmHk5HcsHwY5Jdsn6Cv50hwoNG+A== + dependencies: + "@types/react" "*" + "@types/react-intl@^2.3.15": version "2.3.17" resolved "https://registry.yarnpkg.com/@types/react-intl/-/react-intl-2.3.17.tgz#e1fc6e46e8af58bdef9531259d509380a8a99e8e" @@ -2402,6 +2456,11 @@ "@types/events" "*" "@types/node" "*" +"@types/yargs@^12.0.9": + version "12.0.10" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-12.0.10.tgz#17a8ec65cd8e88f51b418ceb271af18d3137df67" + integrity sha512-WsVzTPshvCSbHThUduGGxbmnwcpkgSctHGHTqzWyFg4lYAuV5qXlyFPOsP3OWqCINfmg/8VXP+zJaa4OxEsBQQ== + "@types/zen-observable@^0.8.0": version "0.8.0" resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.0.tgz#8b63ab7f1aa5321248aad5ac890a485656dcea4d" @@ -2809,19 +2868,17 @@ acorn-jsx@^3.0.0: dependencies: acorn "^3.0.4" -acorn-jsx@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-4.1.1.tgz#e8e41e48ea2fe0c896740610ab6a4ffd8add225e" - integrity sha512-JY+iV6r+cO21KtntVvFkD+iqjtdpRUpGqKWgfkCdZq1R+kbreEl8EcdcJR4SmiIgsIQT33s6QzheQ9a275Q8xw== - dependencies: - acorn "^5.0.3" +acorn-jsx@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e" + integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg== acorn-walk@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.0.1.tgz#c7827bdbb8e21aa97b609adfa225400d9ae348ba" integrity sha512-PqVQ8c6a3kyqdsUZlC7nljp3FFuxipBRHKu+7C1h8QygBFlzTaDX5HD383jej3Peed+1aDG8HwkfB1Z1HMNPkw== -acorn@5.X, acorn@^5.0.3, acorn@^5.5.0, acorn@^5.6.0, acorn@^5.6.2, acorn@^5.7.1: +acorn@5.X, acorn@^5.0.3, acorn@^5.5.0, acorn@^5.6.2, acorn@^5.7.1: version "5.7.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== @@ -2846,6 +2903,11 @@ acorn@^6.0.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.4.tgz#77377e7353b72ec5104550aa2d2097a2fd40b754" integrity sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg== +acorn@^6.0.7: + version "6.1.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f" + integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA== + address@1.0.3, address@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/address/-/address-1.0.3.tgz#b5f50631f8d6cec8bd20c963963afb55e06cbce9" @@ -2928,7 +2990,7 @@ ajv-keywords@^1.0.0: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" integrity sha1-MU3QpLM2j609/NxU7eYXG4htrzw= -ajv-keywords@^3.0.0, ajv-keywords@^3.1.0: +ajv-keywords@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" integrity sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo= @@ -2951,7 +3013,7 @@ ajv@^5.0.0, ajv@^5.1.0: fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.3.0" -ajv@^6.0.1, ajv@^6.1.0, ajv@^6.1.1, ajv@^6.5.3, ajv@^6.5.5: +ajv@^6.1.0, ajv@^6.1.1, ajv@^6.5.5: version "6.5.5" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.5.tgz#cf97cdade71c6399a92c6d6c4177381291b781a1" integrity sha512-7q7gtRQDJSyuEHjuVgHoUa2VuemFiCMrfQc9Tc08XTAc4Zj/5U1buQJ0HU6i7fKjXU09SVgSmxa4sLvuvS8Iyg== @@ -2961,6 +3023,16 @@ ajv@^6.0.1, ajv@^6.1.0, ajv@^6.1.1, ajv@^6.5.3, ajv@^6.5.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^6.9.1: + version "6.9.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.9.2.tgz#4927adb83e7f48e5a32b45729744c71ec39c9c7b" + integrity sha512-4UFy0/LgDo7Oa/+wOAlj44tp9K78u38E5/359eSrqEp1Z5PdVfimCcs7SluXMP755RUQu6d2b4AvF0R1C9RZjg== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + align-text@^0.1.1, align-text@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" @@ -3075,6 +3147,11 @@ ansi-escapes@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.0.0.tgz#ec3e8b4e9f8064fc02c3ac9b65f1c275bda8ef92" integrity sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ== +ansi-escapes@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== + ansi-gray@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" @@ -3868,7 +3945,7 @@ axios@^0.18.0: follow-redirects "^1.3.0" is-buffer "^1.1.5" -axobject-query@^2.0.1: +axobject-query@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.0.2.tgz#ea187abe5b9002b377f925d8bf7d1c561adf38f9" integrity sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww== @@ -3880,28 +3957,6 @@ b64@4.x.x: resolved "https://registry.yarnpkg.com/b64/-/b64-4.0.0.tgz#c37f587f0a383c7019e821120e8c3f58f0d22772" integrity sha512-EhmUQodKB0sdzPPrbIWbGqA5cQeTWxYrAgNeeT1rLZWtD3tbNTnphz8J4vkXI3cPgBNlXBjzEbzDzq0Nwi4f9A== -babel-cli@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.26.0.tgz#502ab54874d7db88ad00b887a06383ce03d002f1" - integrity sha1-UCq1SHTX24itALiHoGODzgPQAvE= - dependencies: - babel-core "^6.26.0" - babel-polyfill "^6.26.0" - babel-register "^6.26.0" - babel-runtime "^6.26.0" - commander "^2.11.0" - convert-source-map "^1.5.0" - fs-readdir-recursive "^1.0.0" - glob "^7.1.2" - lodash "^4.17.4" - output-file-sync "^1.1.2" - path-is-absolute "^1.0.1" - slash "^1.0.0" - source-map "^0.5.6" - v8flags "^2.1.1" - optionalDependencies: - chokidar "^1.6.1" - babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" @@ -3911,60 +3966,10 @@ babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: esutils "^2.0.2" js-tokens "^3.0.2" -babel-core@6.26.3, babel-core@^6.26.3: - version "6.26.3" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" - integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA== - dependencies: - babel-code-frame "^6.26.0" - babel-generator "^6.26.0" - babel-helpers "^6.24.1" - babel-messages "^6.23.0" - babel-register "^6.26.0" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - convert-source-map "^1.5.1" - debug "^2.6.9" - json5 "^0.5.1" - lodash "^4.17.4" - minimatch "^3.0.4" - path-is-absolute "^1.0.1" - private "^0.1.8" - slash "^1.0.0" - source-map "^0.5.7" - -babel-core@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" - integrity sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g= - dependencies: - babel-code-frame "^6.26.0" - babel-generator "^6.26.0" - babel-helpers "^6.24.1" - babel-messages "^6.23.0" - babel-register "^6.26.0" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - convert-source-map "^1.5.0" - debug "^2.6.8" - json5 "^0.5.1" - lodash "^4.17.4" - minimatch "^3.0.4" - path-is-absolute "^1.0.1" - private "^0.1.7" - slash "^1.0.0" - source-map "^0.5.6" - -babel-eslint@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-9.0.0.tgz#7d9445f81ed9f60aff38115f838970df9f2b6220" - integrity sha512-itv1MwE3TMbY0QtNfeL7wzak1mV47Uy+n6HtSOO4Xd7rvmO+tsGQSgyOEEgo6Y2vHZKZphaoelNeSVj4vkLA1g== +babel-eslint@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.1.tgz#919681dc099614cd7d31d45c8908695092a1faed" + integrity sha512-z7OT1iNV+TjOwHNLLyJk+HN+YVWX+CLE6fPD2SymJZOZQBs+QIexFjhm4keGTm8MW9xr4EC9Q0PbaLB24V5GoQ== dependencies: "@babel/code-frame" "^7.0.0" "@babel/parser" "^7.0.0" @@ -3987,104 +3992,16 @@ babel-generator@^6.18.0: source-map "^0.5.7" trim-right "^1.0.1" -babel-generator@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.0.tgz#ac1ae20070b79f6e3ca1d3269613053774f20dc5" - integrity sha1-rBriAHC3n248odMmlhMFN3TyDcU= - dependencies: - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - detect-indent "^4.0.0" - jsesc "^1.3.0" - lodash "^4.17.4" - source-map "^0.5.6" - trim-right "^1.0.1" - -babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" - integrity sha1-zORReto1b0IgvK6KAsKzRvmlZmQ= - dependencies: - babel-helper-explode-assignable-expression "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-builder-react-jsx@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz#39ff8313b75c8b65dceff1f31d383e0ff2a408a0" - integrity sha1-Of+DE7dci2Xc7/HzHTg+D/KkCKA= - dependencies: - babel-runtime "^6.26.0" - babel-types "^6.26.0" - esutils "^2.0.2" - -babel-helper-call-delegate@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" - integrity sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340= - dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-define-map@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" - integrity sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8= - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - babel-helper-evaluate-path@^0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.5.0.tgz#a62fa9c4e64ff7ea5cea9353174ef023a900a67c" integrity sha512-mUh0UhS607bGh5wUMAQfOpt2JX2ThXMtppHRdRU1kL7ZLRWIXxoV2UIV1r2cAeeNeU1M5SB5/RSUgUxrK8yOkA== -babel-helper-explode-assignable-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" - integrity sha1-8luCz33BBDPFX3BZLVdGQArCLKo= - dependencies: - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - babel-helper-flip-expressions@^0.4.3: version "0.4.3" resolved "https://registry.yarnpkg.com/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.4.3.tgz#3696736a128ac18bc25254b5f40a22ceb3c1d3fd" integrity sha1-NpZzahKKwYvCUlS19AoizrPB0/0= -babel-helper-function-name@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" - integrity sha1-00dbjAPtmCQqJbSDUasYOZ01gKk= - dependencies: - babel-helper-get-function-arity "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-get-function-arity@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" - integrity sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-hoist-variables@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" - integrity sha1-HssnaJydJVE+rbyZFKc/VAi+enY= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - babel-helper-is-nodes-equiv@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/babel-helper-is-nodes-equiv/-/babel-helper-is-nodes-equiv-0.0.1.tgz#34e9b300b1479ddd98ec77ea0bbe9342dfe39684" @@ -4100,72 +4017,16 @@ babel-helper-mark-eval-scopes@^0.4.3: resolved "https://registry.yarnpkg.com/babel-helper-mark-eval-scopes/-/babel-helper-mark-eval-scopes-0.4.3.tgz#d244a3bef9844872603ffb46e22ce8acdf551562" integrity sha1-0kSjvvmESHJgP/tG4izorN9VFWI= -babel-helper-optimise-call-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" - integrity sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-regex@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" - integrity sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI= - dependencies: - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-helper-remap-async-to-generator@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" - integrity sha1-XsWBgnrXI/7N04HxySg5BnbkVRs= - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - babel-helper-remove-or-void@^0.4.3: version "0.4.3" resolved "https://registry.yarnpkg.com/babel-helper-remove-or-void/-/babel-helper-remove-or-void-0.4.3.tgz#a4f03b40077a0ffe88e45d07010dee241ff5ae60" integrity sha1-pPA7QAd6D/6I5F0HAQ3uJB/1rmA= -babel-helper-replace-supers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" - integrity sha1-v22/5Dk40XNpohPKiov3S2qQqxo= - dependencies: - babel-helper-optimise-call-expression "^6.24.1" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - babel-helper-to-multiple-sequence-expressions@^0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.5.0.tgz#a3f924e3561882d42fcf48907aa98f7979a4588d" integrity sha512-m2CvfDW4+1qfDdsrtf4dwOslQC3yhbgyBFptncp4wvtdrDHqueW7slsYv4gArie056phvQFhT2nRcGS4bnm6mA== -babel-helpers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" - integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI= - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-jest@^23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-23.6.0.tgz#a644232366557a2240a0c083da6b25786185a2f1" - integrity sha512-lqKGG6LYXYu+DQh/slrQ8nxXQkEkhugdXsU6St7GmhVS7Ilc/22ArwqXNJrf0QaOBjZB0360qZMwXqDYQHXaew== - dependencies: - babel-plugin-istanbul "^4.1.6" - babel-preset-jest "^23.2.0" - babel-jest@^24.1.0: version "24.1.0" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-24.1.0.tgz#441e23ef75ded3bd547e300ac3194cef87b55190" @@ -4176,14 +4037,15 @@ babel-jest@^24.1.0: chalk "^2.4.2" slash "^2.0.0" -babel-loader@7.1.5, babel-loader@^7.1.5: - version "7.1.5" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-7.1.5.tgz#e3ee0cd7394aa557e013b02d3e492bfd07aa6d68" - integrity sha512-iCHfbieL5d1LfOQeeVJEUyD9rTwBcP/fcEbRCfempxTDuqrKpu0AZjLAQHEQa3Yqyj9ORKe2iHfoj4rHLf7xpw== +babel-loader@8.0.5, babel-loader@^8.0.5: + version "8.0.5" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.0.5.tgz#225322d7509c2157655840bba52e46b6c2f2fe33" + integrity sha512-NTnHnVRd2JnRqPC0vW+iOQWU5pchDbYXsG2E6DMXEpMfUcQKclF9gmf3G3ZMhzG7IG9ji4coL0cm+FxeWxDpnw== dependencies: - find-cache-dir "^1.0.0" + find-cache-dir "^2.0.0" loader-utils "^1.0.2" mkdirp "^0.5.1" + util.promisify "^1.0.0" babel-messages@^6.23.0: version "6.23.0" @@ -4192,40 +4054,24 @@ babel-messages@^6.23.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-add-module-exports@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-0.2.1.tgz#9ae9a1f4a8dc67f0cdec4f4aeda1e43a5ff65e25" - integrity sha1-mumh9KjcZ/DN7E9K7aHkOl/2XiU= - -babel-plugin-check-es2015-constants@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" - integrity sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o= - dependencies: - babel-runtime "^6.22.0" +babel-plugin-add-module-exports@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-1.0.0.tgz#72b5424d941a336c6a35357f373d8b8366263031" + integrity sha512-m0sMxPL4FaN2K69GQgaRJa4Ny15qKSdoknIcpN+gz+NaJlAW9pge/povs13tPYsKDboflrEQC+/3kfIsONBTaw== + optionalDependencies: + chokidar "^2.0.4" -babel-plugin-inline-react-svg@^0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/babel-plugin-inline-react-svg/-/babel-plugin-inline-react-svg-0.5.4.tgz#bc818f351cd9d78f5b3bfa7cc1da5f83e7b4010a" - integrity sha512-Pr/J5kicFEpIvwooR3mytJWXfyGXoP4gp4QzTdN0jLoa7lU2OJVyhHMm17ekA3okxwbLaQehSc0kV/UVrj343w== +babel-plugin-inline-react-svg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-plugin-inline-react-svg/-/babel-plugin-inline-react-svg-1.0.1.tgz#1457edae1035a12b3c5026ef28a1239edc71d2a2" + integrity sha512-vTsG/L2cUN4XRJdJ1scYXMSBlgAxkZm/tgo1Lo/FulbPADztEtVOPUNuNDeEoRHZCz9RC0ZHXdVSJ/GaqahF/Q== dependencies: - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babylon "^6.18.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/parser" "^7.0.0" lodash.isplainobject "^4.0.6" resolve "^1.8.1" svgo "^0.7.2" -babel-plugin-istanbul@^4.1.6: - version "4.1.6" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz#36c59b2192efce81c5b378321b74175add1c9a45" - integrity sha512-PWP9FQ1AhZhS01T/4qLSKoHGY/xvkZdVBGlKM/HuxxS3+sC66HhTNR7+MpbO/so/cz/wY94MeSWJuP1hXIPfwQ== - dependencies: - babel-plugin-syntax-object-rest-spread "^6.13.0" - find-up "^2.1.0" - istanbul-lib-instrument "^1.10.1" - test-exclude "^4.2.1" - babel-plugin-istanbul@^5.1.0: version "5.1.1" resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.1.tgz#7981590f1956d75d67630ba46f0c22493588c893" @@ -4235,11 +4081,6 @@ babel-plugin-istanbul@^5.1.0: istanbul-lib-instrument "^3.0.0" test-exclude "^5.0.0" -babel-plugin-jest-hoist@^23.2.0: - version "23.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-23.2.0.tgz#e61fae05a1ca8801aadee57a6d66b8cefaf44167" - integrity sha1-5h+uBaHKiAGq3uV6bWa4zvr0QWc= - babel-plugin-jest-hoist@^24.1.0: version "24.1.0" resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.1.0.tgz#dfecc491fb15e2668abbd690a697a8fd1411a7f8" @@ -4327,10 +4168,10 @@ babel-plugin-minify-type-constructors@^0.4.3: dependencies: babel-helper-is-void-0 "^0.4.3" -babel-plugin-mock-imports@^0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/babel-plugin-mock-imports/-/babel-plugin-mock-imports-0.0.5.tgz#caa865f017d8972fe47772e0fb57f2924e5ce3c5" - integrity sha1-yqhl8BfYly/kd3Lg+1fykk5c48U= +babel-plugin-mock-imports@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-plugin-mock-imports/-/babel-plugin-mock-imports-1.0.1.tgz#1476ed4de911347d344fc81caab4beced80804b1" + integrity sha512-Nu4unCGKeqOfLlfnLPnv/pEHancdAGTqFqyArZ27gsKIiKxeZvMr87IHB8BxhMu3Bfc8fA8bx7hWt32aZbEwpQ== babel-plugin-react-docgen@^2.0.0: version "2.0.0" @@ -4340,78 +4181,10 @@ babel-plugin-react-docgen@^2.0.0: lodash "^4.17.10" react-docgen "^3.0.0-rc.1" -babel-plugin-require-context-hook@^1.0.0: +"babel-plugin-require-context-hook@npm:babel-plugin-require-context-hook-babel7@^1.0.0": version "1.0.0" - resolved "https://registry.yarnpkg.com/babel-plugin-require-context-hook/-/babel-plugin-require-context-hook-1.0.0.tgz#3f0e7cce87c338f53639b948632fd4e73834632d" - integrity sha512-EMZD1563QUqLhzrqcThk759RhuNVX/ZJdrtGK6drwzgvnR+ARjWyXIHPbu+tUNaMGtPz/gQeAM2M6VUw2UiUeA== - -babel-plugin-syntax-async-functions@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" - integrity sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU= - -babel-plugin-syntax-async-generators@^6.5.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz#6bc963ebb16eccbae6b92b596eb7f35c342a8b9a" - integrity sha1-a8lj67FuzLrmuStZbrfzXDQqi5o= - -babel-plugin-syntax-class-properties@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" - integrity sha1-1+sjt5oxf4VDlixQW4J8fWysJ94= - -babel-plugin-syntax-exponentiation-operator@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" - integrity sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4= - -babel-plugin-syntax-flow@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" - integrity sha1-TDqyCiryaqIM0lmVw5jE63AxDI0= - -babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" - integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY= - -babel-plugin-syntax-object-rest-spread@^6.13.0, babel-plugin-syntax-object-rest-spread@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" - integrity sha1-/WU28rzhODb/o6VFjEkDpZe7O/U= - -babel-plugin-syntax-trailing-function-commas@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" - integrity sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM= - -babel-plugin-transform-async-generator-functions@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz#f058900145fd3e9907a6ddf28da59f215258a5db" - integrity sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds= - dependencies: - babel-helper-remap-async-to-generator "^6.24.1" - babel-plugin-syntax-async-generators "^6.5.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-async-to-generator@^6.22.0, babel-plugin-transform-async-to-generator@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" - integrity sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E= - dependencies: - babel-helper-remap-async-to-generator "^6.24.1" - babel-plugin-syntax-async-functions "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-class-properties@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac" - integrity sha1-anl2PqYdM9NvN7YRqp3vgagbRqw= - dependencies: - babel-helper-function-name "^6.24.1" - babel-plugin-syntax-class-properties "^6.8.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-require-context-hook-babel7/-/babel-plugin-require-context-hook-babel7-1.0.0.tgz#1273d4cee7e343d0860966653759a45d727e815d" + integrity sha512-kez0BAN/cQoyO1Yu1nre1bQSYZEF93Fg7VQiBHFfMWuaZTy7vJSTT4FY68FwHTYG53Nyt0A7vpSObSVxwweQeQ== babel-plugin-transform-define@^1.3.1: version "1.3.1" @@ -4421,213 +4194,6 @@ babel-plugin-transform-define@^1.3.1: lodash "^4.17.11" traverse "0.6.6" -babel-plugin-transform-es2015-arrow-functions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" - integrity sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" - integrity sha1-u8UbSflk1wy42OC5ToICRs46YUE= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-block-scoping@^6.23.0, babel-plugin-transform-es2015-block-scoping@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" - integrity sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8= - dependencies: - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-plugin-transform-es2015-classes@^6.23.0, babel-plugin-transform-es2015-classes@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" - integrity sha1-WkxYpQyclGHlZLSyo7+ryXolhNs= - dependencies: - babel-helper-define-map "^6.24.1" - babel-helper-function-name "^6.24.1" - babel-helper-optimise-call-expression "^6.24.1" - babel-helper-replace-supers "^6.24.1" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-computed-properties@^6.22.0, babel-plugin-transform-es2015-computed-properties@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" - integrity sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM= - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-destructuring@^6.22.0, babel-plugin-transform-es2015-destructuring@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" - integrity sha1-mXux8auWf2gtKwh2/jWNYOdlxW0= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-duplicate-keys@^6.22.0, babel-plugin-transform-es2015-duplicate-keys@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" - integrity sha1-c+s9MQypaePvnskcU3QabxV2Qj4= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-for-of@^6.22.0, babel-plugin-transform-es2015-for-of@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" - integrity sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-function-name@^6.22.0, babel-plugin-transform-es2015-function-name@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" - integrity sha1-g0yJhTvDaxrw86TF26qU/Y6sqos= - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-literals@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" - integrity sha1-T1SgLWzWbPkVKAAZox0xklN3yi4= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" - integrity sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ= - dependencies: - babel-plugin-transform-es2015-modules-commonjs "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a" - integrity sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo= - dependencies: - babel-plugin-transform-strict-mode "^6.24.1" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-types "^6.26.0" - -babel-plugin-transform-es2015-modules-systemjs@^6.23.0, babel-plugin-transform-es2015-modules-systemjs@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" - integrity sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM= - dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-modules-umd@^6.23.0, babel-plugin-transform-es2015-modules-umd@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" - integrity sha1-rJl+YoXNGO1hdq22B9YCNErThGg= - dependencies: - babel-plugin-transform-es2015-modules-amd "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-object-super@^6.22.0, babel-plugin-transform-es2015-object-super@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" - integrity sha1-JM72muIcuDp/hgPa0CH1cusnj40= - dependencies: - babel-helper-replace-supers "^6.24.1" - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-parameters@^6.23.0, babel-plugin-transform-es2015-parameters@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" - integrity sha1-V6w1GrScrxSpfNE7CfZv3wpiXys= - dependencies: - babel-helper-call-delegate "^6.24.1" - babel-helper-get-function-arity "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-shorthand-properties@^6.22.0, babel-plugin-transform-es2015-shorthand-properties@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" - integrity sha1-JPh11nIch2YbvZmkYi5R8U3jiqA= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-spread@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" - integrity sha1-1taKmfia7cRTbIGlQujdnxdG+NE= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-sticky-regex@^6.22.0, babel-plugin-transform-es2015-sticky-regex@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" - integrity sha1-AMHNsaynERLN8M9hJsLta0V8zbw= - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-template-literals@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" - integrity sha1-qEs0UPfp+PH2g51taH2oS7EjbY0= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-typeof-symbol@^6.22.0, babel-plugin-transform-es2015-typeof-symbol@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" - integrity sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-unicode-regex@^6.22.0, babel-plugin-transform-es2015-unicode-regex@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" - integrity sha1-04sS9C6nMj9yk4fxinxa4frrNek= - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - regexpu-core "^2.0.0" - -babel-plugin-transform-exponentiation-operator@^6.22.0, babel-plugin-transform-exponentiation-operator@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" - integrity sha1-KrDJx/MJj6SJB3cruBP+QejeOg4= - dependencies: - babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" - babel-plugin-syntax-exponentiation-operator "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-flow-strip-types@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf" - integrity sha1-hMtnKTXUNxT9wyvOhFaNh0Qc988= - dependencies: - babel-plugin-syntax-flow "^6.18.0" - babel-runtime "^6.22.0" - babel-plugin-transform-inline-consecutive-adds@^0.4.3: version "0.4.3" resolved "https://registry.yarnpkg.com/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.4.3.tgz#323d47a3ea63a83a7ac3c811ae8e6941faf2b0d1" @@ -4648,14 +4214,6 @@ babel-plugin-transform-minify-booleans@^6.9.4: resolved "https://registry.yarnpkg.com/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.9.4.tgz#acbb3e56a3555dd23928e4b582d285162dd2b198" integrity sha1-rLs+VqNVXdI5KOS1gtKFFi3SsZg= -babel-plugin-transform-object-rest-spread@^6.22.0, babel-plugin-transform-object-rest-spread@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06" - integrity sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY= - dependencies: - babel-plugin-syntax-object-rest-spread "^6.8.0" - babel-runtime "^6.26.0" - babel-plugin-transform-property-literals@^6.9.4: version "6.9.4" resolved "https://registry.yarnpkg.com/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.9.4.tgz#98c1d21e255736573f93ece54459f6ce24985d39" @@ -4663,49 +4221,10 @@ babel-plugin-transform-property-literals@^6.9.4: dependencies: esutils "^2.0.2" -babel-plugin-transform-react-display-name@^6.23.0: - version "6.25.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz#67e2bf1f1e9c93ab08db96792e05392bf2cc28d1" - integrity sha1-Z+K/Hx6ck6sI25Z5LgU5K/LMKNE= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-react-jsx-self@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz#df6d80a9da2612a121e6ddd7558bcbecf06e636e" - integrity sha1-322AqdomEqEh5t3XVYvL7PBuY24= - dependencies: - babel-plugin-syntax-jsx "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-react-jsx-source@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz#66ac12153f5cd2d17b3c19268f4bf0197f44ecd6" - integrity sha1-ZqwSFT9c0tF7PBkmj0vwGX9E7NY= - dependencies: - babel-plugin-syntax-jsx "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-react-jsx@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz#840a028e7df460dfc3a2d29f0c0d91f6376e66a3" - integrity sha1-hAoCjn30YN/DotKfDA2R9jduZqM= - dependencies: - babel-helper-builder-react-jsx "^6.24.1" - babel-plugin-syntax-jsx "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-react-remove-prop-types@^0.4.14: - version "0.4.15" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.15.tgz#7ba830e77276a0e788cd58ea527b5f70396e12a7" - integrity sha512-bFxxYdkZBwTjTgtZEPTLqu9g8Ajz8x8uEP/O1iVuaZIz2RuxJ2gtx0EXDJRonC++KGsgsW/4Hqvk4KViEtE2nw== - -babel-plugin-transform-regenerator@^6.22.0, babel-plugin-transform-regenerator@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" - integrity sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8= - dependencies: - regenerator-transform "^0.10.0" +babel-plugin-transform-react-remove-prop-types@^0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz#f2edaf9b4c6a5fbe5c1d678bfb531078c1555f3a" + integrity sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA== babel-plugin-transform-regexp-constructors@^0.4.3: version "0.4.3" @@ -4729,41 +4248,22 @@ babel-plugin-transform-remove-undefined@^0.5.0: dependencies: babel-helper-evaluate-path "^0.5.0" -babel-plugin-transform-runtime@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz#88490d446502ea9b8e7efb0fe09ec4d99479b1ee" - integrity sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4= - dependencies: - babel-runtime "^6.22.0" - babel-plugin-transform-simplify-comparison-operators@^6.9.4: version "6.9.4" resolved "https://registry.yarnpkg.com/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.9.4.tgz#f62afe096cab0e1f68a2d753fdf283888471ceb9" integrity sha1-9ir+CWyrDh9ootdT/fKDiIRxzrk= -babel-plugin-transform-strict-mode@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" - integrity sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - babel-plugin-transform-undefined-to-void@^6.9.4: version "6.9.4" resolved "https://registry.yarnpkg.com/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.9.4.tgz#be241ca81404030678b748717322b89d0c8fe280" integrity sha1-viQcqBQEAwZ4t0hxcyK4nQyP4oA= -babel-polyfill@6.20.0: - version "6.20.0" - resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.20.0.tgz#de4a371006139e20990aac0be367d398331204e7" - integrity sha1-3ko3EAYTniCZCqwL42fTmDMSBOc= - dependencies: - babel-runtime "^6.20.0" - core-js "^2.4.0" - regenerator-runtime "^0.10.0" +babel-plugin-typescript-strip-namespaces@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-typescript-strip-namespaces/-/babel-plugin-typescript-strip-namespaces-1.1.1.tgz#160433b17e424b57cf72e3b4d8f08195ad28d7fd" + integrity sha512-dVB9caEANbEVwUylL8g3lsYU5JjaXE2KNIVLib3KVcGJF32QunxvQqP6kf+lzW/fyDed/zWD/e/hdyimyc/79Q== -babel-polyfill@6.26.0, babel-polyfill@^6.26.0: +babel-polyfill@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" integrity sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM= @@ -4772,87 +4272,6 @@ babel-polyfill@6.26.0, babel-polyfill@^6.26.0: core-js "^2.5.0" regenerator-runtime "^0.10.5" -babel-preset-env@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" - integrity sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg== - dependencies: - babel-plugin-check-es2015-constants "^6.22.0" - babel-plugin-syntax-trailing-function-commas "^6.22.0" - babel-plugin-transform-async-to-generator "^6.22.0" - babel-plugin-transform-es2015-arrow-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoping "^6.23.0" - babel-plugin-transform-es2015-classes "^6.23.0" - babel-plugin-transform-es2015-computed-properties "^6.22.0" - babel-plugin-transform-es2015-destructuring "^6.23.0" - babel-plugin-transform-es2015-duplicate-keys "^6.22.0" - babel-plugin-transform-es2015-for-of "^6.23.0" - babel-plugin-transform-es2015-function-name "^6.22.0" - babel-plugin-transform-es2015-literals "^6.22.0" - babel-plugin-transform-es2015-modules-amd "^6.22.0" - babel-plugin-transform-es2015-modules-commonjs "^6.23.0" - babel-plugin-transform-es2015-modules-systemjs "^6.23.0" - babel-plugin-transform-es2015-modules-umd "^6.23.0" - babel-plugin-transform-es2015-object-super "^6.22.0" - babel-plugin-transform-es2015-parameters "^6.23.0" - babel-plugin-transform-es2015-shorthand-properties "^6.22.0" - babel-plugin-transform-es2015-spread "^6.22.0" - babel-plugin-transform-es2015-sticky-regex "^6.22.0" - babel-plugin-transform-es2015-template-literals "^6.22.0" - babel-plugin-transform-es2015-typeof-symbol "^6.23.0" - babel-plugin-transform-es2015-unicode-regex "^6.22.0" - babel-plugin-transform-exponentiation-operator "^6.22.0" - babel-plugin-transform-regenerator "^6.22.0" - browserslist "^3.2.6" - invariant "^2.2.2" - semver "^5.3.0" - -babel-preset-es2015@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939" - integrity sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk= - dependencies: - babel-plugin-check-es2015-constants "^6.22.0" - babel-plugin-transform-es2015-arrow-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoping "^6.24.1" - babel-plugin-transform-es2015-classes "^6.24.1" - babel-plugin-transform-es2015-computed-properties "^6.24.1" - babel-plugin-transform-es2015-destructuring "^6.22.0" - babel-plugin-transform-es2015-duplicate-keys "^6.24.1" - babel-plugin-transform-es2015-for-of "^6.22.0" - babel-plugin-transform-es2015-function-name "^6.24.1" - babel-plugin-transform-es2015-literals "^6.22.0" - babel-plugin-transform-es2015-modules-amd "^6.24.1" - babel-plugin-transform-es2015-modules-commonjs "^6.24.1" - babel-plugin-transform-es2015-modules-systemjs "^6.24.1" - babel-plugin-transform-es2015-modules-umd "^6.24.1" - babel-plugin-transform-es2015-object-super "^6.24.1" - babel-plugin-transform-es2015-parameters "^6.24.1" - babel-plugin-transform-es2015-shorthand-properties "^6.24.1" - babel-plugin-transform-es2015-spread "^6.22.0" - babel-plugin-transform-es2015-sticky-regex "^6.24.1" - babel-plugin-transform-es2015-template-literals "^6.22.0" - babel-plugin-transform-es2015-typeof-symbol "^6.22.0" - babel-plugin-transform-es2015-unicode-regex "^6.24.1" - babel-plugin-transform-regenerator "^6.24.1" - -babel-preset-flow@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz#e71218887085ae9a24b5be4169affb599816c49d" - integrity sha1-5xIYiHCFrpoktb5Baa/7WZgWxJ0= - dependencies: - babel-plugin-transform-flow-strip-types "^6.22.0" - -babel-preset-jest@^23.2.0: - version "23.2.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-23.2.0.tgz#8ec7a03a138f001a1a8fb1e8113652bf1a55da46" - integrity sha1-jsegOhOPABoaj7HoETZSvxpV2kY= - dependencies: - babel-plugin-jest-hoist "^23.2.0" - babel-plugin-syntax-object-rest-spread "^6.13.0" - babel-preset-jest@^24.1.0: version "24.1.0" resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-24.1.0.tgz#83bc564fdcd4903641af65ec63f2f5de6b04132e" @@ -4890,43 +4309,7 @@ babel-preset-minify@^0.5.0: babel-plugin-transform-undefined-to-void "^6.9.4" lodash.isplainobject "^4.0.6" -babel-preset-react@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-6.24.1.tgz#ba69dfaea45fc3ec639b6a4ecea6e17702c91380" - integrity sha1-umnfrqRfw+xjm2pOzqbhdwLJE4A= - dependencies: - babel-plugin-syntax-jsx "^6.3.13" - babel-plugin-transform-react-display-name "^6.23.0" - babel-plugin-transform-react-jsx "^6.24.1" - babel-plugin-transform-react-jsx-self "^6.22.0" - babel-plugin-transform-react-jsx-source "^6.22.0" - babel-preset-flow "^6.23.0" - -babel-preset-stage-3@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz#836ada0a9e7a7fa37cb138fb9326f87934a48395" - integrity sha1-g2raCp56f6N8sTj7kyb4eTSkg5U= - dependencies: - babel-plugin-syntax-trailing-function-commas "^6.22.0" - babel-plugin-transform-async-generator-functions "^6.24.1" - babel-plugin-transform-async-to-generator "^6.24.1" - babel-plugin-transform-exponentiation-operator "^6.24.1" - babel-plugin-transform-object-rest-spread "^6.22.0" - -babel-register@6.26.0, babel-register@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" - integrity sha1-btAhFz4vy0htestFxgCahW9kcHE= - dependencies: - babel-core "^6.26.0" - babel-runtime "^6.26.0" - core-js "^2.5.0" - home-or-tmp "^2.0.0" - lodash "^4.17.4" - mkdirp "^0.5.1" - source-map-support "^0.4.15" - -babel-runtime@6.x.x, babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.20.0, babel-runtime@^6.22.0, babel-runtime@^6.23.0, babel-runtime@^6.26.0, babel-runtime@^6.5.0: +babel-runtime@6.x.x, babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.23.0, babel-runtime@^6.26.0, babel-runtime@^6.5.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= @@ -4939,7 +4322,7 @@ babel-standalone@^6.26.0: resolved "https://registry.yarnpkg.com/babel-standalone/-/babel-standalone-6.26.0.tgz#15fb3d35f2c456695815ebf1ed96fe7f015b6886" integrity sha1-Ffs9NfLEVmlYFevx7Zb+fwFbaIY= -babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0: +babel-template@^6.16.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= @@ -4950,7 +4333,7 @@ babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0: babylon "^6.18.0" lodash "^4.17.4" -babel-traverse@^6.18.0, babel-traverse@^6.24.1, babel-traverse@^6.26.0: +babel-traverse@^6.18.0, babel-traverse@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= @@ -4974,7 +4357,7 @@ babel-types@7.0.0-beta.3: lodash "^4.2.0" to-fast-properties "^2.0.0" -babel-types@^6.0.0, babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: +babel-types@^6.0.0, babel-types@^6.18.0, babel-types@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= @@ -4984,13 +4367,6 @@ babel-types@^6.0.0, babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24. lodash "^4.17.4" to-fast-properties "^1.0.3" -"babel7-plugin-add-module-exports@npm:babel-plugin-add-module-exports@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-1.0.0.tgz#72b5424d941a336c6a35357f373d8b8366263031" - integrity sha512-m0sMxPL4FaN2K69GQgaRJa4Ny15qKSdoknIcpN+gz+NaJlAW9pge/povs13tPYsKDboflrEQC+/3kfIsONBTaw== - optionalDependencies: - chokidar "^2.0.4" - babylon@7.0.0-beta.47: version "7.0.0-beta.47" resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.47.tgz#6d1fa44f0abec41ab7c780481e62fd9aafbdea80" @@ -5519,15 +4895,7 @@ browserslist@4.1.1: dependencies: caniuse-lite "^1.0.30000884" electron-to-chromium "^1.3.62" - node-releases "^1.0.0-alpha.11" - -browserslist@^3.2.6: - version "3.2.8" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" - integrity sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ== - dependencies: - caniuse-lite "^1.0.30000844" - electron-to-chromium "^1.3.47" + node-releases "^1.0.0-alpha.11" browserslist@^4.0.1, browserslist@^4.3.4: version "4.4.1" @@ -5604,7 +4972,7 @@ buffer-fill@^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, buffer-from@^1.1.0: +buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== @@ -5906,7 +5274,7 @@ caniuse-db@^1.0.30000539, caniuse-db@^1.0.30000597: resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000813.tgz#e0a1c603f8880ad787b2a35652b2733f32a5e29a" integrity sha1-4KHGA/iICteHsqNWUrJzPzKl4po= -caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30000872, caniuse-lite@^1.0.30000929: +caniuse-lite@^1.0.30000872, caniuse-lite@^1.0.30000929: version "1.0.30000932" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000932.tgz#d01763e9ce77810962ca7391ff827b5949ce4272" integrity sha512-4bghJFItvzz8m0T3lLZbacmEY9X1Z2AtIzTr7s7byqZIOumASfr4ynDx7rtm0J85nDmx8vsgR6vnaSoeU8Oh0A== @@ -6143,6 +5511,11 @@ chardet@^0.5.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.5.0.tgz#fe3ac73c00c3d865ffcc02a0682e2c20b6a06029" integrity sha512-9ZTaoBaePSCFvNlNGrsyI8ZVACP2svUtq0DkM7t4K2ClAa96sqOIRjAzDTc8zXzFt1cZR46rRzLTiHFSJ+Qw0g== +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + checksum@0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/checksum/-/checksum-0.1.1.tgz#dc6527d4c90be8560dbd1ed4cecf3297d528e9e9" @@ -6200,22 +5573,6 @@ chokidar@1.6.0: optionalDependencies: fsevents "^1.0.0" -chokidar@^1.6.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" - integrity sha1-eY5ol3gVHIB2tLNg5e3SjNortGg= - dependencies: - anymatch "^1.3.0" - async-each "^1.0.0" - glob-parent "^2.0.0" - inherits "^2.0.1" - is-binary-path "^1.0.0" - is-glob "^2.0.0" - path-is-absolute "^1.0.0" - readdirp "^2.0.0" - optionalDependencies: - fsevents "^1.0.0" - chokidar@^2.0.0, chokidar@^2.0.2, chokidar@^2.0.3, chokidar@^2.0.4: version "2.1.2" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.2.tgz#9c23ea40b01638439e0513864d362aeacc5ad058" @@ -6525,11 +5882,6 @@ cloneable-readable@^1.0.0: process-nextick-args "^2.0.0" readable-stream "^2.3.5" -closest-file-data@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/closest-file-data/-/closest-file-data-0.1.4.tgz#975f87c132f299d24a0375b9f63ca3fb88f72b3a" - integrity sha1-l1+HwTLymdJKA3W59jyj+4j3Kzo= - cmd-shim@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-2.0.2.tgz#6fcbda99483a8fd15d7d30a196ca69d688a2efdb" @@ -7021,13 +6373,6 @@ convert-source-map@1.X, convert-source-map@^1.1.0, convert-source-map@^1.4.0, co resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" integrity sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU= -convert-source-map@^1.5.1: - version "1.6.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" - integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== - dependencies: - safe-buffer "~5.1.1" - convex-hull@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/convex-hull/-/convex-hull-1.0.3.tgz#20a3aa6ce87f4adea2ff7d17971c9fc1c67e1fff" @@ -7891,7 +7236,7 @@ debug@3.X, debug@^3.1.0, debug@^3.2.5: dependencies: ms "^2.1.1" -debug@^4.1.0, debug@^4.1.1: +debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== @@ -8332,6 +7677,13 @@ doctrine@^2.0.0, doctrine@^2.1.0: dependencies: esutils "^2.0.2" +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + doctypes@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/doctypes/-/doctypes-1.1.0.tgz#ea80b106a87538774e8a3a4a5afe293de489e0a9" @@ -8374,6 +7726,26 @@ dom-serializer@0, dom-serializer@~0.1.0: domelementtype "^1.3.0" entities "^1.1.1" +dom-testing-library@^3.13.1: + version "3.17.1" + resolved "https://registry.yarnpkg.com/dom-testing-library/-/dom-testing-library-3.17.1.tgz#3291bc3cf68c555ba5e663697ee77d604aaa122b" + integrity sha512-SbkaRfQvuLjnv+xFgSo/cmKoN9tjBL6Rh1f3nQH9jnjUe5q+keRwacYSi3uSpcB4D1K768iavCayKH3ZN9ea+g== + dependencies: + "@babel/runtime" "^7.3.4" + "@sheerun/mutationobserver-shim" "^0.3.2" + pretty-format "^24.0.0" + wait-for-expect "^1.1.0" + +dom-testing-library@^3.18.2: + version "3.18.2" + resolved "https://registry.yarnpkg.com/dom-testing-library/-/dom-testing-library-3.18.2.tgz#07d65166743ad3299b7bee5b488e9622c31241bc" + integrity sha512-+nYUgGhHarrCY8kLVmyHlgM+IGwBXXrYsWIJB6vpAx2ne9WFgKfwMGcOkkTKQhuAro0sP6RIuRGfm5NF3+ccmQ== + dependencies: + "@babel/runtime" "^7.3.4" + "@sheerun/mutationobserver-shim" "^0.3.2" + pretty-format "^24.5.0" + wait-for-expect "^1.1.0" + dom-walk@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" @@ -8650,11 +8022,6 @@ electron-to-chromium@^1.3.103: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.108.tgz#2e79a6fcaa4b3e7c75abf871505bda8e268c910e" integrity sha512-/QI4hMpAh48a1Sea6PALGv+kuVne9A2EWGd8HrWHMdYhIzGtbhVVHh6heL5fAzGaDnZuPyrlWJRl8WPm4RyiQQ== -electron-to-chromium@^1.3.47: - version "1.3.82" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.82.tgz#7d13ae4437d2a783de3f4efba96b186c540b67b1" - integrity sha512-NI4nB2IWGcU4JVT1AE8kBb/dFor4zjLHMLsOROPahppeHrR0FG5uslxMmkp/thO1MvPjM2xhlKoY29/I60s0ew== - electron-to-chromium@^1.3.62: version "1.3.67" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.67.tgz#5e8f3ffac89b4b0402c7e1a565be06f3a109abbc" @@ -8690,10 +8057,10 @@ elliptic@^6.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.0" -emoji-regex@^6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.5.1.tgz#9baea929b155565c11ea41c6626eaa65cef992c2" - integrity sha512-PAHp6TxrCy7MGMFidro8uikr+zlJJKJ/Q6mm2ExZ7HwkyR9lSVFfE3kt36qcwa24BQL7y0G9axycGjK1A/0uNQ== +emoji-regex@^7.0.1, emoji-regex@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== emojis-list@^2.0.0: version "2.1.0" @@ -8778,7 +8145,7 @@ engine.io@~3.2.0: engine.io-parser "~2.1.0" ws "~3.3.1" -enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: +enhanced-resolve@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng== @@ -9137,14 +8504,14 @@ escope@^3.6.0: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-config-prettier@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-3.1.0.tgz#2c26d2cdcfa3a05f0642cd7e6e4ef3316cdabfa2" - integrity sha512-QYGfmzuc4q4J6XIhlp8vRKdI/fI0tQfQPy1dME3UOLprE+v4ssH/3W9LM2Q7h5qBcy5m0ehCrBDU2YF8q6OY8w== +eslint-config-prettier@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-4.1.0.tgz#181364895899fff9fd3605fecb5c4f20e7d5f395" + integrity sha512-zILwX9/Ocz4SV2vX7ox85AsrAgXV3f2o2gpIicdMIOra48WYqgUnWNH/cR/iHtmD2Vb3dLSC3LiEJnS05Gkw7w== dependencies: get-stdin "^6.0.0" -eslint-import-resolver-node@^0.3.1, eslint-import-resolver-node@^0.3.2: +eslint-import-resolver-node@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" integrity sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q== @@ -9168,62 +8535,62 @@ eslint-import-resolver-webpack@^0.10.1: resolve "^1.4.0" semver "^5.3.0" -eslint-module-utils@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz#b270362cd88b1a48ad308976ce7fa54e98411746" - integrity sha1-snA2LNiLGkitMIl2zn+lTphBF0Y= +eslint-module-utils@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.3.0.tgz#546178dab5e046c8b562bbb50705e2456d7bda49" + integrity sha512-lmDJgeOOjk8hObTysjqH7wyMi+nsHwwvfBykwfhjR1LNdd7C2uFJBvx4OpWYpXOw4df1yE1cDEVd1yLHitk34w== dependencies: debug "^2.6.8" - pkg-dir "^1.0.0" + pkg-dir "^2.0.0" -eslint-plugin-babel@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-babel/-/eslint-plugin-babel-5.2.0.tgz#3041a0c26aa3ca4a0e0f2aa11591f0396790d981" - integrity sha512-9pNH/e214SN3r2nEwwTLRI27jUN4+nuLMv1+qxfDv8Za9cJ3F+aPkNinYiVeUmAmiEtOttbS32yuwRG2DREvJg== +eslint-plugin-babel@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-babel/-/eslint-plugin-babel-5.3.0.tgz#2e7f251ccc249326da760c1a4c948a91c32d0023" + integrity sha512-HPuNzSPE75O+SnxHIafbW5QB45r2w78fxqwK3HmjqIUoPfPzVrq6rD+CINU3yzoDSzEhUkX07VUphbF73Lth/w== dependencies: eslint-rule-composer "^0.3.0" -eslint-plugin-import@^2.14.0: - version "2.14.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz#6b17626d2e3e6ad52cfce8807a845d15e22111a8" - integrity sha512-FpuRtniD/AY6sXByma2Wr0TXvXJ4nA/2/04VPlfpmUDPOpOY264x+ILiwnrk/k4RINgDAyFZByxqPUbSQ5YE7g== +eslint-plugin-import@^2.16.0: + version "2.16.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.16.0.tgz#97ac3e75d0791c4fac0e15ef388510217be7f66f" + integrity sha512-z6oqWlf1x5GkHIFgrSvtmudnqM6Q60KM4KvpWi5ubonMjycLjndvd5+8VAZIsTlHC03djdgJuyKG6XO577px6A== dependencies: contains-path "^0.1.0" - debug "^2.6.8" + debug "^2.6.9" doctrine "1.5.0" - eslint-import-resolver-node "^0.3.1" - eslint-module-utils "^2.2.0" - has "^1.0.1" - lodash "^4.17.4" - minimatch "^3.0.3" + eslint-import-resolver-node "^0.3.2" + eslint-module-utils "^2.3.0" + has "^1.0.3" + lodash "^4.17.11" + minimatch "^3.0.4" read-pkg-up "^2.0.0" - resolve "^1.6.0" + resolve "^1.9.0" -eslint-plugin-jest@^21.26.2: - version "21.27.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-21.27.2.tgz#2a795b7c3b5e707df48a953d651042bd01d7b0a8" - integrity sha512-0E4OIgBJVlAmf1KfYFtZ3gYxgUzC5Eb3Jzmrc9ikI1OY+/cM8Kh72Ti7KfpeHNeD3HJNf9SmEfmvQLIz44Hrhw== +eslint-plugin-jest@^22.3.0: + version "22.3.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.3.0.tgz#a10f10dedfc92def774ec9bb5bfbd2fb8e1c96d2" + integrity sha512-P1mYVRNlOEoO5T9yTqOfucjOYf1ktmJ26NjwjH8sxpCFQa6IhBGr5TpKl3hcAAT29hOsRJVuMWmTsHoUVo9FoA== -eslint-plugin-jsx-a11y@^6.1.2: - version "6.1.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.1.2.tgz#69bca4890b36dcf0fe16dd2129d2d88b98f33f88" - integrity sha512-7gSSmwb3A+fQwtw0arguwMdOdzmKUgnUcbSNlo+GjKLAQFuC2EZxWqG9XHRI8VscBJD5a8raz3RuxQNFW+XJbw== +eslint-plugin-jsx-a11y@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.1.tgz#4ebba9f339b600ff415ae4166e3e2e008831cf0c" + integrity sha512-cjN2ObWrRz0TTw7vEcGQrx+YltMvZoOEx4hWU8eEERDnBIU00OTq7Vr+jA7DFKxiwLNv4tTh5Pq2GUNEa8b6+w== dependencies: aria-query "^3.0.0" array-includes "^3.0.3" ast-types-flow "^0.0.7" - axobject-query "^2.0.1" + axobject-query "^2.0.2" damerau-levenshtein "^1.0.4" - emoji-regex "^6.5.1" + emoji-regex "^7.0.2" has "^1.0.3" jsx-ast-utils "^2.0.1" -eslint-plugin-mocha@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-mocha/-/eslint-plugin-mocha-5.2.0.tgz#d8786d9fff8cb8b5f6e4b61e40395d6568a5c4e2" - integrity sha512-4VTX/qIoxUFRnXLNm6bEhEJyfGnGagmQzV4TWXKzkZgIYyP2FSubEdCjEFTyS/dGwSVRWCWGX7jO7BK8R0kppg== +eslint-plugin-mocha@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-mocha/-/eslint-plugin-mocha-5.3.0.tgz#cf3eb18ae0e44e433aef7159637095a7cb19b15b" + integrity sha512-3uwlJVLijjEmBeNyH60nzqgA1gacUWLUmcKV8PIGNvj1kwP/CTgAWQHn2ayyJVwziX+KETkr9opNwT1qD/RZ5A== dependencies: - ramda "^0.25.0" + ramda "^0.26.1" eslint-plugin-no-unsanitized@^3.0.2: version "3.0.2" @@ -9243,24 +8610,30 @@ eslint-plugin-prettier@^2.2.0: fast-diff "^1.1.1" jest-docblock "^21.0.0" -eslint-plugin-prettier@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-2.6.2.tgz#71998c60aedfa2141f7bfcbf9d1c459bf98b4fad" - integrity sha512-tGek5clmW5swrAx1mdPYM8oThrBE83ePh7LeseZHBWfHVGrHPhKn7Y5zgRMbU/9D5Td9K4CEmUPjGxA7iw98Og== +eslint-plugin-prettier@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.0.1.tgz#19d521e3981f69dd6d14f64aec8c6a6ac6eb0b0d" + integrity sha512-/PMttrarPAY78PLvV3xfWibMOdMDl57hmlQ2XqFeA37wd+CJ7WSxV7txqjVPHi/AAFKd2lX0ZqfsOc/i5yFCSQ== dependencies: - fast-diff "^1.1.1" - jest-docblock "^21.0.0" + prettier-linter-helpers "^1.0.0" + +eslint-plugin-react-hooks@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.6.0.tgz#348efcda8fb426399ac7b8609607c7b4025a6f5f" + integrity sha512-lHBVRIaz5ibnIgNG07JNiAuBUeKhEf8l4etNx5vfAEwqQ5tcuK3jV9yjmopPgQDagQb7HwIuQVsE3IVcGrRnag== -eslint-plugin-react@^7.11.1: - version "7.11.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.11.1.tgz#c01a7af6f17519457d6116aa94fc6d2ccad5443c" - integrity sha512-cVVyMadRyW7qsIUh3FHp3u6QHNhOgVrLQYdQEB1bPWBsgbNCHdFAeNMquBMCcZJu59eNthX053L70l7gRt4SCw== +eslint-plugin-react@^7.12.4: + version "7.12.4" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.12.4.tgz#b1ecf26479d61aee650da612e425c53a99f48c8c" + integrity sha512-1puHJkXJY+oS1t467MjbqjvX53uQ05HXwjqDgdbGBqf5j9eeydI54G3KwiJmWciQ0HTBacIKw2jgwSBSH3yfgQ== dependencies: array-includes "^3.0.3" doctrine "^2.1.0" has "^1.0.3" jsx-ast-utils "^2.0.1" + object.fromentries "^2.0.0" prop-types "^15.6.2" + resolve "^1.9.0" eslint-rule-composer@^0.3.0: version "0.3.0" @@ -9283,6 +8656,14 @@ eslint-scope@^4.0.0: esrecurse "^4.1.0" estraverse "^4.1.1" +eslint-scope@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.2.tgz#5f10cd6cabb1965bf479fa65745673439e21cb0e" + integrity sha512-5q1+B/ogmHl8+paxtOKx38Z8LtWkVGuNt3+GQNErqwLl6ViNp/gdJGMCjZNxZ8j/VYjDNZ2Fo+eQc1TAVPIzbg== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + eslint-utils@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512" @@ -9332,48 +8713,46 @@ eslint@^2.7.0: text-table "~0.2.0" user-home "^2.0.0" -eslint@^5.6.0: - version "5.6.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.6.0.tgz#b6f7806041af01f71b3f1895cbb20971ea4b6223" - integrity sha512-/eVYs9VVVboX286mBK7bbKnO1yamUy2UCRjiY6MryhQL2PaaXCExsCQ2aO83OeYRhU2eCU/FMFP+tVMoOrzNrA== +eslint@^5.15.1: + version "5.15.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.15.1.tgz#8266b089fd5391e0009a047050795b1d73664524" + integrity sha512-NTcm6vQ+PTgN3UBsALw5BMhgO6i5EpIjQF/Xb5tIh3sk9QhrFafujUOczGz4J24JBlzWclSB9Vmx8d+9Z6bFCg== dependencies: "@babel/code-frame" "^7.0.0" - ajv "^6.5.3" + ajv "^6.9.1" chalk "^2.1.0" cross-spawn "^6.0.5" - debug "^3.1.0" - doctrine "^2.1.0" - eslint-scope "^4.0.0" + debug "^4.0.1" + doctrine "^3.0.0" + eslint-scope "^4.0.2" eslint-utils "^1.3.1" eslint-visitor-keys "^1.0.0" - espree "^4.0.0" + espree "^5.0.1" esquery "^1.0.1" esutils "^2.0.2" - file-entry-cache "^2.0.0" + file-entry-cache "^5.0.1" functional-red-black-tree "^1.0.1" glob "^7.1.2" globals "^11.7.0" ignore "^4.0.6" + import-fresh "^3.0.0" imurmurhash "^0.1.4" - inquirer "^6.1.0" - is-resolvable "^1.1.0" + inquirer "^6.2.2" js-yaml "^3.12.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.3.0" - lodash "^4.17.5" + lodash "^4.17.11" minimatch "^3.0.4" mkdirp "^0.5.1" natural-compare "^1.4.0" optionator "^0.8.2" path-is-inside "^1.0.2" - pluralize "^7.0.0" progress "^2.0.0" - regexpp "^2.0.0" - require-uncached "^1.0.3" + regexpp "^2.0.1" semver "^5.5.1" strip-ansi "^4.0.0" strip-json-comments "^2.0.1" - table "^4.0.3" + table "^5.2.3" text-table "^0.2.0" esm@^3.0.84: @@ -9389,13 +8768,14 @@ espree@^3.1.6: acorn "^5.5.0" acorn-jsx "^3.0.0" -espree@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-4.0.0.tgz#253998f20a0f82db5d866385799d912a83a36634" - integrity sha512-kapdTCt1bjmspxStVKX6huolXVV5ZfyZguY1lcfhVVZstce3bqxH9mcLzNn3/mlgW6wQ732+0fuG9v7h0ZQoKg== +espree@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-5.0.1.tgz#5d6526fa4fc7f0788a5cf75b15f30323e2f81f7a" + integrity sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A== dependencies: - acorn "^5.6.0" - acorn-jsx "^4.1.1" + acorn "^6.0.7" + acorn-jsx "^5.0.0" + eslint-visitor-keys "^1.0.0" esprima@2.7.x, esprima@^2.6.0, esprima@^2.7.1: version "2.7.3" @@ -9707,11 +9087,6 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2: dependencies: homedir-polyfill "^1.0.1" -expect.js@0.3.1, expect.js@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/expect.js/-/expect.js-0.3.1.tgz#b0a59a0d2eff5437544ebf0ceaa6015841d09b5b" - integrity sha1-sKWaDS7/VDdUTr8M6qYBWEHQm1s= - expect.js@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/expect.js/-/expect.js-0.2.0.tgz#1028533d2c1c363f74a6796ff57ec0520ded2be1" @@ -9842,6 +9217,15 @@ external-editor@^3.0.0: iconv-lite "^0.4.22" tmp "^0.0.33" +external-editor@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" + integrity sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + extglob@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" @@ -9955,6 +9339,11 @@ fast-diff@^1.1.1: resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.1.2.tgz#4b62c42b8e03de3f848460b639079920695d0154" integrity sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig== +fast-diff@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + fast-glob@^2.0.2: version "2.0.4" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.0.4.tgz#a4b9f49e36175f5ef1a3456f580226a6e7abcc9e" @@ -10089,13 +9478,12 @@ file-entry-cache@^1.1.1: flat-cache "^1.2.1" object-assign "^4.0.1" -file-entry-cache@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" - integrity sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E= +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== dependencies: - flat-cache "^1.2.1" - object-assign "^4.0.1" + flat-cache "^2.0.1" file-loader@1.1.11: version "1.1.11" @@ -10362,6 +9750,15 @@ flat-cache@^1.2.1: graceful-fs "^4.1.2" write "^0.2.1" +flat-cache@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== + dependencies: + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" + flatted@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.0.tgz#55122b6536ea496b4b44893ee2608141d10d9916" @@ -10567,15 +9964,6 @@ fs-extra@5.0.0: jsonfile "^4.0.0" universalify "^0.1.0" -fs-extra@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-6.0.1.tgz#8abc128f7946e310135ddc93b98bddb410e7a34b" - integrity sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - fs-extra@^0.30.0: version "0.30.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" @@ -10620,7 +10008,7 @@ fs-mkdirp-stream@^1.0.0: graceful-fs "^4.1.11" through2 "^2.0.3" -fs-readdir-recursive@^1.0.0, fs-readdir-recursive@^1.1.0: +fs-readdir-recursive@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA== @@ -11573,10 +10961,10 @@ growly@^1.3.0: resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= -grunt-babel@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/grunt-babel/-/grunt-babel-7.0.0.tgz#13c90c01f154dec214e0eeb5d66ac7c70cedf2d3" - integrity sha512-AFilvH/iPbnIYhL4Wx36AJQCaVEvK55xh0tujAt1DIM5tuxYxRsgUPEpwijBU147B+as/ssGuY9/6JYfTiAWpw== +grunt-babel@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/grunt-babel/-/grunt-babel-8.0.0.tgz#92ef63aafadf938c488dc2f926ac9846e0c93d1b" + integrity sha512-WuiZFvGzcyzlEoPIcY1snI234ydDWeWWV5bpnB7PZsOLHcDsxWKnrR1rMWEUsbdVPPjvIirwFNsuo4CbJmsdFQ== grunt-cli@^1.2.0, grunt-cli@~1.2.0: version "1.2.0" @@ -11695,13 +11083,13 @@ grunt@1.0.3: path-is-absolute "~1.0.0" rimraf "~2.6.2" -gulp-babel@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/gulp-babel/-/gulp-babel-7.0.1.tgz#b9c8e29fa376b36c57989db820fc1c1715bb47cb" - integrity sha512-UqHS3AdxZyJCRxqnAX603Dj3k/Wx6hzcgmav3QcxvsIFq3Y8ZkU7iXd0O+JwD5ivqCc6o0r1S7tCB/xxLnuSNw== +gulp-babel@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/gulp-babel/-/gulp-babel-8.0.0.tgz#e0da96f4f2ec4a88dd3a3030f476e38ab2126d87" + integrity sha512-oomaIqDXxFkg7lbpBou/gnUkX51/Y/M2ZfSjL2hdqXTAlSWZcgZtd2o0cOH0r/eE8LWD0+Q/PsLsr2DKOoqToQ== dependencies: plugin-error "^1.0.1" - replace-ext "0.0.1" + replace-ext "^1.0.0" through2 "^2.0.0" vinyl-sourcemaps-apply "^0.2.0" @@ -12200,13 +11588,10 @@ hoist-non-react-statics@^2.3.1, hoist-non-react-statics@^2.5.0, hoist-non-react- resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47" integrity sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw== -home-or-tmp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" - integrity sha1-42w/LSyufXRqhX440Y1fMqeILbg= - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.1" +home-or-tmp@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-3.0.0.tgz#57a8fe24cf33cdd524860a15821ddc25c86671fb" + integrity sha1-V6j+JM8zzdUkhgoVgh3cJchmcfs= homedir-polyfill@^1.0.0, homedir-polyfill@^1.0.1: version "1.0.1" @@ -12424,7 +11809,7 @@ icalendar@0.7.1: resolved "https://registry.yarnpkg.com/icalendar/-/icalendar-0.7.1.tgz#d0d3486795f8f1c5cf4f8cafac081b4b4e7a32ae" integrity sha1-0NNIZ5X48cXPT4yvrAgbS056Mq4= -iconv-lite@0.4, iconv-lite@^0.4.17, iconv-lite@^0.4.19, iconv-lite@^0.4.22, iconv-lite@^0.4.4, iconv-lite@~0.4.13: +iconv-lite@0.4, iconv-lite@^0.4.17, iconv-lite@^0.4.19, iconv-lite@^0.4.22, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -12534,6 +11919,14 @@ import-fresh@^2.0.0: caller-path "^2.0.0" resolve-from "^3.0.0" +import-fresh@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.0.0.tgz#a3d897f420cab0e671236897f75bc14b4885c390" + integrity sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + import-from@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" @@ -12662,7 +12055,7 @@ inline-style@^2.0.0: dependencies: dashify "^0.1.0" -inquirer@6.2.0, inquirer@^6.1.0, inquirer@^6.2.0: +inquirer@6.2.0, inquirer@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.0.tgz#51adcd776f661369dc1e894859c2560a224abdd8" integrity sha512-QIEQG4YyQ2UYZGDC4srMZ7BjHOmNk1lR2JQj5UknBapklm6WHA+VVH7N+sUdX3A7NeCfGF8o4X1S3Ao7nAcIeg== @@ -12797,6 +12190,25 @@ inquirer@^6.0.0: strip-ansi "^4.0.0" through "^2.3.6" +inquirer@^6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.2.tgz#46941176f65c9eb20804627149b743a218f25406" + integrity sha512-Z2rREiXA6cHRR9KBOarR3WuLlFzlIfAEIiB45ll5SSadMg7WqOh1MKEjjndfuH5ewXdixWCxqnVfGOQzPeiztA== + dependencies: + ansi-escapes "^3.2.0" + chalk "^2.4.2" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^2.0.0" + lodash "^4.17.11" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.4.0" + string-width "^2.1.0" + strip-ansi "^5.0.0" + through "^2.3.6" + insane@2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/insane/-/insane-2.5.0.tgz#3252baec85c53b108cdf731e7962b7ce9c5cff1f" @@ -13384,7 +12796,7 @@ is-relative@^1.0.0: dependencies: is-unc-path "^1.0.0" -is-resolvable@^1.0.0, is-resolvable@^1.1.0: +is-resolvable@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== @@ -13585,7 +12997,7 @@ istanbul-instrumenter-loader@3.0.1: loader-utils "^1.1.0" schema-utils "^0.3.0" -istanbul-lib-coverage@^1.2.0, istanbul-lib-coverage@^1.2.1: +istanbul-lib-coverage@^1.2.0: version "1.2.1" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz#ccf7edcd0a0bb9b8f729feeb0930470f9af664f0" integrity sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ== @@ -13602,19 +13014,6 @@ istanbul-lib-hook@^2.0.3: dependencies: append-transform "^1.0.0" -istanbul-lib-instrument@^1.10.1: - version "1.10.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz#1f55ed10ac3c47f2bdddd5307935126754d0a9ca" - integrity sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A== - dependencies: - babel-generator "^6.18.0" - babel-template "^6.16.0" - babel-traverse "^6.18.0" - babel-types "^6.18.0" - babylon "^6.18.0" - istanbul-lib-coverage "^1.2.1" - semver "^5.3.0" - istanbul-lib-instrument@^1.7.3: version "1.10.1" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.1.tgz#724b4b6caceba8692d3f1f9d0727e279c401af7b" @@ -14416,7 +13815,7 @@ json3@3.3.2, json3@^3.3.2: resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" integrity sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE= -json5@^0.5.0, json5@^0.5.1: +json5@^0.5.0: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= @@ -15713,11 +15112,6 @@ make-dir@^1.0.0, make-dir@^1.3.0: dependencies: pify "^3.0.0" -make-error@^1.1.1: - version "1.3.4" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.4.tgz#19978ed575f9e9545d2ff8c13e33b5d18a67d535" - integrity sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g== - make-error@^1.3.5: version "1.3.5" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8" @@ -17055,6 +16449,11 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" +object-hash@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" + integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA== + object-inspect@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b" @@ -17402,7 +16801,7 @@ os-shim@^0.1.2: resolved "https://registry.yarnpkg.com/os-shim/-/os-shim-0.1.3.tgz#6b62c3791cf7909ea35ed46e17658bb417cb3917" integrity sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc= -os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: +os-tmpdir@^1.0.0, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= @@ -17423,15 +16822,6 @@ osenv@^0.1.4: os-homedir "^1.0.0" os-tmpdir "^1.0.0" -output-file-sync@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76" - integrity sha1-0KM+7+YaIF+suQCS6CZZjVJFznY= - dependencies: - graceful-fs "^4.1.4" - mkdirp "^0.5.1" - object-assign "^4.1.0" - output-file-sync@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-2.0.1.tgz#f53118282f5f553c2799541792b723a4c71430c0" @@ -17630,6 +17020,13 @@ param-case@2.1.x, param-case@^2.1.0: dependencies: no-case "^2.2.0" +parent-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.0.tgz#df250bdc5391f4a085fb589dad761f5ad6b865b5" + integrity sha512-8Mf5juOMmiE4FcmzYc4IaiS9L3+9paz2KOiXzkRviCP6aDmN49Hz6EMWz0lGNp9pX80GvvAuLADtyGfW/Em3TA== + dependencies: + callsites "^3.0.0" + parse-asn1@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.0.tgz#37c4f9b7ed3ab65c74817b5f2480937fbf97c712" @@ -17816,7 +17213,7 @@ path-exists@^3.0.0: resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= -path-is-absolute@^1.0.0, path-is-absolute@^1.0.1, path-is-absolute@~1.0.0: +path-is-absolute@^1.0.0, path-is-absolute@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= @@ -17841,6 +17238,11 @@ path-parse@^1.0.5: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" integrity sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME= +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + path-root-regex@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" @@ -18018,13 +17420,6 @@ pixelmatch@4.0.2, pixelmatch@^4.0.0: dependencies: pngjs "^3.0.0" -pkg-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" - integrity sha1-ektQio1bstYp1EcFb/TpyTFM89Q= - dependencies: - find-up "^1.0.0" - pkg-dir@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" @@ -18101,11 +17496,6 @@ pluralize@^1.2.1: resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" integrity sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU= -pluralize@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" - integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== - pn@^1.0.0, pn@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" @@ -18301,6 +17691,13 @@ preserve@^0.2.0: resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + prettier@1.14.3: version "1.14.3" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.14.3.tgz#90238dd4c0684b7edce5f83b0fb7328e48bd0895" @@ -18340,12 +17737,22 @@ pretty-format@^24.0.0: ansi-regex "^4.0.0" ansi-styles "^3.2.0" +pretty-format@^24.5.0: + version "24.5.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.5.0.tgz#cc69a0281a62cd7242633fc135d6930cd889822d" + integrity sha512-/3RuSghukCf8Riu5Ncve0iI+BzVkbRU5EeUoArKARZobREycuH5O4waxvaNIloEXdb0qwgmEAed5vTpX1HNROQ== + dependencies: + "@jest/types" "^24.5.0" + ansi-regex "^4.0.0" + ansi-styles "^3.2.0" + react-is "^16.8.4" + pretty-hrtime@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE= -private@^0.1.6, private@^0.1.7, private@^0.1.8, private@~0.1.5: +private@^0.1.6, private@~0.1.5: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== @@ -18822,10 +18229,10 @@ ramda@^0.21.0: resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.21.0.tgz#a001abedb3ff61077d4ff1d577d44de77e8d0a35" integrity sha1-oAGr7bP/YQd9T/HVd9RN536NCjU= -ramda@^0.25.0: - version "0.25.0" - resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.25.0.tgz#8fdf68231cffa90bc2f9460390a0cb74a29b29a9" - integrity sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ== +ramda@^0.26.1: + version "0.26.1" + resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06" + integrity sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ== randexp@0.4.6: version "0.4.6" @@ -19151,6 +18558,14 @@ react-grid-layout@^0.16.2: react-draggable "3.x" react-resizable "1.x" +react-hooks-testing-library@^0.3.8: + version "0.3.8" + resolved "https://registry.yarnpkg.com/react-hooks-testing-library/-/react-hooks-testing-library-0.3.8.tgz#717595ed7be500023963dd502f188aa932bf70f0" + integrity sha512-YFnyd2jH2voikSBGufqhprnxMTHgosOHlO5EXhuQycWxfeTCIiw/17aiYbpvRRDRB/0j8QvI/jHXMNVBKw7WzA== + dependencies: + "@babel/runtime" "^7.4.2" + react-testing-library "^6.0.2" + react-input-autosize@^2.1.2, react-input-autosize@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.2.1.tgz#ec428fa15b1592994fb5f9aa15bb1eb6baf420f8" @@ -19192,6 +18607,11 @@ react-is@^16.8.1, react-is@^16.8.2: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.2.tgz#09891d324cad1cb0c1f2d91f70a71a4bee34df0f" integrity sha512-D+NxhSR2HUCjYky1q1DwpNUD44cDpUXzSmmFyC3ug1bClcU/iDNy0YNn1iwme28fn+NFhpA13IndOd42CrFb+Q== +react-is@^16.8.4: + version "16.8.5" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.5.tgz#c54ac229dd66b5afe0de5acbe47647c3da692ff8" + integrity sha512-sudt2uq5P/2TznPV4Wtdi+Lnq3yaYW8LfvPKLM9BKD8jJNBkxMVyB0C9/GmVhLw7Jbdmndk/73n7XQGeN9A3QQ== + react-is@~16.3.0: version "16.3.2" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.3.2.tgz#f4d3d0e2f5fbb6ac46450641eb2e25bf05d36b22" @@ -19438,6 +18858,22 @@ react-test-renderer@^16.0.0-0, react-test-renderer@^16.8.0: react-is "^16.8.2" scheduler "^0.13.2" +react-testing-library@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/react-testing-library/-/react-testing-library-6.0.0.tgz#81edfcfae8a795525f48685be9bf561df45bb35d" + integrity sha512-h0h+YLe4KWptK6HxOMnoNN4ngu3W8isrwDmHjPC5gxc+nOZOCurOvbKVYCvvuAw91jdO7VZSm/5KR7TxKnz0qA== + dependencies: + "@babel/runtime" "^7.3.1" + dom-testing-library "^3.13.1" + +react-testing-library@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/react-testing-library/-/react-testing-library-6.0.3.tgz#8b5d276a353c17ce4f7486015bb7a1c8827c442c" + integrity sha512-tN0A6nywSOoL8kriqru3rSdw31PxuquL7xnW6xBI0aTNw0VO3kZQtaEa0npUH9dX0MIsSunB0nbElRrc4VtAzw== + dependencies: + "@babel/runtime" "^7.4.2" + dom-testing-library "^3.18.2" + react-textarea-autosize@^7.0.4: version "7.0.4" resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-7.0.4.tgz#4e4be649b544a88713e7b5043f76950f35d3d503" @@ -19891,7 +19327,7 @@ regenerate@^1.4.0: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== -regenerator-runtime@^0.10.0, regenerator-runtime@^0.10.5: +regenerator-runtime@^0.10.5: version "0.10.5" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" integrity sha1-M2w+/BIgrc7dosn6tntaeVWjNlg= @@ -19906,14 +19342,10 @@ regenerator-runtime@^0.12.0, regenerator-runtime@^0.12.1: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== -regenerator-transform@^0.10.0: - version "0.10.1" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" - integrity sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q== - dependencies: - babel-runtime "^6.18.0" - babel-types "^6.19.0" - private "^0.1.6" +regenerator-runtime@^0.13.2: + version "0.13.2" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz#32e59c9a6fb9b1a4aff09b4930ca2d4477343447" + integrity sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA== regenerator-transform@^0.13.3: version "0.13.3" @@ -19967,10 +19399,10 @@ regexp.prototype.flags@^1.2.0: dependencies: define-properties "^1.1.2" -regexpp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.0.tgz#b2a7534a85ca1b033bcf5ce9ff8e56d4e0755365" - integrity sha512-g2FAVtR8Uh8GO1Nv5wpxW7VFVwHcCEr4wyA8/MHiRkO8uHoR5ntAA8Uq3P1vvMTX/BeQiRVSpDGLd+Wn5HNOTA== +regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== regexpu-core@^1.0.0: version "1.0.0" @@ -19981,15 +19413,6 @@ regexpu-core@^1.0.0: regjsgen "^0.2.0" regjsparser "^0.1.4" -regexpu-core@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" - integrity sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA= - dependencies: - regenerate "^1.2.1" - regjsgen "^0.2.0" - regjsparser "^0.1.4" - regexpu-core@^4.1.3, regexpu-core@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.2.0.tgz#a3744fa03806cffe146dea4421a3e73bdcc47b1d" @@ -20303,7 +19726,7 @@ require-main-filename@^1.0.1: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= -require-uncached@^1.0.2, require-uncached@^1.0.3: +require-uncached@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM= @@ -20404,7 +19827,7 @@ resolve@^1.1.5, resolve@^1.1.6, resolve@^1.1.7: dependencies: path-parse "^1.0.5" -resolve@^1.3.2, resolve@^1.4.0, resolve@^1.6.0, resolve@^1.8.1: +resolve@^1.3.2, resolve@^1.4.0, resolve@^1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA== @@ -20418,6 +19841,13 @@ resolve@^1.5.0, resolve@^1.7.1: dependencies: path-parse "^1.0.5" +resolve@^1.9.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.10.0.tgz#3bdaaeaf45cc07f375656dfd2e54ed0810b101ba" + integrity sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg== + dependencies: + path-parse "^1.0.6" + responselike@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" @@ -20484,18 +19914,18 @@ rimraf@2.4.3: dependencies: glob "^5.0.14" -rimraf@~2.2.6: - version "2.2.8" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" - integrity sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI= - -rimraf@~2.6.2: +rimraf@2.6.3, rimraf@~2.6.2: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== dependencies: glob "^7.1.3" +rimraf@~2.2.6: + version "2.2.8" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" + integrity sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI= + ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.1.tgz#0f4584295c53a3628af7e6d79aca21ce57d1c6e7" @@ -20646,6 +20076,13 @@ rxjs@^6.2.1: dependencies: tslib "^1.9.0" +rxjs@^6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.4.0.tgz#f3bb0fe7bda7fb69deac0c16f17b50b0b8790504" + integrity sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw== + dependencies: + tslib "^1.9.0" + safe-buffer@5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" @@ -21250,11 +20687,13 @@ slice-ansi@0.0.4: resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU= -slice-ansi@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" - integrity sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg== +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" is-fullwidth-code-point "^2.0.0" slide@^1.1.5, slide@~1.1.3: @@ -21415,13 +20854,6 @@ source-map-resolve@^0.5.0, source-map-resolve@^0.5.2: source-map-url "^0.4.0" urix "^0.1.0" -source-map-support@^0.4.15: - version "0.4.18" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" - integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== - dependencies: - source-map "^0.5.6" - source-map-support@^0.5.1: version "0.5.6" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.6.tgz#4435cee46b1aab62b8e8610ce60f788091c51c13" @@ -21438,6 +20870,14 @@ source-map-support@^0.5.6, source-map-support@~0.5.6: buffer-from "^1.0.0" source-map "^0.6.0" +source-map-support@^0.5.9: + version "0.5.10" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.10.tgz#2214080bc9d51832511ee2bab96e3c2f9353120c" + integrity sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map-url@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" @@ -21861,6 +21301,15 @@ string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" +string-width@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.0.0.tgz#5a1690a57cc78211fffd9bf24bbe24d090604eb1" + integrity sha512-rr8CUxBbvOZDUvc5lNIJ+OC1nPVpz+Siw9VBtUjB9b6jZehZLFt0JMCZzShFHIsI8cbhm0EsNIfWJMFV3cu3Ew== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.0.0" + string.prototype.matchall@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-3.0.0.tgz#66f4d8dd5c6c6cea4dffb55ec5f3184a8dd0dd59" @@ -22293,17 +21742,15 @@ table@^3.7.8: slice-ansi "0.0.4" string-width "^2.0.0" -table@^4.0.3: - version "4.0.3" - resolved "http://registry.npmjs.org/table/-/table-4.0.3.tgz#00b5e2b602f1794b9acaf9ca908a76386a7813bc" - integrity sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg== +table@^5.2.3: + version "5.2.3" + resolved "https://registry.yarnpkg.com/table/-/table-5.2.3.tgz#cde0cc6eb06751c009efab27e8c820ca5b67b7f2" + integrity sha512-N2RsDAMvDLvYwFcwbPyF3VmVSSkuF+G1e+8inhBLtHpvwXGw4QRPEZhihQNeEN0i1up6/f6ObCJXNdlRG3YVyQ== dependencies: - ajv "^6.0.1" - ajv-keywords "^3.0.0" - chalk "^2.1.0" - lodash "^4.17.4" - slice-ansi "1.0.0" - string-width "^2.1.1" + ajv "^6.9.1" + lodash "^4.17.11" + slice-ansi "^2.1.0" + string-width "^3.0.0" tabtab@^1.3.2: version "1.3.2" @@ -22475,17 +21922,6 @@ terser@^3.8.1: source-map "~0.6.1" source-map-support "~0.5.6" -test-exclude@^4.2.1: - version "4.2.3" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.3.tgz#a9a5e64474e4398339245a0a769ad7c2f4a97c20" - integrity sha512-SYbXgY64PT+4GAL2ocI3HwPa4Q4TBKm0cwAVeKOt/Aoc0gSpNRjJX8w0pA1LMKZ3LBmd8pYBqApFNQLII9kavA== - dependencies: - arrify "^1.0.1" - micromatch "^2.3.11" - object-assign "^4.1.0" - read-pkg-up "^1.0.1" - require-main-filename "^1.0.1" - test-exclude@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.1.0.tgz#6ba6b25179d2d38724824661323b73e03c0c1de1" @@ -22935,46 +22371,11 @@ trunc-text@1.0.2: resolved "https://registry.yarnpkg.com/trunc-text/-/trunc-text-1.0.2.tgz#b582bb3ddea9c9adc25017d737c48ebdd2157406" integrity sha1-tYK7Pd6pya3CUBfXN8SOvdIVdAY= -ts-jest@^23.1.4: - version "23.1.4" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-23.1.4.tgz#66ac1d8d3fbf8f9a98432b11aa377aa850664b2b" - integrity sha512-9rCSxbWfoZxxeXnSoEIzRNr9hDIQ8iEJAWmSRsWhDHDT8OeuGfURhJQUE8jtJlkyEygs6rngH8RYtHz9cfjmEA== - dependencies: - closest-file-data "^0.1.4" - fs-extra "6.0.1" - json5 "^0.5.0" - lodash "^4.17.10" - -ts-loader@^5.2.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-5.2.2.tgz#a707849b08ca754cc46f5c7053e79fe1c84caf0e" - integrity sha512-vM/TrEKXBqRYq5yLatsXyKFnYSpv53klmGtrILGlNqcMsxPVi8+e4yr1Agbu9oMZepx/4szDVn5QpFo83IQdQg== - dependencies: - chalk "^2.3.0" - enhanced-resolve "^4.0.0" - loader-utils "^1.0.2" - micromatch "^3.1.4" - semver "^5.0.1" - ts-log@2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ts-log/-/ts-log-2.1.3.tgz#9e30aca1baffe7693a2e4142b8f07ecb01cb8340" integrity sha512-VIk9+hzE80UjhJcSANst8LGRBpfNh32y9d3LVDMtEqcEb1x0hB71IO0aObNcLJ5VpK5tKeF9uI4pwEco03SkwA== -ts-node@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-7.0.1.tgz#9562dc2d1e6d248d24bc55f773e3f614337d9baf" - integrity sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw== - dependencies: - arrify "^1.0.0" - buffer-from "^1.1.0" - diff "^3.1.0" - make-error "^1.1.1" - minimist "^1.2.0" - mkdirp "^0.5.1" - source-map-support "^0.5.6" - yn "^2.0.0" - tslib@1.9.3, tslib@^1.7.1, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.2, tslib@^1.9.3: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" @@ -24087,7 +23488,7 @@ v8-compile-cache@^2.0.2: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.2.tgz#a428b28bb26790734c4fc8bc9fa106fccebf6a6c" integrity sha512-1wFuMUIM16MDJRCrpbpuEPTUGmM5QMUg0cr3KFwra2XgOgFcPGDQHDh3CszSCD2Zewc/dh/pamNEW8CbfDebUw== -v8flags@^2.0.2, v8flags@^2.1.1: +v8flags@^2.0.2: version "2.1.1" resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4" integrity sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ= @@ -24619,6 +24020,11 @@ w3c-hr-time@^1.0.1: dependencies: browser-process-hrtime "^0.1.2" +wait-for-expect@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/wait-for-expect/-/wait-for-expect-1.1.0.tgz#6607375c3f79d32add35cd2c87ce13f351a3d453" + integrity sha512-vQDokqxyMyknfX3luCDn16bSaRcOyH6gGuUXMIbxBLeTo6nWuEWYqMTT9a+44FmW8c2m6TRWBdNvBBjA1hwEKg== + walk@2.3.x: version "2.3.9" resolved "https://registry.yarnpkg.com/walk/-/walk-2.3.9.tgz#31b4db6678f2ae01c39ea9fb8725a9031e558a7b" @@ -25139,6 +24545,13 @@ write-pkg@^3.1.0: sort-keys "^2.0.0" write-json-file "^2.2.0" +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== + dependencies: + mkdirp "^0.5.1" + write@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" @@ -25628,11 +25041,6 @@ yeoman-generator@1.1.1: user-home "^2.0.0" yeoman-environment "^1.1.0" -yn@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" - integrity sha1-5a2ryKz0CPY4X8dklWhMiOavaJo= - yo@2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/yo/-/yo-2.0.5.tgz#2f747f5d279ab777e0167b0aa63d7b607507d73d"