diff --git a/.ci/Jenkinsfile_coverage b/.ci/Jenkinsfile_coverage index ebb9c3dc86dd2..1c1d21024ce91 100644 --- a/.ci/Jenkinsfile_coverage +++ b/.ci/Jenkinsfile_coverage @@ -12,8 +12,12 @@ kibanaPipeline(timeoutMinutes: 240) { ]) { workers.base(name: 'coverage-worker', size: 'l', ramDisk: false, bootstrapped: false) { catchError { + + kibanaPipeline.bash(""" + echo '${TIME_STAMP}' + """, "### Print Canonical Time Stamp") + kibanaCoverage.runTests() - kibanaTeamAssign.load('team_assignment', "### Upload Team Assignment JSON") handleIngestion(TIME_STAMP) } handleFail() @@ -30,8 +34,8 @@ def handleIngestion(timestamp) { kibanaCoverage.collectVcsInfo("### Collect VCS Info") kibanaCoverage.generateReports("### Merge coverage reports") kibanaCoverage.uploadCombinedReports() - kibanaCoverage.ingest(env.JOB_NAME, BUILD_NUMBER, BUILD_URL, timestamp, previousSha, '### Ingest && Upload') kibanaCoverage.uploadCoverageStaticSite(timestamp) + kibanaCoverage.ingest(env.JOB_NAME, BUILD_NUMBER, BUILD_URL, timestamp, previousSha, teamAssignmentsPath(), '### Generate Team Assignments && Ingest') } def handlePreviousSha() { @@ -42,7 +46,7 @@ def handlePreviousSha() { def handleFail() { def buildStatus = buildUtils.getBuildStatus() - if(params.NOTIFY_ON_FAILURE && buildStatus != 'SUCCESS' && buildStatus != 'ABORTED' && buildStatus != 'UNSTABLE') { + if (params.NOTIFY_ON_FAILURE && buildStatus != 'SUCCESS' && buildStatus != 'ABORTED' && buildStatus != 'UNSTABLE') { slackNotifications.sendFailedBuild( channel: '#kibana-qa', username: 'Kibana QA' @@ -50,3 +54,7 @@ def handleFail() { } } +def teamAssignmentsPath() { + return 'src/dev/code_coverage/ingest_coverage/team_assignment/team_assignments.txt' +} + diff --git a/.eslintrc.js b/.eslintrc.js index 5802f67a7cd65..a0363e77e3596 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -388,6 +388,7 @@ module.exports = { */ { files: [ + '**/*.stories.tsx', 'x-pack/test/apm_api_integration/**/*.ts', 'x-pack/test/functional/apps/**/*.js', 'x-pack/plugins/apm/**/*.js', diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 2f5e14f1f1599..d1cf0300b9e17 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,6 +2,9 @@ # Identify which groups will be pinged by changes to different parts of the codebase. # For more info, see https://help.github.com/articles/about-codeowners/ +# The #CC# prefix delineates Code Coverage, +# used for the 'team' designator within Kibana Stats + # App /x-pack/plugins/dashboard_enhanced/ @elastic/kibana-app /x-pack/plugins/discover_enhanced/ @elastic/kibana-app @@ -14,6 +17,7 @@ /src/plugins/input_control_vis/ @elastic/kibana-app /src/plugins/management/ @elastic/kibana-app /src/plugins/kibana_legacy/ @elastic/kibana-app +/src/plugins/timelion/ @elastic/kibana-app /src/plugins/vis_default_editor/ @elastic/kibana-app /src/plugins/vis_type_markdown/ @elastic/kibana-app /src/plugins/vis_type_metric/ @elastic/kibana-app @@ -26,6 +30,24 @@ /src/plugins/vis_type_xy/ @elastic/kibana-app /src/plugins/visualize/ @elastic/kibana-app /src/plugins/visualizations/ @elastic/kibana-app +#CC# /src/legacy/core_plugins/kibana/public/local_application_service/ @elastic/kibana-app +#CC# /src/legacy/core_plugins/kibana/ @elastic/kibana-app +#CC# /src/legacy/core_plugins/kibana/common/utils @elastic/kibana-app +#CC# /src/legacy/core_plugins/kibana/migrations @elastic/kibana-app +#CC# /src/legacy/core_plugins/kibana/public @elastic/kibana-app +#CC# /src/legacy/core_plugins/kibana/public/dashboard/ @elastic/kibana-app +#CC# /src/legacy/core_plugins/kibana/public/discover/ @elastic/kibana-app +#CC# /src/legacy/core_plugins/kibana/public/local_application_service/ @elastic/kibana-app +#CC# /src/legacy/core_plugins/input_control_vis @elastic/kibana-app +#CC# /src/legacy/core_plugins/timelion @elastic/kibana-app +#CC# /src/legacy/core_plugins/vis_type_tagcloud @elastic/kibana-app +#CC# /src/legacy/core_plugins/vis_type_vega @elastic/kibana-app +#CC# /src/legacy/core_plugins/vis_type_vislib/ @elastic/kibana-app +#CC# /src/legacy/server/url_shortening/ @elastic/kibana-app +#CC# /src/legacy/ui/public/state_management @elastic/kibana-app +#CC# /src/plugins/index_pattern_management/public @elastic/kibana-app +#CC# /x-pack/legacy/plugins/dashboard_mode/ @elastic/kibana-app +#CC# /x-pack/plugins/dashboard_mode @elastic/kibana-app # App Architecture /examples/bfetch_explorer/ @elastic/kibana-app-arch @@ -56,12 +78,37 @@ /x-pack/plugins/data_enhanced/ @elastic/kibana-app-arch /x-pack/plugins/embeddable_enhanced/ @elastic/kibana-app-arch /x-pack/plugins/ui_actions_enhanced/ @elastic/kibana-app-arch +#CC# /src/legacy/core_plugins/kibana/public/management/ @elastic/kibana-app-arch +#CC# /src/legacy/core_plugins/kibana/server/routes/api/management/ @elastic/kibana-app-arch +#CC# /src/legacy/core_plugins/embeddable_api/ @elastic/kibana-app-arch +#CC# /src/legacy/core_plugins/interpreter/ @elastic/kibana-app-arch +#CC# /src/legacy/core_plugins/kibana_react/ @elastic/kibana-app-arch +#CC# /src/legacy/core_plugins/status_page/public @elastic/kibana-app-arch +#CC# /src/legacy/server/index_patterns/ @elastic/kibana-app-arch +#CC# /src/legacy/ui/public/field_editor @elastic/kibana-app-arch +#CC# /src/legacy/ui/public/management @elastic/kibana-app-arch +#CC# /src/plugins/advanced_settings/ @elastic/kibana-app-arch +#CC# /src/plugins/bfetch/ @elastic/kibana-app-arch +#CC# /src/plugins/charts/ @elastic/kibana-app-arch +#CC# /src/plugins/index_pattern_management/public/service @elastic/kibana-app-arch +#CC# /src/plugins/inspector/ @elastic/kibana-app-arch +#CC# /src/plugins/saved_objects/ @elastic/kibana-app-arch +#CC# /src/plugins/share/ @elastic/kibana-app-arch +#CC# /src/plugins/vis_default_editor @elastic/kibana-app-arch +#CC# /x-pack/plugins/advanced_ui_actions/ @elastic/kibana-app-arch +#CC# /x-pack/plugins/drilldowns/ @elastic/kibana-app-arch +#CC# /packages/kbn-interpreter/ @elastic/kibana-app-arch # APM /x-pack/plugins/apm/ @elastic/apm-ui /x-pack/test/functional/apps/apm/ @elastic/apm-ui /src/plugins/apm_oss/ @elastic/apm-ui /src/apm.js @watson @vigneshshanmugam +#CC# /src/plugins/apm_oss/ @elastic/apm-ui +#CC# /src/legacy/core_plugins/apm_oss/ @elastic/apm-ui +#CC# /src/legacy/ui/public/apm @elastic/apm-ui +#CC# /x-pack/legacy/plugins/apm/ @elastic/apm-ui +#CC# /x-pack/plugins/observability/ @elastic/apm-ui # Client Side Monitoring (lives in APM directories but owned by Uptime) /x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm @elastic/uptime @@ -71,13 +118,19 @@ /x-pack/plugins/apm/server/lib/rum_client @elastic/uptime /x-pack/plugins/apm/server/routes/rum_client.ts @elastic/uptime /x-pack/plugins/apm/server/projections/rum_page_load_transactions.ts @elastic/uptime +/x-pack/plugins/apm/server/projections/rum_overview.ts @elastic/uptime +#CC# /x-pack/legacy/plugins/uptime @elastic/uptime # Beats /x-pack/plugins/beats_management/ @elastic/beats +/x-pack/legacy/plugins/beats_management/ @elastic/beats +#CC# /x-pack/plugins/beats_management/ @elastic/beats # Canvas /x-pack/plugins/canvas/ @elastic/kibana-canvas /x-pack/test/functional/apps/canvas/ @elastic/kibana-canvas +#CC# /src/plugins/kibana_react/public/code_editor/ @elastic/kibana-canvas +#CC# /x-pack/legacy/plugins/canvas/ @elastic/kibana-canvas # Core UI # Exclude tutorials folder for now because they are not owned by Kibana app and most will move out soon @@ -85,6 +138,13 @@ /src/plugins/home/server/*.ts @elastic/kibana-core-ui /src/plugins/home/server/services/ @elastic/kibana-core-ui /x-pack/plugins/global_search_bar/ @elastic/kibana-core-ui +#CC# /src/legacy/core_plugins/newsfeed @elastic/kibana-core-ui +#CC# /src/legacy/server/sample_data/ @elastic/kibana-core-ui +#CC# /src/plugins/newsfeed @elastic/kibana-core-ui +#CC# /src/plugins/home/public @elastic/kibana-core-ui +#CC# /src/plugins/home/server/services/ @elastic/kibana-core-ui +#CC# /src/plugins/home/ @elastic/kibana-core-ui +#CC# /x-pack/plugins/global_search_providers/ @elastic/kibana-core-ui # Observability UIs /x-pack/plugins/infra/ @elastic/logs-metrics-ui @@ -110,6 +170,14 @@ /x-pack/test/functional/apps/maps/ @elastic/kibana-gis /x-pack/test/functional/es_archives/maps/ @elastic/kibana-gis /x-pack/test/visual_regression/tests/maps/index.js @elastic/kibana-gis +#CC# /src/legacy/core_plugins/region_map @elastic/kibana-gis +#CC# /src/legacy/core_plugins/tile_map @elastic/kibana-gis +#CC# /src/plugins/maps_legacy/ @elastic/kibana-gis +#CC# /x-pack/plugins/file_upload @elastic/kibana-gis +#CC# /x-pack/plugins/maps_legacy_licensing @elastic/kibana-gis +#CC# /src/plugins/home/server/tutorials @elastic/kibana-gis +#CC# /src/plugins/tile_map/ @elastic/kibana-gis +#CC# /src/plugins/region_map/ @elastic/kibana-gis # Operations /src/dev/ @elastic/kibana-operations @@ -132,6 +200,7 @@ /src/legacy/server/warnings/ @elastic/kibana-operations /.ci/es-snapshots/ @elastic/kibana-operations /vars/ @elastic/kibana-operations +#CC# /packages/kbn-expect/ @elastic/kibana-operations # Quality Assurance /src/dev/code_coverage @elastic/kibana-qa @@ -158,6 +227,31 @@ /src/plugins/status_page/ @elastic/kibana-platform /src/plugins/saved_objects_management/ @elastic/kibana-platform /src/dev/run_check_published_api_changes.ts @elastic/kibana-platform +#CC# /src/core/server/csp/ @elastic/kibana-platform +#CC# /src/legacy/core_plugins/kibana/server/lib @elastic/kibana-platform +#CC# /src/legacy/core_plugins/kibana/server/lib/management/saved_objects @elastic/kibana-platform +#CC# /src/legacy/core_plugins/kibana/server/routes/api/import/ @elastic/kibana-platform +#CC# /src/legacy/core_plugins/kibana/server/routes/api/export/ @elastic/kibana-platform +#CC# /src/legacy/core_plugins/elasticsearch @elastic/kibana-platform +#CC# /src/legacy/core_plugins/testbed @elastic/kibana-platform +#CC# /src/legacy/server/config/ @elastic/kibana-platform +#CC# /src/legacy/server/http/ @elastic/kibana-platform +#CC# /src/legacy/server/status/ @elastic/kibana-platform +#CC# /src/legacy/ui/public/new_platform @elastic/kibana-platform +#CC# /src/legacy/ui/public/plugin_discovery @elastic/kibana-platform +#CC# /src/legacy/ui/public/chrome @elastic/kibana-platform +#CC# /src/legacy/ui/public/notify @elastic/kibana-platform +#CC# /src/legacy/ui/public/documentation_links @elastic/kibana-platform +#CC# /src/legacy/ui/public/autoload @elastic/kibana-platform +#CC# /src/plugins/legacy_export/ @elastic/kibana-platform +#CC# /src/plugins/status_page/ @elastic/kibana-platform +#CC# /src/plugins/testbed/server/ @elastic/kibana-platform +#CC# /x-pack/legacy/plugins/xpack_main/server/ @elastic/kibana-platform +#CC# /x-pack/legacy/server/lib/ @elastic/kibana-platform +#CC# /x-pack/plugins/cloud/ @elastic/kibana-platform +#CC# /x-pack/plugins/features/ @elastic/kibana-platform +#CC# /x-pack/plugins/global_search/ @elastic/kibana-platform +#CC# /src/legacy/plugin_discovery/ @elastic/kibana-platform # Security /src/core/server/csp/ @elastic/kibana-security @elastic/kibana-platform @@ -177,12 +271,19 @@ /x-pack/test/security_functional/ @elastic/kibana-security /x-pack/test/spaces_api_integration/ @elastic/kibana-security /x-pack/test/token_api_integration/ @elastic/kibana-security +#CC# /src/legacy/ui/public/capabilities @elastic/kibana-security +#CC# /x-pack/legacy/plugins/encrypted_saved_objects/ @elastic/kibana-security +#CC# /x-pack/plugins/security_solution/ @elastic/kibana-security +#CC# /x-pack/plugins/security/ @elastic/kibana-security +#CC# /x-pack/plugins/audit_trail/ @elastic/kibana-security # Kibana Localization /src/dev/i18n/ @elastic/kibana-localization /src/legacy/server/i18n/ @elastic/kibana-localization /src/core/public/i18n/ @elastic/kibana-localization /packages/kbn-i18n/ @elastic/kibana-localization +#CC# /src/legacy/server/i18n/ @elastic/kibana-localization +#CC# /x-pack/plugins/translations/ @elastic/kibana-localization # Kibana Telemetry /packages/kbn-analytics/ @elastic/kibana-telemetry @@ -211,21 +312,16 @@ x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json @elastic/kib /x-pack/plugins/triggers_actions_ui/ @elastic/kibana-alerting-services /x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/ @elastic/kibana-alerting-services /x-pack/test/functional_with_es_ssl/fixtures/plugins/alerts/ @elastic/kibana-alerting-services +#CC# /x-pack/legacy/plugins/actions/ @elastic/kibana-alerting-services +#CC# /x-pack/legacy/plugins/alerting/ @elastic/kibana-alerting-services +#CC# /x-pack/legacy/plugins/task_manager @elastic/kibana-alerting-services +#CC# /x-pack/legacy/plugins/triggers_actions_ui/ @elastic/kibana-alerting-services +#CC# /x-pack/plugins/alerting_builtins @elastic/kibana-alerting-services # Enterprise Search # Shared /x-pack/plugins/enterprise_search/ @elastic/enterprise-search-frontend /x-pack/test/functional_enterprise_search/ @elastic/enterprise-search-frontend -# App Search -/x-pack/plugins/enterprise_search/public/applications/app_search @elastic/app-search-frontend -/x-pack/plugins/enterprise_search/server/routes/app_search @elastic/app-search-frontend -/x-pack/plugins/enterprise_search/server/collectors/app_search @elastic/app-search-frontend -/x-pack/plugins/enterprise_search/server/saved_objects/app_search @elastic/app-search-frontend -# Workplace Search -/x-pack/plugins/enterprise_search/public/applications/workplace_search @elastic/workplace-search-frontend -/x-pack/plugins/enterprise_search/server/routes/workplace_search @elastic/workplace-search-frontend -/x-pack/plugins/enterprise_search/server/collectors/workplace_search @elastic/workplace-search-frontend -/x-pack/plugins/enterprise_search/server/saved_objects/workplace_search @elastic/workplace-search-frontend # Elasticsearch UI /src/plugins/dev_tools/ @elastic/es-ui @@ -248,6 +344,14 @@ x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json @elastic/kib /x-pack/plugins/ingest_pipelines/ @elastic/es-ui /packages/kbn-ace/ @elastic/es-ui /packages/kbn-monaco/ @elastic/es-ui +#CC# /src/legacy/core_plugins/kibana/public/dev_tools/ @elastic/es-ui +#CC# /src/legacy/core_plugins/console_legacy @elastic/es-ui +#CC# /x-pack/legacy/plugins/rollup/ @elastic/es-ui +#CC# /x-pack/legacy/server/lib/create_router/ @elastic/es-ui +#CC# /x-pack/legacy/server/lib/check_license/ @elastic/es-ui +#CC# /x-pack/plugins/console_extensions/ @elastic/es-ui +#CC# /x-pack/plugins/cross_cluster_replication/ @elastic/es-ui +#CC# /x-pack/plugins/es_ui_shared/ @elastic/es-u # Endpoint /x-pack/plugins/endpoint/ @elastic/endpoint-app-team @elastic/siem @@ -257,6 +361,9 @@ x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json @elastic/kib /x-pack/test/functional/es_archives/endpoint/ @elastic/endpoint-app-team @elastic/siem /x-pack/test/plugin_functional/plugins/resolver_test/ @elastic/endpoint-app-team @elastic/siem /x-pack/test/plugin_functional/test_suites/resolver/ @elastic/endpoint-app-team @elastic/siem +#CC# /x-pack/legacy/plugins/siem/ @elastic/siem +#CC# /x-pack/plugins/siem/ @elastic/siem +#CC# /x-pack/plugins/security_solution/ @elastic/siem # Security Solution /x-pack/plugins/security_solution/ @elastic/siem @elastic/endpoint-app-team @@ -271,6 +378,7 @@ x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json @elastic/kib # Design (at the bottom for specificity of SASS files) **/*.scss @elastic/kibana-design +#CC# /packages/kbn-ui-framework/ @elastic/kibana-design # Core design /src/plugins/dashboard/**/*.scss @elastic/kibana-core-ui-designers @@ -292,3 +400,9 @@ x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json @elastic/kib /x-pack/plugins/endpoint/**/*.scss @elastic/security-design /x-pack/plugins/security_solution/**/*.scss @elastic/security-design +# Logstash +#CC# /x-pack/plugins/logstash/ @elastic/logstash + +# Reporting +#CC# /x-pack/plugins/reporting/ @elastic/kibana-reporting-services + diff --git a/.telemetryrc.json b/.telemetryrc.json index d3446b45033ee..3d1b0df1d8f93 100644 --- a/.telemetryrc.json +++ b/.telemetryrc.json @@ -5,8 +5,7 @@ "exclude": [ "src/plugins/kibana_react/", "src/plugins/testbed/", - "src/plugins/kibana_utils/", - "src/plugins/kibana_usage_collection/server/collectors/ui_metric/telemetry_ui_metric_collector.ts" + "src/plugins/kibana_utils/" ] } ] diff --git a/NOTICE.txt b/NOTICE.txt index d689abf4c4e05..0504b7f7d6db2 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -208,6 +208,30 @@ 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. +--- +MIT License + +Copyright (c) 2014-present Sebastian McKenzie and other contributors + +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/config/kibana.yml b/config/kibana.yml index 72e0764f849a0..58ae8b9346f51 100644 --- a/config/kibana.yml +++ b/config/kibana.yml @@ -27,11 +27,6 @@ # The URLs of the Elasticsearch instances to use for all your queries. #elasticsearch.hosts: ["http://localhost:9200"] -# When this setting's value is true Kibana uses the hostname specified in the server.host -# setting. When the value of this setting is false, Kibana uses the hostname of the host -# that connects to this Kibana instance. -#elasticsearch.preserveHost: true - # Kibana uses an index in Elasticsearch to store saved searches, visualizations and # dashboards. Kibana creates a new index if the index doesn't already exist. #kibana.index: ".kibana" @@ -81,9 +76,6 @@ # Time in milliseconds for Elasticsearch to wait for responses from shards. Set to 0 to disable. #elasticsearch.shardTimeout: 30000 -# Time in milliseconds to wait for Elasticsearch at Kibana startup before retrying. -#elasticsearch.startupTimeout: 5000 - # Logs queries sent to Elasticsearch. Requires logging.verbose set to true. #elasticsearch.logQueries: false diff --git a/docs/api/saved-objects/bulk_create.asciidoc b/docs/api/saved-objects/bulk_create.asciidoc index 4f572b49ee5ff..5149cef3d30c6 100644 --- a/docs/api/saved-objects/bulk_create.asciidoc +++ b/docs/api/saved-objects/bulk_create.asciidoc @@ -41,6 +41,10 @@ experimental[] Create multiple {kib} saved objects. `references`:: (Optional, array) Objects with `name`, `id`, and `type` properties that describe the other saved objects in the referenced object. To refer to the other saved object, use `name` in the attributes. Never use `id` to refer to the other saved object. `id` can be automatically updated during migrations, import, or export. +`namespaces`:: + (Optional, string array) Identifiers for the <> in which this object should be created. If this is not provided, the + object will be created in the current space. + `version`:: (Optional, number) Specifies the version. diff --git a/docs/api/saved-objects/create.asciidoc b/docs/api/saved-objects/create.asciidoc index e6f3301bfea2b..c8cd9c8bfca27 100644 --- a/docs/api/saved-objects/create.asciidoc +++ b/docs/api/saved-objects/create.asciidoc @@ -46,6 +46,10 @@ any data that you send to the API is properly formed. `references`:: (Optional, array) Objects with `name`, `id`, and `type` properties that describe the other saved objects that this object references. Use `name` in attributes to refer to the other saved object, but never the `id`, which can update automatically during migrations or import/export. +`namespaces`:: + (Optional, string array) Identifiers for the <> in which this object should be created. If this is not provided, the + object will be created in the current space. + [[saved-objects-api-create-request-codes]] ==== Response code diff --git a/docs/api/saved-objects/delete.asciidoc b/docs/api/saved-objects/delete.asciidoc index af587b0e7af10..9c342cb4d843e 100644 --- a/docs/api/saved-objects/delete.asciidoc +++ b/docs/api/saved-objects/delete.asciidoc @@ -27,6 +27,14 @@ WARNING: Once you delete a saved object, _it cannot be recovered_. `id`:: (Required, string) The object ID that you want to remove. +[[saved-objects-api-delete-query-params]] +==== Query parameters + +`force`:: + (Optional, boolean) When true, forces an object to be deleted if it exists in multiple namespaces. ++ +TIP: Use this if you attempted to delete an object and received an HTTP 400 error with the following message: _"Unable to delete saved object that exists in multiple namespaces, use the `force` option to delete it anyway"_ + [[saved-objects-api-delete-response-codes]] ==== Response code diff --git a/docs/developer/architecture/code-exploration.asciidoc b/docs/developer/architecture/code-exploration.asciidoc deleted file mode 100644 index 4a390336da34f..0000000000000 --- a/docs/developer/architecture/code-exploration.asciidoc +++ /dev/null @@ -1,598 +0,0 @@ -//// - -NOTE: - This is an automatically generated file. Please do not edit directly. Instead, run the - following from within the kibana repository: - - node scripts/build_plugin_list_docs - - You can update the template within packages/kbn-dev-utils/target/plugin_list/generate_plugin_list.js - -//// - -[[code-exploration]] -== Exploring Kibana code - -The goals of our folder heirarchy are: - -- Easy for developers to know where to add new services, plugins and applications. -- Easy for developers to know where to find the code from services, plugins and applications. -- Easy to browse and understand our folder structure. - -To that aim, we strive to: - -- Avoid too many files in any given folder. -- Choose clear, unambigious folder names. -- Organize by domain. -- Every folder should contain a README that describes the contents of that folder. - -[discrete] -[[kibana-services-applications]] -=== Services and Applications - -[discrete] -==== src/plugins - -- {kib-repo}blob/{branch}/src/plugins/advanced_settings[advancedSettings] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/src/plugins/apm_oss[apmOss] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/src/plugins/bfetch/README.md[bfetch] - -bfetch allows to batch HTTP requests and streams responses back. - - -- {kib-repo}blob/{branch}/src/plugins/charts/README.md[charts] - -The Charts plugin is a way to create easier integration of shared colors, themes, types and other utilities across all Kibana charts and visualizations. - - -- {kib-repo}blob/{branch}/src/plugins/console[console] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/src/plugins/dashboard/README.md[dashboard] - -Contains the dashboard application. - - -- {kib-repo}blob/{branch}/src/plugins/data/README.md[data] - -data plugin provides common data access services. - - -- {kib-repo}blob/{branch}/src/plugins/dev_tools/README.md[devTools] - -The ui/registry/dev_tools is removed in favor of the devTools plugin which exposes a register method in the setup contract. -Registering app works mostly the same as registering apps in core.application.register. -Routing will be handled by the id of the dev tool - your dev tool will be mounted when the URL matches /app/dev_tools#/. -This API doesn't support angular, for registering angular dev tools, bootstrap a local module on mount into the given HTML element. - - -- {kib-repo}blob/{branch}/src/plugins/discover/README.md[discover] - -Contains the Discover application and the saved search embeddable. - - -- {kib-repo}blob/{branch}/src/plugins/embeddable/README.md[embeddable] - -Embeddables are re-usable widgets that can be rendered in any environment or plugin. Developers can embed them directly in their plugin. End users can dynamically add them to any embeddable containers. - - -- {kib-repo}blob/{branch}/src/plugins/es_ui_shared/README.md[esUiShared] - -This plugin contains reusable code in the form of self-contained modules (or libraries). Each of these modules exports a set of functionality relevant to the domain of the module. - - -- {kib-repo}blob/{branch}/src/plugins/expressions/README.md[expressions] - -This plugin provides methods which will parse & execute an expression pipeline -string for you, as well as a series of registries for advanced users who might -want to incorporate their own functions, types, and renderers into the service -for use in their own application. - - -- {kib-repo}blob/{branch}/src/plugins/home/README.md[home] - -Moves the legacy ui/registry/feature_catalogue module for registering "features" that should be shown in the home page's feature catalogue to a service within a "home" plugin. The feature catalogue refered to here should not be confused with the "feature" plugin for registering features used to derive UI capabilities for feature controls. - - -- {kib-repo}blob/{branch}/src/plugins/index_pattern_management[indexPatternManagement] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/src/plugins/input_control_vis/README.md[inputControlVis] - -Contains the input control visualization allowing to place custom filter controls on a dashboard. - - -- {kib-repo}blob/{branch}/src/plugins/inspector/README.md[inspector] - -The inspector is a contextual tool to gain insights into different elements -in Kibana, e.g. visualizations. It has the form of a flyout panel. - - -- {kib-repo}blob/{branch}/src/plugins/kibana_legacy/README.md[kibanaLegacy] - -This plugin will contain several helpers and services to integrate pieces of the legacy Kibana app with the new Kibana platform. - - -- {kib-repo}blob/{branch}/src/plugins/kibana_react/README.md[kibanaReact] - -Tools for building React applications in Kibana. - - -- {kib-repo}blob/{branch}/src/plugins/kibana_usage_collection/README.md[kibanaUsageCollection] - -This plugin registers the basic usage collectors from Kibana: - - -- {kib-repo}blob/{branch}/src/plugins/kibana_utils/README.md[kibanaUtils] - -Utilities for building Kibana plugins. - - -- {kib-repo}blob/{branch}/src/plugins/legacy_export[legacyExport] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/src/plugins/management[management] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/src/plugins/maps_legacy[mapsLegacy] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/src/plugins/navigation/README.md[navigation] - -The navigation plugins exports the TopNavMenu component. -It also provides a stateful version of it on the start contract. - - -- {kib-repo}blob/{branch}/src/plugins/newsfeed[newsfeed] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/src/plugins/region_map[regionMap] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/src/plugins/saved_objects[savedObjects] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/src/plugins/saved_objects_management[savedObjectsManagement] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/src/plugins/share/README.md[share] - -Replaces the legacy ui/share module for registering share context menus. - - -- {kib-repo}blob/{branch}/src/plugins/telemetry/README.md[telemetry] - -Telemetry allows Kibana features to have usage tracked in the wild. The general term "telemetry" refers to multiple things: - - -- {kib-repo}blob/{branch}/src/plugins/telemetry_collection_manager/README.md[telemetryCollectionManager] - -Telemetry's collection manager to go through all the telemetry sources when fetching it before reporting. - - -- {kib-repo}blob/{branch}/src/plugins/telemetry_management_section/README.md[telemetryManagementSection] - -This plugin adds the Advanced Settings section for the Usage Data collection (aka Telemetry). - - -- {kib-repo}blob/{branch}/src/plugins/tile_map[tileMap] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/src/plugins/timelion/README.md[timelion] - -Contains the deprecated timelion application. For the timelion visualization, -which also contains the timelion APIs and backend, look at the vis_type_timelion plugin. - - -- {kib-repo}blob/{branch}/src/plugins/ui_actions/README.md[uiActions] - -An API for: - - -- {kib-repo}blob/{branch}/src/plugins/usage_collection/README.md[usageCollection] - -Usage Collection allows collecting usage data for other services to consume (telemetry and monitoring). -To integrate with the telemetry services for usage collection of your feature, there are 2 steps: - - -- {kib-repo}blob/{branch}/src/plugins/vis_type_markdown/README.md[visTypeMarkdown] - -The markdown visualization that can be used to place text panels on dashboards. - - -- {kib-repo}blob/{branch}/src/plugins/vis_type_metric/README.md[visTypeMetric] - -Contains the metric visualization. - - -- {kib-repo}blob/{branch}/src/plugins/vis_type_table/README.md[visTypeTable] - -Contains the data table visualization, that allows presenting data in a simple table format. - - -- {kib-repo}blob/{branch}/src/plugins/vis_type_tagcloud/README.md[visTypeTagcloud] - -Contains the tagcloud visualization. - - -- {kib-repo}blob/{branch}/src/plugins/vis_type_timelion/README.md[visTypeTimelion] - -Contains the timelion visualization and the timelion backend. - - -- {kib-repo}blob/{branch}/src/plugins/vis_type_timeseries/README.md[visTypeTimeseries] - -Contains everything around TSVB (the editor, visualizatin implementations and backends). - - -- {kib-repo}blob/{branch}/src/plugins/vis_type_vega/README.md[visTypeVega] - -Contains the Vega visualization. - - -- {kib-repo}blob/{branch}/src/plugins/vis_type_vislib/README.md[visTypeVislib] - -Contains the vislib visualizations. These are the classical area/line/bar, pie, gauge/goal and -heatmap charts. - - -- {kib-repo}blob/{branch}/src/plugins/vis_type_xy/README.md[visTypeXy] - -Contains the new xy-axis chart using the elastic-charts library, which will eventually -replace the vislib xy-axis (bar, area, line) charts. - - -- {kib-repo}blob/{branch}/src/plugins/visualizations/README.md[visualizations] - -Contains most of the visualization infrastructure, e.g. the visualization type registry or the -visualization embeddable. - - -- {kib-repo}blob/{branch}/src/plugins/visualize/README.md[visualize] - -Contains the visualize application which includes the listing page and the app frame, -which will load the visualization's editor. - - -[discrete] -==== x-pack/plugins - -- {kib-repo}blob/{branch}/x-pack/plugins/actions/README.md[actions] - -The Kibana actions plugin provides a framework to create executable actions. You can: - - -- {kib-repo}blob/{branch}/x-pack/plugins/alerting_builtins/README.md[alertingBuiltins] - -This plugin provides alertTypes shipped with Kibana for use with the -the alerts plugin. When enabled, it will register -the built-in alertTypes with the alerting plugin, register associated HTTP -routes, etc. - - -- {kib-repo}blob/{branch}/x-pack/plugins/alerts/README.md[alerts] - -The Kibana alerting plugin provides a common place to set up alerts. You can: - - -- {kib-repo}blob/{branch}/x-pack/plugins/apm/readme.md[apm] - -To access an elasticsearch instance that has live data you have two options: - - -- {kib-repo}blob/{branch}/x-pack/plugins/audit_trail[auditTrail] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/x-pack/plugins/beats_management/readme.md[beatsManagement] - -Notes: -Failure to have auth enabled in Kibana will make for a broken UI. UI-based errors not yet in place - - -- {kib-repo}blob/{branch}/x-pack/plugins/canvas/README.md[canvas] - -"Never look back. The past is done. The future is a blank canvas." ― Suzy Kassem, Rise Up and Salute the Sun - - -- {kib-repo}blob/{branch}/x-pack/plugins/case/README.md[case] - -Experimental Feature - - -- {kib-repo}blob/{branch}/x-pack/plugins/cloud[cloud] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/x-pack/plugins/code[code] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/x-pack/plugins/console_extensions[consoleExtensions] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/x-pack/plugins/cross_cluster_replication/README.md[crossClusterReplication] - -You can run a local cluster and simulate a remote cluster within a single Kibana directory. - - -- {kib-repo}blob/{branch}/x-pack/plugins/dashboard_enhanced/README.md[dashboardEnhanced] - -Contains the enhancements to the OSS dashboard app. - - -- {kib-repo}blob/{branch}/x-pack/plugins/dashboard_mode/README.md[dashboardMode] - -The deprecated dashboard only mode. - - -- {kib-repo}blob/{branch}/x-pack/plugins/data_enhanced[dataEnhanced] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/x-pack/plugins/discover_enhanced/README.md[discoverEnhanced] - -Contains the enhancements to the OSS discover app. - - -- {kib-repo}blob/{branch}/x-pack/plugins/embeddable_enhanced[embeddableEnhanced] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/x-pack/plugins/encrypted_saved_objects/README.md[encryptedSavedObjects] - -The purpose of this plugin is to provide a way to encrypt/decrypt attributes on the custom Saved Objects that works with -security and spaces filtering as well as performing audit logging. - - -- {kib-repo}blob/{branch}/x-pack/plugins/enterprise_search/README.md[enterpriseSearch] - -This plugin's goal is to provide a Kibana user interface to the Enterprise Search solution's products (App Search and Workplace Search). In it's current MVP state, the plugin provides the following with the goal of gathering user feedback and raising product awareness: - - -- {kib-repo}blob/{branch}/x-pack/plugins/event_log/README.md[eventLog] - -The purpose of this plugin is to provide a way to persist a history of events -occuring in Kibana, initially just for the Make It Action project - alerts -and actions. - - -- {kib-repo}blob/{branch}/x-pack/plugins/features[features] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/x-pack/plugins/file_upload[fileUpload] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/x-pack/plugins/global_search/README.md[globalSearch] - -The GlobalSearch plugin provides an easy way to search for various objects, such as applications -or dashboards from the Kibana instance, from both server and client-side plugins - - -- {kib-repo}blob/{branch}/x-pack/plugins/global_search_bar/README.md[globalSearchBar] - -The GlobalSearchBar plugin provides a search interface for navigating Kibana. (It is the UI to the GlobalSearch plugin.) - - -- {kib-repo}blob/{branch}/x-pack/plugins/global_search_providers[globalSearchProviders] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/x-pack/plugins/graph/README.md[graph] - -This is the main source folder of the Graph plugin. It contains all of the Kibana server and client source code. x-pack/test/functional/apps/graph contains additional functional tests. - - -- {kib-repo}blob/{branch}/x-pack/plugins/grokdebugger/README.md[grokdebugger] - -- {kib-repo}blob/{branch}/x-pack/plugins/index_lifecycle_management/README.md[indexLifecycleManagement] - -You can test that the Frozen badge, phase filtering, and lifecycle information is surfaced in -Index Management by running this series of requests in Console: - - -- {kib-repo}blob/{branch}/x-pack/plugins/index_management[indexManagement] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/x-pack/plugins/infra/README.md[infra] - -This is the home of the infra plugin, which aims to provide a solution for -the infrastructure monitoring use-case within Kibana. - - -- {kib-repo}blob/{branch}/x-pack/plugins/ingest_manager/README.md[ingestManager] - -Fleet needs to have Elasticsearch API keys enabled, and also to have TLS enabled on kibana, (if you want to run Kibana without TLS you can provide the following config flag --xpack.ingestManager.fleet.tlsCheckDisabled=false) - - -- {kib-repo}blob/{branch}/x-pack/plugins/ingest_pipelines/README.md[ingestPipelines] - -The ingest_pipelines plugin provides Kibana support for Elasticsearch's ingest nodes. Please refer to the Elasticsearch documentation for more details. - - -- {kib-repo}blob/{branch}/x-pack/plugins/lens/readme.md[lens] - -Run all tests from the x-pack root directory - - -- {kib-repo}blob/{branch}/x-pack/plugins/license_management[licenseManagement] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/x-pack/plugins/licensing/README.md[licensing] - -The licensing plugin retrieves license data from Elasticsearch at regular configurable intervals. - - -- {kib-repo}blob/{branch}/x-pack/plugins/lists/README.md[lists] - -README.md for developers working on the backend lists on how to get started -using the CURL scripts in the scripts folder. - - -- {kib-repo}blob/{branch}/x-pack/plugins/logstash[logstash] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/x-pack/plugins/maps/README.md[maps] - -Visualize geo data from Elasticsearch or 3rd party geo-services. - - -- {kib-repo}blob/{branch}/x-pack/plugins/maps_legacy_licensing/README.md[mapsLegacyLicensing] - -This plugin provides access to the detailed tile map services from Elastic. - - -- {kib-repo}blob/{branch}/x-pack/plugins/ml[ml] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/x-pack/plugins/monitoring[monitoring] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/x-pack/plugins/observability/README.md[observability] - -This plugin provides shared components and services for use across observability solutions, as well as the observability landing page UI. - - -- {kib-repo}blob/{branch}/x-pack/plugins/oss_telemetry[ossTelemetry] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/x-pack/plugins/painless_lab[painlessLab] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/x-pack/plugins/remote_clusters[remoteClusters] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/x-pack/plugins/reporting/README.md[reporting] - -An awesome Kibana reporting plugin - - -- {kib-repo}blob/{branch}/x-pack/plugins/rollup/README.md[rollup] - -Welcome to the Kibana rollup plugin! This plugin provides Kibana support for Elasticsearch's rollup feature. Please refer to the Elasticsearch documentation to understand rollup indices and how to create rollup jobs. - - -- {kib-repo}blob/{branch}/x-pack/plugins/searchprofiler[searchprofiler] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/x-pack/plugins/security/README.md[security] - -See Configuring security in Kibana. - - -- {kib-repo}blob/{branch}/x-pack/plugins/security_solution/README.md[securitySolution] - -Welcome to the Kibana Security Solution plugin! This README will go over getting started with development and testing. - - -- {kib-repo}blob/{branch}/x-pack/plugins/snapshot_restore/README.md[snapshotRestore] - -or - - -- {kib-repo}blob/{branch}/x-pack/plugins/spaces[spaces] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/x-pack/plugins/task_manager[taskManager] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/x-pack/plugins/telemetry_collection_xpack/README.md[telemetryCollectionXpack] - -Gathers all usage collection, retrieving them from both: OSS and X-Pack plugins. - - -- {kib-repo}blob/{branch}/x-pack/plugins/transform[transform] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/x-pack/plugins/translations[translations] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/x-pack/plugins/triggers_actions_ui/README.md[triggers_actions_ui] - -The Kibana alerts and actions UI plugin provides a user interface for managing alerts and actions. -As a developer you can reuse and extend built-in alerts and actions UI functionality: - - -- {kib-repo}blob/{branch}/x-pack/plugins/ui_actions_enhanced/README.md[uiActionsEnhanced] - -- {kib-repo}blob/{branch}/x-pack/plugins/upgrade_assistant[upgradeAssistant] - -WARNING: Missing README. - - -- {kib-repo}blob/{branch}/x-pack/plugins/uptime/README.md[uptime] - -The purpose of this plugin is to provide users of Heartbeat more visibility of what's happening -in their infrastructure. - - -- {kib-repo}blob/{branch}/x-pack/plugins/watcher/README.md[watcher] - -This plugins adopts some conventions in addition to or in place of conventions in Kibana (at the time of the plugin's creation): - diff --git a/docs/developer/contributing/development-github.asciidoc b/docs/developer/contributing/development-github.asciidoc index 84f51843098a7..c5a3d942f2af3 100644 --- a/docs/developer/contributing/development-github.asciidoc +++ b/docs/developer/contributing/development-github.asciidoc @@ -25,7 +25,7 @@ Pull requests are made into the `master` branch and then backported when it is s * Breaking changes do not get backported and only go into `master`. * All non-breaking changes can be backported to the `.x` branch. * Features should not be backported to a `.` branch. -* Bugs can be backported to a `.` branch if the changes are safe and appropriate. Safety is a judgment call you make based on factors like the bug's severity, test coverage, confidence in the changes, etc. Your reasoning should be included in the pull request description. +* Bug fixes can be backported to a `.` branch if the changes are safe and appropriate. Safety is a judgment call you make based on factors like the bug's severity, test coverage, confidence in the changes, etc. Your reasoning should be included in the pull request description. * Documentation changes can be backported to any branch at any time. [discrete] diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index 5a4a60c2e628e..67b7aa8e6a011 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -16,7 +16,7 @@ NOTE: [discrete] === src/plugins -[%header,cols=2*] +[%header,cols=2*] |=== |Name |Description @@ -48,7 +48,7 @@ NOTE: |{kib-repo}blob/{branch}/src/plugins/data/README.md[data] -|data plugin provides common data access services. +|The data plugin provides common data access services, such as search and query, for solutions and application developers. |{kib-repo}blob/{branch}/src/plugins/dev_tools/README.md[devTools] @@ -62,16 +62,28 @@ This API doesn't support angular, for registering angular dev tools, bootstrap a |Contains the Discover application and the saved search embeddable. -|{kib-repo}blob/{branch}/src/plugins/embeddable/README.md[embeddable] -|Embeddables are re-usable widgets that can be rendered in any environment or plugin. Developers can embed them directly in their plugin. End users can dynamically add them to any embeddable containers. +|<> +|Embeddables are re-usable widgets that can be rendered in any environment or plugin. Developers can embed them directly in their plugin. End users can dynamically add them to any embeddable _containers_. |{kib-repo}blob/{branch}/src/plugins/es_ui_shared/README.md[esUiShared] |This plugin contains reusable code in the form of self-contained modules (or libraries). Each of these modules exports a set of functionality relevant to the domain of the module. -|{kib-repo}blob/{branch}/src/plugins/expressions/README.md[expressions] -|This plugin provides methods which will parse & execute an expression pipeline +|<> +|Expression pipeline is a chain of functions that *pipe* its output to the +input of the next function. Functions can be configured using arguments provided +by the user. The final output of the expression pipeline can be rendered using +one of the *renderers* registered in `expressions` plugin. + +All the arguments to expression functions need to be serializable, as well as input and output. +Expression functions should try to stay 'pure'. This makes functions easy to reuse and also +make it possible to serialize the whole chain as well as output at every step of execution. + +Expressions power visualizations in Dashboard and Lens, as well as, every +*element* in Canvas is backed by an expression. + +This plugin provides methods which will parse & execute an *expression pipeline* string for you, as well as a series of registries for advanced users who might want to incorporate their own functions, types, and renderers into the service for use in their own application. @@ -156,7 +168,7 @@ It also provides a stateful version of it on the start contract. |{kib-repo}blob/{branch}/src/plugins/telemetry_management_section/README.md[telemetryManagementSection] -|This plugin adds the Advanced Settings section for the Usage Data collection (aka Telemetry). +|This plugin adds the Advanced Settings section for the Usage and Security Data collection (aka Telemetry). |{kib-repo}blob/{branch}/src/plugins/tile_map[tileMap] @@ -168,9 +180,16 @@ It also provides a stateful version of it on the start contract. which also contains the timelion APIs and backend, look at the vis_type_timelion plugin. -|{kib-repo}blob/{branch}/src/plugins/ui_actions/README.md[uiActions] +|<> |An API for: +- creating custom functionality (`actions`) +- creating custom user interaction events (`triggers`) +- attaching and detaching `actions` to `triggers`. +- emitting `trigger` events +- executing `actions` attached to a given `trigger`. +- exposing a context menu for the user to choose the appropriate action when there are multiple actions attached to a single trigger. + |{kib-repo}blob/{branch}/src/plugins/url_forwarding/README.md[urlForwarding] |This plugins contains helpers to redirect legacy URLs. It can be used to forward old URLs to their new counterparts. @@ -240,7 +259,7 @@ which will load the visualization's editor. [discrete] === x-pack/plugins -[%header,cols=2*] +[%header,cols=2*] |=== |Name |Description @@ -496,6 +515,10 @@ As a developer you can reuse and extend built-in alerts and actions UI functiona in their infrastructure. +|{kib-repo}blob/{branch}/x-pack/plugins/drilldowns/url_drilldown/README.md[urlDrilldown] +|NOTE: This plugin contains implementation of URL drilldown. For drilldowns infrastructure code refer to ui_actions_enhanced plugin. + + |{kib-repo}blob/{branch}/x-pack/plugins/watcher/README.md[watcher] |This plugins adopts some conventions in addition to or in place of conventions in Kibana (at the time of the plugin's creation): @@ -504,12 +527,11 @@ in their infrastructure. |Contains HTTP endpoints and UiSettings that are slated for removal. -|{kib-repo}blob/{branch}/x-pack/plugins/drilldowns/url_drilldown/README.md[urlDrilldown] -|NOTE: This plugin contains implementation of URL drilldown. For drilldowns infrastructure code refer to ui_actions_enhanced plugin. - - |=== include::{kibana-root}/src/plugins/dashboard/README.asciidoc[leveloffset=+1] +include::{kibana-root}/src/plugins/embeddable/README.asciidoc[leveloffset=+1] +include::{kibana-root}/src/plugins/expressions/README.asciidoc[leveloffset=+1] +include::{kibana-root}/src/plugins/ui_actions/README.asciidoc[leveloffset=+1] include::{kibana-root}/x-pack/plugins/dashboard_enhanced/README.asciidoc[leveloffset=+1] include::{kibana-root}/x-pack/plugins/embeddable_enhanced/README.asciidoc[leveloffset=+1] diff --git a/docs/development/core/public/kibana-plugin-core-public.applicationstart.geturlforapp.md b/docs/development/core/public/kibana-plugin-core-public.applicationstart.geturlforapp.md index 055ad9f37e654..1eaf00c7a678d 100644 --- a/docs/development/core/public/kibana-plugin-core-public.applicationstart.geturlforapp.md +++ b/docs/development/core/public/kibana-plugin-core-public.applicationstart.geturlforapp.md @@ -4,9 +4,11 @@ ## ApplicationStart.getUrlForApp() method -Returns an URL to a given app, including the global base path. By default, the URL is relative (/basePath/app/my-app). Use the `absolute` option to generate an absolute url (http://host:port/basePath/app/my-app) +Returns the absolute path (or URL) to a given app, including the global base path. -Note that when generating absolute urls, the origin (protocol, host and port) are determined from the browser's location. +By default, it returns the absolute path of the application (e.g `/basePath/app/my-app`). Use the `absolute` option to generate an absolute url instead (e.g `http://host:port/basePath/app/my-app`) + +Note that when generating absolute urls, the origin (protocol, host and port) are determined from the browser's current location. Signature: diff --git a/docs/development/core/public/kibana-plugin-core-public.applicationstart.md b/docs/development/core/public/kibana-plugin-core-public.applicationstart.md index 00318f32984e9..ae62a7767a0e9 100644 --- a/docs/development/core/public/kibana-plugin-core-public.applicationstart.md +++ b/docs/development/core/public/kibana-plugin-core-public.applicationstart.md @@ -23,8 +23,8 @@ export interface ApplicationStart | Method | Description | | --- | --- | -| [getUrlForApp(appId, options)](./kibana-plugin-core-public.applicationstart.geturlforapp.md) | Returns an URL to a given app, including the global base path. By default, the URL is relative (/basePath/app/my-app). Use the absolute option to generate an absolute url (http://host:port/basePath/app/my-app)Note that when generating absolute urls, the origin (protocol, host and port) are determined from the browser's location. | +| [getUrlForApp(appId, options)](./kibana-plugin-core-public.applicationstart.geturlforapp.md) | Returns the absolute path (or URL) to a given app, including the global base path.By default, it returns the absolute path of the application (e.g /basePath/app/my-app). Use the absolute option to generate an absolute url instead (e.g http://host:port/basePath/app/my-app)Note that when generating absolute urls, the origin (protocol, host and port) are determined from the browser's current location. | | [navigateToApp(appId, options)](./kibana-plugin-core-public.applicationstart.navigatetoapp.md) | Navigate to a given app | -| [navigateToUrl(url)](./kibana-plugin-core-public.applicationstart.navigatetourl.md) | Navigate to given url, which can either be an absolute url or a relative path, in a SPA friendly way when possible.If all these criteria are true for the given url: - (only for absolute URLs) The origin of the URL matches the origin of the browser's current location - The pathname of the URL starts with the current basePath (eg. /mybasepath/s/my-space) - The pathname segment after the basePath matches any known application route (eg. /app// or any application's appRoute configuration)Then a SPA navigation will be performed using navigateToApp using the corresponding application and path. Otherwise, fallback to a full page reload to navigate to the url using window.location.assign | +| [navigateToUrl(url)](./kibana-plugin-core-public.applicationstart.navigatetourl.md) | Navigate to given URL in a SPA friendly way when possible (when the URL will redirect to a valid application within the current basePath).The method resolves pathnames the same way browsers do when resolving a <a href> value. The provided url can be: - an absolute URL - an absolute path - a path relative to the current URL (window.location.href)If all these criteria are true for the given URL: - (only for absolute URLs) The origin of the URL matches the origin of the browser's current location - The resolved pathname of the provided URL/path starts with the current basePath (eg. /mybasepath/s/my-space) - The pathname segment after the basePath matches any known application route (eg. /app// or any application's appRoute configuration)Then a SPA navigation will be performed using navigateToApp using the corresponding application and path. Otherwise, fallback to a full page reload to navigate to the url using window.location.assign | | [registerMountContext(contextName, provider)](./kibana-plugin-core-public.applicationstart.registermountcontext.md) | Register a context provider for application mounting. Will only be available to applications that depend on the plugin that registered this context. Deprecated, use [CoreSetup.getStartServices](./kibana-plugin-core-public.coresetup.getstartservices.md). | diff --git a/docs/development/core/public/kibana-plugin-core-public.applicationstart.navigatetourl.md b/docs/development/core/public/kibana-plugin-core-public.applicationstart.navigatetourl.md index 86b86776b0b12..8639394cbc421 100644 --- a/docs/development/core/public/kibana-plugin-core-public.applicationstart.navigatetourl.md +++ b/docs/development/core/public/kibana-plugin-core-public.applicationstart.navigatetourl.md @@ -4,9 +4,11 @@ ## ApplicationStart.navigateToUrl() method -Navigate to given url, which can either be an absolute url or a relative path, in a SPA friendly way when possible. +Navigate to given URL in a SPA friendly way when possible (when the URL will redirect to a valid application within the current basePath). -If all these criteria are true for the given url: - (only for absolute URLs) The origin of the URL matches the origin of the browser's current location - The pathname of the URL starts with the current basePath (eg. /mybasepath/s/my-space) - The pathname segment after the basePath matches any known application route (eg. /app// or any application's `appRoute` configuration) +The method resolves pathnames the same way browsers do when resolving a `` value. The provided `url` can be: - an absolute URL - an absolute path - a path relative to the current URL (window.location.href) + +If all these criteria are true for the given URL: - (only for absolute URLs) The origin of the URL matches the origin of the browser's current location - The resolved pathname of the provided URL/path starts with the current basePath (eg. /mybasepath/s/my-space) - The pathname segment after the basePath matches any known application route (eg. /app// or any application's `appRoute` configuration) Then a SPA navigation will be performed using `navigateToApp` using the corresponding application and path. Otherwise, fallback to a full page reload to navigate to the url using `window.location.assign` @@ -20,7 +22,7 @@ navigateToUrl(url: string): Promise; | Parameter | Type | Description | | --- | --- | --- | -| url | string | an absolute url, or a relative path, to navigate to. | +| url | string | an absolute URL, an absolute path or a relative path, to navigate to. | Returns: @@ -35,11 +37,14 @@ navigateToUrl(url: string): Promise; // will call `application.navigateToApp('discover', { path: '/some-path?foo=bar'})` application.navigateToUrl('https://kibana:8080/base-path/s/my-space/app/discover/some-path?foo=bar') application.navigateToUrl('/base-path/s/my-space/app/discover/some-path?foo=bar') +application.navigateToUrl('./discover/some-path?foo=bar') // will perform a full page reload using `window.location.assign` application.navigateToUrl('https://elsewhere:8080/base-path/s/my-space/app/discover/some-path') // origin does not match application.navigateToUrl('/app/discover/some-path') // does not include the current basePath application.navigateToUrl('/base-path/s/my-space/app/unknown-app/some-path') // unknown application +application.navigateToUrl('../discover') // resolve to `/base-path/s/my-space/discover` which is not a path of a known app. +application.navigateToUrl('../../other-space/discover') // resolve to `/base-path/s/other-space/discover` which is not within the current basePath. ``` diff --git a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md index f7b55b0650d8b..3afd5eaa6f1f7 100644 --- a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md +++ b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md @@ -91,6 +91,7 @@ readonly links: { readonly gettingStarted: string; }; readonly query: { + readonly eql: string; readonly luceneQuerySyntax: string; readonly queryDsl: string; readonly kueryQuerySyntax: string; diff --git a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md index 3f58cf08ee6b6..5249381969b98 100644 --- a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md +++ b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md @@ -17,5 +17,5 @@ export interface DocLinksStart | --- | --- | --- | | [DOC\_LINK\_VERSION](./kibana-plugin-core-public.doclinksstart.doc_link_version.md) | string | | | [ELASTIC\_WEBSITE\_URL](./kibana-plugin-core-public.doclinksstart.elastic_website_url.md) | string | | -| [links](./kibana-plugin-core-public.doclinksstart.links.md) | {
readonly dashboard: {
readonly drilldowns: string;
readonly drilldownsTriggerPicker: string;
readonly urlDrilldownTemplateSyntax: string;
readonly urlDrilldownVariables: string;
};
readonly filebeat: {
readonly base: string;
readonly installation: string;
readonly configuration: string;
readonly elasticsearchOutput: string;
readonly startup: string;
readonly exportedFields: string;
};
readonly auditbeat: {
readonly base: string;
};
readonly metricbeat: {
readonly base: string;
};
readonly heartbeat: {
readonly base: string;
};
readonly logstash: {
readonly base: string;
};
readonly functionbeat: {
readonly base: string;
};
readonly winlogbeat: {
readonly base: string;
};
readonly aggs: {
readonly date_histogram: string;
readonly date_range: string;
readonly filter: string;
readonly filters: string;
readonly geohash_grid: string;
readonly histogram: string;
readonly ip_range: string;
readonly range: string;
readonly significant_terms: string;
readonly terms: string;
readonly avg: string;
readonly avg_bucket: string;
readonly max_bucket: string;
readonly min_bucket: string;
readonly sum_bucket: string;
readonly cardinality: string;
readonly count: string;
readonly cumulative_sum: string;
readonly derivative: string;
readonly geo_bounds: string;
readonly geo_centroid: string;
readonly max: string;
readonly median: string;
readonly min: string;
readonly moving_avg: string;
readonly percentile_ranks: string;
readonly serial_diff: string;
readonly std_dev: string;
readonly sum: string;
readonly top_hits: string;
};
readonly scriptedFields: {
readonly scriptFields: string;
readonly scriptAggs: string;
readonly painless: string;
readonly painlessApi: string;
readonly painlessSyntax: string;
readonly luceneExpressions: string;
};
readonly indexPatterns: {
readonly loadingData: string;
readonly introduction: string;
};
readonly addData: string;
readonly kibana: string;
readonly siem: {
readonly guide: string;
readonly gettingStarted: string;
};
readonly query: {
readonly luceneQuerySyntax: string;
readonly queryDsl: string;
readonly kueryQuerySyntax: string;
};
readonly date: {
readonly dateMath: string;
};
readonly management: Record<string, string>;
readonly visualize: Record<string, string>;
} | | +| [links](./kibana-plugin-core-public.doclinksstart.links.md) | {
readonly dashboard: {
readonly drilldowns: string;
readonly drilldownsTriggerPicker: string;
readonly urlDrilldownTemplateSyntax: string;
readonly urlDrilldownVariables: string;
};
readonly filebeat: {
readonly base: string;
readonly installation: string;
readonly configuration: string;
readonly elasticsearchOutput: string;
readonly startup: string;
readonly exportedFields: string;
};
readonly auditbeat: {
readonly base: string;
};
readonly metricbeat: {
readonly base: string;
};
readonly heartbeat: {
readonly base: string;
};
readonly logstash: {
readonly base: string;
};
readonly functionbeat: {
readonly base: string;
};
readonly winlogbeat: {
readonly base: string;
};
readonly aggs: {
readonly date_histogram: string;
readonly date_range: string;
readonly filter: string;
readonly filters: string;
readonly geohash_grid: string;
readonly histogram: string;
readonly ip_range: string;
readonly range: string;
readonly significant_terms: string;
readonly terms: string;
readonly avg: string;
readonly avg_bucket: string;
readonly max_bucket: string;
readonly min_bucket: string;
readonly sum_bucket: string;
readonly cardinality: string;
readonly count: string;
readonly cumulative_sum: string;
readonly derivative: string;
readonly geo_bounds: string;
readonly geo_centroid: string;
readonly max: string;
readonly median: string;
readonly min: string;
readonly moving_avg: string;
readonly percentile_ranks: string;
readonly serial_diff: string;
readonly std_dev: string;
readonly sum: string;
readonly top_hits: string;
};
readonly scriptedFields: {
readonly scriptFields: string;
readonly scriptAggs: string;
readonly painless: string;
readonly painlessApi: string;
readonly painlessSyntax: string;
readonly luceneExpressions: string;
};
readonly indexPatterns: {
readonly loadingData: string;
readonly introduction: string;
};
readonly addData: string;
readonly kibana: string;
readonly siem: {
readonly guide: string;
readonly gettingStarted: string;
};
readonly query: {
readonly eql: string;
readonly luceneQuerySyntax: string;
readonly queryDsl: string;
readonly kueryQuerySyntax: string;
};
readonly date: {
readonly dateMath: string;
};
readonly management: Record<string, string>;
readonly visualize: Record<string, string>;
} | | diff --git a/docs/development/core/public/kibana-plugin-core-public.savedobjectsclient.delete.md b/docs/development/core/public/kibana-plugin-core-public.savedobjectsclient.delete.md index 3b5f5630e8060..3a5dcb51e2c42 100644 --- a/docs/development/core/public/kibana-plugin-core-public.savedobjectsclient.delete.md +++ b/docs/development/core/public/kibana-plugin-core-public.savedobjectsclient.delete.md @@ -9,5 +9,5 @@ Deletes an object Signature: ```typescript -delete: (type: string, id: string) => ReturnType; +delete: (type: string, id: string, options?: SavedObjectsDeleteOptions | undefined) => ReturnType; ``` diff --git a/docs/development/core/public/kibana-plugin-core-public.savedobjectsclient.md b/docs/development/core/public/kibana-plugin-core-public.savedobjectsclient.md index 904b9cce09d4e..6e53b169b8bed 100644 --- a/docs/development/core/public/kibana-plugin-core-public.savedobjectsclient.md +++ b/docs/development/core/public/kibana-plugin-core-public.savedobjectsclient.md @@ -23,7 +23,7 @@ The constructor for this class is marked as internal. Third-party code should no | [bulkCreate](./kibana-plugin-core-public.savedobjectsclient.bulkcreate.md) | | (objects?: SavedObjectsBulkCreateObject[], options?: SavedObjectsBulkCreateOptions) => Promise<SavedObjectsBatchResponse<unknown>> | Creates multiple documents at once | | [bulkGet](./kibana-plugin-core-public.savedobjectsclient.bulkget.md) | | (objects?: Array<{
id: string;
type: string;
}>) => Promise<SavedObjectsBatchResponse<unknown>> | Returns an array of objects by id | | [create](./kibana-plugin-core-public.savedobjectsclient.create.md) | | <T = unknown>(type: string, attributes: T, options?: SavedObjectsCreateOptions) => Promise<SimpleSavedObject<T>> | Persists an object | -| [delete](./kibana-plugin-core-public.savedobjectsclient.delete.md) | | (type: string, id: string) => ReturnType<SavedObjectsApi['delete']> | Deletes an object | +| [delete](./kibana-plugin-core-public.savedobjectsclient.delete.md) | | (type: string, id: string, options?: SavedObjectsDeleteOptions | undefined) => ReturnType<SavedObjectsApi['delete']> | Deletes an object | | [find](./kibana-plugin-core-public.savedobjectsclient.find.md) | | <T = unknown>(options: SavedObjectsFindOptions) => Promise<SavedObjectsFindResponsePublic<T>> | Search for objects | | [get](./kibana-plugin-core-public.savedobjectsclient.get.md) | | <T = unknown>(type: string, id: string) => Promise<SimpleSavedObject<T>> | Fetches a single object | diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsbulkcreateobject.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsbulkcreateobject.md index 019d30570ab36..aabbfeeff75af 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsbulkcreateobject.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsbulkcreateobject.md @@ -18,6 +18,7 @@ export interface SavedObjectsBulkCreateObject | [attributes](./kibana-plugin-core-server.savedobjectsbulkcreateobject.attributes.md) | T | | | [id](./kibana-plugin-core-server.savedobjectsbulkcreateobject.id.md) | string | | | [migrationVersion](./kibana-plugin-core-server.savedobjectsbulkcreateobject.migrationversion.md) | SavedObjectsMigrationVersion | Information about the migrations that have been applied to this SavedObject. When Kibana starts up, KibanaMigrator detects outdated documents and migrates them based on this value. For each migration that has been applied, the plugin's name is used as a key and the latest migration version as the value. | +| [namespaces](./kibana-plugin-core-server.savedobjectsbulkcreateobject.namespaces.md) | string[] | Optional initial namespaces for the object to be created in. If this is defined, it will supersede the namespace ID that is in [SavedObjectsCreateOptions](./kibana-plugin-core-server.savedobjectscreateoptions.md).Note: this can only be used for multi-namespace object types. | | [originId](./kibana-plugin-core-server.savedobjectsbulkcreateobject.originid.md) | string | Optional ID of the original saved object, if this object's id was regenerated | | [references](./kibana-plugin-core-server.savedobjectsbulkcreateobject.references.md) | SavedObjectReference[] | | | [type](./kibana-plugin-core-server.savedobjectsbulkcreateobject.type.md) | string | | diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsbulkcreateobject.namespaces.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsbulkcreateobject.namespaces.md new file mode 100644 index 0000000000000..7db1c53c67b52 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsbulkcreateobject.namespaces.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [SavedObjectsBulkCreateObject](./kibana-plugin-core-server.savedobjectsbulkcreateobject.md) > [namespaces](./kibana-plugin-core-server.savedobjectsbulkcreateobject.namespaces.md) + +## SavedObjectsBulkCreateObject.namespaces property + +Optional initial namespaces for the object to be created in. If this is defined, it will supersede the namespace ID that is in [SavedObjectsCreateOptions](./kibana-plugin-core-server.savedobjectscreateoptions.md). + +Note: this can only be used for multi-namespace object types. + +Signature: + +```typescript +namespaces?: string[]; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectscreateoptions.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectscreateoptions.md index d936829443753..63aebf6c5e791 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectscreateoptions.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectscreateoptions.md @@ -17,6 +17,7 @@ export interface SavedObjectsCreateOptions extends SavedObjectsBaseOptions | --- | --- | --- | | [id](./kibana-plugin-core-server.savedobjectscreateoptions.id.md) | string | (not recommended) Specify an id for the document | | [migrationVersion](./kibana-plugin-core-server.savedobjectscreateoptions.migrationversion.md) | SavedObjectsMigrationVersion | Information about the migrations that have been applied to this SavedObject. When Kibana starts up, KibanaMigrator detects outdated documents and migrates them based on this value. For each migration that has been applied, the plugin's name is used as a key and the latest migration version as the value. | +| [namespaces](./kibana-plugin-core-server.savedobjectscreateoptions.namespaces.md) | string[] | Optional initial namespaces for the object to be created in. If this is defined, it will supersede the namespace ID that is in [SavedObjectsCreateOptions](./kibana-plugin-core-server.savedobjectscreateoptions.md).Note: this can only be used for multi-namespace object types. | | [originId](./kibana-plugin-core-server.savedobjectscreateoptions.originid.md) | string | Optional ID of the original saved object, if this object's id was regenerated | | [overwrite](./kibana-plugin-core-server.savedobjectscreateoptions.overwrite.md) | boolean | Overwrite existing documents (defaults to false) | | [references](./kibana-plugin-core-server.savedobjectscreateoptions.references.md) | SavedObjectReference[] | | diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectscreateoptions.namespaces.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectscreateoptions.namespaces.md new file mode 100644 index 0000000000000..67804999dfd44 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectscreateoptions.namespaces.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [SavedObjectsCreateOptions](./kibana-plugin-core-server.savedobjectscreateoptions.md) > [namespaces](./kibana-plugin-core-server.savedobjectscreateoptions.namespaces.md) + +## SavedObjectsCreateOptions.namespaces property + +Optional initial namespaces for the object to be created in. If this is defined, it will supersede the namespace ID that is in [SavedObjectsCreateOptions](./kibana-plugin-core-server.savedobjectscreateoptions.md). + +Note: this can only be used for multi-namespace object types. + +Signature: + +```typescript +namespaces?: string[]; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsdeleteoptions.force.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsdeleteoptions.force.md new file mode 100644 index 0000000000000..f869d1f863a9f --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsdeleteoptions.force.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [SavedObjectsDeleteOptions](./kibana-plugin-core-server.savedobjectsdeleteoptions.md) > [force](./kibana-plugin-core-server.savedobjectsdeleteoptions.force.md) + +## SavedObjectsDeleteOptions.force property + +Force deletion of an object that exists in multiple namespaces + +Signature: + +```typescript +force?: boolean; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsdeleteoptions.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsdeleteoptions.md index 760c30edcdfb5..245819e44d37d 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsdeleteoptions.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsdeleteoptions.md @@ -15,5 +15,6 @@ export interface SavedObjectsDeleteOptions extends SavedObjectsBaseOptions | Property | Type | Description | | --- | --- | --- | +| [force](./kibana-plugin-core-server.savedobjectsdeleteoptions.force.md) | boolean | Force deletion of an object that exists in multiple namespaces | | [refresh](./kibana-plugin-core-server.savedobjectsdeleteoptions.refresh.md) | MutatingOperationRefreshSetting | The Elasticsearch Refresh setting for this operation | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern._constructor_.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern._constructor_.md index 4baf98038f89a..f81d03a28ec12 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern._constructor_.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern._constructor_.md @@ -9,12 +9,12 @@ Constructs a new instance of the `IndexPattern` class Signature: ```typescript -constructor({ spec, savedObjectsClient, fieldFormats, shortDotsEnable, metaFields, }: IndexPatternDeps); +constructor({ spec, fieldFormats, shortDotsEnable, metaFields, }: IndexPatternDeps); ``` ## Parameters | Parameter | Type | Description | | --- | --- | --- | -| { spec, savedObjectsClient, fieldFormats, shortDotsEnable, metaFields, } | IndexPatternDeps | | +| { spec, fieldFormats, shortDotsEnable, metaFields, } | IndexPatternDeps | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md index 325b97383e328..c07041470d102 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.md @@ -14,7 +14,7 @@ export declare class IndexPattern implements IIndexPattern | Constructor | Modifiers | Description | | --- | --- | --- | -| [(constructor)({ spec, savedObjectsClient, fieldFormats, shortDotsEnable, metaFields, })](./kibana-plugin-plugins-data-public.indexpattern._constructor_.md) | | Constructs a new instance of the IndexPattern class | +| [(constructor)({ spec, fieldFormats, shortDotsEnable, metaFields, })](./kibana-plugin-plugins-data-public.indexpattern._constructor_.md) | | Constructs a new instance of the IndexPattern class | ## Properties @@ -53,7 +53,6 @@ export declare class IndexPattern implements IIndexPattern | [getTimeField()](./kibana-plugin-plugins-data-public.indexpattern.gettimefield.md) | | | | [isTimeBased()](./kibana-plugin-plugins-data-public.indexpattern.istimebased.md) | | | | [isTimeNanosBased()](./kibana-plugin-plugins-data-public.indexpattern.istimenanosbased.md) | | | -| [popularizeField(fieldName, unit)](./kibana-plugin-plugins-data-public.indexpattern.popularizefield.md) | | | | [removeScriptedField(fieldName)](./kibana-plugin-plugins-data-public.indexpattern.removescriptedfield.md) | | Remove scripted field from field list | | [toSpec()](./kibana-plugin-plugins-data-public.indexpattern.tospec.md) | | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.popularizefield.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.popularizefield.md deleted file mode 100644 index eba5382158520..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.popularizefield.md +++ /dev/null @@ -1,23 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IndexPattern](./kibana-plugin-plugins-data-public.indexpattern.md) > [popularizeField](./kibana-plugin-plugins-data-public.indexpattern.popularizefield.md) - -## IndexPattern.popularizeField() method - -Signature: - -```typescript -popularizeField(fieldName: string, unit?: number): Promise; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| fieldName | string | | -| unit | number | | - -Returns: - -`Promise` - diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.md index af087344268d7..34df8656e9175 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.md @@ -43,5 +43,5 @@ export declare class IndexPatternsService | [createAndSave(spec, override, skipFetchFields)](./kibana-plugin-plugins-data-public.indexpatternsservice.createandsave.md) | | Create a new index pattern and save it right away | | [createSavedObject(indexPattern, override)](./kibana-plugin-plugins-data-public.indexpatternsservice.createsavedobject.md) | | Save a new index pattern | | [delete(indexPatternId)](./kibana-plugin-plugins-data-public.indexpatternsservice.delete.md) | | Deletes an index pattern from .kibana index | -| [updateSavedObject(indexPattern, saveAttempts)](./kibana-plugin-plugins-data-public.indexpatternsservice.updatesavedobject.md) | | Save existing index pattern. Will attempt to merge differences if there are conflicts | +| [updateSavedObject(indexPattern, saveAttempts, ignoreErrors)](./kibana-plugin-plugins-data-public.indexpatternsservice.updatesavedobject.md) | | Save existing index pattern. Will attempt to merge differences if there are conflicts | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.updatesavedobject.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.updatesavedobject.md index 3973f5d4c3e7b..5fc16c70de7ed 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.updatesavedobject.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternsservice.updatesavedobject.md @@ -9,7 +9,7 @@ Save existing index pattern. Will attempt to merge differences if there are conf Signature: ```typescript -updateSavedObject(indexPattern: IndexPattern, saveAttempts?: number): Promise; +updateSavedObject(indexPattern: IndexPattern, saveAttempts?: number, ignoreErrors?: boolean): Promise; ``` ## Parameters @@ -18,6 +18,7 @@ updateSavedObject(indexPattern: IndexPattern, saveAttempts?: number): PromiseIndexPattern | | | saveAttempts | number | | +| ignoreErrors | boolean | | Returns: diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern._constructor_.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern._constructor_.md index f7f8e51c4b632..22ee6f15933ea 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern._constructor_.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern._constructor_.md @@ -9,12 +9,12 @@ Constructs a new instance of the `IndexPattern` class Signature: ```typescript -constructor({ spec, savedObjectsClient, fieldFormats, shortDotsEnable, metaFields, }: IndexPatternDeps); +constructor({ spec, fieldFormats, shortDotsEnable, metaFields, }: IndexPatternDeps); ``` ## Parameters | Parameter | Type | Description | | --- | --- | --- | -| { spec, savedObjectsClient, fieldFormats, shortDotsEnable, metaFields, } | IndexPatternDeps | | +| { spec, fieldFormats, shortDotsEnable, metaFields, } | IndexPatternDeps | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.md index e5a9e7d8f9f93..603864234d34b 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.md @@ -14,7 +14,7 @@ export declare class IndexPattern implements IIndexPattern | Constructor | Modifiers | Description | | --- | --- | --- | -| [(constructor)({ spec, savedObjectsClient, fieldFormats, shortDotsEnable, metaFields, })](./kibana-plugin-plugins-data-server.indexpattern._constructor_.md) | | Constructs a new instance of the IndexPattern class | +| [(constructor)({ spec, fieldFormats, shortDotsEnable, metaFields, })](./kibana-plugin-plugins-data-server.indexpattern._constructor_.md) | | Constructs a new instance of the IndexPattern class | ## Properties @@ -53,7 +53,6 @@ export declare class IndexPattern implements IIndexPattern | [getTimeField()](./kibana-plugin-plugins-data-server.indexpattern.gettimefield.md) | | | | [isTimeBased()](./kibana-plugin-plugins-data-server.indexpattern.istimebased.md) | | | | [isTimeNanosBased()](./kibana-plugin-plugins-data-server.indexpattern.istimenanosbased.md) | | | -| [popularizeField(fieldName, unit)](./kibana-plugin-plugins-data-server.indexpattern.popularizefield.md) | | | | [removeScriptedField(fieldName)](./kibana-plugin-plugins-data-server.indexpattern.removescriptedfield.md) | | Remove scripted field from field list | | [toSpec()](./kibana-plugin-plugins-data-server.indexpattern.tospec.md) | | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.popularizefield.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.popularizefield.md deleted file mode 100644 index 8b2c9242a6256..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.popularizefield.md +++ /dev/null @@ -1,23 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [IndexPattern](./kibana-plugin-plugins-data-server.indexpattern.md) > [popularizeField](./kibana-plugin-plugins-data-server.indexpattern.popularizefield.md) - -## IndexPattern.popularizeField() method - -Signature: - -```typescript -popularizeField(fieldName: string, unit?: number): Promise; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| fieldName | string | | -| unit | number | | - -Returns: - -`Promise` - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.md index b8b6ee1f0b28c..9c47ea1a166d5 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.md @@ -17,4 +17,5 @@ export interface ISearchStartAggsStart | | | [getSearchStrategy](./kibana-plugin-plugins-data-server.isearchstart.getsearchstrategy.md) | (name: string) => ISearchStrategy<SearchStrategyRequest, SearchStrategyResponse> | Get other registered search strategies. For example, if a new strategy needs to use the already-registered ES search strategy, it can use this function to accomplish that. | | [search](./kibana-plugin-plugins-data-server.isearchstart.search.md) | (context: RequestHandlerContext, request: SearchStrategyRequest, options: ISearchOptions) => Promise<SearchStrategyResponse> | | +| [searchSource](./kibana-plugin-plugins-data-server.isearchstart.searchsource.md) | {
asScoped: (request: KibanaRequest) => Promise<ISearchStartSearchSource>;
} | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.searchsource.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.searchsource.md new file mode 100644 index 0000000000000..66a43fe29c43b --- /dev/null +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchstart.searchsource.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ISearchStart](./kibana-plugin-plugins-data-server.isearchstart.md) > [searchSource](./kibana-plugin-plugins-data-server.isearchstart.searchsource.md) + +## ISearchStart.searchSource property + +Signature: + +```typescript +searchSource: { + asScoped: (request: KibanaRequest) => Promise; + }; +``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md index 84aeb4cf80cce..e44cb5c657747 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.plugin.start.md @@ -8,13 +8,13 @@ ```typescript start(core: CoreStart): { - search: ISearchStart>; fieldFormats: { fieldFormatServiceFactory: (uiSettings: import("../../../core/server").IUiSettingsClient) => Promise; }; indexPatterns: { indexPatternsServiceFactory: (kibanaRequest: import("../../../core/server").KibanaRequest) => Promise; }; + search: ISearchStart>; }; ``` @@ -27,12 +27,12 @@ start(core: CoreStart): { Returns: `{ - search: ISearchStart>; fieldFormats: { fieldFormatServiceFactory: (uiSettings: import("../../../core/server").IUiSettingsClient) => Promise; }; indexPatterns: { indexPatternsServiceFactory: (kibanaRequest: import("../../../core/server").KibanaRequest) => Promise; }; + search: ISearchStart>; }` diff --git a/docs/development/plugins/embeddable/public/index.md b/docs/development/plugins/embeddable/public/index.md new file mode 100644 index 0000000000000..5de9666f6d0b9 --- /dev/null +++ b/docs/development/plugins/embeddable/public/index.md @@ -0,0 +1,12 @@ + + +[Home](./index.md) + +## API Reference + +## Packages + +| Package | Description | +| --- | --- | +| [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.action_add_panel.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.action_add_panel.md new file mode 100644 index 0000000000000..37c7a546d11ed --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.action_add_panel.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [ACTION\_ADD\_PANEL](./kibana-plugin-plugins-embeddable-public.action_add_panel.md) + +## ACTION\_ADD\_PANEL variable + +Signature: + +```typescript +ACTION_ADD_PANEL = "ACTION_ADD_PANEL" +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.action_edit_panel.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.action_edit_panel.md new file mode 100644 index 0000000000000..89f02e69f2260 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.action_edit_panel.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [ACTION\_EDIT\_PANEL](./kibana-plugin-plugins-embeddable-public.action_edit_panel.md) + +## ACTION\_EDIT\_PANEL variable + +Signature: + +```typescript +ACTION_EDIT_PANEL = "editPanel" +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.adapters.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.adapters.md new file mode 100644 index 0000000000000..9635b36cdf05a --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.adapters.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Adapters](./kibana-plugin-plugins-embeddable-public.adapters.md) + +## Adapters interface + +The interface that the adapters used to open an inspector have to fullfill. + +Signature: + +```typescript +export interface Adapters +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.addpanelaction._constructor_.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.addpanelaction._constructor_.md new file mode 100644 index 0000000000000..388f0e064d866 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.addpanelaction._constructor_.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [AddPanelAction](./kibana-plugin-plugins-embeddable-public.addpanelaction.md) > [(constructor)](./kibana-plugin-plugins-embeddable-public.addpanelaction._constructor_.md) + +## AddPanelAction.(constructor) + +Constructs a new instance of the `AddPanelAction` class + +Signature: + +```typescript +constructor(getFactory: EmbeddableStart['getEmbeddableFactory'], getAllFactories: EmbeddableStart['getEmbeddableFactories'], overlays: OverlayStart, notifications: NotificationsStart, SavedObjectFinder: React.ComponentType); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| getFactory | EmbeddableStart['getEmbeddableFactory'] | | +| getAllFactories | EmbeddableStart['getEmbeddableFactories'] | | +| overlays | OverlayStart | | +| notifications | NotificationsStart | | +| SavedObjectFinder | React.ComponentType<any> | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.addpanelaction.execute.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.addpanelaction.execute.md new file mode 100644 index 0000000000000..46629f3c654f8 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.addpanelaction.execute.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [AddPanelAction](./kibana-plugin-plugins-embeddable-public.addpanelaction.md) > [execute](./kibana-plugin-plugins-embeddable-public.addpanelaction.execute.md) + +## AddPanelAction.execute() method + +Signature: + +```typescript +execute(context: ActionExecutionContext): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| context | ActionExecutionContext<ActionContext> | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.addpanelaction.getdisplayname.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.addpanelaction.getdisplayname.md new file mode 100644 index 0000000000000..b3a181861572b --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.addpanelaction.getdisplayname.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [AddPanelAction](./kibana-plugin-plugins-embeddable-public.addpanelaction.md) > [getDisplayName](./kibana-plugin-plugins-embeddable-public.addpanelaction.getdisplayname.md) + +## AddPanelAction.getDisplayName() method + +Signature: + +```typescript +getDisplayName(): string; +``` +Returns: + +`string` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.addpanelaction.geticontype.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.addpanelaction.geticontype.md new file mode 100644 index 0000000000000..c02aa6613630b --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.addpanelaction.geticontype.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [AddPanelAction](./kibana-plugin-plugins-embeddable-public.addpanelaction.md) > [getIconType](./kibana-plugin-plugins-embeddable-public.addpanelaction.geticontype.md) + +## AddPanelAction.getIconType() method + +Signature: + +```typescript +getIconType(): string; +``` +Returns: + +`string` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.addpanelaction.id.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.addpanelaction.id.md new file mode 100644 index 0000000000000..781fb8ed29372 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.addpanelaction.id.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [AddPanelAction](./kibana-plugin-plugins-embeddable-public.addpanelaction.md) > [id](./kibana-plugin-plugins-embeddable-public.addpanelaction.id.md) + +## AddPanelAction.id property + +Signature: + +```typescript +readonly id = "ACTION_ADD_PANEL"; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.addpanelaction.iscompatible.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.addpanelaction.iscompatible.md new file mode 100644 index 0000000000000..c8349b86cf348 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.addpanelaction.iscompatible.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [AddPanelAction](./kibana-plugin-plugins-embeddable-public.addpanelaction.md) > [isCompatible](./kibana-plugin-plugins-embeddable-public.addpanelaction.iscompatible.md) + +## AddPanelAction.isCompatible() method + +Signature: + +```typescript +isCompatible(context: ActionExecutionContext): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| context | ActionExecutionContext<ActionContext> | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.addpanelaction.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.addpanelaction.md new file mode 100644 index 0000000000000..74a6c2b2183a2 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.addpanelaction.md @@ -0,0 +1,34 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [AddPanelAction](./kibana-plugin-plugins-embeddable-public.addpanelaction.md) + +## AddPanelAction class + +Signature: + +```typescript +export declare class AddPanelAction implements Action +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(getFactory, getAllFactories, overlays, notifications, SavedObjectFinder)](./kibana-plugin-plugins-embeddable-public.addpanelaction._constructor_.md) | | Constructs a new instance of the AddPanelAction class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [id](./kibana-plugin-plugins-embeddable-public.addpanelaction.id.md) | | | | +| [type](./kibana-plugin-plugins-embeddable-public.addpanelaction.type.md) | | | | + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [execute(context)](./kibana-plugin-plugins-embeddable-public.addpanelaction.execute.md) | | | +| [getDisplayName()](./kibana-plugin-plugins-embeddable-public.addpanelaction.getdisplayname.md) | | | +| [getIconType()](./kibana-plugin-plugins-embeddable-public.addpanelaction.geticontype.md) | | | +| [isCompatible(context)](./kibana-plugin-plugins-embeddable-public.addpanelaction.iscompatible.md) | | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.addpanelaction.type.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.addpanelaction.type.md new file mode 100644 index 0000000000000..d57974c984025 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.addpanelaction.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [AddPanelAction](./kibana-plugin-plugins-embeddable-public.addpanelaction.md) > [type](./kibana-plugin-plugins-embeddable-public.addpanelaction.type.md) + +## AddPanelAction.type property + +Signature: + +```typescript +readonly type = "ACTION_ADD_PANEL"; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.chartactioncontext.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.chartactioncontext.md new file mode 100644 index 0000000000000..1c9fc27d53f19 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.chartactioncontext.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [ChartActionContext](./kibana-plugin-plugins-embeddable-public.chartactioncontext.md) + +## ChartActionContext type + +Signature: + +```typescript +export declare type ChartActionContext = ValueClickContext | RangeSelectContext; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container._constructor_.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container._constructor_.md new file mode 100644 index 0000000000000..c571bae7c7613 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container._constructor_.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Container](./kibana-plugin-plugins-embeddable-public.container.md) > [(constructor)](./kibana-plugin-plugins-embeddable-public.container._constructor_.md) + +## Container.(constructor) + +Constructs a new instance of the `Container` class + +Signature: + +```typescript +constructor(input: TContainerInput, output: TContainerOutput, getFactory: EmbeddableStart['getEmbeddableFactory'], parent?: Container); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| input | TContainerInput | | +| output | TContainerOutput | | +| getFactory | EmbeddableStart['getEmbeddableFactory'] | | +| parent | Container | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.addnewembeddable.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.addnewembeddable.md new file mode 100644 index 0000000000000..1a7b32fea5361 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.addnewembeddable.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Container](./kibana-plugin-plugins-embeddable-public.container.md) > [addNewEmbeddable](./kibana-plugin-plugins-embeddable-public.container.addnewembeddable.md) + +## Container.addNewEmbeddable() method + +Signature: + +```typescript +addNewEmbeddable = IEmbeddable>(type: string, explicitInput: Partial): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| type | string | | +| explicitInput | Partial<EEI> | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.children.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.children.md new file mode 100644 index 0000000000000..e8f140219ed9c --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.children.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Container](./kibana-plugin-plugins-embeddable-public.container.md) > [children](./kibana-plugin-plugins-embeddable-public.container.children.md) + +## Container.children property + +Signature: + +```typescript +protected readonly children: { + [key: string]: IEmbeddable | ErrorEmbeddable; + }; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.createnewpanelstate.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.createnewpanelstate.md new file mode 100644 index 0000000000000..cb084192ccf23 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.createnewpanelstate.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Container](./kibana-plugin-plugins-embeddable-public.container.md) > [createNewPanelState](./kibana-plugin-plugins-embeddable-public.container.createnewpanelstate.md) + +## Container.createNewPanelState() method + +Signature: + +```typescript +protected createNewPanelState>(factory: EmbeddableFactory, partial?: Partial): PanelState; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| factory | EmbeddableFactory<TEmbeddableInput, any, TEmbeddable> | | +| partial | Partial<TEmbeddableInput> | | + +Returns: + +`PanelState` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.destroy.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.destroy.md new file mode 100644 index 0000000000000..d2776fb9e5944 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.destroy.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Container](./kibana-plugin-plugins-embeddable-public.container.md) > [destroy](./kibana-plugin-plugins-embeddable-public.container.destroy.md) + +## Container.destroy() method + +Signature: + +```typescript +destroy(): void; +``` +Returns: + +`void` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.getchild.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.getchild.md new file mode 100644 index 0000000000000..56d6a8a105bc7 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.getchild.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Container](./kibana-plugin-plugins-embeddable-public.container.md) > [getChild](./kibana-plugin-plugins-embeddable-public.container.getchild.md) + +## Container.getChild() method + +Signature: + +```typescript +getChild(id: string): E; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| id | string | | + +Returns: + +`E` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.getchildids.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.getchildids.md new file mode 100644 index 0000000000000..83a9b134cad3f --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.getchildids.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Container](./kibana-plugin-plugins-embeddable-public.container.md) > [getChildIds](./kibana-plugin-plugins-embeddable-public.container.getchildids.md) + +## Container.getChildIds() method + +Signature: + +```typescript +getChildIds(): string[]; +``` +Returns: + +`string[]` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.getfactory.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.getfactory.md new file mode 100644 index 0000000000000..f4ac95abbf372 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.getfactory.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Container](./kibana-plugin-plugins-embeddable-public.container.md) > [getFactory](./kibana-plugin-plugins-embeddable-public.container.getfactory.md) + +## Container.getFactory property + +Signature: + +```typescript +protected readonly getFactory: EmbeddableStart['getEmbeddableFactory']; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.getinheritedinput.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.getinheritedinput.md new file mode 100644 index 0000000000000..4c5823b890e65 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.getinheritedinput.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Container](./kibana-plugin-plugins-embeddable-public.container.md) > [getInheritedInput](./kibana-plugin-plugins-embeddable-public.container.getinheritedinput.md) + +## Container.getInheritedInput() method + +Return state that comes from the container and is passed down to the child. For instance, time range and filters are common inherited input state. Note that any state stored in `this.input.panels[embeddableId].explicitInput` will override inherited input. + +Signature: + +```typescript +protected abstract getInheritedInput(id: string): TChildInput; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| id | string | | + +Returns: + +`TChildInput` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.getinputforchild.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.getinputforchild.md new file mode 100644 index 0000000000000..803356d554012 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.getinputforchild.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Container](./kibana-plugin-plugins-embeddable-public.container.md) > [getInputForChild](./kibana-plugin-plugins-embeddable-public.container.getinputforchild.md) + +## Container.getInputForChild() method + +Signature: + +```typescript +getInputForChild(embeddableId: string): TEmbeddableInput; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| embeddableId | string | | + +Returns: + +`TEmbeddableInput` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.getpanelstate.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.getpanelstate.md new file mode 100644 index 0000000000000..5981284e0497c --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.getpanelstate.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Container](./kibana-plugin-plugins-embeddable-public.container.md) > [getPanelState](./kibana-plugin-plugins-embeddable-public.container.getpanelstate.md) + +## Container.getPanelState() method + +Signature: + +```typescript +protected getPanelState(embeddableId: string): PanelState; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| embeddableId | string | | + +Returns: + +`PanelState` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.iscontainer.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.iscontainer.md new file mode 100644 index 0000000000000..af65381de78f7 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.iscontainer.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Container](./kibana-plugin-plugins-embeddable-public.container.md) > [isContainer](./kibana-plugin-plugins-embeddable-public.container.iscontainer.md) + +## Container.isContainer property + +Signature: + +```typescript +readonly isContainer: boolean; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.md new file mode 100644 index 0000000000000..d14adc31e4123 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.md @@ -0,0 +1,43 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Container](./kibana-plugin-plugins-embeddable-public.container.md) + +## Container class + +Signature: + +```typescript +export declare abstract class Container = {}, TContainerInput extends ContainerInput = ContainerInput, TContainerOutput extends ContainerOutput = ContainerOutput> extends Embeddable implements IContainer +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(input, output, getFactory, parent)](./kibana-plugin-plugins-embeddable-public.container._constructor_.md) | | Constructs a new instance of the Container class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [children](./kibana-plugin-plugins-embeddable-public.container.children.md) | | {
[key: string]: IEmbeddable<any, any> | ErrorEmbeddable;
} | | +| [getFactory](./kibana-plugin-plugins-embeddable-public.container.getfactory.md) | | EmbeddableStart['getEmbeddableFactory'] | | +| [isContainer](./kibana-plugin-plugins-embeddable-public.container.iscontainer.md) | | boolean | | + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [addNewEmbeddable(type, explicitInput)](./kibana-plugin-plugins-embeddable-public.container.addnewembeddable.md) | | | +| [createNewPanelState(factory, partial)](./kibana-plugin-plugins-embeddable-public.container.createnewpanelstate.md) | | | +| [destroy()](./kibana-plugin-plugins-embeddable-public.container.destroy.md) | | | +| [getChild(id)](./kibana-plugin-plugins-embeddable-public.container.getchild.md) | | | +| [getChildIds()](./kibana-plugin-plugins-embeddable-public.container.getchildids.md) | | | +| [getInheritedInput(id)](./kibana-plugin-plugins-embeddable-public.container.getinheritedinput.md) | | Return state that comes from the container and is passed down to the child. For instance, time range and filters are common inherited input state. Note that any state stored in this.input.panels[embeddableId].explicitInput will override inherited input. | +| [getInputForChild(embeddableId)](./kibana-plugin-plugins-embeddable-public.container.getinputforchild.md) | | | +| [getPanelState(embeddableId)](./kibana-plugin-plugins-embeddable-public.container.getpanelstate.md) | | | +| [reload()](./kibana-plugin-plugins-embeddable-public.container.reload.md) | | | +| [removeEmbeddable(embeddableId)](./kibana-plugin-plugins-embeddable-public.container.removeembeddable.md) | | | +| [untilEmbeddableLoaded(id)](./kibana-plugin-plugins-embeddable-public.container.untilembeddableloaded.md) | | | +| [updateInputForChild(id, changes)](./kibana-plugin-plugins-embeddable-public.container.updateinputforchild.md) | | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.reload.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.reload.md new file mode 100644 index 0000000000000..902da827ac46c --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.reload.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Container](./kibana-plugin-plugins-embeddable-public.container.md) > [reload](./kibana-plugin-plugins-embeddable-public.container.reload.md) + +## Container.reload() method + +Signature: + +```typescript +reload(): void; +``` +Returns: + +`void` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.removeembeddable.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.removeembeddable.md new file mode 100644 index 0000000000000..44594c0649d46 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.removeembeddable.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Container](./kibana-plugin-plugins-embeddable-public.container.md) > [removeEmbeddable](./kibana-plugin-plugins-embeddable-public.container.removeembeddable.md) + +## Container.removeEmbeddable() method + +Signature: + +```typescript +removeEmbeddable(embeddableId: string): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| embeddableId | string | | + +Returns: + +`void` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.untilembeddableloaded.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.untilembeddableloaded.md new file mode 100644 index 0000000000000..45c115f370694 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.untilembeddableloaded.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Container](./kibana-plugin-plugins-embeddable-public.container.md) > [untilEmbeddableLoaded](./kibana-plugin-plugins-embeddable-public.container.untilembeddableloaded.md) + +## Container.untilEmbeddableLoaded() method + +Signature: + +```typescript +untilEmbeddableLoaded(id: string): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| id | string | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.updateinputforchild.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.updateinputforchild.md new file mode 100644 index 0000000000000..ae25f373a907b --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.container.updateinputforchild.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Container](./kibana-plugin-plugins-embeddable-public.container.md) > [updateInputForChild](./kibana-plugin-plugins-embeddable-public.container.updateinputforchild.md) + +## Container.updateInputForChild() method + +Signature: + +```typescript +updateInputForChild(id: string, changes: Partial): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| id | string | | +| changes | Partial<EEI> | | + +Returns: + +`void` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.containerinput.hidepaneltitles.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.containerinput.hidepaneltitles.md new file mode 100644 index 0000000000000..5bb80ae411a78 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.containerinput.hidepaneltitles.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [ContainerInput](./kibana-plugin-plugins-embeddable-public.containerinput.md) > [hidePanelTitles](./kibana-plugin-plugins-embeddable-public.containerinput.hidepaneltitles.md) + +## ContainerInput.hidePanelTitles property + +Signature: + +```typescript +hidePanelTitles?: boolean; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.containerinput.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.containerinput.md new file mode 100644 index 0000000000000..dc24507b71cfb --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.containerinput.md @@ -0,0 +1,19 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [ContainerInput](./kibana-plugin-plugins-embeddable-public.containerinput.md) + +## ContainerInput interface + +Signature: + +```typescript +export interface ContainerInput extends EmbeddableInput +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [hidePanelTitles](./kibana-plugin-plugins-embeddable-public.containerinput.hidepaneltitles.md) | boolean | | +| [panels](./kibana-plugin-plugins-embeddable-public.containerinput.panels.md) | {
[key: string]: PanelState<PanelExplicitInput & EmbeddableInput & {
id: string;
}>;
} | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.containerinput.panels.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.containerinput.panels.md new file mode 100644 index 0000000000000..82d45ebe9a10e --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.containerinput.panels.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [ContainerInput](./kibana-plugin-plugins-embeddable-public.containerinput.md) > [panels](./kibana-plugin-plugins-embeddable-public.containerinput.panels.md) + +## ContainerInput.panels property + +Signature: + +```typescript +panels: { + [key: string]: PanelState; + }; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.containeroutput.embeddableloaded.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.containeroutput.embeddableloaded.md new file mode 100644 index 0000000000000..3f0db4eba0bc3 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.containeroutput.embeddableloaded.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [ContainerOutput](./kibana-plugin-plugins-embeddable-public.containeroutput.md) > [embeddableLoaded](./kibana-plugin-plugins-embeddable-public.containeroutput.embeddableloaded.md) + +## ContainerOutput.embeddableLoaded property + +Signature: + +```typescript +embeddableLoaded: { + [key: string]: boolean; + }; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.containeroutput.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.containeroutput.md new file mode 100644 index 0000000000000..f448f0f3ac059 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.containeroutput.md @@ -0,0 +1,18 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [ContainerOutput](./kibana-plugin-plugins-embeddable-public.containeroutput.md) + +## ContainerOutput interface + +Signature: + +```typescript +export interface ContainerOutput extends EmbeddableOutput +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [embeddableLoaded](./kibana-plugin-plugins-embeddable-public.containeroutput.embeddableloaded.md) | {
[key: string]: boolean;
} | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.context_menu_trigger.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.context_menu_trigger.md new file mode 100644 index 0000000000000..bcfcf6a321661 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.context_menu_trigger.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [CONTEXT\_MENU\_TRIGGER](./kibana-plugin-plugins-embeddable-public.context_menu_trigger.md) + +## CONTEXT\_MENU\_TRIGGER variable + +Signature: + +```typescript +CONTEXT_MENU_TRIGGER = "CONTEXT_MENU_TRIGGER" +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.contextmenutrigger.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.contextmenutrigger.md new file mode 100644 index 0000000000000..0a88e1e0a2ea8 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.contextmenutrigger.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [contextMenuTrigger](./kibana-plugin-plugins-embeddable-public.contextmenutrigger.md) + +## contextMenuTrigger variable + +Signature: + +```typescript +contextMenuTrigger: Trigger<'CONTEXT_MENU_TRIGGER'> +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.defaultembeddablefactoryprovider.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.defaultembeddablefactoryprovider.md new file mode 100644 index 0000000000000..08047a7a441b8 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.defaultembeddablefactoryprovider.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [defaultEmbeddableFactoryProvider](./kibana-plugin-plugins-embeddable-public.defaultembeddablefactoryprovider.md) + +## defaultEmbeddableFactoryProvider variable + +Signature: + +```typescript +defaultEmbeddableFactoryProvider: = IEmbeddable, T extends SavedObjectAttributes = SavedObjectAttributes>(def: EmbeddableFactoryDefinition) => EmbeddableFactory +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction._constructor_.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction._constructor_.md new file mode 100644 index 0000000000000..55bb3d76b99d8 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction._constructor_.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EditPanelAction](./kibana-plugin-plugins-embeddable-public.editpanelaction.md) > [(constructor)](./kibana-plugin-plugins-embeddable-public.editpanelaction._constructor_.md) + +## EditPanelAction.(constructor) + +Constructs a new instance of the `EditPanelAction` class + +Signature: + +```typescript +constructor(getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'], application: ApplicationStart, stateTransfer?: EmbeddableStateTransfer | undefined); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| getEmbeddableFactory | EmbeddableStart['getEmbeddableFactory'] | | +| application | ApplicationStart | | +| stateTransfer | EmbeddableStateTransfer | undefined | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.currentappid.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.currentappid.md new file mode 100644 index 0000000000000..db94b1482d8b5 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.currentappid.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EditPanelAction](./kibana-plugin-plugins-embeddable-public.editpanelaction.md) > [currentAppId](./kibana-plugin-plugins-embeddable-public.editpanelaction.currentappid.md) + +## EditPanelAction.currentAppId property + +Signature: + +```typescript +currentAppId: string | undefined; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.execute.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.execute.md new file mode 100644 index 0000000000000..6cfd88f17ba85 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.execute.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EditPanelAction](./kibana-plugin-plugins-embeddable-public.editpanelaction.md) > [execute](./kibana-plugin-plugins-embeddable-public.editpanelaction.execute.md) + +## EditPanelAction.execute() method + +Signature: + +```typescript +execute(context: ActionContext): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| context | ActionContext | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.getapptarget.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.getapptarget.md new file mode 100644 index 0000000000000..c9ede0f48b285 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.getapptarget.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EditPanelAction](./kibana-plugin-plugins-embeddable-public.editpanelaction.md) > [getAppTarget](./kibana-plugin-plugins-embeddable-public.editpanelaction.getapptarget.md) + +## EditPanelAction.getAppTarget() method + +Signature: + +```typescript +getAppTarget({ embeddable }: ActionContext): NavigationContext | undefined; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| { embeddable } | ActionContext | | + +Returns: + +`NavigationContext | undefined` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.getdisplayname.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.getdisplayname.md new file mode 100644 index 0000000000000..227fdb8877149 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.getdisplayname.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EditPanelAction](./kibana-plugin-plugins-embeddable-public.editpanelaction.md) > [getDisplayName](./kibana-plugin-plugins-embeddable-public.editpanelaction.getdisplayname.md) + +## EditPanelAction.getDisplayName() method + +Signature: + +```typescript +getDisplayName({ embeddable }: ActionContext): string; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| { embeddable } | ActionContext | | + +Returns: + +`string` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.gethref.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.gethref.md new file mode 100644 index 0000000000000..1139278ab781f --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.gethref.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EditPanelAction](./kibana-plugin-plugins-embeddable-public.editpanelaction.md) > [getHref](./kibana-plugin-plugins-embeddable-public.editpanelaction.gethref.md) + +## EditPanelAction.getHref() method + +Signature: + +```typescript +getHref({ embeddable }: ActionContext): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| { embeddable } | ActionContext | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.geticontype.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.geticontype.md new file mode 100644 index 0000000000000..bc5a1f054ca75 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.geticontype.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EditPanelAction](./kibana-plugin-plugins-embeddable-public.editpanelaction.md) > [getIconType](./kibana-plugin-plugins-embeddable-public.editpanelaction.geticontype.md) + +## EditPanelAction.getIconType() method + +Signature: + +```typescript +getIconType(): string; +``` +Returns: + +`string` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.id.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.id.md new file mode 100644 index 0000000000000..d8b0888b51801 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.id.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EditPanelAction](./kibana-plugin-plugins-embeddable-public.editpanelaction.md) > [id](./kibana-plugin-plugins-embeddable-public.editpanelaction.id.md) + +## EditPanelAction.id property + +Signature: + +```typescript +readonly id = "editPanel"; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.iscompatible.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.iscompatible.md new file mode 100644 index 0000000000000..7f2714f14f0e9 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.iscompatible.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EditPanelAction](./kibana-plugin-plugins-embeddable-public.editpanelaction.md) > [isCompatible](./kibana-plugin-plugins-embeddable-public.editpanelaction.iscompatible.md) + +## EditPanelAction.isCompatible() method + +Signature: + +```typescript +isCompatible({ embeddable }: ActionContext): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| { embeddable } | ActionContext | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.md new file mode 100644 index 0000000000000..a39eae812ebfc --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.md @@ -0,0 +1,38 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EditPanelAction](./kibana-plugin-plugins-embeddable-public.editpanelaction.md) + +## EditPanelAction class + +Signature: + +```typescript +export declare class EditPanelAction implements Action +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(getEmbeddableFactory, application, stateTransfer)](./kibana-plugin-plugins-embeddable-public.editpanelaction._constructor_.md) | | Constructs a new instance of the EditPanelAction class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [currentAppId](./kibana-plugin-plugins-embeddable-public.editpanelaction.currentappid.md) | | string | undefined | | +| [id](./kibana-plugin-plugins-embeddable-public.editpanelaction.id.md) | | | | +| [order](./kibana-plugin-plugins-embeddable-public.editpanelaction.order.md) | | number | | +| [type](./kibana-plugin-plugins-embeddable-public.editpanelaction.type.md) | | | | + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [execute(context)](./kibana-plugin-plugins-embeddable-public.editpanelaction.execute.md) | | | +| [getAppTarget({ embeddable })](./kibana-plugin-plugins-embeddable-public.editpanelaction.getapptarget.md) | | | +| [getDisplayName({ embeddable })](./kibana-plugin-plugins-embeddable-public.editpanelaction.getdisplayname.md) | | | +| [getHref({ embeddable })](./kibana-plugin-plugins-embeddable-public.editpanelaction.gethref.md) | | | +| [getIconType()](./kibana-plugin-plugins-embeddable-public.editpanelaction.geticontype.md) | | | +| [isCompatible({ embeddable })](./kibana-plugin-plugins-embeddable-public.editpanelaction.iscompatible.md) | | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.order.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.order.md new file mode 100644 index 0000000000000..0ec5cde54b279 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.order.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EditPanelAction](./kibana-plugin-plugins-embeddable-public.editpanelaction.md) > [order](./kibana-plugin-plugins-embeddable-public.editpanelaction.order.md) + +## EditPanelAction.order property + +Signature: + +```typescript +order: number; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.type.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.type.md new file mode 100644 index 0000000000000..329f08abaaa3c --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.editpanelaction.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EditPanelAction](./kibana-plugin-plugins-embeddable-public.editpanelaction.md) > [type](./kibana-plugin-plugins-embeddable-public.editpanelaction.type.md) + +## EditPanelAction.type property + +Signature: + +```typescript +readonly type = "editPanel"; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable._constructor_.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable._constructor_.md new file mode 100644 index 0000000000000..c5e8788bf5d4d --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable._constructor_.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) > [(constructor)](./kibana-plugin-plugins-embeddable-public.embeddable._constructor_.md) + +## Embeddable.(constructor) + +Constructs a new instance of the `Embeddable` class + +Signature: + +```typescript +constructor(input: TEmbeddableInput, output: TEmbeddableOutput, parent?: IContainer); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| input | TEmbeddableInput | | +| output | TEmbeddableOutput | | +| parent | IContainer | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.destroy.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.destroy.md new file mode 100644 index 0000000000000..1ff16eec0b750 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.destroy.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) > [destroy](./kibana-plugin-plugins-embeddable-public.embeddable.destroy.md) + +## Embeddable.destroy() method + +Called when this embeddable is no longer used, this should be the place for implementors to add any additional clean up tasks, like unmounting and unsubscribing. + +Signature: + +```typescript +destroy(): void; +``` +Returns: + +`void` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.getinput.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.getinput.md new file mode 100644 index 0000000000000..f4a0724d42680 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.getinput.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) > [getInput](./kibana-plugin-plugins-embeddable-public.embeddable.getinput.md) + +## Embeddable.getInput() method + +Signature: + +```typescript +getInput(): Readonly; +``` +Returns: + +`Readonly` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.getinput_.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.getinput_.md new file mode 100644 index 0000000000000..e4910d3eb1bf2 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.getinput_.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) > [getInput$](./kibana-plugin-plugins-embeddable-public.embeddable.getinput_.md) + +## Embeddable.getInput$() method + +Signature: + +```typescript +getInput$(): Readonly>; +``` +Returns: + +`Readonly>` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.getinspectoradapters.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.getinspectoradapters.md new file mode 100644 index 0000000000000..490eaca32e685 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.getinspectoradapters.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) > [getInspectorAdapters](./kibana-plugin-plugins-embeddable-public.embeddable.getinspectoradapters.md) + +## Embeddable.getInspectorAdapters() method + +An embeddable can return inspector adapters if it want the inspector to be available via the context menu of that panel. Inspector adapters that will be used to open an inspector for. + +Signature: + +```typescript +getInspectorAdapters(): Adapters | undefined; +``` +Returns: + +`Adapters | undefined` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.getiscontainer.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.getiscontainer.md new file mode 100644 index 0000000000000..cb9945ea31293 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.getiscontainer.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) > [getIsContainer](./kibana-plugin-plugins-embeddable-public.embeddable.getiscontainer.md) + +## Embeddable.getIsContainer() method + +Signature: + +```typescript +getIsContainer(): this is IContainer; +``` +Returns: + +`this is IContainer` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.getoutput.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.getoutput.md new file mode 100644 index 0000000000000..b24c5aefddb40 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.getoutput.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) > [getOutput](./kibana-plugin-plugins-embeddable-public.embeddable.getoutput.md) + +## Embeddable.getOutput() method + +Signature: + +```typescript +getOutput(): Readonly; +``` +Returns: + +`Readonly` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.getoutput_.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.getoutput_.md new file mode 100644 index 0000000000000..34b5f864dd0c8 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.getoutput_.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) > [getOutput$](./kibana-plugin-plugins-embeddable-public.embeddable.getoutput_.md) + +## Embeddable.getOutput$() method + +Signature: + +```typescript +getOutput$(): Readonly>; +``` +Returns: + +`Readonly>` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.getroot.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.getroot.md new file mode 100644 index 0000000000000..79397911d5bc7 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.getroot.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) > [getRoot](./kibana-plugin-plugins-embeddable-public.embeddable.getroot.md) + +## Embeddable.getRoot() method + +Returns the top most parent embeddable, or itself if this embeddable is not within a parent. + +Signature: + +```typescript +getRoot(): IEmbeddable | IContainer; +``` +Returns: + +`IEmbeddable | IContainer` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.gettitle.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.gettitle.md new file mode 100644 index 0000000000000..4dc1900b4b011 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.gettitle.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) > [getTitle](./kibana-plugin-plugins-embeddable-public.embeddable.gettitle.md) + +## Embeddable.getTitle() method + +Signature: + +```typescript +getTitle(): string; +``` +Returns: + +`string` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.id.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.id.md new file mode 100644 index 0000000000000..348934b9fb65c --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.id.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) > [id](./kibana-plugin-plugins-embeddable-public.embeddable.id.md) + +## Embeddable.id property + +Signature: + +```typescript +readonly id: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.input.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.input.md new file mode 100644 index 0000000000000..4541aeacd5bc8 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.input.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) > [input](./kibana-plugin-plugins-embeddable-public.embeddable.input.md) + +## Embeddable.input property + +Signature: + +```typescript +protected input: TEmbeddableInput; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.iscontainer.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.iscontainer.md new file mode 100644 index 0000000000000..db15653d40c4c --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.iscontainer.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) > [isContainer](./kibana-plugin-plugins-embeddable-public.embeddable.iscontainer.md) + +## Embeddable.isContainer property + +Signature: + +```typescript +readonly isContainer: boolean; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.md new file mode 100644 index 0000000000000..295cc10b1bb19 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.md @@ -0,0 +1,51 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) + +## Embeddable class + +Signature: + +```typescript +export declare abstract class Embeddable implements IEmbeddable +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(input, output, parent)](./kibana-plugin-plugins-embeddable-public.embeddable._constructor_.md) | | Constructs a new instance of the Embeddable class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [id](./kibana-plugin-plugins-embeddable-public.embeddable.id.md) | | string | | +| [input](./kibana-plugin-plugins-embeddable-public.embeddable.input.md) | | TEmbeddableInput | | +| [isContainer](./kibana-plugin-plugins-embeddable-public.embeddable.iscontainer.md) | | boolean | | +| [output](./kibana-plugin-plugins-embeddable-public.embeddable.output.md) | | TEmbeddableOutput | | +| [parent](./kibana-plugin-plugins-embeddable-public.embeddable.parent.md) | | IContainer | | +| [renderComplete](./kibana-plugin-plugins-embeddable-public.embeddable.rendercomplete.md) | | RenderCompleteDispatcher | | +| [runtimeId](./kibana-plugin-plugins-embeddable-public.embeddable.runtimeid.md) | | number | | +| [runtimeId](./kibana-plugin-plugins-embeddable-public.embeddable.runtimeid.md) | static | number | | +| [type](./kibana-plugin-plugins-embeddable-public.embeddable.type.md) | | string | | + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [destroy()](./kibana-plugin-plugins-embeddable-public.embeddable.destroy.md) | | Called when this embeddable is no longer used, this should be the place for implementors to add any additional clean up tasks, like unmounting and unsubscribing. | +| [getInput()](./kibana-plugin-plugins-embeddable-public.embeddable.getinput.md) | | | +| [getInput$()](./kibana-plugin-plugins-embeddable-public.embeddable.getinput_.md) | | | +| [getInspectorAdapters()](./kibana-plugin-plugins-embeddable-public.embeddable.getinspectoradapters.md) | | An embeddable can return inspector adapters if it want the inspector to be available via the context menu of that panel. Inspector adapters that will be used to open an inspector for. | +| [getIsContainer()](./kibana-plugin-plugins-embeddable-public.embeddable.getiscontainer.md) | | | +| [getOutput()](./kibana-plugin-plugins-embeddable-public.embeddable.getoutput.md) | | | +| [getOutput$()](./kibana-plugin-plugins-embeddable-public.embeddable.getoutput_.md) | | | +| [getRoot()](./kibana-plugin-plugins-embeddable-public.embeddable.getroot.md) | | Returns the top most parent embeddable, or itself if this embeddable is not within a parent. | +| [getTitle()](./kibana-plugin-plugins-embeddable-public.embeddable.gettitle.md) | | | +| [reload()](./kibana-plugin-plugins-embeddable-public.embeddable.reload.md) | | Reload will be called when there is a request to refresh the data or view, even if the input data did not change. | +| [render(el)](./kibana-plugin-plugins-embeddable-public.embeddable.render.md) | | | +| [supportedTriggers()](./kibana-plugin-plugins-embeddable-public.embeddable.supportedtriggers.md) | | | +| [updateInput(changes)](./kibana-plugin-plugins-embeddable-public.embeddable.updateinput.md) | | | +| [updateOutput(outputChanges)](./kibana-plugin-plugins-embeddable-public.embeddable.updateoutput.md) | | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.output.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.output.md new file mode 100644 index 0000000000000..db854e2a69cec --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.output.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) > [output](./kibana-plugin-plugins-embeddable-public.embeddable.output.md) + +## Embeddable.output property + +Signature: + +```typescript +protected output: TEmbeddableOutput; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.parent.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.parent.md new file mode 100644 index 0000000000000..bfd82f53e96f1 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.parent.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) > [parent](./kibana-plugin-plugins-embeddable-public.embeddable.parent.md) + +## Embeddable.parent property + +Signature: + +```typescript +readonly parent?: IContainer; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.reload.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.reload.md new file mode 100644 index 0000000000000..e3b06f414cb5b --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.reload.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) > [reload](./kibana-plugin-plugins-embeddable-public.embeddable.reload.md) + +## Embeddable.reload() method + +Reload will be called when there is a request to refresh the data or view, even if the input data did not change. + +Signature: + +```typescript +abstract reload(): void; +``` +Returns: + +`void` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.render.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.render.md new file mode 100644 index 0000000000000..171a3c6a30a85 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.render.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) > [render](./kibana-plugin-plugins-embeddable-public.embeddable.render.md) + +## Embeddable.render() method + +Signature: + +```typescript +render(el: HTMLElement): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| el | HTMLElement | | + +Returns: + +`void` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.rendercomplete.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.rendercomplete.md new file mode 100644 index 0000000000000..c86bb2e998044 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.rendercomplete.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) > [renderComplete](./kibana-plugin-plugins-embeddable-public.embeddable.rendercomplete.md) + +## Embeddable.renderComplete property + +Signature: + +```typescript +protected renderComplete: RenderCompleteDispatcher; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.runtimeid.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.runtimeid.md new file mode 100644 index 0000000000000..a5cdd12b6f198 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.runtimeid.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) > [runtimeId](./kibana-plugin-plugins-embeddable-public.embeddable.runtimeid.md) + +## Embeddable.runtimeId property + +Signature: + +```typescript +static runtimeId: number; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.supportedtriggers.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.supportedtriggers.md new file mode 100644 index 0000000000000..16676bc732b1c --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.supportedtriggers.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) > [supportedTriggers](./kibana-plugin-plugins-embeddable-public.embeddable.supportedtriggers.md) + +## Embeddable.supportedTriggers() method + +Signature: + +```typescript +supportedTriggers(): Array; +``` +Returns: + +`Array` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.type.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.type.md new file mode 100644 index 0000000000000..bb3ae7384686c --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) > [type](./kibana-plugin-plugins-embeddable-public.embeddable.type.md) + +## Embeddable.type property + +Signature: + +```typescript +abstract readonly type: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.updateinput.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.updateinput.md new file mode 100644 index 0000000000000..36c46bb71c6b6 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.updateinput.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) > [updateInput](./kibana-plugin-plugins-embeddable-public.embeddable.updateinput.md) + +## Embeddable.updateInput() method + +Signature: + +```typescript +updateInput(changes: Partial): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| changes | Partial<TEmbeddableInput> | | + +Returns: + +`void` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.updateoutput.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.updateoutput.md new file mode 100644 index 0000000000000..0b0244e7a5853 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddable.updateoutput.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) > [updateOutput](./kibana-plugin-plugins-embeddable-public.embeddable.updateoutput.md) + +## Embeddable.updateOutput() method + +Signature: + +```typescript +protected updateOutput(outputChanges: Partial): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| outputChanges | Partial<TEmbeddableOutput> | | + +Returns: + +`void` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanel._constructor_.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanel._constructor_.md new file mode 100644 index 0000000000000..76412de0d5419 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanel._constructor_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableChildPanel](./kibana-plugin-plugins-embeddable-public.embeddablechildpanel.md) > [(constructor)](./kibana-plugin-plugins-embeddable-public.embeddablechildpanel._constructor_.md) + +## EmbeddableChildPanel.(constructor) + +Constructs a new instance of the `EmbeddableChildPanel` class + +Signature: + +```typescript +constructor(props: EmbeddableChildPanelProps); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| props | EmbeddableChildPanelProps | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanel.componentdidmount.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanel.componentdidmount.md new file mode 100644 index 0000000000000..5302d3e986d94 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanel.componentdidmount.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableChildPanel](./kibana-plugin-plugins-embeddable-public.embeddablechildpanel.md) > [componentDidMount](./kibana-plugin-plugins-embeddable-public.embeddablechildpanel.componentdidmount.md) + +## EmbeddableChildPanel.componentDidMount() method + +Signature: + +```typescript +componentDidMount(): Promise; +``` +Returns: + +`Promise` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanel.componentwillunmount.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanel.componentwillunmount.md new file mode 100644 index 0000000000000..17c23a5ba2fd1 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanel.componentwillunmount.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableChildPanel](./kibana-plugin-plugins-embeddable-public.embeddablechildpanel.md) > [componentWillUnmount](./kibana-plugin-plugins-embeddable-public.embeddablechildpanel.componentwillunmount.md) + +## EmbeddableChildPanel.componentWillUnmount() method + +Signature: + +```typescript +componentWillUnmount(): void; +``` +Returns: + +`void` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanel.embeddable.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanel.embeddable.md new file mode 100644 index 0000000000000..298697167e127 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanel.embeddable.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableChildPanel](./kibana-plugin-plugins-embeddable-public.embeddablechildpanel.md) > [embeddable](./kibana-plugin-plugins-embeddable-public.embeddablechildpanel.embeddable.md) + +## EmbeddableChildPanel.embeddable property + +Signature: + +```typescript +embeddable: IEmbeddable | ErrorEmbeddable; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanel.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanel.md new file mode 100644 index 0000000000000..d52033b4fd6ad --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanel.md @@ -0,0 +1,35 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableChildPanel](./kibana-plugin-plugins-embeddable-public.embeddablechildpanel.md) + +## EmbeddableChildPanel class + +This component can be used by embeddable containers using react to easily render children. It waits for the child to be initialized, showing a loading indicator until that is complete. + +Signature: + +```typescript +export declare class EmbeddableChildPanel extends React.Component +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(props)](./kibana-plugin-plugins-embeddable-public.embeddablechildpanel._constructor_.md) | | Constructs a new instance of the EmbeddableChildPanel class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [embeddable](./kibana-plugin-plugins-embeddable-public.embeddablechildpanel.embeddable.md) | | IEmbeddable | ErrorEmbeddable | | +| [mounted](./kibana-plugin-plugins-embeddable-public.embeddablechildpanel.mounted.md) | | boolean | | + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [componentDidMount()](./kibana-plugin-plugins-embeddable-public.embeddablechildpanel.componentdidmount.md) | | | +| [componentWillUnmount()](./kibana-plugin-plugins-embeddable-public.embeddablechildpanel.componentwillunmount.md) | | | +| [render()](./kibana-plugin-plugins-embeddable-public.embeddablechildpanel.render.md) | | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanel.mounted.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanel.mounted.md new file mode 100644 index 0000000000000..169f27ea5afa6 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanel.mounted.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableChildPanel](./kibana-plugin-plugins-embeddable-public.embeddablechildpanel.md) > [mounted](./kibana-plugin-plugins-embeddable-public.embeddablechildpanel.mounted.md) + +## EmbeddableChildPanel.mounted property + +Signature: + +```typescript +mounted: boolean; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanel.render.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanel.render.md new file mode 100644 index 0000000000000..01d70eb5f628f --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanel.render.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableChildPanel](./kibana-plugin-plugins-embeddable-public.embeddablechildpanel.md) > [render](./kibana-plugin-plugins-embeddable-public.embeddablechildpanel.render.md) + +## EmbeddableChildPanel.render() method + +Signature: + +```typescript +render(): JSX.Element; +``` +Returns: + +`JSX.Element` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.classname.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.classname.md new file mode 100644 index 0000000000000..d18dea31545d9 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.classname.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableChildPanelProps](./kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.md) > [className](./kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.classname.md) + +## EmbeddableChildPanelProps.className property + +Signature: + +```typescript +className?: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.container.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.container.md new file mode 100644 index 0000000000000..91120f955b15e --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.container.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableChildPanelProps](./kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.md) > [container](./kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.container.md) + +## EmbeddableChildPanelProps.container property + +Signature: + +```typescript +container: IContainer; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.embeddableid.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.embeddableid.md new file mode 100644 index 0000000000000..6765010e1b696 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.embeddableid.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableChildPanelProps](./kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.md) > [embeddableId](./kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.embeddableid.md) + +## EmbeddableChildPanelProps.embeddableId property + +Signature: + +```typescript +embeddableId: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.md new file mode 100644 index 0000000000000..7ed3bd1e20768 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableChildPanelProps](./kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.md) + +## EmbeddableChildPanelProps interface + +Signature: + +```typescript +export interface EmbeddableChildPanelProps +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [className](./kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.classname.md) | string | | +| [container](./kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.container.md) | IContainer | | +| [embeddableId](./kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.embeddableid.md) | string | | +| [PanelComponent](./kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.panelcomponent.md) | EmbeddableStart['EmbeddablePanel'] | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.panelcomponent.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.panelcomponent.md new file mode 100644 index 0000000000000..e1bb6b41d3887 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.panelcomponent.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableChildPanelProps](./kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.md) > [PanelComponent](./kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.panelcomponent.md) + +## EmbeddableChildPanelProps.PanelComponent property + +Signature: + +```typescript +PanelComponent: EmbeddableStart['EmbeddablePanel']; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablecontext.embeddable.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablecontext.embeddable.md new file mode 100644 index 0000000000000..06e51958a2d1e --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablecontext.embeddable.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableContext](./kibana-plugin-plugins-embeddable-public.embeddablecontext.md) > [embeddable](./kibana-plugin-plugins-embeddable-public.embeddablecontext.embeddable.md) + +## EmbeddableContext.embeddable property + +Signature: + +```typescript +embeddable: IEmbeddable; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablecontext.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablecontext.md new file mode 100644 index 0000000000000..a2c2d9245eabe --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablecontext.md @@ -0,0 +1,18 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableContext](./kibana-plugin-plugins-embeddable-public.embeddablecontext.md) + +## EmbeddableContext interface + +Signature: + +```typescript +export interface EmbeddableContext +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [embeddable](./kibana-plugin-plugins-embeddable-public.embeddablecontext.embeddable.md) | IEmbeddable | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableeditorstate.embeddableid.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableeditorstate.embeddableid.md new file mode 100644 index 0000000000000..d998e982cc9d5 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableeditorstate.embeddableid.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableEditorState](./kibana-plugin-plugins-embeddable-public.embeddableeditorstate.md) > [embeddableId](./kibana-plugin-plugins-embeddable-public.embeddableeditorstate.embeddableid.md) + +## EmbeddableEditorState.embeddableId property + +Signature: + +```typescript +embeddableId?: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableeditorstate.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableeditorstate.md new file mode 100644 index 0000000000000..63302f50204fe --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableeditorstate.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableEditorState](./kibana-plugin-plugins-embeddable-public.embeddableeditorstate.md) + +## EmbeddableEditorState interface + +A state package that contains information an editor will need to create or edit an embeddable then redirect back. + +Signature: + +```typescript +export interface EmbeddableEditorState +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [embeddableId](./kibana-plugin-plugins-embeddable-public.embeddableeditorstate.embeddableid.md) | string | | +| [originatingApp](./kibana-plugin-plugins-embeddable-public.embeddableeditorstate.originatingapp.md) | string | | +| [valueInput](./kibana-plugin-plugins-embeddable-public.embeddableeditorstate.valueinput.md) | EmbeddableInput | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableeditorstate.originatingapp.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableeditorstate.originatingapp.md new file mode 100644 index 0000000000000..640b0894ef2c7 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableeditorstate.originatingapp.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableEditorState](./kibana-plugin-plugins-embeddable-public.embeddableeditorstate.md) > [originatingApp](./kibana-plugin-plugins-embeddable-public.embeddableeditorstate.originatingapp.md) + +## EmbeddableEditorState.originatingApp property + +Signature: + +```typescript +originatingApp: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableeditorstate.valueinput.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableeditorstate.valueinput.md new file mode 100644 index 0000000000000..61ebfc61634b8 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableeditorstate.valueinput.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableEditorState](./kibana-plugin-plugins-embeddable-public.embeddableeditorstate.md) > [valueInput](./kibana-plugin-plugins-embeddable-public.embeddableeditorstate.valueinput.md) + +## EmbeddableEditorState.valueInput property + +Signature: + +```typescript +valueInput?: EmbeddableInput; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.cancreatenew.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.cancreatenew.md new file mode 100644 index 0000000000000..78bcb4f31a5be --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.cancreatenew.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableFactory](./kibana-plugin-plugins-embeddable-public.embeddablefactory.md) > [canCreateNew](./kibana-plugin-plugins-embeddable-public.embeddablefactory.cancreatenew.md) + +## EmbeddableFactory.canCreateNew() method + +If false, this type of embeddable can't be created with the "createNew" functionality. Instead, use createFromSavedObject, where an existing saved object must first exist. + +Signature: + +```typescript +canCreateNew(): boolean; +``` +Returns: + +`boolean` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.create.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.create.md new file mode 100644 index 0000000000000..130c8cb760625 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.create.md @@ -0,0 +1,27 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableFactory](./kibana-plugin-plugins-embeddable-public.embeddablefactory.md) > [create](./kibana-plugin-plugins-embeddable-public.embeddablefactory.create.md) + +## EmbeddableFactory.create() method + +Resolves to undefined if a new Embeddable cannot be directly created and the user will instead be redirected elsewhere. + +This will likely change in future iterations when we improve in place editing capabilities. + +Signature: + +```typescript +create(initialInput: TEmbeddableInput, parent?: IContainer): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| initialInput | TEmbeddableInput | | +| parent | IContainer | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.createfromsavedobject.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.createfromsavedobject.md new file mode 100644 index 0000000000000..7a411988ca3b0 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.createfromsavedobject.md @@ -0,0 +1,26 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableFactory](./kibana-plugin-plugins-embeddable-public.embeddablefactory.md) > [createFromSavedObject](./kibana-plugin-plugins-embeddable-public.embeddablefactory.createfromsavedobject.md) + +## EmbeddableFactory.createFromSavedObject() method + +Creates a new embeddable instance based off the saved object id. + +Signature: + +```typescript +createFromSavedObject(savedObjectId: string, input: Partial, parent?: IContainer): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| savedObjectId | string | | +| input | Partial<TEmbeddableInput> | some input may come from a parent, or user, if it's not stored with the saved object. For example, the time range of the parent container. | +| parent | IContainer | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.getdefaultinput.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.getdefaultinput.md new file mode 100644 index 0000000000000..bf1ca6abd9ba0 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.getdefaultinput.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableFactory](./kibana-plugin-plugins-embeddable-public.embeddablefactory.md) > [getDefaultInput](./kibana-plugin-plugins-embeddable-public.embeddablefactory.getdefaultinput.md) + +## EmbeddableFactory.getDefaultInput() method + +Can be used to get any default input, to be passed in to during the creation process. Default input will not be stored in a parent container, so any inherited input from a container will trump default input parameters. + +Signature: + +```typescript +getDefaultInput(partial: Partial): Partial; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| partial | Partial<TEmbeddableInput> | | + +Returns: + +`Partial` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.getdisplayname.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.getdisplayname.md new file mode 100644 index 0000000000000..5b97645d4947d --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.getdisplayname.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableFactory](./kibana-plugin-plugins-embeddable-public.embeddablefactory.md) > [getDisplayName](./kibana-plugin-plugins-embeddable-public.embeddablefactory.getdisplayname.md) + +## EmbeddableFactory.getDisplayName() method + +Returns a display name for this type of embeddable. Used in "Create new... " options in the add panel for containers. + +Signature: + +```typescript +getDisplayName(): string; +``` +Returns: + +`string` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.getexplicitinput.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.getexplicitinput.md new file mode 100644 index 0000000000000..3ec05f50005d0 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.getexplicitinput.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableFactory](./kibana-plugin-plugins-embeddable-public.embeddablefactory.md) > [getExplicitInput](./kibana-plugin-plugins-embeddable-public.embeddablefactory.getexplicitinput.md) + +## EmbeddableFactory.getExplicitInput() method + +Can be used to request explicit input from the user, to be passed in to `EmbeddableFactory:create`. Explicit input is stored on the parent container for this embeddable. It overrides any inherited input passed down from the parent container. + +Signature: + +```typescript +getExplicitInput(): Promise>; +``` +Returns: + +`Promise>` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.iscontainertype.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.iscontainertype.md new file mode 100644 index 0000000000000..f3ba375ab575c --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.iscontainertype.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableFactory](./kibana-plugin-plugins-embeddable-public.embeddablefactory.md) > [isContainerType](./kibana-plugin-plugins-embeddable-public.embeddablefactory.iscontainertype.md) + +## EmbeddableFactory.isContainerType property + +True if is this factory create embeddables that are Containers. Used in the add panel to conditionally show whether these can be added to another container. It's just not supported right now, but once nested containers are officially supported we can probably get rid of this interface. + +Signature: + +```typescript +readonly isContainerType: boolean; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.iseditable.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.iseditable.md new file mode 100644 index 0000000000000..f1ad10dfaa1f6 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.iseditable.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableFactory](./kibana-plugin-plugins-embeddable-public.embeddablefactory.md) > [isEditable](./kibana-plugin-plugins-embeddable-public.embeddablefactory.iseditable.md) + +## EmbeddableFactory.isEditable property + +Returns whether the current user should be allowed to edit this type of embeddable. Most of the time this should be based off the capabilities service, hence it's async. + +Signature: + +```typescript +readonly isEditable: () => Promise; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.md new file mode 100644 index 0000000000000..d543cf3d096df --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.md @@ -0,0 +1,34 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableFactory](./kibana-plugin-plugins-embeddable-public.embeddablefactory.md) + +## EmbeddableFactory interface + +EmbeddableFactories create and initialize an embeddable instance + +Signature: + +```typescript +export interface EmbeddableFactory = IEmbeddable, TSavedObjectAttributes extends SavedObjectAttributes = SavedObjectAttributes> extends PersistableState +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [isContainerType](./kibana-plugin-plugins-embeddable-public.embeddablefactory.iscontainertype.md) | boolean | True if is this factory create embeddables that are Containers. Used in the add panel to conditionally show whether these can be added to another container. It's just not supported right now, but once nested containers are officially supported we can probably get rid of this interface. | +| [isEditable](./kibana-plugin-plugins-embeddable-public.embeddablefactory.iseditable.md) | () => Promise<boolean> | Returns whether the current user should be allowed to edit this type of embeddable. Most of the time this should be based off the capabilities service, hence it's async. | +| [savedObjectMetaData](./kibana-plugin-plugins-embeddable-public.embeddablefactory.savedobjectmetadata.md) | SavedObjectMetaData<TSavedObjectAttributes> | | +| [type](./kibana-plugin-plugins-embeddable-public.embeddablefactory.type.md) | string | | + +## Methods + +| Method | Description | +| --- | --- | +| [canCreateNew()](./kibana-plugin-plugins-embeddable-public.embeddablefactory.cancreatenew.md) | If false, this type of embeddable can't be created with the "createNew" functionality. Instead, use createFromSavedObject, where an existing saved object must first exist. | +| [create(initialInput, parent)](./kibana-plugin-plugins-embeddable-public.embeddablefactory.create.md) | Resolves to undefined if a new Embeddable cannot be directly created and the user will instead be redirected elsewhere.This will likely change in future iterations when we improve in place editing capabilities. | +| [createFromSavedObject(savedObjectId, input, parent)](./kibana-plugin-plugins-embeddable-public.embeddablefactory.createfromsavedobject.md) | Creates a new embeddable instance based off the saved object id. | +| [getDefaultInput(partial)](./kibana-plugin-plugins-embeddable-public.embeddablefactory.getdefaultinput.md) | Can be used to get any default input, to be passed in to during the creation process. Default input will not be stored in a parent container, so any inherited input from a container will trump default input parameters. | +| [getDisplayName()](./kibana-plugin-plugins-embeddable-public.embeddablefactory.getdisplayname.md) | Returns a display name for this type of embeddable. Used in "Create new... " options in the add panel for containers. | +| [getExplicitInput()](./kibana-plugin-plugins-embeddable-public.embeddablefactory.getexplicitinput.md) | Can be used to request explicit input from the user, to be passed in to EmbeddableFactory:create. Explicit input is stored on the parent container for this embeddable. It overrides any inherited input passed down from the parent container. | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.savedobjectmetadata.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.savedobjectmetadata.md new file mode 100644 index 0000000000000..ec5bf420aac3e --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.savedobjectmetadata.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableFactory](./kibana-plugin-plugins-embeddable-public.embeddablefactory.md) > [savedObjectMetaData](./kibana-plugin-plugins-embeddable-public.embeddablefactory.savedobjectmetadata.md) + +## EmbeddableFactory.savedObjectMetaData property + +Signature: + +```typescript +readonly savedObjectMetaData?: SavedObjectMetaData; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.type.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.type.md new file mode 100644 index 0000000000000..307f808de9bcd --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactory.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableFactory](./kibana-plugin-plugins-embeddable-public.embeddablefactory.md) > [type](./kibana-plugin-plugins-embeddable-public.embeddablefactory.type.md) + +## EmbeddableFactory.type property + +Signature: + +```typescript +readonly type: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactorydefinition.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactorydefinition.md new file mode 100644 index 0000000000000..4e342d3cf73a1 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactorydefinition.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableFactoryDefinition](./kibana-plugin-plugins-embeddable-public.embeddablefactorydefinition.md) + +## EmbeddableFactoryDefinition type + +Signature: + +```typescript +export declare type EmbeddableFactoryDefinition = IEmbeddable, T extends SavedObjectAttributes = SavedObjectAttributes> = Pick, 'create' | 'type' | 'isEditable' | 'getDisplayName'> & Partial, 'createFromSavedObject' | 'isContainerType' | 'getExplicitInput' | 'savedObjectMetaData' | 'canCreateNew' | 'getDefaultInput' | 'telemetry' | 'extract' | 'inject'>>; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactorynotfounderror._constructor_.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactorynotfounderror._constructor_.md new file mode 100644 index 0000000000000..273126936ce91 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactorynotfounderror._constructor_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableFactoryNotFoundError](./kibana-plugin-plugins-embeddable-public.embeddablefactorynotfounderror.md) > [(constructor)](./kibana-plugin-plugins-embeddable-public.embeddablefactorynotfounderror._constructor_.md) + +## EmbeddableFactoryNotFoundError.(constructor) + +Constructs a new instance of the `EmbeddableFactoryNotFoundError` class + +Signature: + +```typescript +constructor(type: string); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| type | string | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactorynotfounderror.code.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactorynotfounderror.code.md new file mode 100644 index 0000000000000..2ad75d3e68ba4 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactorynotfounderror.code.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableFactoryNotFoundError](./kibana-plugin-plugins-embeddable-public.embeddablefactorynotfounderror.md) > [code](./kibana-plugin-plugins-embeddable-public.embeddablefactorynotfounderror.code.md) + +## EmbeddableFactoryNotFoundError.code property + +Signature: + +```typescript +code: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactorynotfounderror.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactorynotfounderror.md new file mode 100644 index 0000000000000..028271d36fee0 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablefactorynotfounderror.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableFactoryNotFoundError](./kibana-plugin-plugins-embeddable-public.embeddablefactorynotfounderror.md) + +## EmbeddableFactoryNotFoundError class + +Signature: + +```typescript +export declare class EmbeddableFactoryNotFoundError extends Error +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(type)](./kibana-plugin-plugins-embeddable-public.embeddablefactorynotfounderror._constructor_.md) | | Constructs a new instance of the EmbeddableFactoryNotFoundError class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [code](./kibana-plugin-plugins-embeddable-public.embeddablefactorynotfounderror.code.md) | | string | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableinput.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableinput.md new file mode 100644 index 0000000000000..d1d97d50f5948 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableinput.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableInput](./kibana-plugin-plugins-embeddable-public.embeddableinput.md) + +## EmbeddableInput type + +Signature: + +```typescript +export declare type EmbeddableInput = { + viewMode?: ViewMode; + title?: string; + id: string; + lastReloadRequestTime?: number; + hidePanelTitles?: boolean; + enhancements?: SerializableState; + disabledActions?: string[]; + disableTriggers?: boolean; + timeRange?: TimeRange; + query?: Query; + filters?: Filter[]; +}; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableinstanceconfiguration.id.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableinstanceconfiguration.id.md new file mode 100644 index 0000000000000..2298c6fb111a0 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableinstanceconfiguration.id.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableInstanceConfiguration](./kibana-plugin-plugins-embeddable-public.embeddableinstanceconfiguration.md) > [id](./kibana-plugin-plugins-embeddable-public.embeddableinstanceconfiguration.id.md) + +## EmbeddableInstanceConfiguration.id property + +Signature: + +```typescript +id: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableinstanceconfiguration.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableinstanceconfiguration.md new file mode 100644 index 0000000000000..84f6bcefef447 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableinstanceconfiguration.md @@ -0,0 +1,19 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableInstanceConfiguration](./kibana-plugin-plugins-embeddable-public.embeddableinstanceconfiguration.md) + +## EmbeddableInstanceConfiguration interface + +Signature: + +```typescript +export interface EmbeddableInstanceConfiguration +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [id](./kibana-plugin-plugins-embeddable-public.embeddableinstanceconfiguration.id.md) | string | | +| [savedObjectId](./kibana-plugin-plugins-embeddable-public.embeddableinstanceconfiguration.savedobjectid.md) | string | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableinstanceconfiguration.savedobjectid.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableinstanceconfiguration.savedobjectid.md new file mode 100644 index 0000000000000..c1584403c5bba --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableinstanceconfiguration.savedobjectid.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableInstanceConfiguration](./kibana-plugin-plugins-embeddable-public.embeddableinstanceconfiguration.md) > [savedObjectId](./kibana-plugin-plugins-embeddable-public.embeddableinstanceconfiguration.savedobjectid.md) + +## EmbeddableInstanceConfiguration.savedObjectId property + +Signature: + +```typescript +savedObjectId?: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.defaulttitle.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.defaulttitle.md new file mode 100644 index 0000000000000..c9d616a96e8e2 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.defaulttitle.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableOutput](./kibana-plugin-plugins-embeddable-public.embeddableoutput.md) > [defaultTitle](./kibana-plugin-plugins-embeddable-public.embeddableoutput.defaulttitle.md) + +## EmbeddableOutput.defaultTitle property + +Signature: + +```typescript +defaultTitle?: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.editable.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.editable.md new file mode 100644 index 0000000000000..4bf84a8f2abf8 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.editable.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableOutput](./kibana-plugin-plugins-embeddable-public.embeddableoutput.md) > [editable](./kibana-plugin-plugins-embeddable-public.embeddableoutput.editable.md) + +## EmbeddableOutput.editable property + +Signature: + +```typescript +editable?: boolean; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.editapp.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.editapp.md new file mode 100644 index 0000000000000..5c5acd6288ba4 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.editapp.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableOutput](./kibana-plugin-plugins-embeddable-public.embeddableoutput.md) > [editApp](./kibana-plugin-plugins-embeddable-public.embeddableoutput.editapp.md) + +## EmbeddableOutput.editApp property + +Signature: + +```typescript +editApp?: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.editpath.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.editpath.md new file mode 100644 index 0000000000000..da282ece32f20 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.editpath.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableOutput](./kibana-plugin-plugins-embeddable-public.embeddableoutput.md) > [editPath](./kibana-plugin-plugins-embeddable-public.embeddableoutput.editpath.md) + +## EmbeddableOutput.editPath property + +Signature: + +```typescript +editPath?: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.editurl.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.editurl.md new file mode 100644 index 0000000000000..a0c4bed4ad8bb --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.editurl.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableOutput](./kibana-plugin-plugins-embeddable-public.embeddableoutput.md) > [editUrl](./kibana-plugin-plugins-embeddable-public.embeddableoutput.editurl.md) + +## EmbeddableOutput.editUrl property + +Signature: + +```typescript +editUrl?: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.error.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.error.md new file mode 100644 index 0000000000000..db3f27ecf295b --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.error.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableOutput](./kibana-plugin-plugins-embeddable-public.embeddableoutput.md) > [error](./kibana-plugin-plugins-embeddable-public.embeddableoutput.error.md) + +## EmbeddableOutput.error property + +Signature: + +```typescript +error?: EmbeddableError; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.loading.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.loading.md new file mode 100644 index 0000000000000..a9472b1663f1a --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.loading.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableOutput](./kibana-plugin-plugins-embeddable-public.embeddableoutput.md) > [loading](./kibana-plugin-plugins-embeddable-public.embeddableoutput.loading.md) + +## EmbeddableOutput.loading property + +Signature: + +```typescript +loading?: boolean; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.md new file mode 100644 index 0000000000000..92e1560c34e31 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.md @@ -0,0 +1,26 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableOutput](./kibana-plugin-plugins-embeddable-public.embeddableoutput.md) + +## EmbeddableOutput interface + +Signature: + +```typescript +export interface EmbeddableOutput +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [defaultTitle](./kibana-plugin-plugins-embeddable-public.embeddableoutput.defaulttitle.md) | string | | +| [editable](./kibana-plugin-plugins-embeddable-public.embeddableoutput.editable.md) | boolean | | +| [editApp](./kibana-plugin-plugins-embeddable-public.embeddableoutput.editapp.md) | string | | +| [editPath](./kibana-plugin-plugins-embeddable-public.embeddableoutput.editpath.md) | string | | +| [editUrl](./kibana-plugin-plugins-embeddable-public.embeddableoutput.editurl.md) | string | | +| [error](./kibana-plugin-plugins-embeddable-public.embeddableoutput.error.md) | EmbeddableError | | +| [loading](./kibana-plugin-plugins-embeddable-public.embeddableoutput.loading.md) | boolean | | +| [savedObjectId](./kibana-plugin-plugins-embeddable-public.embeddableoutput.savedobjectid.md) | string | | +| [title](./kibana-plugin-plugins-embeddable-public.embeddableoutput.title.md) | string | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.savedobjectid.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.savedobjectid.md new file mode 100644 index 0000000000000..29aca26621d79 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.savedobjectid.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableOutput](./kibana-plugin-plugins-embeddable-public.embeddableoutput.md) > [savedObjectId](./kibana-plugin-plugins-embeddable-public.embeddableoutput.savedobjectid.md) + +## EmbeddableOutput.savedObjectId property + +Signature: + +```typescript +savedObjectId?: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.title.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.title.md new file mode 100644 index 0000000000000..0748a60b38e0f --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableoutput.title.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableOutput](./kibana-plugin-plugins-embeddable-public.embeddableoutput.md) > [title](./kibana-plugin-plugins-embeddable-public.embeddableoutput.title.md) + +## EmbeddableOutput.title property + +Signature: + +```typescript +title?: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepackagestate.embeddableid.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepackagestate.embeddableid.md new file mode 100644 index 0000000000000..de1598d92b6de --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepackagestate.embeddableid.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddablePackageState](./kibana-plugin-plugins-embeddable-public.embeddablepackagestate.md) > [embeddableId](./kibana-plugin-plugins-embeddable-public.embeddablepackagestate.embeddableid.md) + +## EmbeddablePackageState.embeddableId property + +Signature: + +```typescript +embeddableId?: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepackagestate.input.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepackagestate.input.md new file mode 100644 index 0000000000000..2f4b1a1fa4237 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepackagestate.input.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddablePackageState](./kibana-plugin-plugins-embeddable-public.embeddablepackagestate.md) > [input](./kibana-plugin-plugins-embeddable-public.embeddablepackagestate.input.md) + +## EmbeddablePackageState.input property + +Signature: + +```typescript +input: Optional | Optional; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepackagestate.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepackagestate.md new file mode 100644 index 0000000000000..1c0b1b8bf8b46 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepackagestate.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddablePackageState](./kibana-plugin-plugins-embeddable-public.embeddablepackagestate.md) + +## EmbeddablePackageState interface + +A state package that contains all fields necessary to create or update an embeddable by reference or by value in a container. + +Signature: + +```typescript +export interface EmbeddablePackageState +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [embeddableId](./kibana-plugin-plugins-embeddable-public.embeddablepackagestate.embeddableid.md) | string | | +| [input](./kibana-plugin-plugins-embeddable-public.embeddablepackagestate.input.md) | Optional<EmbeddableInput, 'id'> | Optional<SavedObjectEmbeddableInput, 'id'> | | +| [type](./kibana-plugin-plugins-embeddable-public.embeddablepackagestate.type.md) | string | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepackagestate.type.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepackagestate.type.md new file mode 100644 index 0000000000000..67ca5b8803dd5 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepackagestate.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddablePackageState](./kibana-plugin-plugins-embeddable-public.embeddablepackagestate.md) > [type](./kibana-plugin-plugins-embeddable-public.embeddablepackagestate.type.md) + +## EmbeddablePackageState.type property + +Signature: + +```typescript +type: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel._constructor_.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel._constructor_.md new file mode 100644 index 0000000000000..741e5df8a1590 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel._constructor_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddablePanel](./kibana-plugin-plugins-embeddable-public.embeddablepanel.md) > [(constructor)](./kibana-plugin-plugins-embeddable-public.embeddablepanel._constructor_.md) + +## EmbeddablePanel.(constructor) + +Constructs a new instance of the `EmbeddablePanel` class + +Signature: + +```typescript +constructor(props: Props); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| props | Props | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel.closemycontextmenupanel.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel.closemycontextmenupanel.md new file mode 100644 index 0000000000000..6869257675aa4 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel.closemycontextmenupanel.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddablePanel](./kibana-plugin-plugins-embeddable-public.embeddablepanel.md) > [closeMyContextMenuPanel](./kibana-plugin-plugins-embeddable-public.embeddablepanel.closemycontextmenupanel.md) + +## EmbeddablePanel.closeMyContextMenuPanel property + +Signature: + +```typescript +closeMyContextMenuPanel: () => void; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel.componentdidmount.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel.componentdidmount.md new file mode 100644 index 0000000000000..fb281dcf1107f --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel.componentdidmount.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddablePanel](./kibana-plugin-plugins-embeddable-public.embeddablepanel.md) > [componentDidMount](./kibana-plugin-plugins-embeddable-public.embeddablepanel.componentdidmount.md) + +## EmbeddablePanel.componentDidMount() method + +Signature: + +```typescript +componentDidMount(): void; +``` +Returns: + +`void` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel.componentwillunmount.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel.componentwillunmount.md new file mode 100644 index 0000000000000..41050f9c7c82a --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel.componentwillunmount.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddablePanel](./kibana-plugin-plugins-embeddable-public.embeddablepanel.md) > [componentWillUnmount](./kibana-plugin-plugins-embeddable-public.embeddablepanel.componentwillunmount.md) + +## EmbeddablePanel.componentWillUnmount() method + +Signature: + +```typescript +componentWillUnmount(): void; +``` +Returns: + +`void` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel.md new file mode 100644 index 0000000000000..643649ede51ef --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel.md @@ -0,0 +1,35 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddablePanel](./kibana-plugin-plugins-embeddable-public.embeddablepanel.md) + +## EmbeddablePanel class + +Signature: + +```typescript +export declare class EmbeddablePanel extends React.Component +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(props)](./kibana-plugin-plugins-embeddable-public.embeddablepanel._constructor_.md) | | Constructs a new instance of the EmbeddablePanel class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [closeMyContextMenuPanel](./kibana-plugin-plugins-embeddable-public.embeddablepanel.closemycontextmenupanel.md) | | () => void | | +| [onBlur](./kibana-plugin-plugins-embeddable-public.embeddablepanel.onblur.md) | | (blurredPanelIndex: string) => void | | +| [onFocus](./kibana-plugin-plugins-embeddable-public.embeddablepanel.onfocus.md) | | (focusedPanelIndex: string) => void | | + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [componentDidMount()](./kibana-plugin-plugins-embeddable-public.embeddablepanel.componentdidmount.md) | | | +| [componentWillUnmount()](./kibana-plugin-plugins-embeddable-public.embeddablepanel.componentwillunmount.md) | | | +| [render()](./kibana-plugin-plugins-embeddable-public.embeddablepanel.render.md) | | | +| [UNSAFE\_componentWillMount()](./kibana-plugin-plugins-embeddable-public.embeddablepanel.unsafe_componentwillmount.md) | | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel.onblur.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel.onblur.md new file mode 100644 index 0000000000000..f1db746801818 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel.onblur.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddablePanel](./kibana-plugin-plugins-embeddable-public.embeddablepanel.md) > [onBlur](./kibana-plugin-plugins-embeddable-public.embeddablepanel.onblur.md) + +## EmbeddablePanel.onBlur property + +Signature: + +```typescript +onBlur: (blurredPanelIndex: string) => void; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel.onfocus.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel.onfocus.md new file mode 100644 index 0000000000000..3c9b713eab950 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel.onfocus.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddablePanel](./kibana-plugin-plugins-embeddable-public.embeddablepanel.md) > [onFocus](./kibana-plugin-plugins-embeddable-public.embeddablepanel.onfocus.md) + +## EmbeddablePanel.onFocus property + +Signature: + +```typescript +onFocus: (focusedPanelIndex: string) => void; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel.render.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel.render.md new file mode 100644 index 0000000000000..13e87df47a242 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel.render.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddablePanel](./kibana-plugin-plugins-embeddable-public.embeddablepanel.md) > [render](./kibana-plugin-plugins-embeddable-public.embeddablepanel.render.md) + +## EmbeddablePanel.render() method + +Signature: + +```typescript +render(): JSX.Element; +``` +Returns: + +`JSX.Element` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel.unsafe_componentwillmount.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel.unsafe_componentwillmount.md new file mode 100644 index 0000000000000..286d7e9cee1f3 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanel.unsafe_componentwillmount.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddablePanel](./kibana-plugin-plugins-embeddable-public.embeddablepanel.md) > [UNSAFE\_componentWillMount](./kibana-plugin-plugins-embeddable-public.embeddablepanel.unsafe_componentwillmount.md) + +## EmbeddablePanel.UNSAFE\_componentWillMount() method + +Signature: + +```typescript +UNSAFE_componentWillMount(): void; +``` +Returns: + +`void` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanelhoc.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanelhoc.md new file mode 100644 index 0000000000000..3f57ac562e6d5 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablepanelhoc.md @@ -0,0 +1,14 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddablePanelHOC](./kibana-plugin-plugins-embeddable-public.embeddablepanelhoc.md) + +## EmbeddablePanelHOC type + +Signature: + +```typescript +export declare type EmbeddablePanelHOC = React.FC<{ + embeddable: IEmbeddable; + hideHeader?: boolean; +}>; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablerenderer.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablerenderer.md new file mode 100644 index 0000000000000..1bc55e6007910 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablerenderer.md @@ -0,0 +1,32 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableRenderer](./kibana-plugin-plugins-embeddable-public.embeddablerenderer.md) + +## EmbeddableRenderer variable + +Helper react component to render an embeddable Can be used if you have an embeddable object or an embeddable factory Supports updating input by passing `input` prop + +Signature: + +```typescript +EmbeddableRenderer: (props: EmbeddableRendererProps) => JSX.Element +``` + +## Remarks + +This component shouldn't be used inside an embeddable container to render embeddable children because children may lose inherited input, here is why: + +When passing `input` inside a prop, internally there is a call: + +```ts +embeddable.updateInput(input); + +``` +If you are simply rendering an embeddable, it's no problem. + +However when you are dealing with containers, you want to be sure to only pass into updateInput the actual state that changed. This is because calling child.updateInput({ foo }) will make foo explicit state. It cannot be inherited from it's parent. + +For example, on a dashboard, the time range is inherited by all children, unless they had their time range set explicitly. This is how "per panel time range" works. That action calls embeddable.updateInput({ timeRange }), and the time range will no longer be inherited from the container. + +see: https://github.com/elastic/kibana/pull/67783\#discussion\_r435447657 for more details. refer to: examples/embeddable\_explorer for examples with correct usage of this component. + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablerendererprops.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablerendererprops.md new file mode 100644 index 0000000000000..c21864b1140e8 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablerendererprops.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableRendererProps](./kibana-plugin-plugins-embeddable-public.embeddablerendererprops.md) + +## EmbeddableRendererProps type + +This type is a publicly exposed props of [EmbeddableRenderer](./kibana-plugin-plugins-embeddable-public.embeddablerenderer.md) Union is used to validate that or factory or embeddable is passed in, but it can't be both simultaneously In case when embeddable is passed in, input is optional, because there is already an input inside of embeddable object In case when factory is used, then input is required, because it will be used as initial input to create an embeddable object + +Signature: + +```typescript +export declare type EmbeddableRendererProps = EmbeddableRendererPropsWithEmbeddable | EmbeddableRendererWithFactory; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableroot._constructor_.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableroot._constructor_.md new file mode 100644 index 0000000000000..4e0a2a6880d29 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableroot._constructor_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableRoot](./kibana-plugin-plugins-embeddable-public.embeddableroot.md) > [(constructor)](./kibana-plugin-plugins-embeddable-public.embeddableroot._constructor_.md) + +## EmbeddableRoot.(constructor) + +Constructs a new instance of the `EmbeddableRoot` class + +Signature: + +```typescript +constructor(props: Props); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| props | Props | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableroot.componentdidmount.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableroot.componentdidmount.md new file mode 100644 index 0000000000000..7085339dd8868 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableroot.componentdidmount.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableRoot](./kibana-plugin-plugins-embeddable-public.embeddableroot.md) > [componentDidMount](./kibana-plugin-plugins-embeddable-public.embeddableroot.componentdidmount.md) + +## EmbeddableRoot.componentDidMount() method + +Signature: + +```typescript +componentDidMount(): void; +``` +Returns: + +`void` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableroot.componentdidupdate.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableroot.componentdidupdate.md new file mode 100644 index 0000000000000..386c8c61681d5 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableroot.componentdidupdate.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableRoot](./kibana-plugin-plugins-embeddable-public.embeddableroot.md) > [componentDidUpdate](./kibana-plugin-plugins-embeddable-public.embeddableroot.componentdidupdate.md) + +## EmbeddableRoot.componentDidUpdate() method + +Signature: + +```typescript +componentDidUpdate(prevProps?: Props): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| prevProps | Props | | + +Returns: + +`void` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableroot.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableroot.md new file mode 100644 index 0000000000000..49d8a184f334c --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableroot.md @@ -0,0 +1,27 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableRoot](./kibana-plugin-plugins-embeddable-public.embeddableroot.md) + +## EmbeddableRoot class + +Signature: + +```typescript +export declare class EmbeddableRoot extends React.Component +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(props)](./kibana-plugin-plugins-embeddable-public.embeddableroot._constructor_.md) | | Constructs a new instance of the EmbeddableRoot class | + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [componentDidMount()](./kibana-plugin-plugins-embeddable-public.embeddableroot.componentdidmount.md) | | | +| [componentDidUpdate(prevProps)](./kibana-plugin-plugins-embeddable-public.embeddableroot.componentdidupdate.md) | | | +| [render()](./kibana-plugin-plugins-embeddable-public.embeddableroot.render.md) | | | +| [shouldComponentUpdate(newProps)](./kibana-plugin-plugins-embeddable-public.embeddableroot.shouldcomponentupdate.md) | | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableroot.render.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableroot.render.md new file mode 100644 index 0000000000000..d9b3820dede15 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableroot.render.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableRoot](./kibana-plugin-plugins-embeddable-public.embeddableroot.md) > [render](./kibana-plugin-plugins-embeddable-public.embeddableroot.render.md) + +## EmbeddableRoot.render() method + +Signature: + +```typescript +render(): JSX.Element; +``` +Returns: + +`JSX.Element` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableroot.shouldcomponentupdate.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableroot.shouldcomponentupdate.md new file mode 100644 index 0000000000000..36b08f72c0e40 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddableroot.shouldcomponentupdate.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableRoot](./kibana-plugin-plugins-embeddable-public.embeddableroot.md) > [shouldComponentUpdate](./kibana-plugin-plugins-embeddable-public.embeddableroot.shouldcomponentupdate.md) + +## EmbeddableRoot.shouldComponentUpdate() method + +Signature: + +```typescript +shouldComponentUpdate(newProps: Props): boolean; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| newProps | Props | | + +Returns: + +`boolean` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetup.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetup.md new file mode 100644 index 0000000000000..97d6eda66bdcd --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetup.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableSetup](./kibana-plugin-plugins-embeddable-public.embeddablesetup.md) + +## EmbeddableSetup interface + +Signature: + +```typescript +export interface EmbeddableSetup +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [registerEmbeddableFactory](./kibana-plugin-plugins-embeddable-public.embeddablesetup.registerembeddablefactory.md) | <I extends EmbeddableInput, O extends EmbeddableOutput, E extends IEmbeddable<I, O> = IEmbeddable<I, O>>(id: string, factory: EmbeddableFactoryDefinition<I, O, E>) => () => EmbeddableFactory<I, O, E> | | +| [registerEnhancement](./kibana-plugin-plugins-embeddable-public.embeddablesetup.registerenhancement.md) | (enhancement: EnhancementRegistryDefinition) => void | | +| [setCustomEmbeddableFactoryProvider](./kibana-plugin-plugins-embeddable-public.embeddablesetup.setcustomembeddablefactoryprovider.md) | (customProvider: EmbeddableFactoryProvider) => void | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetup.registerembeddablefactory.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetup.registerembeddablefactory.md new file mode 100644 index 0000000000000..d9f63b30dfe6d --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetup.registerembeddablefactory.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableSetup](./kibana-plugin-plugins-embeddable-public.embeddablesetup.md) > [registerEmbeddableFactory](./kibana-plugin-plugins-embeddable-public.embeddablesetup.registerembeddablefactory.md) + +## EmbeddableSetup.registerEmbeddableFactory property + +Signature: + +```typescript +registerEmbeddableFactory: = IEmbeddable>(id: string, factory: EmbeddableFactoryDefinition) => () => EmbeddableFactory; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetup.registerenhancement.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetup.registerenhancement.md new file mode 100644 index 0000000000000..46baaf6dbf268 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetup.registerenhancement.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableSetup](./kibana-plugin-plugins-embeddable-public.embeddablesetup.md) > [registerEnhancement](./kibana-plugin-plugins-embeddable-public.embeddablesetup.registerenhancement.md) + +## EmbeddableSetup.registerEnhancement property + +Signature: + +```typescript +registerEnhancement: (enhancement: EnhancementRegistryDefinition) => void; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetup.setcustomembeddablefactoryprovider.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetup.setcustomembeddablefactoryprovider.md new file mode 100644 index 0000000000000..463ff80e5818b --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetup.setcustomembeddablefactoryprovider.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableSetup](./kibana-plugin-plugins-embeddable-public.embeddablesetup.md) > [setCustomEmbeddableFactoryProvider](./kibana-plugin-plugins-embeddable-public.embeddablesetup.setcustomembeddablefactoryprovider.md) + +## EmbeddableSetup.setCustomEmbeddableFactoryProvider property + +Signature: + +```typescript +setCustomEmbeddableFactoryProvider: (customProvider: EmbeddableFactoryProvider) => void; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.data.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.data.md new file mode 100644 index 0000000000000..d3a62657372ac --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.data.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableSetupDependencies](./kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.md) > [data](./kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.data.md) + +## EmbeddableSetupDependencies.data property + +Signature: + +```typescript +data: DataPublicPluginSetup; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.md new file mode 100644 index 0000000000000..fdd31ca75be2a --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.md @@ -0,0 +1,19 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableSetupDependencies](./kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.md) + +## EmbeddableSetupDependencies interface + +Signature: + +```typescript +export interface EmbeddableSetupDependencies +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [data](./kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.data.md) | DataPublicPluginSetup | | +| [uiActions](./kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.uiactions.md) | UiActionsSetup | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.uiactions.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.uiactions.md new file mode 100644 index 0000000000000..7eff6e2b0b28b --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.uiactions.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableSetupDependencies](./kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.md) > [uiActions](./kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.uiactions.md) + +## EmbeddableSetupDependencies.uiActions property + +Signature: + +```typescript +uiActions: UiActionsSetup; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestart.embeddablepanel.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestart.embeddablepanel.md new file mode 100644 index 0000000000000..b8c10bf0e4473 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestart.embeddablepanel.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableStart](./kibana-plugin-plugins-embeddable-public.embeddablestart.md) > [EmbeddablePanel](./kibana-plugin-plugins-embeddable-public.embeddablestart.embeddablepanel.md) + +## EmbeddableStart.EmbeddablePanel property + +Signature: + +```typescript +EmbeddablePanel: EmbeddablePanelHOC; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestart.getembeddablefactories.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestart.getembeddablefactories.md new file mode 100644 index 0000000000000..cc6b1187903bf --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestart.getembeddablefactories.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableStart](./kibana-plugin-plugins-embeddable-public.embeddablestart.md) > [getEmbeddableFactories](./kibana-plugin-plugins-embeddable-public.embeddablestart.getembeddablefactories.md) + +## EmbeddableStart.getEmbeddableFactories property + +Signature: + +```typescript +getEmbeddableFactories: () => IterableIterator; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestart.getembeddablefactory.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestart.getembeddablefactory.md new file mode 100644 index 0000000000000..d91878754bd7d --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestart.getembeddablefactory.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableStart](./kibana-plugin-plugins-embeddable-public.embeddablestart.md) > [getEmbeddableFactory](./kibana-plugin-plugins-embeddable-public.embeddablestart.getembeddablefactory.md) + +## EmbeddableStart.getEmbeddableFactory property + +Signature: + +```typescript +getEmbeddableFactory: = IEmbeddable>(embeddableFactoryId: string) => EmbeddableFactory | undefined; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestart.getembeddablepanel.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestart.getembeddablepanel.md new file mode 100644 index 0000000000000..7ba24a62a3893 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestart.getembeddablepanel.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableStart](./kibana-plugin-plugins-embeddable-public.embeddablestart.md) > [getEmbeddablePanel](./kibana-plugin-plugins-embeddable-public.embeddablestart.getembeddablepanel.md) + +## EmbeddableStart.getEmbeddablePanel property + +Signature: + +```typescript +getEmbeddablePanel: (stateTransfer?: EmbeddableStateTransfer) => EmbeddablePanelHOC; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestart.getstatetransfer.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestart.getstatetransfer.md new file mode 100644 index 0000000000000..dafc66b1a6e15 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestart.getstatetransfer.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableStart](./kibana-plugin-plugins-embeddable-public.embeddablestart.md) > [getStateTransfer](./kibana-plugin-plugins-embeddable-public.embeddablestart.getstatetransfer.md) + +## EmbeddableStart.getStateTransfer property + +Signature: + +```typescript +getStateTransfer: (history?: ScopedHistory) => EmbeddableStateTransfer; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestart.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestart.md new file mode 100644 index 0000000000000..f8e0028d8344b --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestart.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableStart](./kibana-plugin-plugins-embeddable-public.embeddablestart.md) + +## EmbeddableStart interface + +Signature: + +```typescript +export interface EmbeddableStart extends PersistableState +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [EmbeddablePanel](./kibana-plugin-plugins-embeddable-public.embeddablestart.embeddablepanel.md) | EmbeddablePanelHOC | | +| [getEmbeddableFactories](./kibana-plugin-plugins-embeddable-public.embeddablestart.getembeddablefactories.md) | () => IterableIterator<EmbeddableFactory> | | +| [getEmbeddableFactory](./kibana-plugin-plugins-embeddable-public.embeddablestart.getembeddablefactory.md) | <I extends EmbeddableInput = EmbeddableInput, O extends EmbeddableOutput = EmbeddableOutput, E extends IEmbeddable<I, O> = IEmbeddable<I, O>>(embeddableFactoryId: string) => EmbeddableFactory<I, O, E> | undefined | | +| [getEmbeddablePanel](./kibana-plugin-plugins-embeddable-public.embeddablestart.getembeddablepanel.md) | (stateTransfer?: EmbeddableStateTransfer) => EmbeddablePanelHOC | | +| [getStateTransfer](./kibana-plugin-plugins-embeddable-public.embeddablestart.getstatetransfer.md) | (history?: ScopedHistory) => EmbeddableStateTransfer | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.data.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.data.md new file mode 100644 index 0000000000000..0595609b11e49 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.data.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableStartDependencies](./kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.md) > [data](./kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.data.md) + +## EmbeddableStartDependencies.data property + +Signature: + +```typescript +data: DataPublicPluginStart; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.inspector.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.inspector.md new file mode 100644 index 0000000000000..299cc945104ab --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.inspector.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableStartDependencies](./kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.md) > [inspector](./kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.inspector.md) + +## EmbeddableStartDependencies.inspector property + +Signature: + +```typescript +inspector: InspectorStart; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.md new file mode 100644 index 0000000000000..5a1b5d1e06861 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableStartDependencies](./kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.md) + +## EmbeddableStartDependencies interface + +Signature: + +```typescript +export interface EmbeddableStartDependencies +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [data](./kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.data.md) | DataPublicPluginStart | | +| [inspector](./kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.inspector.md) | InspectorStart | | +| [uiActions](./kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.uiactions.md) | UiActionsStart | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.uiactions.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.uiactions.md new file mode 100644 index 0000000000000..398ee3fbcbc50 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.uiactions.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableStartDependencies](./kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.md) > [uiActions](./kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.uiactions.md) + +## EmbeddableStartDependencies.uiActions property + +Signature: + +```typescript +uiActions: UiActionsStart; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer._constructor_.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer._constructor_.md new file mode 100644 index 0000000000000..323ed5e38bde1 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer._constructor_.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableStateTransfer](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.md) > [(constructor)](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer._constructor_.md) + +## EmbeddableStateTransfer.(constructor) + +Constructs a new instance of the `EmbeddableStateTransfer` class + +Signature: + +```typescript +constructor(navigateToApp: ApplicationStart['navigateToApp'], scopedHistory?: ScopedHistory | undefined, appList?: ReadonlyMap | undefined); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| navigateToApp | ApplicationStart['navigateToApp'] | | +| scopedHistory | ScopedHistory<unknown> | undefined | | +| appList | ReadonlyMap<string, PublicAppInfo> | undefined | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.getappnamefromid.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.getappnamefromid.md new file mode 100644 index 0000000000000..f15574593e853 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.getappnamefromid.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableStateTransfer](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.md) > [getAppNameFromId](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.getappnamefromid.md) + +## EmbeddableStateTransfer.getAppNameFromId property + +Fetches an internationalized app title when given an appId. + +Signature: + +```typescript +getAppNameFromId: (appId: string) => string | undefined; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.getincomingeditorstate.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.getincomingeditorstate.md new file mode 100644 index 0000000000000..2a0823a9bf835 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.getincomingeditorstate.md @@ -0,0 +1,26 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableStateTransfer](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.md) > [getIncomingEditorState](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.getincomingeditorstate.md) + +## EmbeddableStateTransfer.getIncomingEditorState() method + +Fetches an [originating app](./kibana-plugin-plugins-embeddable-public.embeddableeditorstate.md) argument from the scoped history's location state. + +Signature: + +```typescript +getIncomingEditorState(options?: { + keysToRemoveAfterFetch?: string[]; + }): EmbeddableEditorState | undefined; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| options | {
keysToRemoveAfterFetch?: string[];
} | | + +Returns: + +`EmbeddableEditorState | undefined` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.getincomingembeddablepackage.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.getincomingembeddablepackage.md new file mode 100644 index 0000000000000..2069f0ce084f9 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.getincomingembeddablepackage.md @@ -0,0 +1,26 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableStateTransfer](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.md) > [getIncomingEmbeddablePackage](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.getincomingembeddablepackage.md) + +## EmbeddableStateTransfer.getIncomingEmbeddablePackage() method + +Fetches an [embeddable package](./kibana-plugin-plugins-embeddable-public.embeddablepackagestate.md) argument from the scoped history's location state. + +Signature: + +```typescript +getIncomingEmbeddablePackage(options?: { + keysToRemoveAfterFetch?: string[]; + }): EmbeddablePackageState | undefined; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| options | {
keysToRemoveAfterFetch?: string[];
} | | + +Returns: + +`EmbeddablePackageState | undefined` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.md new file mode 100644 index 0000000000000..2b44693e14846 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.md @@ -0,0 +1,35 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableStateTransfer](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.md) + +## EmbeddableStateTransfer class + +A wrapper around the state object in which provides strongly typed helper methods for common incoming and outgoing states used by the embeddable infrastructure. + +Signature: + +```typescript +export declare class EmbeddableStateTransfer +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(navigateToApp, scopedHistory, appList)](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer._constructor_.md) | | Constructs a new instance of the EmbeddableStateTransfer class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [getAppNameFromId](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.getappnamefromid.md) | | (appId: string) => string | undefined | Fetches an internationalized app title when given an appId. | + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [getIncomingEditorState(options)](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.getincomingeditorstate.md) | | Fetches an [originating app](./kibana-plugin-plugins-embeddable-public.embeddableeditorstate.md) argument from the scoped history's location state. | +| [getIncomingEmbeddablePackage(options)](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.getincomingembeddablepackage.md) | | Fetches an [embeddable package](./kibana-plugin-plugins-embeddable-public.embeddablepackagestate.md) argument from the scoped history's location state. | +| [navigateToEditor(appId, options)](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.navigatetoeditor.md) | | A wrapper around the method which navigates to the specified appId with [embeddable editor state](./kibana-plugin-plugins-embeddable-public.embeddableeditorstate.md) | +| [navigateToWithEmbeddablePackage(appId, options)](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.navigatetowithembeddablepackage.md) | | A wrapper around the method which navigates to the specified appId with [embeddable package state](./kibana-plugin-plugins-embeddable-public.embeddablepackagestate.md) | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.navigatetoeditor.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.navigatetoeditor.md new file mode 100644 index 0000000000000..fa24784d9aac5 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.navigatetoeditor.md @@ -0,0 +1,29 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableStateTransfer](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.md) > [navigateToEditor](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.navigatetoeditor.md) + +## EmbeddableStateTransfer.navigateToEditor() method + +A wrapper around the method which navigates to the specified appId with [embeddable editor state](./kibana-plugin-plugins-embeddable-public.embeddableeditorstate.md) + +Signature: + +```typescript +navigateToEditor(appId: string, options?: { + path?: string; + state: EmbeddableEditorState; + appendToExistingState?: boolean; + }): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| appId | string | | +| options | {
path?: string;
state: EmbeddableEditorState;
appendToExistingState?: boolean;
} | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.navigatetowithembeddablepackage.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.navigatetowithembeddablepackage.md new file mode 100644 index 0000000000000..7173bc8b127cd --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.navigatetowithembeddablepackage.md @@ -0,0 +1,29 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableStateTransfer](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.md) > [navigateToWithEmbeddablePackage](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.navigatetowithembeddablepackage.md) + +## EmbeddableStateTransfer.navigateToWithEmbeddablePackage() method + +A wrapper around the method which navigates to the specified appId with [embeddable package state](./kibana-plugin-plugins-embeddable-public.embeddablepackagestate.md) + +Signature: + +```typescript +navigateToWithEmbeddablePackage(appId: string, options?: { + path?: string; + state: EmbeddablePackageState; + appendToExistingState?: boolean; + }): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| appId | string | | +| options | {
path?: string;
state: EmbeddablePackageState;
appendToExistingState?: boolean;
} | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.enhancementregistrydefinition.id.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.enhancementregistrydefinition.id.md new file mode 100644 index 0000000000000..083b3931bcf7d --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.enhancementregistrydefinition.id.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EnhancementRegistryDefinition](./kibana-plugin-plugins-embeddable-public.enhancementregistrydefinition.md) > [id](./kibana-plugin-plugins-embeddable-public.enhancementregistrydefinition.id.md) + +## EnhancementRegistryDefinition.id property + +Signature: + +```typescript +id: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.enhancementregistrydefinition.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.enhancementregistrydefinition.md new file mode 100644 index 0000000000000..c54ebe4b1712d --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.enhancementregistrydefinition.md @@ -0,0 +1,18 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EnhancementRegistryDefinition](./kibana-plugin-plugins-embeddable-public.enhancementregistrydefinition.md) + +## EnhancementRegistryDefinition interface + +Signature: + +```typescript +export interface EnhancementRegistryDefinition

extends PersistableStateDefinition

+``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [id](./kibana-plugin-plugins-embeddable-public.enhancementregistrydefinition.id.md) | string | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.errorembeddable._constructor_.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.errorembeddable._constructor_.md new file mode 100644 index 0000000000000..0facb07b41692 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.errorembeddable._constructor_.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [ErrorEmbeddable](./kibana-plugin-plugins-embeddable-public.errorembeddable.md) > [(constructor)](./kibana-plugin-plugins-embeddable-public.errorembeddable._constructor_.md) + +## ErrorEmbeddable.(constructor) + +Constructs a new instance of the `ErrorEmbeddable` class + +Signature: + +```typescript +constructor(error: Error | string, input: EmbeddableInput, parent?: IContainer); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| error | Error | string | | +| input | EmbeddableInput | | +| parent | IContainer | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.errorembeddable.destroy.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.errorembeddable.destroy.md new file mode 100644 index 0000000000000..eeb605f2140ec --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.errorembeddable.destroy.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [ErrorEmbeddable](./kibana-plugin-plugins-embeddable-public.errorembeddable.md) > [destroy](./kibana-plugin-plugins-embeddable-public.errorembeddable.destroy.md) + +## ErrorEmbeddable.destroy() method + +Signature: + +```typescript +destroy(): void; +``` +Returns: + +`void` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.errorembeddable.error.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.errorembeddable.error.md new file mode 100644 index 0000000000000..7e4def3d52923 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.errorembeddable.error.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [ErrorEmbeddable](./kibana-plugin-plugins-embeddable-public.errorembeddable.md) > [error](./kibana-plugin-plugins-embeddable-public.errorembeddable.error.md) + +## ErrorEmbeddable.error property + +Signature: + +```typescript +error: Error | string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.errorembeddable.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.errorembeddable.md new file mode 100644 index 0000000000000..75f3fc6d503d5 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.errorembeddable.md @@ -0,0 +1,33 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [ErrorEmbeddable](./kibana-plugin-plugins-embeddable-public.errorembeddable.md) + +## ErrorEmbeddable class + +Signature: + +```typescript +export declare class ErrorEmbeddable extends Embeddable +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(error, input, parent)](./kibana-plugin-plugins-embeddable-public.errorembeddable._constructor_.md) | | Constructs a new instance of the ErrorEmbeddable class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [error](./kibana-plugin-plugins-embeddable-public.errorembeddable.error.md) | | Error | string | | +| [type](./kibana-plugin-plugins-embeddable-public.errorembeddable.type.md) | | | | + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [destroy()](./kibana-plugin-plugins-embeddable-public.errorembeddable.destroy.md) | | | +| [reload()](./kibana-plugin-plugins-embeddable-public.errorembeddable.reload.md) | | | +| [render(dom)](./kibana-plugin-plugins-embeddable-public.errorembeddable.render.md) | | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.errorembeddable.reload.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.errorembeddable.reload.md new file mode 100644 index 0000000000000..14d7c9fcf7ee0 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.errorembeddable.reload.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [ErrorEmbeddable](./kibana-plugin-plugins-embeddable-public.errorembeddable.md) > [reload](./kibana-plugin-plugins-embeddable-public.errorembeddable.reload.md) + +## ErrorEmbeddable.reload() method + +Signature: + +```typescript +reload(): void; +``` +Returns: + +`void` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.errorembeddable.render.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.errorembeddable.render.md new file mode 100644 index 0000000000000..70c9d169f3f7e --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.errorembeddable.render.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [ErrorEmbeddable](./kibana-plugin-plugins-embeddable-public.errorembeddable.md) > [render](./kibana-plugin-plugins-embeddable-public.errorembeddable.render.md) + +## ErrorEmbeddable.render() method + +Signature: + +```typescript +render(dom: HTMLElement): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| dom | HTMLElement | | + +Returns: + +`void` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.errorembeddable.type.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.errorembeddable.type.md new file mode 100644 index 0000000000000..d407e743a89af --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.errorembeddable.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [ErrorEmbeddable](./kibana-plugin-plugins-embeddable-public.errorembeddable.md) > [type](./kibana-plugin-plugins-embeddable-public.errorembeddable.type.md) + +## ErrorEmbeddable.type property + +Signature: + +```typescript +readonly type = "error"; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.icontainer.addnewembeddable.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.icontainer.addnewembeddable.md new file mode 100644 index 0000000000000..ca0095580a0ba --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.icontainer.addnewembeddable.md @@ -0,0 +1,25 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IContainer](./kibana-plugin-plugins-embeddable-public.icontainer.md) > [addNewEmbeddable](./kibana-plugin-plugins-embeddable-public.icontainer.addnewembeddable.md) + +## IContainer.addNewEmbeddable() method + +Adds a new embeddable to the container. `explicitInput` may partially specify the required embeddable input, but the remainder must come from inherited container state. + +Signature: + +```typescript +addNewEmbeddable = Embeddable>(type: string, explicitInput: Partial): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| type | string | | +| explicitInput | Partial<EEI> | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.icontainer.getchild.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.icontainer.getchild.md new file mode 100644 index 0000000000000..4355cfb68ad3f --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.icontainer.getchild.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IContainer](./kibana-plugin-plugins-embeddable-public.icontainer.md) > [getChild](./kibana-plugin-plugins-embeddable-public.icontainer.getchild.md) + +## IContainer.getChild() method + +Returns the child embeddable with the given id. + +Signature: + +```typescript +getChild = Embeddable>(id: string): E; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| id | string | | + +Returns: + +`E` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.icontainer.getinputforchild.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.icontainer.getinputforchild.md new file mode 100644 index 0000000000000..e5afc0eac3ce0 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.icontainer.getinputforchild.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IContainer](./kibana-plugin-plugins-embeddable-public.icontainer.md) > [getInputForChild](./kibana-plugin-plugins-embeddable-public.icontainer.getinputforchild.md) + +## IContainer.getInputForChild() method + +Returns the input for the given child. Uses a combination of explicit input for the child stored on the parent and derived/inherited input taken from the container itself. + +Signature: + +```typescript +getInputForChild(id: string): EEI; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| id | string | | + +Returns: + +`EEI` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.icontainer.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.icontainer.md new file mode 100644 index 0000000000000..cba430069c7a4 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.icontainer.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IContainer](./kibana-plugin-plugins-embeddable-public.icontainer.md) + +## IContainer interface + +Signature: + +```typescript +export interface IContainer = ContainerInput, O extends ContainerOutput = ContainerOutput> extends IEmbeddable +``` + +## Methods + +| Method | Description | +| --- | --- | +| [addNewEmbeddable(type, explicitInput)](./kibana-plugin-plugins-embeddable-public.icontainer.addnewembeddable.md) | Adds a new embeddable to the container. explicitInput may partially specify the required embeddable input, but the remainder must come from inherited container state. | +| [getChild(id)](./kibana-plugin-plugins-embeddable-public.icontainer.getchild.md) | Returns the child embeddable with the given id. | +| [getInputForChild(id)](./kibana-plugin-plugins-embeddable-public.icontainer.getinputforchild.md) | Returns the input for the given child. Uses a combination of explicit input for the child stored on the parent and derived/inherited input taken from the container itself. | +| [removeEmbeddable(embeddableId)](./kibana-plugin-plugins-embeddable-public.icontainer.removeembeddable.md) | Removes the embeddable with the given id. | +| [untilEmbeddableLoaded(id)](./kibana-plugin-plugins-embeddable-public.icontainer.untilembeddableloaded.md) | Call if you want to wait until an embeddable with that id has finished loading. | +| [updateInputForChild(id, changes)](./kibana-plugin-plugins-embeddable-public.icontainer.updateinputforchild.md) | Changes the input for a given child. Note, this will override any inherited state taken from the container itself. | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.icontainer.removeembeddable.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.icontainer.removeembeddable.md new file mode 100644 index 0000000000000..94a991ca20a14 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.icontainer.removeembeddable.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IContainer](./kibana-plugin-plugins-embeddable-public.icontainer.md) > [removeEmbeddable](./kibana-plugin-plugins-embeddable-public.icontainer.removeembeddable.md) + +## IContainer.removeEmbeddable() method + +Removes the embeddable with the given id. + +Signature: + +```typescript +removeEmbeddable(embeddableId: string): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| embeddableId | string | | + +Returns: + +`void` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.icontainer.untilembeddableloaded.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.icontainer.untilembeddableloaded.md new file mode 100644 index 0000000000000..0d6d4a3d8ccf0 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.icontainer.untilembeddableloaded.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IContainer](./kibana-plugin-plugins-embeddable-public.icontainer.md) > [untilEmbeddableLoaded](./kibana-plugin-plugins-embeddable-public.icontainer.untilembeddableloaded.md) + +## IContainer.untilEmbeddableLoaded() method + +Call if you want to wait until an embeddable with that id has finished loading. + +Signature: + +```typescript +untilEmbeddableLoaded(id: string): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| id | string | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.icontainer.updateinputforchild.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.icontainer.updateinputforchild.md new file mode 100644 index 0000000000000..04a82b0065516 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.icontainer.updateinputforchild.md @@ -0,0 +1,25 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IContainer](./kibana-plugin-plugins-embeddable-public.icontainer.md) > [updateInputForChild](./kibana-plugin-plugins-embeddable-public.icontainer.updateinputforchild.md) + +## IContainer.updateInputForChild() method + +Changes the input for a given child. Note, this will override any inherited state taken from the container itself. + +Signature: + +```typescript +updateInputForChild(id: string, changes: Partial): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| id | string | | +| changes | Partial<EEI> | | + +Returns: + +`void` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.destroy.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.destroy.md new file mode 100644 index 0000000000000..7fc636f40f3c2 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.destroy.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IEmbeddable](./kibana-plugin-plugins-embeddable-public.iembeddable.md) > [destroy](./kibana-plugin-plugins-embeddable-public.iembeddable.destroy.md) + +## IEmbeddable.destroy() method + +Cleans up subscriptions, destroy nodes mounted from calls to render. + +Signature: + +```typescript +destroy(): void; +``` +Returns: + +`void` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.enhancements.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.enhancements.md new file mode 100644 index 0000000000000..9183cd6887872 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.enhancements.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IEmbeddable](./kibana-plugin-plugins-embeddable-public.iembeddable.md) > [enhancements](./kibana-plugin-plugins-embeddable-public.iembeddable.enhancements.md) + +## IEmbeddable.enhancements property + +Extra abilities added to Embeddable by `*_enhanced` plugins. + +Signature: + +```typescript +enhancements?: object; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.getinput.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.getinput.md new file mode 100644 index 0000000000000..2fd8db07fa342 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.getinput.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IEmbeddable](./kibana-plugin-plugins-embeddable-public.iembeddable.md) > [getInput](./kibana-plugin-plugins-embeddable-public.iembeddable.getinput.md) + +## IEmbeddable.getInput() method + +Get the input used to instantiate this embeddable. The input is a serialized representation of this embeddable instance and can be used to clone or re-instantiate it. Input state: + +- Can be updated externally - Can change multiple times for a single embeddable instance. + +Examples: title, pie slice colors, custom search columns and sort order. + +Signature: + +```typescript +getInput(): Readonly; +``` +Returns: + +`Readonly` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.getinput_.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.getinput_.md new file mode 100644 index 0000000000000..ad91ad56b3d72 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.getinput_.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IEmbeddable](./kibana-plugin-plugins-embeddable-public.iembeddable.md) > [getInput$](./kibana-plugin-plugins-embeddable-public.iembeddable.getinput_.md) + +## IEmbeddable.getInput$() method + +Returns an observable which will be notified when input state changes. + +Signature: + +```typescript +getInput$(): Readonly>; +``` +Returns: + +`Readonly>` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.getinspectoradapters.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.getinspectoradapters.md new file mode 100644 index 0000000000000..84b083acac6f4 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.getinspectoradapters.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IEmbeddable](./kibana-plugin-plugins-embeddable-public.iembeddable.md) > [getInspectorAdapters](./kibana-plugin-plugins-embeddable-public.iembeddable.getinspectoradapters.md) + +## IEmbeddable.getInspectorAdapters() method + +An embeddable can return inspector adapters if it wants the inspector to be available via the context menu of that panel. Inspector adapters that will be used to open an inspector for. + +Signature: + +```typescript +getInspectorAdapters(): Adapters | undefined; +``` +Returns: + +`Adapters | undefined` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.getiscontainer.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.getiscontainer.md new file mode 100644 index 0000000000000..f9bfbbc4ca9bd --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.getiscontainer.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IEmbeddable](./kibana-plugin-plugins-embeddable-public.iembeddable.md) > [getIsContainer](./kibana-plugin-plugins-embeddable-public.iembeddable.getiscontainer.md) + +## IEmbeddable.getIsContainer() method + +A functional representation of the isContainer variable, but helpful for typescript to know the shape if this returns true + +Signature: + +```typescript +getIsContainer(): this is IContainer; +``` +Returns: + +`this is IContainer` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.getoutput.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.getoutput.md new file mode 100644 index 0000000000000..7e4e4fd3d4329 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.getoutput.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IEmbeddable](./kibana-plugin-plugins-embeddable-public.iembeddable.md) > [getOutput](./kibana-plugin-plugins-embeddable-public.iembeddable.getoutput.md) + +## IEmbeddable.getOutput() method + +Output state is: + +- State that should not change once the embeddable is instantiated, or - State that is derived from the input state, or - State that only the embeddable instance itself knows about, or the factory. + +Examples: editUrl, title taken from a saved object, if your input state was first name and last name, your output state could be greeting. + +Signature: + +```typescript +getOutput(): Readonly; +``` +Returns: + +`Readonly` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.getoutput_.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.getoutput_.md new file mode 100644 index 0000000000000..11ec3e0d1c8ea --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.getoutput_.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IEmbeddable](./kibana-plugin-plugins-embeddable-public.iembeddable.md) > [getOutput$](./kibana-plugin-plugins-embeddable-public.iembeddable.getoutput_.md) + +## IEmbeddable.getOutput$() method + +Returns an observable which will be notified when output state changes. + +Signature: + +```typescript +getOutput$(): Readonly>; +``` +Returns: + +`Readonly>` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.getroot.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.getroot.md new file mode 100644 index 0000000000000..eacec168b4d8a --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.getroot.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IEmbeddable](./kibana-plugin-plugins-embeddable-public.iembeddable.md) > [getRoot](./kibana-plugin-plugins-embeddable-public.iembeddable.getroot.md) + +## IEmbeddable.getRoot() method + +Returns the top most parent embeddable, or itself if this embeddable is not within a parent. + +Signature: + +```typescript +getRoot(): IEmbeddable | IContainer; +``` +Returns: + +`IEmbeddable | IContainer` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.gettitle.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.gettitle.md new file mode 100644 index 0000000000000..eed80882f4b93 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.gettitle.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IEmbeddable](./kibana-plugin-plugins-embeddable-public.iembeddable.md) > [getTitle](./kibana-plugin-plugins-embeddable-public.iembeddable.gettitle.md) + +## IEmbeddable.getTitle() method + +Returns the title of this embeddable. + +Signature: + +```typescript +getTitle(): string | undefined; +``` +Returns: + +`string | undefined` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.id.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.id.md new file mode 100644 index 0000000000000..7d2f5b9c7e71b --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.id.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IEmbeddable](./kibana-plugin-plugins-embeddable-public.iembeddable.md) > [id](./kibana-plugin-plugins-embeddable-public.iembeddable.id.md) + +## IEmbeddable.id property + +A unique identifier for this embeddable. Mainly only used by containers to map their Panel States to a child embeddable instance. + +Signature: + +```typescript +readonly id: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.iscontainer.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.iscontainer.md new file mode 100644 index 0000000000000..93b910ee6f6a1 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.iscontainer.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IEmbeddable](./kibana-plugin-plugins-embeddable-public.iembeddable.md) > [isContainer](./kibana-plugin-plugins-embeddable-public.iembeddable.iscontainer.md) + +## IEmbeddable.isContainer property + +Is this embeddable an instance of a Container class, can it contain nested embeddables? + +Signature: + +```typescript +readonly isContainer: boolean; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.md new file mode 100644 index 0000000000000..b3b6f961e56d1 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.md @@ -0,0 +1,41 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IEmbeddable](./kibana-plugin-plugins-embeddable-public.iembeddable.md) + +## IEmbeddable interface + +Signature: + +```typescript +export interface IEmbeddable +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [enhancements](./kibana-plugin-plugins-embeddable-public.iembeddable.enhancements.md) | object | Extra abilities added to Embeddable by *_enhanced plugins. | +| [id](./kibana-plugin-plugins-embeddable-public.iembeddable.id.md) | string | A unique identifier for this embeddable. Mainly only used by containers to map their Panel States to a child embeddable instance. | +| [isContainer](./kibana-plugin-plugins-embeddable-public.iembeddable.iscontainer.md) | boolean | Is this embeddable an instance of a Container class, can it contain nested embeddables? | +| [parent](./kibana-plugin-plugins-embeddable-public.iembeddable.parent.md) | IContainer | If this embeddable is nested inside a container, this will contain a reference to its parent. | +| [runtimeId](./kibana-plugin-plugins-embeddable-public.iembeddable.runtimeid.md) | number | Unique ID an embeddable is assigned each time it is initialized. This ID is different for different instances of the same embeddable. For example, if the same dashboard is rendered twice on the screen, all embeddable instances will have a unique runtimeId. | +| [type](./kibana-plugin-plugins-embeddable-public.iembeddable.type.md) | string | The type of embeddable, this is what will be used to take a serialized embeddable and find the correct factory for which to create an instance of it. | + +## Methods + +| Method | Description | +| --- | --- | +| [destroy()](./kibana-plugin-plugins-embeddable-public.iembeddable.destroy.md) | Cleans up subscriptions, destroy nodes mounted from calls to render. | +| [getInput()](./kibana-plugin-plugins-embeddable-public.iembeddable.getinput.md) | Get the input used to instantiate this embeddable. The input is a serialized representation of this embeddable instance and can be used to clone or re-instantiate it. Input state:- Can be updated externally - Can change multiple times for a single embeddable instance.Examples: title, pie slice colors, custom search columns and sort order. | +| [getInput$()](./kibana-plugin-plugins-embeddable-public.iembeddable.getinput_.md) | Returns an observable which will be notified when input state changes. | +| [getInspectorAdapters()](./kibana-plugin-plugins-embeddable-public.iembeddable.getinspectoradapters.md) | An embeddable can return inspector adapters if it wants the inspector to be available via the context menu of that panel. Inspector adapters that will be used to open an inspector for. | +| [getIsContainer()](./kibana-plugin-plugins-embeddable-public.iembeddable.getiscontainer.md) | A functional representation of the isContainer variable, but helpful for typescript to know the shape if this returns true | +| [getOutput()](./kibana-plugin-plugins-embeddable-public.iembeddable.getoutput.md) | Output state is:- State that should not change once the embeddable is instantiated, or - State that is derived from the input state, or - State that only the embeddable instance itself knows about, or the factory.Examples: editUrl, title taken from a saved object, if your input state was first name and last name, your output state could be greeting. | +| [getOutput$()](./kibana-plugin-plugins-embeddable-public.iembeddable.getoutput_.md) | Returns an observable which will be notified when output state changes. | +| [getRoot()](./kibana-plugin-plugins-embeddable-public.iembeddable.getroot.md) | Returns the top most parent embeddable, or itself if this embeddable is not within a parent. | +| [getTitle()](./kibana-plugin-plugins-embeddable-public.iembeddable.gettitle.md) | Returns the title of this embeddable. | +| [reload()](./kibana-plugin-plugins-embeddable-public.iembeddable.reload.md) | Reload the embeddable so output and rendering is up to date. Especially relevant if the embeddable takes relative time as input (e.g. now to now-15) | +| [render(domNode)](./kibana-plugin-plugins-embeddable-public.iembeddable.render.md) | Renders the embeddable at the given node. | +| [supportedTriggers()](./kibana-plugin-plugins-embeddable-public.iembeddable.supportedtriggers.md) | List of triggers that this embeddable will execute. | +| [updateInput(changes)](./kibana-plugin-plugins-embeddable-public.iembeddable.updateinput.md) | Updates input state with the given changes. | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.parent.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.parent.md new file mode 100644 index 0000000000000..d20102902cdb0 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.parent.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IEmbeddable](./kibana-plugin-plugins-embeddable-public.iembeddable.md) > [parent](./kibana-plugin-plugins-embeddable-public.iembeddable.parent.md) + +## IEmbeddable.parent property + +If this embeddable is nested inside a container, this will contain a reference to its parent. + +Signature: + +```typescript +readonly parent?: IContainer; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.reload.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.reload.md new file mode 100644 index 0000000000000..8caea9d8dc511 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.reload.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IEmbeddable](./kibana-plugin-plugins-embeddable-public.iembeddable.md) > [reload](./kibana-plugin-plugins-embeddable-public.iembeddable.reload.md) + +## IEmbeddable.reload() method + +Reload the embeddable so output and rendering is up to date. Especially relevant if the embeddable takes relative time as input (e.g. now to now-15) + +Signature: + +```typescript +reload(): void; +``` +Returns: + +`void` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.render.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.render.md new file mode 100644 index 0000000000000..9079227b622dc --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.render.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IEmbeddable](./kibana-plugin-plugins-embeddable-public.iembeddable.md) > [render](./kibana-plugin-plugins-embeddable-public.iembeddable.render.md) + +## IEmbeddable.render() method + +Renders the embeddable at the given node. + +Signature: + +```typescript +render(domNode: HTMLElement | Element): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| domNode | HTMLElement | Element | | + +Returns: + +`void` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.runtimeid.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.runtimeid.md new file mode 100644 index 0000000000000..5ddd8ddd0f8dd --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.runtimeid.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IEmbeddable](./kibana-plugin-plugins-embeddable-public.iembeddable.md) > [runtimeId](./kibana-plugin-plugins-embeddable-public.iembeddable.runtimeid.md) + +## IEmbeddable.runtimeId property + +Unique ID an embeddable is assigned each time it is initialized. This ID is different for different instances of the same embeddable. For example, if the same dashboard is rendered twice on the screen, all embeddable instances will have a unique `runtimeId`. + +Signature: + +```typescript +readonly runtimeId?: number; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.supportedtriggers.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.supportedtriggers.md new file mode 100644 index 0000000000000..5480f3b246648 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.supportedtriggers.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IEmbeddable](./kibana-plugin-plugins-embeddable-public.iembeddable.md) > [supportedTriggers](./kibana-plugin-plugins-embeddable-public.iembeddable.supportedtriggers.md) + +## IEmbeddable.supportedTriggers() method + +List of triggers that this embeddable will execute. + +Signature: + +```typescript +supportedTriggers(): Array; +``` +Returns: + +`Array` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.type.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.type.md new file mode 100644 index 0000000000000..46b9d40685dba --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.type.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IEmbeddable](./kibana-plugin-plugins-embeddable-public.iembeddable.md) > [type](./kibana-plugin-plugins-embeddable-public.iembeddable.type.md) + +## IEmbeddable.type property + +The type of embeddable, this is what will be used to take a serialized embeddable and find the correct factory for which to create an instance of it. + +Signature: + +```typescript +readonly type: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.updateinput.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.updateinput.md new file mode 100644 index 0000000000000..523464103bd1a --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iembeddable.updateinput.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [IEmbeddable](./kibana-plugin-plugins-embeddable-public.iembeddable.md) > [updateInput](./kibana-plugin-plugins-embeddable-public.iembeddable.updateinput.md) + +## IEmbeddable.updateInput() method + +Updates input state with the given changes. + +Signature: + +```typescript +updateInput(changes: Partial): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| changes | Partial<I> | | + +Returns: + +`void` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iserrorembeddable.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iserrorembeddable.md new file mode 100644 index 0000000000000..358d085ea9bba --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.iserrorembeddable.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [isErrorEmbeddable](./kibana-plugin-plugins-embeddable-public.iserrorembeddable.md) + +## isErrorEmbeddable() function + +Signature: + +```typescript +export declare function isErrorEmbeddable(embeddable: TEmbeddable | ErrorEmbeddable): embeddable is ErrorEmbeddable; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| embeddable | TEmbeddable | ErrorEmbeddable | | + +Returns: + +`embeddable is ErrorEmbeddable` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.israngeselecttriggercontext.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.israngeselecttriggercontext.md new file mode 100644 index 0000000000000..cd28494fe3a09 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.israngeselecttriggercontext.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [isRangeSelectTriggerContext](./kibana-plugin-plugins-embeddable-public.israngeselecttriggercontext.md) + +## isRangeSelectTriggerContext variable + +Signature: + +```typescript +isRangeSelectTriggerContext: (context: ChartActionContext) => context is RangeSelectContext> +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.isreferenceorvalueembeddable.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.isreferenceorvalueembeddable.md new file mode 100644 index 0000000000000..26a221d929ce6 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.isreferenceorvalueembeddable.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [isReferenceOrValueEmbeddable](./kibana-plugin-plugins-embeddable-public.isreferenceorvalueembeddable.md) + +## isReferenceOrValueEmbeddable() function + +Signature: + +```typescript +export declare function isReferenceOrValueEmbeddable(incoming: unknown): incoming is ReferenceOrValueEmbeddable; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| incoming | unknown | | + +Returns: + +`incoming is ReferenceOrValueEmbeddable` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.issavedobjectembeddableinput.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.issavedobjectembeddableinput.md new file mode 100644 index 0000000000000..663cc41f1bffc --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.issavedobjectembeddableinput.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [isSavedObjectEmbeddableInput](./kibana-plugin-plugins-embeddable-public.issavedobjectembeddableinput.md) + +## isSavedObjectEmbeddableInput() function + +Signature: + +```typescript +export declare function isSavedObjectEmbeddableInput(input: EmbeddableInput | SavedObjectEmbeddableInput): input is SavedObjectEmbeddableInput; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| input | EmbeddableInput | SavedObjectEmbeddableInput | | + +Returns: + +`input is SavedObjectEmbeddableInput` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.isvalueclicktriggercontext.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.isvalueclicktriggercontext.md new file mode 100644 index 0000000000000..4e3c970d9b437 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.isvalueclicktriggercontext.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [isValueClickTriggerContext](./kibana-plugin-plugins-embeddable-public.isvalueclicktriggercontext.md) + +## isValueClickTriggerContext variable + +Signature: + +```typescript +isValueClickTriggerContext: (context: ChartActionContext) => context is ValueClickContext> +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.md new file mode 100644 index 0000000000000..64dfdd1c6dc22 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.md @@ -0,0 +1,95 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) + +## kibana-plugin-plugins-embeddable-public package + +## Classes + +| Class | Description | +| --- | --- | +| [AddPanelAction](./kibana-plugin-plugins-embeddable-public.addpanelaction.md) | | +| [Container](./kibana-plugin-plugins-embeddable-public.container.md) | | +| [EditPanelAction](./kibana-plugin-plugins-embeddable-public.editpanelaction.md) | | +| [Embeddable](./kibana-plugin-plugins-embeddable-public.embeddable.md) | | +| [EmbeddableChildPanel](./kibana-plugin-plugins-embeddable-public.embeddablechildpanel.md) | This component can be used by embeddable containers using react to easily render children. It waits for the child to be initialized, showing a loading indicator until that is complete. | +| [EmbeddableFactoryNotFoundError](./kibana-plugin-plugins-embeddable-public.embeddablefactorynotfounderror.md) | | +| [EmbeddablePanel](./kibana-plugin-plugins-embeddable-public.embeddablepanel.md) | | +| [EmbeddableRoot](./kibana-plugin-plugins-embeddable-public.embeddableroot.md) | | +| [EmbeddableStateTransfer](./kibana-plugin-plugins-embeddable-public.embeddablestatetransfer.md) | A wrapper around the state object in which provides strongly typed helper methods for common incoming and outgoing states used by the embeddable infrastructure. | +| [ErrorEmbeddable](./kibana-plugin-plugins-embeddable-public.errorembeddable.md) | | +| [PanelNotFoundError](./kibana-plugin-plugins-embeddable-public.panelnotfounderror.md) | | + +## Enumerations + +| Enumeration | Description | +| --- | --- | +| [ViewMode](./kibana-plugin-plugins-embeddable-public.viewmode.md) | | + +## Functions + +| Function | Description | +| --- | --- | +| [isErrorEmbeddable(embeddable)](./kibana-plugin-plugins-embeddable-public.iserrorembeddable.md) | | +| [isReferenceOrValueEmbeddable(incoming)](./kibana-plugin-plugins-embeddable-public.isreferenceorvalueembeddable.md) | | +| [isSavedObjectEmbeddableInput(input)](./kibana-plugin-plugins-embeddable-public.issavedobjectembeddableinput.md) | | +| [openAddPanelFlyout(options)](./kibana-plugin-plugins-embeddable-public.openaddpanelflyout.md) | | +| [plugin(initializerContext)](./kibana-plugin-plugins-embeddable-public.plugin.md) | | + +## Interfaces + +| Interface | Description | +| --- | --- | +| [Adapters](./kibana-plugin-plugins-embeddable-public.adapters.md) | The interface that the adapters used to open an inspector have to fullfill. | +| [ContainerInput](./kibana-plugin-plugins-embeddable-public.containerinput.md) | | +| [ContainerOutput](./kibana-plugin-plugins-embeddable-public.containeroutput.md) | | +| [EmbeddableChildPanelProps](./kibana-plugin-plugins-embeddable-public.embeddablechildpanelprops.md) | | +| [EmbeddableContext](./kibana-plugin-plugins-embeddable-public.embeddablecontext.md) | | +| [EmbeddableEditorState](./kibana-plugin-plugins-embeddable-public.embeddableeditorstate.md) | A state package that contains information an editor will need to create or edit an embeddable then redirect back. | +| [EmbeddableFactory](./kibana-plugin-plugins-embeddable-public.embeddablefactory.md) | EmbeddableFactories create and initialize an embeddable instance | +| [EmbeddableInstanceConfiguration](./kibana-plugin-plugins-embeddable-public.embeddableinstanceconfiguration.md) | | +| [EmbeddableOutput](./kibana-plugin-plugins-embeddable-public.embeddableoutput.md) | | +| [EmbeddablePackageState](./kibana-plugin-plugins-embeddable-public.embeddablepackagestate.md) | A state package that contains all fields necessary to create or update an embeddable by reference or by value in a container. | +| [EmbeddableSetup](./kibana-plugin-plugins-embeddable-public.embeddablesetup.md) | | +| [EmbeddableSetupDependencies](./kibana-plugin-plugins-embeddable-public.embeddablesetupdependencies.md) | | +| [EmbeddableStart](./kibana-plugin-plugins-embeddable-public.embeddablestart.md) | | +| [EmbeddableStartDependencies](./kibana-plugin-plugins-embeddable-public.embeddablestartdependencies.md) | | +| [EnhancementRegistryDefinition](./kibana-plugin-plugins-embeddable-public.enhancementregistrydefinition.md) | | +| [IContainer](./kibana-plugin-plugins-embeddable-public.icontainer.md) | | +| [IEmbeddable](./kibana-plugin-plugins-embeddable-public.iembeddable.md) | | +| [OutputSpec](./kibana-plugin-plugins-embeddable-public.outputspec.md) | | +| [PanelState](./kibana-plugin-plugins-embeddable-public.panelstate.md) | | +| [PropertySpec](./kibana-plugin-plugins-embeddable-public.propertyspec.md) | | +| [RangeSelectContext](./kibana-plugin-plugins-embeddable-public.rangeselectcontext.md) | | +| [ReferenceOrValueEmbeddable](./kibana-plugin-plugins-embeddable-public.referenceorvalueembeddable.md) | Any embeddable that implements this interface will be able to use input that is either by reference (backed by a saved object) OR by value, (provided by the container). | +| [SavedObjectEmbeddableInput](./kibana-plugin-plugins-embeddable-public.savedobjectembeddableinput.md) | | +| [ValueClickContext](./kibana-plugin-plugins-embeddable-public.valueclickcontext.md) | | + +## Variables + +| Variable | Description | +| --- | --- | +| [ACTION\_ADD\_PANEL](./kibana-plugin-plugins-embeddable-public.action_add_panel.md) | | +| [ACTION\_EDIT\_PANEL](./kibana-plugin-plugins-embeddable-public.action_edit_panel.md) | | +| [CONTEXT\_MENU\_TRIGGER](./kibana-plugin-plugins-embeddable-public.context_menu_trigger.md) | | +| [contextMenuTrigger](./kibana-plugin-plugins-embeddable-public.contextmenutrigger.md) | | +| [defaultEmbeddableFactoryProvider](./kibana-plugin-plugins-embeddable-public.defaultembeddablefactoryprovider.md) | | +| [EmbeddableRenderer](./kibana-plugin-plugins-embeddable-public.embeddablerenderer.md) | Helper react component to render an embeddable Can be used if you have an embeddable object or an embeddable factory Supports updating input by passing input prop | +| [isRangeSelectTriggerContext](./kibana-plugin-plugins-embeddable-public.israngeselecttriggercontext.md) | | +| [isValueClickTriggerContext](./kibana-plugin-plugins-embeddable-public.isvalueclicktriggercontext.md) | | +| [PANEL\_BADGE\_TRIGGER](./kibana-plugin-plugins-embeddable-public.panel_badge_trigger.md) | | +| [PANEL\_NOTIFICATION\_TRIGGER](./kibana-plugin-plugins-embeddable-public.panel_notification_trigger.md) | | +| [panelBadgeTrigger](./kibana-plugin-plugins-embeddable-public.panelbadgetrigger.md) | | +| [panelNotificationTrigger](./kibana-plugin-plugins-embeddable-public.panelnotificationtrigger.md) | | +| [withEmbeddableSubscription](./kibana-plugin-plugins-embeddable-public.withembeddablesubscription.md) | | + +## Type Aliases + +| Type Alias | Description | +| --- | --- | +| [ChartActionContext](./kibana-plugin-plugins-embeddable-public.chartactioncontext.md) | | +| [EmbeddableFactoryDefinition](./kibana-plugin-plugins-embeddable-public.embeddablefactorydefinition.md) | | +| [EmbeddableInput](./kibana-plugin-plugins-embeddable-public.embeddableinput.md) | | +| [EmbeddablePanelHOC](./kibana-plugin-plugins-embeddable-public.embeddablepanelhoc.md) | | +| [EmbeddableRendererProps](./kibana-plugin-plugins-embeddable-public.embeddablerendererprops.md) | This type is a publicly exposed props of [EmbeddableRenderer](./kibana-plugin-plugins-embeddable-public.embeddablerenderer.md) Union is used to validate that or factory or embeddable is passed in, but it can't be both simultaneously In case when embeddable is passed in, input is optional, because there is already an input inside of embeddable object In case when factory is used, then input is required, because it will be used as initial input to create an embeddable object | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.openaddpanelflyout.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.openaddpanelflyout.md new file mode 100644 index 0000000000000..ce97f79b4beb9 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.openaddpanelflyout.md @@ -0,0 +1,29 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [openAddPanelFlyout](./kibana-plugin-plugins-embeddable-public.openaddpanelflyout.md) + +## openAddPanelFlyout() function + +Signature: + +```typescript +export declare function openAddPanelFlyout(options: { + embeddable: IContainer; + getFactory: EmbeddableStart['getEmbeddableFactory']; + getAllFactories: EmbeddableStart['getEmbeddableFactories']; + overlays: OverlayStart; + notifications: NotificationsStart; + SavedObjectFinder: React.ComponentType; +}): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| options | {
embeddable: IContainer;
getFactory: EmbeddableStart['getEmbeddableFactory'];
getAllFactories: EmbeddableStart['getEmbeddableFactories'];
overlays: OverlayStart;
notifications: NotificationsStart;
SavedObjectFinder: React.ComponentType<any>;
} | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.outputspec.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.outputspec.md new file mode 100644 index 0000000000000..eead69b4e487c --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.outputspec.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [OutputSpec](./kibana-plugin-plugins-embeddable-public.outputspec.md) + +## OutputSpec interface + +Signature: + +```typescript +export interface OutputSpec +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panel_badge_trigger.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panel_badge_trigger.md new file mode 100644 index 0000000000000..d5032d98ef4aa --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panel_badge_trigger.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [PANEL\_BADGE\_TRIGGER](./kibana-plugin-plugins-embeddable-public.panel_badge_trigger.md) + +## PANEL\_BADGE\_TRIGGER variable + +Signature: + +```typescript +PANEL_BADGE_TRIGGER = "PANEL_BADGE_TRIGGER" +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panel_notification_trigger.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panel_notification_trigger.md new file mode 100644 index 0000000000000..cd8a4a1ca4581 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panel_notification_trigger.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [PANEL\_NOTIFICATION\_TRIGGER](./kibana-plugin-plugins-embeddable-public.panel_notification_trigger.md) + +## PANEL\_NOTIFICATION\_TRIGGER variable + +Signature: + +```typescript +PANEL_NOTIFICATION_TRIGGER = "PANEL_NOTIFICATION_TRIGGER" +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelbadgetrigger.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelbadgetrigger.md new file mode 100644 index 0000000000000..f6113c93a1c66 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelbadgetrigger.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [panelBadgeTrigger](./kibana-plugin-plugins-embeddable-public.panelbadgetrigger.md) + +## panelBadgeTrigger variable + +Signature: + +```typescript +panelBadgeTrigger: Trigger<'PANEL_BADGE_TRIGGER'> +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelnotfounderror._constructor_.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelnotfounderror._constructor_.md new file mode 100644 index 0000000000000..d1704403b2336 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelnotfounderror._constructor_.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [PanelNotFoundError](./kibana-plugin-plugins-embeddable-public.panelnotfounderror.md) > [(constructor)](./kibana-plugin-plugins-embeddable-public.panelnotfounderror._constructor_.md) + +## PanelNotFoundError.(constructor) + +Constructs a new instance of the `PanelNotFoundError` class + +Signature: + +```typescript +constructor(); +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelnotfounderror.code.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelnotfounderror.code.md new file mode 100644 index 0000000000000..d169fb97480cc --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelnotfounderror.code.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [PanelNotFoundError](./kibana-plugin-plugins-embeddable-public.panelnotfounderror.md) > [code](./kibana-plugin-plugins-embeddable-public.panelnotfounderror.code.md) + +## PanelNotFoundError.code property + +Signature: + +```typescript +code: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelnotfounderror.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelnotfounderror.md new file mode 100644 index 0000000000000..2191fdecf1ac5 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelnotfounderror.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [PanelNotFoundError](./kibana-plugin-plugins-embeddable-public.panelnotfounderror.md) + +## PanelNotFoundError class + +Signature: + +```typescript +export declare class PanelNotFoundError extends Error +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)()](./kibana-plugin-plugins-embeddable-public.panelnotfounderror._constructor_.md) | | Constructs a new instance of the PanelNotFoundError class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [code](./kibana-plugin-plugins-embeddable-public.panelnotfounderror.code.md) | | string | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelnotificationtrigger.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelnotificationtrigger.md new file mode 100644 index 0000000000000..df606c11f64ce --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelnotificationtrigger.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [panelNotificationTrigger](./kibana-plugin-plugins-embeddable-public.panelnotificationtrigger.md) + +## panelNotificationTrigger variable + +Signature: + +```typescript +panelNotificationTrigger: Trigger<'PANEL_NOTIFICATION_TRIGGER'> +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelstate.explicitinput.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelstate.explicitinput.md new file mode 100644 index 0000000000000..16123958d4db1 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelstate.explicitinput.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [PanelState](./kibana-plugin-plugins-embeddable-public.panelstate.md) > [explicitInput](./kibana-plugin-plugins-embeddable-public.panelstate.explicitinput.md) + +## PanelState.explicitInput property + +Signature: + +```typescript +explicitInput: Partial & { + id: string; + }; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelstate.id.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelstate.id.md new file mode 100644 index 0000000000000..e6fd4e0264f0d --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelstate.id.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [PanelState](./kibana-plugin-plugins-embeddable-public.panelstate.md) > [id](./kibana-plugin-plugins-embeddable-public.panelstate.id.md) + +## PanelState.id property + +Signature: + +```typescript +id: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelstate.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelstate.md new file mode 100644 index 0000000000000..b37f652b5021c --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelstate.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [PanelState](./kibana-plugin-plugins-embeddable-public.panelstate.md) + +## PanelState interface + +Signature: + +```typescript +export interface PanelState +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [explicitInput](./kibana-plugin-plugins-embeddable-public.panelstate.explicitinput.md) | Partial<E> & {
id: string;
} | | +| [id](./kibana-plugin-plugins-embeddable-public.panelstate.id.md) | string | | +| [type](./kibana-plugin-plugins-embeddable-public.panelstate.type.md) | string | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelstate.type.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelstate.type.md new file mode 100644 index 0000000000000..8be470a77f1c7 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.panelstate.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [PanelState](./kibana-plugin-plugins-embeddable-public.panelstate.md) > [type](./kibana-plugin-plugins-embeddable-public.panelstate.type.md) + +## PanelState.type property + +Signature: + +```typescript +type: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.plugin.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.plugin.md new file mode 100644 index 0000000000000..4e3ae760153cb --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.plugin.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [plugin](./kibana-plugin-plugins-embeddable-public.plugin.md) + +## plugin() function + +Signature: + +```typescript +export declare function plugin(initializerContext: PluginInitializerContext): EmbeddablePublicPlugin; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| initializerContext | PluginInitializerContext | | + +Returns: + +`EmbeddablePublicPlugin` + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.propertyspec.accesspath.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.propertyspec.accesspath.md new file mode 100644 index 0000000000000..2a337e4b0141a --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.propertyspec.accesspath.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [PropertySpec](./kibana-plugin-plugins-embeddable-public.propertyspec.md) > [accessPath](./kibana-plugin-plugins-embeddable-public.propertyspec.accesspath.md) + +## PropertySpec.accessPath property + +Signature: + +```typescript +accessPath: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.propertyspec.description.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.propertyspec.description.md new file mode 100644 index 0000000000000..f36309c657795 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.propertyspec.description.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [PropertySpec](./kibana-plugin-plugins-embeddable-public.propertyspec.md) > [description](./kibana-plugin-plugins-embeddable-public.propertyspec.description.md) + +## PropertySpec.description property + +Signature: + +```typescript +description: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.propertyspec.displayname.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.propertyspec.displayname.md new file mode 100644 index 0000000000000..16311493fa5dd --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.propertyspec.displayname.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [PropertySpec](./kibana-plugin-plugins-embeddable-public.propertyspec.md) > [displayName](./kibana-plugin-plugins-embeddable-public.propertyspec.displayname.md) + +## PropertySpec.displayName property + +Signature: + +```typescript +displayName: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.propertyspec.id.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.propertyspec.id.md new file mode 100644 index 0000000000000..a37ed9000b67a --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.propertyspec.id.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [PropertySpec](./kibana-plugin-plugins-embeddable-public.propertyspec.md) > [id](./kibana-plugin-plugins-embeddable-public.propertyspec.id.md) + +## PropertySpec.id property + +Signature: + +```typescript +id: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.propertyspec.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.propertyspec.md new file mode 100644 index 0000000000000..02534b5d9d4da --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.propertyspec.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [PropertySpec](./kibana-plugin-plugins-embeddable-public.propertyspec.md) + +## PropertySpec interface + +Signature: + +```typescript +export interface PropertySpec +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [accessPath](./kibana-plugin-plugins-embeddable-public.propertyspec.accesspath.md) | string | | +| [description](./kibana-plugin-plugins-embeddable-public.propertyspec.description.md) | string | | +| [displayName](./kibana-plugin-plugins-embeddable-public.propertyspec.displayname.md) | string | | +| [id](./kibana-plugin-plugins-embeddable-public.propertyspec.id.md) | string | | +| [value](./kibana-plugin-plugins-embeddable-public.propertyspec.value.md) | string | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.propertyspec.value.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.propertyspec.value.md new file mode 100644 index 0000000000000..3360a9fff783c --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.propertyspec.value.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [PropertySpec](./kibana-plugin-plugins-embeddable-public.propertyspec.md) > [value](./kibana-plugin-plugins-embeddable-public.propertyspec.value.md) + +## PropertySpec.value property + +Signature: + +```typescript +value?: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.rangeselectcontext.data.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.rangeselectcontext.data.md new file mode 100644 index 0000000000000..6d2774d86f109 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.rangeselectcontext.data.md @@ -0,0 +1,16 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [RangeSelectContext](./kibana-plugin-plugins-embeddable-public.rangeselectcontext.md) > [data](./kibana-plugin-plugins-embeddable-public.rangeselectcontext.data.md) + +## RangeSelectContext.data property + +Signature: + +```typescript +data: { + table: KibanaDatatable; + column: number; + range: number[]; + timeFieldName?: string; + }; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.rangeselectcontext.embeddable.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.rangeselectcontext.embeddable.md new file mode 100644 index 0000000000000..a6c9f0f7e4253 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.rangeselectcontext.embeddable.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [RangeSelectContext](./kibana-plugin-plugins-embeddable-public.rangeselectcontext.md) > [embeddable](./kibana-plugin-plugins-embeddable-public.rangeselectcontext.embeddable.md) + +## RangeSelectContext.embeddable property + +Signature: + +```typescript +embeddable?: T; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.rangeselectcontext.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.rangeselectcontext.md new file mode 100644 index 0000000000000..0f92ed86301da --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.rangeselectcontext.md @@ -0,0 +1,19 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [RangeSelectContext](./kibana-plugin-plugins-embeddable-public.rangeselectcontext.md) + +## RangeSelectContext interface + +Signature: + +```typescript +export interface RangeSelectContext +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [data](./kibana-plugin-plugins-embeddable-public.rangeselectcontext.data.md) | {
table: KibanaDatatable;
column: number;
range: number[];
timeFieldName?: string;
} | | +| [embeddable](./kibana-plugin-plugins-embeddable-public.rangeselectcontext.embeddable.md) | T | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.referenceorvalueembeddable.getinputasreftype.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.referenceorvalueembeddable.getinputasreftype.md new file mode 100644 index 0000000000000..559787c75ab66 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.referenceorvalueembeddable.getinputasreftype.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [ReferenceOrValueEmbeddable](./kibana-plugin-plugins-embeddable-public.referenceorvalueembeddable.md) > [getInputAsRefType](./kibana-plugin-plugins-embeddable-public.referenceorvalueembeddable.getinputasreftype.md) + +## ReferenceOrValueEmbeddable.getInputAsRefType property + +Gets the embeddable's current input as its Reference type + +Signature: + +```typescript +getInputAsRefType: () => Promise; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.referenceorvalueembeddable.getinputasvaluetype.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.referenceorvalueembeddable.getinputasvaluetype.md new file mode 100644 index 0000000000000..f9cd23b97858a --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.referenceorvalueembeddable.getinputasvaluetype.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [ReferenceOrValueEmbeddable](./kibana-plugin-plugins-embeddable-public.referenceorvalueembeddable.md) > [getInputAsValueType](./kibana-plugin-plugins-embeddable-public.referenceorvalueembeddable.getinputasvaluetype.md) + +## ReferenceOrValueEmbeddable.getInputAsValueType property + +Gets the embeddable's current input as its Value type + +Signature: + +```typescript +getInputAsValueType: () => Promise; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.referenceorvalueembeddable.inputisreftype.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.referenceorvalueembeddable.inputisreftype.md new file mode 100644 index 0000000000000..9de0447769397 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.referenceorvalueembeddable.inputisreftype.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [ReferenceOrValueEmbeddable](./kibana-plugin-plugins-embeddable-public.referenceorvalueembeddable.md) > [inputIsRefType](./kibana-plugin-plugins-embeddable-public.referenceorvalueembeddable.inputisreftype.md) + +## ReferenceOrValueEmbeddable.inputIsRefType property + +determines whether the input is by value or by reference. + +Signature: + +```typescript +inputIsRefType: (input: ValTypeInput | RefTypeInput) => input is RefTypeInput; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.referenceorvalueembeddable.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.referenceorvalueembeddable.md new file mode 100644 index 0000000000000..47d6d8a0772d8 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.referenceorvalueembeddable.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [ReferenceOrValueEmbeddable](./kibana-plugin-plugins-embeddable-public.referenceorvalueembeddable.md) + +## ReferenceOrValueEmbeddable interface + +Any embeddable that implements this interface will be able to use input that is either by reference (backed by a saved object) OR by value, (provided by the container). + +Signature: + +```typescript +export interface ReferenceOrValueEmbeddable +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [getInputAsRefType](./kibana-plugin-plugins-embeddable-public.referenceorvalueembeddable.getinputasreftype.md) | () => Promise<RefTypeInput> | Gets the embeddable's current input as its Reference type | +| [getInputAsValueType](./kibana-plugin-plugins-embeddable-public.referenceorvalueembeddable.getinputasvaluetype.md) | () => Promise<ValTypeInput> | Gets the embeddable's current input as its Value type | +| [inputIsRefType](./kibana-plugin-plugins-embeddable-public.referenceorvalueembeddable.inputisreftype.md) | (input: ValTypeInput | RefTypeInput) => input is RefTypeInput | determines whether the input is by value or by reference. | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.savedobjectembeddableinput.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.savedobjectembeddableinput.md new file mode 100644 index 0000000000000..ae0df9ec01ba1 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.savedobjectembeddableinput.md @@ -0,0 +1,18 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [SavedObjectEmbeddableInput](./kibana-plugin-plugins-embeddable-public.savedobjectembeddableinput.md) + +## SavedObjectEmbeddableInput interface + +Signature: + +```typescript +export interface SavedObjectEmbeddableInput extends EmbeddableInput +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [savedObjectId](./kibana-plugin-plugins-embeddable-public.savedobjectembeddableinput.savedobjectid.md) | string | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.savedobjectembeddableinput.savedobjectid.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.savedobjectembeddableinput.savedobjectid.md new file mode 100644 index 0000000000000..d8cb3bbda9d01 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.savedobjectembeddableinput.savedobjectid.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [SavedObjectEmbeddableInput](./kibana-plugin-plugins-embeddable-public.savedobjectembeddableinput.md) > [savedObjectId](./kibana-plugin-plugins-embeddable-public.savedobjectembeddableinput.savedobjectid.md) + +## SavedObjectEmbeddableInput.savedObjectId property + +Signature: + +```typescript +savedObjectId: string; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.valueclickcontext.data.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.valueclickcontext.data.md new file mode 100644 index 0000000000000..92c33affc47a9 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.valueclickcontext.data.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [ValueClickContext](./kibana-plugin-plugins-embeddable-public.valueclickcontext.md) > [data](./kibana-plugin-plugins-embeddable-public.valueclickcontext.data.md) + +## ValueClickContext.data property + +Signature: + +```typescript +data: { + data: Array<{ + table: Pick; + column: number; + row: number; + value: any; + }>; + timeFieldName?: string; + negate?: boolean; + }; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.valueclickcontext.embeddable.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.valueclickcontext.embeddable.md new file mode 100644 index 0000000000000..38adee9346945 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.valueclickcontext.embeddable.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [ValueClickContext](./kibana-plugin-plugins-embeddable-public.valueclickcontext.md) > [embeddable](./kibana-plugin-plugins-embeddable-public.valueclickcontext.embeddable.md) + +## ValueClickContext.embeddable property + +Signature: + +```typescript +embeddable?: T; +``` diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.valueclickcontext.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.valueclickcontext.md new file mode 100644 index 0000000000000..13133095956c6 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.valueclickcontext.md @@ -0,0 +1,19 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [ValueClickContext](./kibana-plugin-plugins-embeddable-public.valueclickcontext.md) + +## ValueClickContext interface + +Signature: + +```typescript +export interface ValueClickContext +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [data](./kibana-plugin-plugins-embeddable-public.valueclickcontext.data.md) | {
data: Array<{
table: Pick<KibanaDatatable, 'rows' | 'columns'>;
column: number;
row: number;
value: any;
}>;
timeFieldName?: string;
negate?: boolean;
} | | +| [embeddable](./kibana-plugin-plugins-embeddable-public.valueclickcontext.embeddable.md) | T | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.viewmode.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.viewmode.md new file mode 100644 index 0000000000000..f47169951018d --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.viewmode.md @@ -0,0 +1,19 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [ViewMode](./kibana-plugin-plugins-embeddable-public.viewmode.md) + +## ViewMode enum + +Signature: + +```typescript +export declare enum ViewMode +``` + +## Enumeration Members + +| Member | Value | Description | +| --- | --- | --- | +| EDIT | "edit" | | +| VIEW | "view" | | + diff --git a/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.withembeddablesubscription.md b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.withembeddablesubscription.md new file mode 100644 index 0000000000000..a815292f3a0c3 --- /dev/null +++ b/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.withembeddablesubscription.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [withEmbeddableSubscription](./kibana-plugin-plugins-embeddable-public.withembeddablesubscription.md) + +## withEmbeddableSubscription variable + +Signature: + +```typescript +withEmbeddableSubscription: = IEmbeddable, ExtraProps = {}>(WrappedComponent: React.ComponentType<{ + input: I; + output: O; + embeddable: E; +} & ExtraProps>) => React.ComponentType<{ + embeddable: E; +} & ExtraProps> +``` diff --git a/docs/development/plugins/embeddable/server/index.md b/docs/development/plugins/embeddable/server/index.md new file mode 100644 index 0000000000000..3c4d4ce3aed36 --- /dev/null +++ b/docs/development/plugins/embeddable/server/index.md @@ -0,0 +1,12 @@ + + +[Home](./index.md) + +## API Reference + +## Packages + +| Package | Description | +| --- | --- | +| [kibana-plugin-plugins-embeddable-server](./kibana-plugin-plugins-embeddable-server.md) | | + diff --git a/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.embeddableregistrydefinition.id.md b/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.embeddableregistrydefinition.id.md new file mode 100644 index 0000000000000..ce3e532fcaa3b --- /dev/null +++ b/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.embeddableregistrydefinition.id.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-server](./kibana-plugin-plugins-embeddable-server.md) > [EmbeddableRegistryDefinition](./kibana-plugin-plugins-embeddable-server.embeddableregistrydefinition.md) > [id](./kibana-plugin-plugins-embeddable-server.embeddableregistrydefinition.id.md) + +## EmbeddableRegistryDefinition.id property + +Signature: + +```typescript +id: string; +``` diff --git a/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.embeddableregistrydefinition.md b/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.embeddableregistrydefinition.md new file mode 100644 index 0000000000000..de46d91d90c65 --- /dev/null +++ b/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.embeddableregistrydefinition.md @@ -0,0 +1,18 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-server](./kibana-plugin-plugins-embeddable-server.md) > [EmbeddableRegistryDefinition](./kibana-plugin-plugins-embeddable-server.embeddableregistrydefinition.md) + +## EmbeddableRegistryDefinition interface + +Signature: + +```typescript +export interface EmbeddableRegistryDefinition

extends PersistableStateDefinition

+``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [id](./kibana-plugin-plugins-embeddable-server.embeddableregistrydefinition.id.md) | string | | + diff --git a/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.embeddablesetup.md b/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.embeddablesetup.md new file mode 100644 index 0000000000000..59ca4a2bbca75 --- /dev/null +++ b/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.embeddablesetup.md @@ -0,0 +1,19 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-server](./kibana-plugin-plugins-embeddable-server.md) > [EmbeddableSetup](./kibana-plugin-plugins-embeddable-server.embeddablesetup.md) + +## EmbeddableSetup interface + +Signature: + +```typescript +export interface EmbeddableSetup +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [registerEmbeddableFactory](./kibana-plugin-plugins-embeddable-server.embeddablesetup.registerembeddablefactory.md) | (factory: EmbeddableRegistryDefinition) => void | | +| [registerEnhancement](./kibana-plugin-plugins-embeddable-server.embeddablesetup.registerenhancement.md) | (enhancement: EnhancementRegistryDefinition) => void | | + diff --git a/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.embeddablesetup.registerembeddablefactory.md b/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.embeddablesetup.registerembeddablefactory.md new file mode 100644 index 0000000000000..442941ce86950 --- /dev/null +++ b/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.embeddablesetup.registerembeddablefactory.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-server](./kibana-plugin-plugins-embeddable-server.md) > [EmbeddableSetup](./kibana-plugin-plugins-embeddable-server.embeddablesetup.md) > [registerEmbeddableFactory](./kibana-plugin-plugins-embeddable-server.embeddablesetup.registerembeddablefactory.md) + +## EmbeddableSetup.registerEmbeddableFactory property + +Signature: + +```typescript +registerEmbeddableFactory: (factory: EmbeddableRegistryDefinition) => void; +``` diff --git a/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.embeddablesetup.registerenhancement.md b/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.embeddablesetup.registerenhancement.md new file mode 100644 index 0000000000000..9ea2846d0300b --- /dev/null +++ b/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.embeddablesetup.registerenhancement.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-server](./kibana-plugin-plugins-embeddable-server.md) > [EmbeddableSetup](./kibana-plugin-plugins-embeddable-server.embeddablesetup.md) > [registerEnhancement](./kibana-plugin-plugins-embeddable-server.embeddablesetup.registerenhancement.md) + +## EmbeddableSetup.registerEnhancement property + +Signature: + +```typescript +registerEnhancement: (enhancement: EnhancementRegistryDefinition) => void; +``` diff --git a/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.enhancementregistrydefinition.id.md b/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.enhancementregistrydefinition.id.md new file mode 100644 index 0000000000000..a93c691246872 --- /dev/null +++ b/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.enhancementregistrydefinition.id.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-server](./kibana-plugin-plugins-embeddable-server.md) > [EnhancementRegistryDefinition](./kibana-plugin-plugins-embeddable-server.enhancementregistrydefinition.md) > [id](./kibana-plugin-plugins-embeddable-server.enhancementregistrydefinition.id.md) + +## EnhancementRegistryDefinition.id property + +Signature: + +```typescript +id: string; +``` diff --git a/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.enhancementregistrydefinition.md b/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.enhancementregistrydefinition.md new file mode 100644 index 0000000000000..09ff48a92158d --- /dev/null +++ b/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.enhancementregistrydefinition.md @@ -0,0 +1,18 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-server](./kibana-plugin-plugins-embeddable-server.md) > [EnhancementRegistryDefinition](./kibana-plugin-plugins-embeddable-server.enhancementregistrydefinition.md) + +## EnhancementRegistryDefinition interface + +Signature: + +```typescript +export interface EnhancementRegistryDefinition

extends PersistableStateDefinition

Welcome to the Alerting plugin example

- - - - - - - -

Documentation links

-
-
-
- - -

Plugin Structure

-

- This example solution has both `server` and a `public` plugins. The `server` handles - registration of example the AlertTypes, while the `public` handles creation of, and - navigation for, these alert types. -

-
- - -
-
- -); diff --git a/examples/alerting_example/public/components/page.tsx b/examples/alerting_example/public/components/page.tsx deleted file mode 100644 index 99076c7ddcedf..0000000000000 --- a/examples/alerting_example/public/components/page.tsx +++ /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 React from 'react'; -import { withRouter, RouteComponentProps } from 'react-router-dom'; - -import { - EuiPageBody, - EuiPageContent, - EuiPageContentBody, - EuiPageHeader, - EuiPageHeaderSection, - EuiTitle, - EuiBreadcrumbs, - EuiSpacer, -} from '@elastic/eui'; - -type PageProps = RouteComponentProps & { - title: string; - children: React.ReactNode; - crumb?: string; - isHome?: boolean; -}; - -export const Page = withRouter(({ title, crumb, children, isHome = false, history }: PageProps) => { - const breadcrumbs: Array<{ - text: string; - onClick?: () => void; - }> = [ - { - text: crumb ?? title, - }, - ]; - if (!isHome) { - breadcrumbs.splice(0, 0, { - text: 'Home', - onClick: () => { - history.push(`/`); - }, - }); - } - return ( - - - - -

{title}

-
-
-
- - - - {children} - -
- ); -}); diff --git a/examples/alerting_example/public/index.ts b/examples/alerting_example/public/index.ts deleted file mode 100644 index 4a2bfc79903c3..0000000000000 --- a/examples/alerting_example/public/index.ts +++ /dev/null @@ -1,22 +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 { AlertingExamplePlugin } from './plugin'; - -export const plugin = () => new AlertingExamplePlugin(); diff --git a/examples/alerting_example/public/plugin.tsx b/examples/alerting_example/public/plugin.tsx deleted file mode 100644 index 3f972fa9fe2ee..0000000000000 --- a/examples/alerting_example/public/plugin.tsx +++ /dev/null @@ -1,86 +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 { Plugin, CoreSetup, AppMountParameters, AppNavLinkStatus } from '../../../src/core/public'; -import { PluginSetupContract as AlertingSetup } from '../../../x-pack/plugins/alerts/public'; -import { ChartsPluginStart } from '../../../src/plugins/charts/public'; -import { TriggersAndActionsUIPublicPluginSetup } from '../../../x-pack/plugins/triggers_actions_ui/public'; -import { DataPublicPluginStart } from '../../../src/plugins/data/public'; -import { getAlertType as getAlwaysFiringAlertType } from './alert_types/always_firing'; -import { getAlertType as getPeopleInSpaceAlertType } from './alert_types/astros'; -import { registerNavigation } from './alert_types'; -import { DeveloperExamplesSetup } from '../../developer_examples/public'; - -export type Setup = void; -export type Start = void; - -export interface AlertingExamplePublicSetupDeps { - alerts: AlertingSetup; - triggers_actions_ui: TriggersAndActionsUIPublicPluginSetup; - developerExamples: DeveloperExamplesSetup; -} - -export interface AlertingExamplePublicStartDeps { - alerts: AlertingSetup; - triggers_actions_ui: TriggersAndActionsUIPublicPluginSetup; - charts: ChartsPluginStart; - data: DataPublicPluginStart; -} - -export class AlertingExamplePlugin implements Plugin { - public setup( - core: CoreSetup, - // eslint-disable-next-line @typescript-eslint/naming-convention - { alerts, triggers_actions_ui, developerExamples }: AlertingExamplePublicSetupDeps - ) { - core.application.register({ - id: 'AlertingExample', - title: 'Alerting Example', - navLinkStatus: AppNavLinkStatus.hidden, - async mount(params: AppMountParameters) { - const [coreStart, depsStart] = await core.getStartServices(); - const { renderApp } = await import('./application'); - return renderApp(coreStart, depsStart, params); - }, - }); - - triggers_actions_ui.alertTypeRegistry.register(getAlwaysFiringAlertType()); - triggers_actions_ui.alertTypeRegistry.register(getPeopleInSpaceAlertType()); - - registerNavigation(alerts); - - developerExamples.register({ - appId: 'AlertingExample', - title: 'Alerting', - description: `This alerting example walks you through how to set up a new alert.`, - links: [ - { - label: 'README', - href: 'https://github.com/elastic/kibana/tree/master/x-pack/plugins/alerting', - iconType: 'logoGithub', - size: 's', - target: '_blank', - }, - ], - }); - } - - public start() {} - public stop() {} -} diff --git a/examples/alerting_example/server/alert_types/always_firing.ts b/examples/alerting_example/server/alert_types/always_firing.ts deleted file mode 100644 index b89e5da089336..0000000000000 --- a/examples/alerting_example/server/alert_types/always_firing.ts +++ /dev/null @@ -1,47 +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 uuid from 'uuid'; -import { range } from 'lodash'; -import { AlertType } from '../../../../x-pack/plugins/alerts/server'; -import { DEFAULT_INSTANCES_TO_GENERATE, ALERTING_EXAMPLE_APP_ID } from '../../common/constants'; - -export const alertType: AlertType = { - id: 'example.always-firing', - name: 'Always firing', - actionGroups: [{ id: 'default', name: 'default' }], - defaultActionGroupId: 'default', - async executor({ services, params: { instances = DEFAULT_INSTANCES_TO_GENERATE }, state }) { - const count = (state.count ?? 0) + 1; - - range(instances) - .map(() => ({ id: uuid.v4() })) - .forEach((instance: { id: string }) => { - services - .alertInstanceFactory(instance.id) - .replaceState({ triggerdOnCycle: count }) - .scheduleActions('default'); - }); - - return { - count, - }; - }, - producer: ALERTING_EXAMPLE_APP_ID, -}; diff --git a/examples/alerting_example/server/alert_types/astros.ts b/examples/alerting_example/server/alert_types/astros.ts deleted file mode 100644 index 1ccf8af4ce623..0000000000000 --- a/examples/alerting_example/server/alert_types/astros.ts +++ /dev/null @@ -1,80 +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 axios from 'axios'; -import { AlertType } from '../../../../x-pack/plugins/alerts/server'; -import { Operator, Craft, ALERTING_EXAMPLE_APP_ID } from '../../common/constants'; - -interface PeopleInSpace { - people: Array<{ - craft: string; - name: string; - }>; - number: number; -} - -function getOperator(op: string) { - switch (op) { - case Operator.AreAbove: - return (left: number, right: number) => left > right; - case Operator.AreBelow: - return (left: number, right: number) => left < right; - case Operator.AreExactly: - return (left: number, right: number) => left === right; - default: - return () => { - throw new Error( - `Invalid Operator "${op}" [${Operator.AreAbove},${Operator.AreBelow},${Operator.AreExactly}]` - ); - }; - } -} - -function getCraftFilter(craft: string) { - return (person: { craft: string; name: string }) => - craft === Craft.OuterSpace ? true : craft === person.craft; -} - -export const alertType: AlertType = { - id: 'example.people-in-space', - name: 'People In Space Right Now', - actionGroups: [{ id: 'default', name: 'default' }], - defaultActionGroupId: 'default', - async executor({ services, params }) { - const { outerSpaceCapacity, craft: craftToTriggerBy, op } = params; - - const response = await axios.get('http://api.open-notify.org/astros.json'); - const { - data: { number: peopleInSpace, people = [] }, - } = response; - - const peopleInCraft = people.filter(getCraftFilter(craftToTriggerBy)); - - if (getOperator(op)(peopleInCraft.length, outerSpaceCapacity)) { - peopleInCraft.forEach(({ craft, name }) => { - services.alertInstanceFactory(name).replaceState({ craft }).scheduleActions('default'); - }); - } - - return { - peopleInSpace, - }; - }, - producer: ALERTING_EXAMPLE_APP_ID, -}; diff --git a/examples/alerting_example/server/index.ts b/examples/alerting_example/server/index.ts deleted file mode 100644 index 32e9b181ebb54..0000000000000 --- a/examples/alerting_example/server/index.ts +++ /dev/null @@ -1,23 +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 { PluginInitializer } from 'kibana/server'; -import { AlertingExamplePlugin } from './plugin'; - -export const plugin: PluginInitializer = () => new AlertingExamplePlugin(); diff --git a/examples/alerting_example/server/plugin.ts b/examples/alerting_example/server/plugin.ts deleted file mode 100644 index 4141b48ffeeaf..0000000000000 --- a/examples/alerting_example/server/plugin.ts +++ /dev/null @@ -1,86 +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 { Plugin, CoreSetup } from 'kibana/server'; -import { i18n } from '@kbn/i18n'; -import { DEFAULT_APP_CATEGORIES } from '../../../src/core/server'; -import { PluginSetupContract as AlertingSetup } from '../../../x-pack/plugins/alerts/server'; -import { PluginSetupContract as FeaturesPluginSetup } from '../../../x-pack/plugins/features/server'; - -import { alertType as alwaysFiringAlert } from './alert_types/always_firing'; -import { alertType as peopleInSpaceAlert } from './alert_types/astros'; -import { INDEX_THRESHOLD_ID } from '../../../x-pack/plugins/alerting_builtins/server'; -import { ALERTING_EXAMPLE_APP_ID } from '../common/constants'; - -// this plugin's dependendencies -export interface AlertingExampleDeps { - alerts: AlertingSetup; - features: FeaturesPluginSetup; -} - -export class AlertingExamplePlugin implements Plugin { - public setup(core: CoreSetup, { alerts, features }: AlertingExampleDeps) { - alerts.registerType(alwaysFiringAlert); - alerts.registerType(peopleInSpaceAlert); - - features.registerKibanaFeature({ - id: ALERTING_EXAMPLE_APP_ID, - name: i18n.translate('alertsExample.featureRegistry.alertsExampleFeatureName', { - defaultMessage: 'Alerts Example', - }), - app: [], - management: { - insightsAndAlerting: ['triggersActions'], - }, - category: DEFAULT_APP_CATEGORIES.management, - alerting: [alwaysFiringAlert.id, peopleInSpaceAlert.id, INDEX_THRESHOLD_ID], - privileges: { - all: { - alerting: { - all: [alwaysFiringAlert.id, peopleInSpaceAlert.id, INDEX_THRESHOLD_ID], - }, - savedObject: { - all: [], - read: [], - }, - management: { - insightsAndAlerting: ['triggersActions'], - }, - ui: [], - }, - read: { - alerting: { - read: [alwaysFiringAlert.id, peopleInSpaceAlert.id, INDEX_THRESHOLD_ID], - }, - savedObject: { - all: [], - read: [], - }, - management: { - insightsAndAlerting: ['triggersActions'], - }, - ui: [], - }, - }, - }); - } - - public start() {} - public stop() {} -} diff --git a/examples/alerting_example/tsconfig.json b/examples/alerting_example/tsconfig.json deleted file mode 100644 index 214e4b78a9a70..0000000000000 --- a/examples/alerting_example/tsconfig.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "outDir": "./target" - }, - "include": [ - "index.ts", - "public/**/*.ts", - "public/**/*.tsx", - "server/**/*.ts", - "common/**/*.ts", - "../../typings/**/*", - ], - "exclude": [], - "references": [ - { "path": "../../src/core/tsconfig.json" } - ] -} diff --git a/examples/bfetch_explorer/tsconfig.json b/examples/bfetch_explorer/tsconfig.json index 86b35c5e4943f..253fdd9ee6c89 100644 --- a/examples/bfetch_explorer/tsconfig.json +++ b/examples/bfetch_explorer/tsconfig.json @@ -13,6 +13,7 @@ ], "exclude": [], "references": [ - { "path": "../../src/core/tsconfig.json" } + { "path": "../../src/core/tsconfig.json" }, + { "path": "../../src/plugins/kibana_react/tsconfig.json" }, ] } diff --git a/examples/embeddable_examples/public/book/book_embeddable.tsx b/examples/embeddable_examples/public/book/book_embeddable.tsx index 48b81c27e8b8d..65ec22a2759e2 100644 --- a/examples/embeddable_examples/public/book/book_embeddable.tsx +++ b/examples/embeddable_examples/public/book/book_embeddable.tsx @@ -89,6 +89,7 @@ export class BookEmbeddable } else { this.updateOutput({ attributes: this.attributes, + defaultTitle: this.attributes.title, hasMatch: getHasMatch(this.input.search, this.attributes), }); } @@ -125,6 +126,7 @@ export class BookEmbeddable this.updateOutput({ attributes: this.attributes, + defaultTitle: this.attributes.title, hasMatch: getHasMatch(this.input.search, this.attributes), }); } diff --git a/examples/embeddable_examples/tsconfig.json b/examples/embeddable_examples/tsconfig.json index 78098339c16f5..a922c6defcd4c 100644 --- a/examples/embeddable_examples/tsconfig.json +++ b/examples/embeddable_examples/tsconfig.json @@ -14,6 +14,7 @@ ], "exclude": [], "references": [ - { "path": "../../src/core/tsconfig.json" } + { "path": "../../src/core/tsconfig.json" }, + { "path": "../../src/plugins/kibana_react/tsconfig.json" }, ] } diff --git a/examples/state_containers_examples/tsconfig.json b/examples/state_containers_examples/tsconfig.json index 6cfb9f9dc2321..442fa08022dc4 100644 --- a/examples/state_containers_examples/tsconfig.json +++ b/examples/state_containers_examples/tsconfig.json @@ -14,6 +14,8 @@ ], "exclude": [], "references": [ - { "path": "../../src/core/tsconfig.json" } + { "path": "../../src/core/tsconfig.json" }, + { "path": "../../src/plugins/kibana_utils/tsconfig.json" }, + { "path": "../../src/plugins/kibana_react/tsconfig.json" }, ] } diff --git a/examples/ui_action_examples/tsconfig.json b/examples/ui_action_examples/tsconfig.json index 86b35c5e4943f..253fdd9ee6c89 100644 --- a/examples/ui_action_examples/tsconfig.json +++ b/examples/ui_action_examples/tsconfig.json @@ -13,6 +13,7 @@ ], "exclude": [], "references": [ - { "path": "../../src/core/tsconfig.json" } + { "path": "../../src/core/tsconfig.json" }, + { "path": "../../src/plugins/kibana_react/tsconfig.json" }, ] } diff --git a/examples/ui_actions_explorer/tsconfig.json b/examples/ui_actions_explorer/tsconfig.json index 782b9cd57fa7b..b4449819b25a6 100644 --- a/examples/ui_actions_explorer/tsconfig.json +++ b/examples/ui_actions_explorer/tsconfig.json @@ -12,6 +12,7 @@ ], "exclude": [], "references": [ - { "path": "../../src/core/tsconfig.json" } + { "path": "../../src/core/tsconfig.json" }, + { "path": "../../src/plugins/kibana_react/tsconfig.json" }, ] } diff --git a/package.json b/package.json index 505fac1df935e..b2252e2bd264b 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "kbn:watch": "node scripts/kibana --dev --logging.json=false", "build:types": "rm -rf ./target/types && tsc --p tsconfig.types.json", "docs:acceptApiChanges": "node --max-old-space-size=6144 scripts/check_published_api_changes.js --accept", - "kbn:bootstrap": "node scripts/build_ts_refs && node scripts/register_git_hook", + "kbn:bootstrap": "node scripts/build_ts_refs --project tsconfig.refs.json && node scripts/register_git_hook", "spec_to_console": "node scripts/spec_to_console", "backport-skip-ci": "backport --prDescription \"[skip-ci]\"", "storybook": "node scripts/storybook", @@ -115,8 +115,6 @@ ] }, "dependencies": { - "@babel/core": "^7.11.1", - "@babel/register": "^7.10.5", "@elastic/datemath": "5.0.3", "@elastic/elasticsearch": "7.9.1", "@elastic/eui": "29.0.0", @@ -128,7 +126,6 @@ "@hapi/wreck": "^15.0.2", "@kbn/analytics": "1.0.0", "@kbn/apm-config-loader": "1.0.0", - "@kbn/babel-preset": "1.0.0", "@kbn/config": "1.0.0", "@kbn/config-schema": "1.0.0", "@kbn/i18n": "1.0.0", @@ -151,12 +148,12 @@ "angular-sanitize": "^1.8.0", "bluebird": "3.5.5", "boom": "^7.2.0", - "chalk": "^2.4.2", + "chalk": "^4.1.0", "check-disk-space": "^2.1.0", - "chokidar": "3.2.1", + "chokidar": "^3.4.2", "color": "1.0.3", - "commander": "3.0.2", - "core-js": "^3.6.4", + "commander": "^3.0.2", + "core-js": "^3.6.5", "cypress-promise": "^1.1.0", "deep-freeze-strict": "^1.1.1", "del": "^5.1.0", @@ -174,22 +171,23 @@ "handlebars": "4.7.6", "hapi": "^17.5.3", "hapi-auth-cookie": "^9.0.0", + "hjson": "3.2.1", "hoek": "^5.0.4", "http-proxy-agent": "^2.1.0", "https-proxy-agent": "^5.0.0", "inert": "^5.1.0", "inline-style": "^2.0.0", "joi": "^13.5.2", - "js-yaml": "3.13.1", + "js-yaml": "^3.14.0", "json-stable-stringify": "^1.0.1", "json-stringify-safe": "5.0.1", "lodash": "^4.17.20", - "lru-cache": "4.1.5", + "lru-cache": "^4.1.5", "minimatch": "^3.0.4", "moment": "^2.24.0", "moment-timezone": "^0.5.27", - "mustache": "2.3.2", - "node-fetch": "2.6.1", + "mustache": "^2.3.2", + "node-fetch": "^2.6.1", "node-forge": "^0.10.0", "opn": "^5.5.0", "oppsy": "^2.0.0", @@ -212,7 +210,8 @@ "rison-node": "1.0.2", "rxjs": "^6.5.5", "seedrandom": "^3.0.5", - "semver": "^5.5.0", + "semver": "^5.7.0", + "source-map-support": "^0.5.19", "style-it": "^2.1.3", "symbol-observable": "^1.2.0", "tar": "4.4.13", @@ -223,13 +222,15 @@ "uuid": "3.3.2", "vision": "^5.3.3", "whatwg-fetch": "^3.0.0", - "yauzl": "2.10.0" + "yauzl": "^2.10.0" }, "devDependencies": { + "@babel/core": "^7.11.6", "@babel/parser": "^7.11.2", + "@babel/register": "^7.10.5", "@babel/types": "^7.11.0", - "@elastic/apm-rum": "^5.6.0", - "@elastic/charts": "21.1.2", + "@elastic/apm-rum": "^5.6.1", + "@elastic/charts": "23.0.0", "@elastic/ems-client": "7.10.0", "@elastic/eslint-config-kibana": "0.15.0", "@elastic/eslint-plugin-eui": "0.0.2", @@ -237,6 +238,7 @@ "@elastic/github-checks-reporter": "0.0.20b3", "@elastic/makelogs": "^6.0.0", "@elastic/ui-ace": "0.2.3", + "@kbn/babel-preset": "1.0.0", "@kbn/dev-utils": "1.0.0", "@kbn/es": "1.0.0", "@kbn/es-archiver": "1.0.0", @@ -260,7 +262,7 @@ "@types/angular": "^1.6.56", "@types/angular-mocks": "^1.7.0", "@types/archiver": "^3.1.0", - "@types/babel__core": "^7.1.2", + "@types/babel__core": "^7.1.10", "@types/bluebird": "^3.1.1", "@types/boom": "^7.2.0", "@types/chance": "^1.0.0", @@ -279,7 +281,7 @@ "@types/flot": "^0.0.31", "@types/getopts": "^2.0.1", "@types/getos": "^3.0.0", - "@types/glob": "^7.1.1", + "@types/glob": "^7.1.2", "@types/globby": "^8.0.0", "@types/graphql": "^0.13.2", "@types/h2o2": "^8.1.1", @@ -290,7 +292,7 @@ "@types/hjson": "^2.4.2", "@types/hoek": "^4.1.3", "@types/inert": "^5.1.2", - "@types/jest": "^25.2.3", + "@types/jest": "^26.0.14", "@types/jest-when": "^2.7.1", "@types/joi": "^13.4.2", "@types/jquery": "^3.3.31", @@ -312,7 +314,7 @@ "@types/normalize-path": "^3.0.0", "@types/opn": "^5.1.0", "@types/pegjs": "^0.10.1", - "@types/pngjs": "^3.3.2", + "@types/pngjs": "^3.4.0", "@types/podium": "^1.0.0", "@types/prop-types": "^15.7.3", "@types/reach__router": "^1.2.6", @@ -330,17 +332,20 @@ "@types/selenium-webdriver": "^4.0.9", "@types/semver": "^5.5.0", "@types/sinon": "^7.0.13", - "@types/strip-ansi": "^3.0.0", + "@types/strip-ansi": "^5.2.1", "@types/styled-components": "^5.1.0", "@types/supertest": "^2.0.5", "@types/supertest-as-promised": "^2.0.38", + "@types/tapable": "^1.0.6", "@types/tar": "^4.0.3", - "@types/testing-library__jest-dom": "^5.9.2", + "@types/testing-library__jest-dom": "^5.9.3", "@types/testing-library__react-hooks": "^3.4.0", "@types/type-detect": "^4.0.1", "@types/uuid": "^3.4.4", "@types/vinyl": "^2.0.4", "@types/vinyl-fs": "^2.4.11", + "@types/webpack": "^4.41.3", + "@types/webpack-env": "^1.15.2", "@types/zen-observable": "^0.8.0", "@typescript-eslint/eslint-plugin": "^3.10.0", "@typescript-eslint/parser": "^3.10.0", @@ -350,9 +355,9 @@ "angular-route": "^1.8.0", "angular-sortable-view": "^0.0.17", "archiver": "^3.1.1", - "axe-core": "^3.4.1", + "axe-core": "^4.0.2", "babel-eslint": "^10.0.3", - "babel-jest": "^25.5.1", + "babel-jest": "^26.3.0", "babel-plugin-istanbul": "^6.0.0", "backport": "5.6.0", "brace": "0.11.1", @@ -378,7 +383,7 @@ "eslint-plugin-cypress": "^2.8.1", "eslint-plugin-eslint-comments": "^3.2.0", "eslint-plugin-import": "^2.19.1", - "eslint-plugin-jest": "^23.10.0", + "eslint-plugin-jest": "^24.0.2", "eslint-plugin-jsx-a11y": "^6.2.3", "eslint-plugin-mocha": "^6.2.2", "eslint-plugin-no-unsanitized": "^3.0.2", @@ -393,7 +398,7 @@ "fetch-mock": "^7.3.9", "fp-ts": "^2.3.1", "geckodriver": "^1.20.0", - "getopts": "^2.2.4", + "getopts": "^2.2.5", "grunt": "1.0.4", "grunt-available-tasks": "^0.6.3", "grunt-cli": "^1.2.0", @@ -404,14 +409,13 @@ "gulp-sourcemaps": "2.6.5", "has-ansi": "^3.0.0", "history": "^4.9.0", - "hjson": "3.2.1", "iedriver": "^3.14.2", "immer": "^1.5.0", "intl-messageformat-parser": "^1.4.0", - "jest": "^25.5.4", + "jest": "^26.4.2", "jest-canvas-mock": "^2.2.0", - "jest-circus": "^25.5.4", - "jest-cli": "^25.5.4", + "jest-circus": "^26.4.2", + "jest-cli": "^26.4.2", "jest-environment-jsdom-thirteen": "^1.0.1", "jest-raw-loader": "^1.0.1", "jest-when": "^2.7.2", @@ -439,7 +443,7 @@ "multistream": "^2.1.1", "murmurhash3js": "3.0.1", "mutation-observer": "^1.0.3", - "ngreact": "0.5.1", + "ngreact": "^0.5.1", "nock": "12.0.3", "normalize-path": "^3.0.0", "nyc": "^15.0.1", @@ -467,18 +471,18 @@ "selenium-webdriver": "^4.0.0-alpha.7", "simple-git": "1.116.0", "sinon": "^7.4.2", - "strip-ansi": "^3.0.1", + "strip-ansi": "^6.0.0", "supertest": "^3.1.0", "supertest-as-promised": "^4.0.2", - "tape": "^4.13.0", + "tape": "^5.0.1", "topojson-client": "3.0.0", "tree-kill": "^1.2.2", "typescript": "4.0.2", "ui-select": "0.19.8", - "vega": "^5.13.0", - "vega-lite": "^4.13.1", - "vega-schema-url-parser": "^1.1.0", - "vega-tooltip": "^0.12.0", + "vega": "^5.17.0", + "vega-lite": "^4.16.8", + "vega-schema-url-parser": "^2.1.0", + "vega-tooltip": "^0.24.2", "vinyl-fs": "^3.0.3", "xml2js": "^0.4.22", "xmlbuilder": "13.0.2", diff --git a/packages/elastic-eslint-config-kibana/package.json b/packages/elastic-eslint-config-kibana/package.json index a4bb8d5449ee8..3f2c6e9edb261 100644 --- a/packages/elastic-eslint-config-kibana/package.json +++ b/packages/elastic-eslint-config-kibana/package.json @@ -24,7 +24,7 @@ "eslint-plugin-jsx-a11y": "^6.2.3", "eslint-plugin-eslint-comments": "^3.2.0", "eslint-plugin-import": "^2.19.1", - "eslint-plugin-jest": "^23.10.0", + "eslint-plugin-jest": "^24.0.2", "eslint-plugin-mocha": "^6.2.2", "eslint-plugin-no-unsanitized": "^3.0.2", "eslint-plugin-prefer-object-spread": "^1.2.1", diff --git a/packages/kbn-ace/README.md b/packages/kbn-ace/README.md index 54c422a72c6f8..c11d5cc2f24b8 100644 --- a/packages/kbn-ace/README.md +++ b/packages/kbn-ace/README.md @@ -1,5 +1,20 @@ # @kbn/ace -Contains all Kibana-specific brace related code. Excluding the code that still inside of Console because that code is only used inside of console at the moment. +This package contains the XJSON mode for brace. This is an extension of the `brace/mode/json` mode. -This package enables plugins to use this functionality and import it as needed -- behind an async import so that brace does not bloat the JS code needed for first page load of Kibana. +This package also contains an import of the entire brace editor which is used for creating the custom XJSON worker. + +## Note to plugins +_This code should not be eagerly loaded_. + +Make sure imports of this package are behind a lazy-load `import()` statement. + +Your plugin should already be loading application code this way in the `mount` function. + +## Deprecated + +This package is considered deprecated and will be removed in future. + +New and existing editor functionality should use Monaco. + +_Do not add new functionality to this package_. Build new functionality for Monaco and use it instead. diff --git a/packages/kbn-ace/package.json b/packages/kbn-ace/package.json index cf74d745f4cae..6f1cee764adf1 100644 --- a/packages/kbn-ace/package.json +++ b/packages/kbn-ace/package.json @@ -14,7 +14,7 @@ "devDependencies": { "@kbn/dev-utils": "1.0.0", "@kbn/babel-preset": "1.0.0", - "raw-loader": "3.1.0", + "raw-loader": "^3.1.0", "typescript": "4.0.2" } } diff --git a/packages/kbn-apm-config-loader/package.json b/packages/kbn-apm-config-loader/package.json index 1982ccdeda0ff..6865e9ec9bf66 100644 --- a/packages/kbn-apm-config-loader/package.json +++ b/packages/kbn-apm-config-loader/package.json @@ -13,11 +13,11 @@ "dependencies": { "@elastic/safer-lodash-set": "0.0.0", "@kbn/utils": "1.0.0", - "js-yaml": "3.13.1", + "js-yaml": "^3.14.0", "lodash": "^4.17.20" }, "devDependencies": { "typescript": "4.0.2", - "tsd": "^0.7.4" + "tsd": "^0.13.1" } } diff --git a/packages/kbn-babel-preset/node_preset.js b/packages/kbn-babel-preset/node_preset.js index ee06e2588b022..86817ed253e7c 100644 --- a/packages/kbn-babel-preset/node_preset.js +++ b/packages/kbn-babel-preset/node_preset.js @@ -18,23 +18,6 @@ */ module.exports = (_, options = {}) => { - const overrides = []; - if (!process.env.ALLOW_PERFORMANCE_HOOKS_IN_TASK_MANAGER) { - overrides.push({ - test: [/x-pack[\/\\]legacy[\/\\]plugins[\/\\]task_manager/], - plugins: [ - [ - require.resolve('babel-plugin-filter-imports'), - { - imports: { - perf_hooks: ['performance'], - }, - }, - ], - ], - }); - } - return { presets: [ [ @@ -66,14 +49,5 @@ module.exports = (_, options = {}) => { ], require('./common_preset'), ], - plugins: [ - [ - require.resolve('babel-plugin-transform-define'), - { - 'global.__BUILT_WITH_BABEL__': 'true', - }, - ], - ], - overrides, }; }; diff --git a/packages/kbn-babel-preset/package.json b/packages/kbn-babel-preset/package.json index d73294b4cf873..79d2fd8687dae 100644 --- a/packages/kbn-babel-preset/package.json +++ b/packages/kbn-babel-preset/package.json @@ -1,7 +1,7 @@ { "name": "@kbn/babel-preset", - "private": true, "version": "1.0.0", + "private": true, "license": "Apache-2.0", "dependencies": { "@babel/plugin-proposal-class-properties": "^7.10.4", @@ -13,10 +13,8 @@ "@babel/preset-react": "^7.10.4", "@babel/preset-typescript": "^7.10.4", "babel-plugin-add-module-exports": "^1.0.2", - "babel-plugin-filter-imports": "^3.0.0", "babel-plugin-styled-components": "^1.10.7", - "babel-plugin-transform-define": "^1.3.1", - "babel-plugin-transform-imports": "^2.0.0", + "babel-plugin-transform-react-remove-prop-types": "^0.4.24", "react-is": "^16.8.0", "styled-components": "^5.1.0" } diff --git a/packages/kbn-babel-preset/webpack_preset.js b/packages/kbn-babel-preset/webpack_preset.js index 97462a579e3c4..503b99d3c3e8a 100644 --- a/packages/kbn-babel-preset/webpack_preset.js +++ b/packages/kbn-babel-preset/webpack_preset.js @@ -40,24 +40,18 @@ module.exports = () => { }, ], ], - // NOTE: we can enable this by default for everything as soon as we only have one instance - // of lodash across the entire project. For now we are just enabling it for siem - // as they are extensively using the lodash v4 - overrides: [ - { - test: [/x-pack[\/\\]legacy[\/\\]plugins[\/\\]siem[\/\\]public/], + env: { + production: { plugins: [ [ - require.resolve('babel-plugin-transform-imports'), + require.resolve('babel-plugin-transform-react-remove-prop-types'), { - 'lodash/?(((\\w*)?/?)*)': { - transform: 'lodash/${1}/${member}', - preventFullImport: false, - }, + mode: 'remove', + removeImport: true, }, ], ], }, - ], + }, }; }; diff --git a/packages/kbn-config/package.json b/packages/kbn-config/package.json index 2d9dbc3b7ab8f..6d2d56b929ead 100644 --- a/packages/kbn-config/package.json +++ b/packages/kbn-config/package.json @@ -16,7 +16,7 @@ "@kbn/logging": "1.0.0", "@kbn/std": "1.0.0", "@kbn/utility-types": "1.0.0", - "js-yaml": "3.13.1", + "js-yaml": "^3.14.0", "load-json-file": "^6.2.0", "lodash": "^4.17.20", "moment": "^2.24.0", @@ -25,6 +25,6 @@ }, "devDependencies": { "typescript": "4.0.2", - "tsd": "^0.7.4" + "tsd": "^0.13.1" } } diff --git a/packages/kbn-config/src/env.test.ts b/packages/kbn-config/src/env.test.ts index f3d51a021246e..1613a90951d40 100644 --- a/packages/kbn-config/src/env.test.ts +++ b/packages/kbn-config/src/env.test.ts @@ -198,6 +198,18 @@ test('pluginSearchPaths contains x-pack/examples plugins path if --run-examples expect(env.pluginSearchPaths).toContain('/some/home/dir/x-pack/examples'); }); +test('pluginSearchPaths does not contain x-pack/examples plugins path if --oss flag is true', () => { + const env = new Env( + '/some/home/dir', + packageInfos, + getEnvOptions({ + cliArgs: { runExamples: true, oss: true }, + }) + ); + + expect(env.pluginSearchPaths).not.toContain('/some/home/dir/x-pack/examples'); +}); + test('pluginSearchPaths does not contains examples plugins path if --run-examples flag is false', () => { const env = new Env( '/some/home/dir', diff --git a/packages/kbn-config/src/env.ts b/packages/kbn-config/src/env.ts index 250c7b72d47a9..e4585056696f9 100644 --- a/packages/kbn-config/src/env.ts +++ b/packages/kbn-config/src/env.ts @@ -123,8 +123,9 @@ export class Env { resolve(this.homeDir, 'src', 'plugins'), ...(options.cliArgs.oss ? [] : [resolve(this.homeDir, 'x-pack', 'plugins')]), resolve(this.homeDir, 'plugins'), - ...(options.cliArgs.runExamples - ? [resolve(this.homeDir, 'examples'), resolve(this.homeDir, 'x-pack', 'examples')] + ...(options.cliArgs.runExamples ? [resolve(this.homeDir, 'examples')] : []), + ...(options.cliArgs.runExamples && !options.cliArgs.oss + ? [resolve(this.homeDir, 'x-pack', 'examples')] : []), resolve(this.homeDir, '..', 'kibana-extra'), ]; diff --git a/packages/kbn-dev-utils/package.json b/packages/kbn-dev-utils/package.json index a3fe8178822aa..a51734168cf76 100644 --- a/packages/kbn-dev-utils/package.json +++ b/packages/kbn-dev-utils/package.json @@ -10,9 +10,9 @@ "kbn:watch": "yarn build --watch" }, "dependencies": { - "@babel/core": "^7.11.1", + "@babel/core": "^7.11.6", "@kbn/utils": "1.0.0", - "axios": "^0.19.0", + "axios": "^0.19.2", "chalk": "^4.1.0", "cheerio": "0.22.0", "dedent": "^0.7.0", diff --git a/packages/kbn-dev-utils/src/index.ts b/packages/kbn-dev-utils/src/index.ts index 8217999b01128..6a845825f0fd4 100644 --- a/packages/kbn-dev-utils/src/index.ts +++ b/packages/kbn-dev-utils/src/index.ts @@ -17,7 +17,7 @@ * under the License. */ -export { REPO_ROOT } from '@kbn/utils'; +export * from '@kbn/utils'; export { withProcRunner, ProcRunner } from './proc_runner'; export * from './tooling_log'; export * from './serializers'; diff --git a/packages/kbn-dev-utils/src/kbn_client/kbn_client.ts b/packages/kbn-dev-utils/src/kbn_client/kbn_client.ts index 861ea0988692c..7184727fc53de 100644 --- a/packages/kbn-dev-utils/src/kbn_client/kbn_client.ts +++ b/packages/kbn-dev-utils/src/kbn_client/kbn_client.ts @@ -54,8 +54,8 @@ export class KbnClient { /** * Make a direct request to the Kibana server */ - async request(options: ReqOptions) { - return await this.requester.request(options); + async request(options: ReqOptions) { + return await this.requester.request(options); } resolveUrl(relativeUrl: string) { diff --git a/packages/kbn-dev-utils/src/plugin_list/discover_plugins.ts b/packages/kbn-dev-utils/src/plugin_list/discover_plugins.ts index 5d92ddb600aa9..e8f6735205b19 100644 --- a/packages/kbn-dev-utils/src/plugin_list/discover_plugins.ts +++ b/packages/kbn-dev-utils/src/plugin_list/discover_plugins.ts @@ -29,7 +29,7 @@ import { extractAsciidocInfo } from './extract_asciidoc_info'; export interface Plugin { id: string; - relativeDir?: string; + relativeDir: string; relativeReadmePath?: string; readmeSnippet?: string; readmeAsciidocAnchor?: string; diff --git a/packages/kbn-dev-utils/src/plugin_list/generate_plugin_list.ts b/packages/kbn-dev-utils/src/plugin_list/generate_plugin_list.ts index e1a1323553113..680c220adb18c 100644 --- a/packages/kbn-dev-utils/src/plugin_list/generate_plugin_list.ts +++ b/packages/kbn-dev-utils/src/plugin_list/generate_plugin_list.ts @@ -24,9 +24,11 @@ import { REPO_ROOT } from '@kbn/utils'; import { Plugins } from './discover_plugins'; +const sortPlugins = (plugins: Plugins) => plugins.sort((a, b) => a.id.localeCompare(b.id)); + function* printPlugins(plugins: Plugins, includes: string[]) { - for (const plugin of plugins) { - const path = plugin.relativeReadmePath || plugin.relativeDir; + for (const plugin of sortPlugins(plugins)) { + const path = normalizePath(plugin.relativeReadmePath || plugin.relativeDir); yield ''; if (plugin.readmeAsciidocAnchor) { @@ -67,7 +69,7 @@ NOTE: [discrete] === src/plugins -[%header,cols=2*] +[%header,cols=2*] |=== |Name |Description @@ -79,7 +81,7 @@ ${Array.from(printPlugins(ossPlugins, includes)).join('\n')} [discrete] === x-pack/plugins -[%header,cols=2*] +[%header,cols=2*] |=== |Name |Description diff --git a/packages/kbn-es-archiver/package.json b/packages/kbn-es-archiver/package.json index 13b5662519b19..81c1747bb2727 100644 --- a/packages/kbn-es-archiver/package.json +++ b/packages/kbn-es-archiver/package.json @@ -4,8 +4,8 @@ "license": "Apache-2.0", "main": "target/index.js", "scripts": { - "kbn:bootstrap": "tsc", - "kbn:watch": "tsc --watch" + "kbn:bootstrap": "rm -rf target && tsc", + "kbn:watch": "rm -rf target && tsc --watch" }, "dependencies": { "@kbn/dev-utils": "1.0.0", diff --git a/packages/kbn-es/package.json b/packages/kbn-es/package.json index 52ef3fe05e751..c3733094350be 100644 --- a/packages/kbn-es/package.json +++ b/packages/kbn-es/package.json @@ -1,23 +1,32 @@ { "name": "@kbn/es", - "main": "./src/index.js", + "main": "./target/index.js", "version": "1.0.0", "license": "Apache-2.0", "private": true, + "scripts": { + "kbn:bootstrap": "node scripts/build", + "kbn:watch": "node scripts/build --watch" + }, "dependencies": { - "@elastic/elasticsearch": "7.9.0-rc.1", + "@elastic/elasticsearch": "7.9.1", "@kbn/dev-utils": "1.0.0", - "abort-controller": "^2.0.3", + "abort-controller": "^3.0.0", "chalk": "^4.1.0", "dedent": "^0.7.0", "del": "^5.1.0", "execa": "^4.0.2", - "getopts": "^2.2.4", + "getopts": "^2.2.5", "glob": "^7.1.2", "node-fetch": "^2.6.1", - "simple-git": "^1.91.0", + "simple-git": "1.116.0", "tar-fs": "^2.1.0", "tree-kill": "^1.2.2", "yauzl": "^2.10.0" + }, + "devDependencies": { + "@kbn/babel-preset": "1.0.0", + "@babel/cli": "^7.10.5", + "del": "^5.1.0" } } diff --git a/packages/kbn-es/scripts/build.js b/packages/kbn-es/scripts/build.js new file mode 100644 index 0000000000000..50aad665c920b --- /dev/null +++ b/packages/kbn-es/scripts/build.js @@ -0,0 +1,71 @@ +/* + * 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 { resolve } = require('path'); + +const del = require('del'); +const { run, withProcRunner } = require('@kbn/dev-utils'); + +const ROOT_DIR = resolve(__dirname, '..'); +const BUILD_DIR = resolve(ROOT_DIR, 'target'); + +run( + async ({ log, flags }) => { + await withProcRunner(log, async (proc) => { + log.info('Deleting old output'); + await del(BUILD_DIR); + + const cwd = ROOT_DIR; + + log.info(`Starting babel${flags.watch ? ' in watch mode' : ''}`); + await proc.run(`babel`, { + cmd: 'babel', + args: [ + 'src', + '--no-babelrc', + '--presets', + require.resolve('@kbn/babel-preset/node_preset'), + '--extensions', + '.ts,.js', + '--copy-files', + '--out-dir', + BUILD_DIR, + ...(flags.watch ? ['--watch'] : ['--quiet']), + ...(!flags['source-maps'] || !!process.env.CODE_COVERAGE + ? [] + : ['--source-maps', 'inline']), + ], + wait: true, + cwd, + }); + + log.success('Complete'); + }); + }, + { + description: 'Simple build tool for @kbn/es package', + flags: { + boolean: ['watch', 'source-maps'], + help: ` + --watch Run in watch mode + --source-maps Include sourcemaps + `, + }, + } +); diff --git a/packages/kbn-es/src/integration_tests/__fixtures__/es_bin.js b/packages/kbn-es/src/integration_tests/__fixtures__/es_bin.js index b860664443d1a..27e73e6c204e8 100644 --- a/packages/kbn-es/src/integration_tests/__fixtures__/es_bin.js +++ b/packages/kbn-es/src/integration_tests/__fixtures__/es_bin.js @@ -25,65 +25,67 @@ const { exitCode, start, ssl } = JSON.parse(process.argv[2]); const { createServer } = ssl ? require('https') : require('http'); const { ES_KEY_PATH, ES_CERT_PATH } = require('@kbn/dev-utils'); -process.exitCode = exitCode; +(function main() { + process.exitCode = exitCode; -if (!start) { - return; -} + if (!start) { + return; + } + + let serverUrl; + const server = createServer( + { + // Note: the integration uses the ES_P12_PATH, but that keystore contains + // the same key/cert as ES_KEY_PATH and ES_CERT_PATH + key: ssl ? fs.readFileSync(ES_KEY_PATH) : undefined, + cert: ssl ? fs.readFileSync(ES_CERT_PATH) : undefined, + }, + (req, res) => { + const url = new URL(req.url, serverUrl); + const send = (code, body) => { + res.writeHead(code, { 'content-type': 'application/json' }); + res.end(JSON.stringify(body)); + }; -let serverUrl; -const server = createServer( - { - // Note: the integration uses the ES_P12_PATH, but that keystore contains - // the same key/cert as ES_KEY_PATH and ES_CERT_PATH - key: ssl ? fs.readFileSync(ES_KEY_PATH) : undefined, - cert: ssl ? fs.readFileSync(ES_CERT_PATH) : undefined, - }, - (req, res) => { - const url = new URL(req.url, serverUrl); - const send = (code, body) => { - res.writeHead(code, { 'content-type': 'application/json' }); - res.end(JSON.stringify(body)); - }; + if (url.pathname === '/_xpack') { + return send(400, { + error: { + reason: 'foo bar', + }, + }); + } - if (url.pathname === '/_xpack') { - return send(400, { + return send(404, { error: { - reason: 'foo bar', + reason: 'not found', }, }); } + ); - return send(404, { - error: { - reason: 'not found', - }, - }); - } -); - -// setup server auto close after 1 second of silence -let serverCloseTimer; -const delayServerClose = () => { - clearTimeout(serverCloseTimer); - serverCloseTimer = setTimeout(() => server.close(), 1000); -}; -server.on('request', delayServerClose); -server.on('listening', delayServerClose); + // setup server auto close after 1 second of silence + let serverCloseTimer; + const delayServerClose = () => { + clearTimeout(serverCloseTimer); + serverCloseTimer = setTimeout(() => server.close(), 1000); + }; + server.on('request', delayServerClose); + server.on('listening', delayServerClose); -server.listen(0, '127.0.0.1', function () { - const { port, address: hostname } = server.address(); - serverUrl = new URL( - formatUrl({ - protocol: 'http:', - port, - hostname, - }) - ); + server.listen(0, '127.0.0.1', function () { + const { port, address: hostname } = server.address(); + serverUrl = new URL( + formatUrl({ + protocol: 'http:', + port, + hostname, + }) + ); - console.log( - `[o.e.h.AbstractHttpServerTransport] [computer] publish_address {127.0.0.1:${port}}, bound_addresses {[::1]:${port}}, {127.0.0.1:${port}}` - ); + console.log( + `[o.e.h.AbstractHttpServerTransport] [computer] publish_address {127.0.0.1:${port}}, bound_addresses {[::1]:${port}}, {127.0.0.1:${port}}` + ); - console.log('started'); -}); + console.log('started'); + }); +})(); diff --git a/packages/kbn-es/src/integration_tests/cluster.test.js b/packages/kbn-es/src/integration_tests/cluster.test.js index 0ae0ac0aac27a..6229a8add0d24 100644 --- a/packages/kbn-es/src/integration_tests/cluster.test.js +++ b/packages/kbn-es/src/integration_tests/cluster.test.js @@ -60,7 +60,7 @@ async function ensureResolve(promise) { function mockEsBin({ exitCode, start }) { execa.mockImplementationOnce((cmd, args, options) => - require.requireActual('execa')( + jest.requireActual('execa')( process.execPath, [ require.resolve('./__fixtures__/es_bin.js'), diff --git a/packages/kbn-eslint-import-resolver-kibana/package.json b/packages/kbn-eslint-import-resolver-kibana/package.json index 332f7e8a20cc2..223c73e97908e 100755 --- a/packages/kbn-eslint-import-resolver-kibana/package.json +++ b/packages/kbn-eslint-import-resolver-kibana/package.json @@ -13,7 +13,7 @@ "debug": "^2.6.9", "eslint-import-resolver-node": "0.3.2", "eslint-import-resolver-webpack": "0.11.1", - "glob-all": "^3.1.0", + "glob-all": "^3.2.1", "lru-cache": "^4.1.5", "resolve": "^1.7.1", "webpack": "^4.41.5" diff --git a/packages/kbn-i18n/package.json b/packages/kbn-i18n/package.json index eccdff9060cbe..f23faecbeaa67 100644 --- a/packages/kbn-i18n/package.json +++ b/packages/kbn-i18n/package.json @@ -13,13 +13,13 @@ }, "devDependencies": { "@babel/cli": "^7.10.5", - "@babel/core": "^7.11.1", + "@babel/core": "^7.11.6", "@kbn/babel-preset": "1.0.0", "@kbn/dev-utils": "1.0.0", "@types/intl-relativeformat": "^2.1.0", "@types/react-intl": "^2.3.15", "del": "^5.1.0", - "getopts": "^2.2.4", + "getopts": "^2.2.5", "supports-color": "^7.0.0", "typescript": "4.0.2" }, diff --git a/packages/kbn-i18n/src/core/i18n.test.ts b/packages/kbn-i18n/src/core/i18n.test.ts index ec08c82b502db..3364f20879c2a 100644 --- a/packages/kbn-i18n/src/core/i18n.test.ts +++ b/packages/kbn-i18n/src/core/i18n.test.ts @@ -25,7 +25,7 @@ describe('I18n engine', () => { let i18n: typeof i18nModule; beforeEach(() => { - i18n = require.requireActual('./i18n'); + i18n = jest.requireActual('./i18n'); }); afterEach(() => { diff --git a/packages/kbn-interpreter/package.json b/packages/kbn-interpreter/package.json index aef63229ebe96..4d415e96389df 100644 --- a/packages/kbn-interpreter/package.json +++ b/packages/kbn-interpreter/package.json @@ -11,12 +11,12 @@ "dependencies": { "@babel/runtime": "^7.11.2", "@kbn/i18n": "1.0.0", - "lodash": "^4.17.15", + "lodash": "^4.17.20", "uuid": "3.3.2" }, "devDependencies": { "@babel/cli": "^7.10.5", - "@babel/core": "^7.11.1", + "@babel/core": "^7.11.6", "@babel/plugin-transform-modules-commonjs": "^7.10.4", "@babel/plugin-transform-runtime": "^7.11.0", "@kbn/babel-preset": "1.0.0", @@ -25,12 +25,12 @@ "copy-webpack-plugin": "^6.0.2", "css-loader": "^3.4.2", "del": "^5.1.0", - "getopts": "^2.2.4", + "getopts": "^2.2.5", "pegjs": "0.10.0", "sass-loader": "^8.0.2", "style-loader": "^1.1.3", "supports-color": "^7.0.0", - "url-loader": "2.2.0", + "url-loader": "^2.2.0", "webpack": "^4.41.5", "webpack-cli": "^3.3.10" } diff --git a/packages/kbn-monaco/package.json b/packages/kbn-monaco/package.json index ca133010fe230..fcea80c9b7110 100644 --- a/packages/kbn-monaco/package.json +++ b/packages/kbn-monaco/package.json @@ -18,7 +18,7 @@ "babel-loader": "^8.0.6", "css-loader": "^3.4.2", "del": "^5.1.0", - "raw-loader": "3.1.0", + "raw-loader": "^3.1.0", "supports-color": "^7.0.0", "typescript": "4.0.2", "webpack": "^4.41.5", diff --git a/packages/kbn-optimizer/package.json b/packages/kbn-optimizer/package.json index b80d1365659dd..52f9349aec696 100644 --- a/packages/kbn-optimizer/package.json +++ b/packages/kbn-optimizer/package.json @@ -11,6 +11,7 @@ }, "dependencies": { "@babel/cli": "^7.10.5", + "@babel/core": "^7.11.6", "@kbn/babel-preset": "1.0.0", "@kbn/dev-utils": "1.0.0", "@kbn/ui-shared-deps": "1.0.0", @@ -19,21 +20,26 @@ "clean-webpack-plugin": "^3.0.0", "compression-webpack-plugin": "^4.0.0", "cpy": "^8.0.0", + "core-js": "^3.6.5", "css-loader": "^3.4.2", "del": "^5.1.0", "execa": "^4.0.2", "file-loader": "^4.2.0", "istanbul-instrumenter-loader": "^3.0.1", - "jest-diff": "^25.5.0", + "jest-diff": "^26.4.2", + "js-yaml": "^3.14.0", "json-stable-stringify": "^1.0.1", + "lmdb-store": "^0.6.10", "loader-utils": "^1.2.3", - "node-sass": "^4.13.0", + "node-sass": "^4.13.1", "normalize-path": "^3.0.0", + "pirates": "^4.0.1", "postcss": "^7.0.32", "postcss-loader": "^3.0.0", "raw-loader": "^3.1.0", "rxjs": "^6.5.5", "sass-loader": "^8.0.2", + "source-map-support": "^0.5.19", "style-loader": "^1.1.3", "terser-webpack-plugin": "^2.1.2", "tinymath": "1.2.1", @@ -44,8 +50,10 @@ "webpack-merge": "^4.2.2" }, "devDependencies": { + "@types/babel__core": "^7.1.10", "@types/compression-webpack-plugin": "^2.0.2", "@types/loader-utils": "^1.1.3", + "@types/source-map-support": "^0.5.3", "@types/watchpack": "^1.1.5", "@types/webpack": "^4.41.3" } diff --git a/packages/kbn-optimizer/src/index.ts b/packages/kbn-optimizer/src/index.ts index 39cf2120baf0a..549e4b13a4ac0 100644 --- a/packages/kbn-optimizer/src/index.ts +++ b/packages/kbn-optimizer/src/index.ts @@ -21,3 +21,4 @@ export { OptimizerConfig } from './optimizer'; export * from './run_optimizer'; export * from './log_optimizer_state'; export * from './report_optimizer_stats'; +export * from './node'; diff --git a/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap b/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap index 79442c35df265..038beca703720 100644 --- a/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap +++ b/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap @@ -98,7 +98,7 @@ OptimizerConfig { } `; -exports[`prepares assets for distribution: bar bundle 1`] = `"(function(modules){var installedModules={};function __webpack_require__(moduleId){if(installedModules[moduleId]){return installedModules[moduleId].exports}var module=installedModules[moduleId]={i:moduleId,l:false,exports:{}};modules[moduleId].call(module.exports,module,module.exports,__webpack_require__);module.l=true;return module.exports}__webpack_require__.m=modules;__webpack_require__.c=installedModules;__webpack_require__.d=function(exports,name,getter){if(!__webpack_require__.o(exports,name)){Object.defineProperty(exports,name,{enumerable:true,get:getter})}};__webpack_require__.r=function(exports){if(typeof Symbol!==\\"undefined\\"&&Symbol.toStringTag){Object.defineProperty(exports,Symbol.toStringTag,{value:\\"Module\\"})}Object.defineProperty(exports,\\"__esModule\\",{value:true})};__webpack_require__.t=function(value,mode){if(mode&1)value=__webpack_require__(value);if(mode&8)return value;if(mode&4&&typeof value===\\"object\\"&&value&&value.__esModule)return value;var ns=Object.create(null);__webpack_require__.r(ns);Object.defineProperty(ns,\\"default\\",{enumerable:true,value:value});if(mode&2&&typeof value!=\\"string\\")for(var key in value)__webpack_require__.d(ns,key,function(key){return value[key]}.bind(null,key));return ns};__webpack_require__.n=function(module){var getter=module&&module.__esModule?function getDefault(){return module[\\"default\\"]}:function getModuleExports(){return module};__webpack_require__.d(getter,\\"a\\",getter);return getter};__webpack_require__.o=function(object,property){return Object.prototype.hasOwnProperty.call(object,property)};__webpack_require__.p=\\"\\";return __webpack_require__(__webpack_require__.s=3)})([function(module,exports,__webpack_require__){\\"use strict\\";var isOldIE=function isOldIE(){var memo;return function memorize(){if(typeof memo===\\"undefined\\"){memo=Boolean(window&&document&&document.all&&!window.atob)}return memo}}();var getTarget=function getTarget(){var memo={};return function memorize(target){if(typeof memo[target]===\\"undefined\\"){var styleTarget=document.querySelector(target);if(window.HTMLIFrameElement&&styleTarget instanceof window.HTMLIFrameElement){try{styleTarget=styleTarget.contentDocument.head}catch(e){styleTarget=null}}memo[target]=styleTarget}return memo[target]}}();var stylesInDom=[];function getIndexByIdentifier(identifier){var result=-1;for(var i=0;i { + // right now I'm not sure we need to worry about errors, the cache isn't actually + // necessary, and if the cache is broken it should just rebuild on the next restart + // of the process. We don't know how often errors occur though and what types of + // things might fail on different machines so we probably want some way to signal + // to users that something is wrong +}; + +const GLOBAL_ATIME = `${Date.now()}`; +const MINUTE = 1000 * 60; +const HOUR = MINUTE * 60; +const DAY = HOUR * 24; + +interface Lmdb { + get(key: string): T | undefined; + put(key: string, value: T, version?: number, ifVersion?: number): Promise; + remove(key: string, ifVersion?: number): Promise; + openDB(options: { name: string; encoding: 'msgpack' | 'string' | 'json' | 'binary' }): Lmdb; + getRange(options?: { + start?: T; + end?: T; + reverse?: boolean; + limit?: number; + versions?: boolean; + }): Iterable<{ key: string; value: T }>; +} + +export class Cache { + private readonly codes: Lmdb; + private readonly atimes: Lmdb; + private readonly mtimes: Lmdb; + private readonly sourceMaps: Lmdb; + private readonly prefix: string; + + constructor(config: { prefix: string }) { + this.prefix = config.prefix; + + this.codes = LmdbStore.open({ + name: 'codes', + path: CACHE_DIR, + }); + + this.atimes = this.codes.openDB({ + name: 'atimes', + encoding: 'string', + }); + + this.mtimes = this.codes.openDB({ + name: 'mtimes', + encoding: 'string', + }); + + this.sourceMaps = this.codes.openDB({ + name: 'sourceMaps', + encoding: 'msgpack', + }); + + // after the process has been running for 30 minutes prune the + // keys which haven't been used in 30 days. We use `unref()` to + // make sure this timer doesn't hold other processes open + // unexpectedly + setTimeout(() => { + this.pruneOldKeys(); + }, 30 * MINUTE).unref(); + } + + getMtime(path: string) { + return this.mtimes.get(this.getKey(path)); + } + + getCode(path: string) { + const key = this.getKey(path); + + // when we use a file from the cache set the "atime" of that cache entry + // so that we know which cache items we use and which haven't been + // touched in a long time (currently 30 days) + this.atimes.put(key, GLOBAL_ATIME).catch(reportError); + + return this.codes.get(key); + } + + getSourceMap(path: string) { + return this.sourceMaps.get(this.getKey(path)); + } + + update(path: string, file: { mtime: string; code: string; map: any }) { + const key = this.getKey(path); + + Promise.all([ + this.atimes.put(key, GLOBAL_ATIME), + this.mtimes.put(key, file.mtime), + this.codes.put(key, file.code), + this.sourceMaps.put(key, file.map), + ]).catch(reportError); + } + + private getKey(path: string) { + return `${this.prefix}${path}`; + } + + private async pruneOldKeys() { + try { + const ATIME_LIMIT = Date.now() - 30 * DAY; + const BATCH_SIZE = 1000; + + const validKeys: string[] = []; + const invalidKeys: string[] = []; + + for (const { key, value } of this.atimes.getRange()) { + const atime = parseInt(value, 10); + if (atime < ATIME_LIMIT) { + invalidKeys.push(key); + } else { + validKeys.push(key); + } + + if (validKeys.length + invalidKeys.length >= BATCH_SIZE) { + const promises = new Set(); + + if (invalidKeys.length) { + for (const k of invalidKeys) { + // all these promises are the same currently, so Set() will + // optimise this to a single promise, but I wouldn't be shocked + // if a future version starts returning independent promises so + // this is just for some future-proofing + promises.add(this.atimes.remove(k)); + promises.add(this.mtimes.remove(k)); + promises.add(this.codes.remove(k)); + promises.add(this.sourceMaps.remove(k)); + } + } else { + // delay a smidge to allow other things to happen before the next batch of checks + promises.add(new Promise((resolve) => setTimeout(resolve, 1))); + } + + invalidKeys.length = 0; + validKeys.length = 0; + await Promise.all(Array.from(promises)); + } + } + } catch { + // ignore errors, the cache is totally disposable and will rebuild if there is some sort of corruption + } + } +} diff --git a/packages/kbn-optimizer/src/node/index.ts b/packages/kbn-optimizer/src/node/index.ts new file mode 100644 index 0000000000000..64dd75ce573e6 --- /dev/null +++ b/packages/kbn-optimizer/src/node/index.ts @@ -0,0 +1,20 @@ +/* + * 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 * from './node_auto_tranpilation'; diff --git a/packages/kbn-optimizer/src/node/node_auto_tranpilation.ts b/packages/kbn-optimizer/src/node/node_auto_tranpilation.ts new file mode 100644 index 0000000000000..ff6ab1c68da53 --- /dev/null +++ b/packages/kbn-optimizer/src/node/node_auto_tranpilation.ts @@ -0,0 +1,187 @@ +/* eslint-disable @kbn/eslint/require-license-header */ + +/** + * This module is based on @babel/register @ 9808d25, modified to use + * a more efficient caching implementation which writes to disk as + * the cache is built rather than keeping the whole cache in memory + * and then dumping it to disk when the process exits. + */ + +/** + * @notice + * MIT License + * + * Copyright (c) 2014-present Sebastian McKenzie and other contributors + * + * 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. + */ + +import Fs from 'fs'; +import Path from 'path'; +import Crypto from 'crypto'; + +import * as babel from '@babel/core'; +import { addHook } from 'pirates'; +import { REPO_ROOT } from '@kbn/dev-utils'; +import sourceMapSupport from 'source-map-support'; + +import { Cache } from './cache'; + +const cwd = process.cwd(); + +const IGNORE_PATTERNS = [ + /[\/\\]kbn-pm[\/\\]dist[\/\\]/, + + // ignore paths matching `/node_modules/{a}/{b}`, unless `a` + // is `x-pack` and `b` is not `node_modules` + /[\/\\]node_modules[\/\\](?!x-pack[\/\\](?!node_modules)([^\/\\]+))([^\/\\]+[\/\\][^\/\\]+)/, + + // ignore paths matching `/canvas/canvas_plugin/` + /[\/\\]canvas[\/\\]canvas_plugin[\/\\]/, + + // 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)$)(.+$)/, +]; + +function getBabelOptions(path: string) { + return babel.loadOptions({ + cwd, + sourceRoot: Path.dirname(path) + Path.sep, + filename: path, + babelrc: false, + presets: [require.resolve('@kbn/babel-preset/node_preset')], + sourceMaps: 'both', + ast: false, + })!; +} + +/** + * @babel/register uses a JSON encoded copy of the config + babel.version + * as the cache key for files, so we do something similar but we don't need + * a unique cache key for every file as our config isn't different for + * different files (by design). Instead we determine a unique prefix and + * automatically prepend all paths with the prefix to create cache keys + */ +function determineCachePrefix() { + const json = JSON.stringify({ + babelVersion: babel.version, + // get a config for a fake js, ts, and tsx file to make sure we + // capture conditional config portions based on the file extension + js: getBabelOptions(Path.resolve(REPO_ROOT, 'foo.js')), + ts: getBabelOptions(Path.resolve(REPO_ROOT, 'foo.ts')), + tsx: getBabelOptions(Path.resolve(REPO_ROOT, 'foo.tsx')), + }); + + const checksum = Crypto.createHash('sha256').update(json).digest('hex'); + return `${checksum}:`; +} + +function compile(cache: Cache, source: string, path: string) { + try { + const mtime = `${Fs.statSync(path).mtimeMs}`; + if (cache.getMtime(path) === mtime) { + const code = cache.getCode(path); + if (code) { + // code *should* always be defined, but if it isn't for some reason rebuild it + return code; + } + } + + const options = getBabelOptions(path); + const result = babel.transform(source, options); + + if (!result || !result.code || !result.map) { + throw new Error(`babel failed to transpile [${path}]`); + } + + cache.update(path, { + mtime, + map: result.map, + code: result.code, + }); + + return result.code; + } catch (error) { + throw error; + } +} + +let installed = false; + +export function registerNodeAutoTranspilation() { + if (installed) { + return; + } + installed = true; + + const cache = new Cache({ + prefix: determineCachePrefix(), + }); + + sourceMapSupport.install({ + handleUncaughtExceptions: false, + environment: 'node', + // @ts-expect-error bad source-map-support types + retrieveSourceMap(path: string) { + const map = cache.getSourceMap(path); + + if (map) { + return { + url: null, + map, + }; + } else { + return null; + } + }, + }); + + let compiling = false; + + addHook( + (code, path) => { + if (compiling) { + return code; + } + + if (IGNORE_PATTERNS.some((re) => re.test(path))) { + return code; + } + + try { + compiling = true; + return compile(cache, code, path); + } finally { + compiling = false; + } + }, + { + exts: ['.js', '.ts', '.tsx'], + ignoreNodeModules: false, + } + ); + + // require the polyfills after setting up the require hook so that @babel/preset-env + // will spot the import in the polyfill file and replace it with the necessary polyfills + // for the current node.js version + require('./polyfill'); +} diff --git a/packages/kbn-optimizer/src/node/polyfill.ts b/packages/kbn-optimizer/src/node/polyfill.ts new file mode 100644 index 0000000000000..5d445ef89f71e --- /dev/null +++ b/packages/kbn-optimizer/src/node/polyfill.ts @@ -0,0 +1,20 @@ +/* + * 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 'core-js/stable'; diff --git a/packages/kbn-optimizer/src/optimizer/optimizer_config.ts b/packages/kbn-optimizer/src/optimizer/optimizer_config.ts index 45598ff8831b0..b1ab1ebfe49f2 100644 --- a/packages/kbn-optimizer/src/optimizer/optimizer_config.ts +++ b/packages/kbn-optimizer/src/optimizer/optimizer_config.ts @@ -161,7 +161,8 @@ export class OptimizerConfig { Path.resolve(repoRoot, 'src/plugins'), ...(oss ? [] : [Path.resolve(repoRoot, 'x-pack/plugins')]), Path.resolve(repoRoot, 'plugins'), - ...(examples ? [Path.resolve('examples'), Path.resolve('x-pack/examples')] : []), + ...(examples ? [Path.resolve('examples')] : []), + ...(examples && !oss ? [Path.resolve('x-pack/examples')] : []), Path.resolve(repoRoot, '../kibana-extra'), ]; if (!pluginScanDirs.every((p) => Path.isAbsolute(p))) { diff --git a/packages/kbn-optimizer/src/worker/webpack.config.ts b/packages/kbn-optimizer/src/worker/webpack.config.ts index 9f2c5654a8bd4..9678dd5de868b 100644 --- a/packages/kbn-optimizer/src/worker/webpack.config.ts +++ b/packages/kbn-optimizer/src/worker/webpack.config.ts @@ -200,6 +200,7 @@ export function getWebpackConfig(bundle: Bundle, bundleRefs: BundleRefs, worker: loader: 'babel-loader', options: { babelrc: false, + envName: worker.dist ? 'production' : 'development', presets: IS_CODE_COVERAGE ? [ISTANBUL_PRESET_PATH, BABEL_PRESET_PATH] : [BABEL_PRESET_PATH], @@ -216,7 +217,7 @@ export function getWebpackConfig(bundle: Bundle, bundleRefs: BundleRefs, worker: }, resolve: { - extensions: ['.js', '.ts', '.tsx', 'json'], + extensions: ['.js', '.ts', '.tsx', '.json'], mainFields: ['browser', 'main'], alias: { tinymath: require.resolve('tinymath/lib/tinymath.es5.js'), diff --git a/packages/kbn-plugin-helpers/package.json b/packages/kbn-plugin-helpers/package.json index f292387c12521..a2c4e1e2134e7 100644 --- a/packages/kbn-plugin-helpers/package.json +++ b/packages/kbn-plugin-helpers/package.json @@ -18,14 +18,14 @@ "del": "^5.1.0", "execa": "^4.0.2", "gulp-zip": "^5.0.2", - "inquirer": "^1.2.2", + "inquirer": "^7.3.3", "load-json-file": "^6.2.0", "vinyl-fs": "^3.0.3" }, "devDependencies": { "@types/extract-zip": "^1.6.2", "@types/gulp-zip": "^4.0.1", - "@types/inquirer": "^6.5.0", + "@types/inquirer": "^7.3.1", "extract-zip": "^2.0.1", "typescript": "4.0.2" } diff --git a/packages/kbn-pm/dist/index.js b/packages/kbn-pm/dist/index.js index 902cc8839ac09..48dba22505232 100644 --- a/packages/kbn-pm/dist/index.js +++ b/packages/kbn-pm/dist/index.js @@ -94,19 +94,19 @@ __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__(504); +/* harmony import */ var _production__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(507); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return _production__WEBPACK_IMPORTED_MODULE_1__["buildProductionProjects"]; }); -/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(145); +/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(146); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "getProjects", function() { return _utils_projects__WEBPACK_IMPORTED_MODULE_2__["getProjects"]; }); -/* harmony import */ var _utils_project__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(163); +/* harmony import */ var _utils_project__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(164); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Project", function() { return _utils_project__WEBPACK_IMPORTED_MODULE_3__["Project"]; }); -/* harmony import */ var _utils_workspaces__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(279); +/* harmony import */ var _utils_workspaces__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(271); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "copyWorkspacePackages", function() { return _utils_workspaces__WEBPACK_IMPORTED_MODULE_4__["copyWorkspacePackages"]; }); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(280); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(272); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "getProjectPaths", function() { return _config__WEBPACK_IMPORTED_MODULE_5__["getProjectPaths"]; }); /* @@ -149,9 +149,9 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__); /* harmony import */ var _kbn_dev_utils_tooling_log__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5); /* harmony import */ var _kbn_dev_utils_tooling_log__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_kbn_dev_utils_tooling_log__WEBPACK_IMPORTED_MODULE_3__); -/* harmony import */ var _commands__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(127); -/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(497); -/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(143); +/* harmony import */ var _commands__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(128); +/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(500); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(144); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -565,12 +565,12 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.ToolingLogCollectingWriter = exports.parseLogLevel = exports.pickLevelFromFlags = exports.ToolingLogTextWriter = exports.ToolingLog = void 0; var tooling_log_1 = __webpack_require__(6); Object.defineProperty(exports, "ToolingLog", { enumerable: true, get: function () { return tooling_log_1.ToolingLog; } }); -var tooling_log_text_writer_1 = __webpack_require__(110); +var tooling_log_text_writer_1 = __webpack_require__(111); Object.defineProperty(exports, "ToolingLogTextWriter", { enumerable: true, get: function () { return tooling_log_text_writer_1.ToolingLogTextWriter; } }); -var log_levels_1 = __webpack_require__(125); +var log_levels_1 = __webpack_require__(126); Object.defineProperty(exports, "pickLevelFromFlags", { enumerable: true, get: function () { return log_levels_1.pickLevelFromFlags; } }); Object.defineProperty(exports, "parseLogLevel", { enumerable: true, get: function () { return log_levels_1.parseLogLevel; } }); -var tooling_log_collecting_writer_1 = __webpack_require__(126); +var tooling_log_collecting_writer_1 = __webpack_require__(127); Object.defineProperty(exports, "ToolingLogCollectingWriter", { enumerable: true, get: function () { return tooling_log_collecting_writer_1.ToolingLogCollectingWriter; } }); @@ -602,7 +602,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.ToolingLog = void 0; const tslib_1 = __webpack_require__(7); const Rx = tslib_1.__importStar(__webpack_require__(8)); -const tooling_log_text_writer_1 = __webpack_require__(110); +const tooling_log_text_writer_1 = __webpack_require__(111); class ToolingLog { constructor(writerConfig) { this.identWidth = 0; @@ -711,7 +711,7 @@ PERFORMANCE OF THIS SOFTWARE. var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; @@ -805,8 +805,8 @@ var __createBinding = Object.create ? (function(o, m, k, k2) { o[k2] = m[k]; }); -function __exportStar(m, exports) { - for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p); +function __exportStar(m, o) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); } function __values(o) { @@ -896,7 +896,7 @@ var __setModuleDefault = Object.create ? (function(o, v) { function __importStar(mod) { if (mod && mod.__esModule) return mod; var result = {}; - if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; } @@ -952,16 +952,24 @@ __webpack_require__.r(__webpack_exports__); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "AsyncSubject", function() { return _internal_AsyncSubject__WEBPACK_IMPORTED_MODULE_7__["AsyncSubject"]; }); /* harmony import */ var _internal_scheduler_asap__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(51); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "asapScheduler", function() { return _internal_scheduler_asap__WEBPACK_IMPORTED_MODULE_8__["asap"]; }); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "asap", function() { return _internal_scheduler_asap__WEBPACK_IMPORTED_MODULE_8__["asap"]; }); + +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "asapScheduler", function() { return _internal_scheduler_asap__WEBPACK_IMPORTED_MODULE_8__["asapScheduler"]; }); /* harmony import */ var _internal_scheduler_async__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(55); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "asyncScheduler", function() { return _internal_scheduler_async__WEBPACK_IMPORTED_MODULE_9__["async"]; }); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "async", function() { return _internal_scheduler_async__WEBPACK_IMPORTED_MODULE_9__["async"]; }); + +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "asyncScheduler", function() { return _internal_scheduler_async__WEBPACK_IMPORTED_MODULE_9__["asyncScheduler"]; }); /* harmony import */ var _internal_scheduler_queue__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(34); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "queueScheduler", function() { return _internal_scheduler_queue__WEBPACK_IMPORTED_MODULE_10__["queue"]; }); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "queue", function() { return _internal_scheduler_queue__WEBPACK_IMPORTED_MODULE_10__["queue"]; }); + +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "queueScheduler", function() { return _internal_scheduler_queue__WEBPACK_IMPORTED_MODULE_10__["queueScheduler"]; }); /* harmony import */ var _internal_scheduler_animationFrame__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(56); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "animationFrameScheduler", function() { return _internal_scheduler_animationFrame__WEBPACK_IMPORTED_MODULE_11__["animationFrame"]; }); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "animationFrame", function() { return _internal_scheduler_animationFrame__WEBPACK_IMPORTED_MODULE_11__["animationFrame"]; }); + +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "animationFrameScheduler", function() { return _internal_scheduler_animationFrame__WEBPACK_IMPORTED_MODULE_11__["animationFrameScheduler"]; }); /* harmony import */ var _internal_scheduler_VirtualTimeScheduler__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(59); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VirtualTimeScheduler", function() { return _internal_scheduler_VirtualTimeScheduler__WEBPACK_IMPORTED_MODULE_12__["VirtualTimeScheduler"]; }); @@ -1021,67 +1029,67 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _internal_observable_concat__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(79); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concat", function() { return _internal_observable_concat__WEBPACK_IMPORTED_MODULE_29__["concat"]; }); -/* harmony import */ var _internal_observable_defer__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(90); +/* harmony import */ var _internal_observable_defer__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(91); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "defer", function() { return _internal_observable_defer__WEBPACK_IMPORTED_MODULE_30__["defer"]; }); /* harmony import */ var _internal_observable_empty__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(43); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "empty", function() { return _internal_observable_empty__WEBPACK_IMPORTED_MODULE_31__["empty"]; }); -/* harmony import */ var _internal_observable_forkJoin__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(91); +/* harmony import */ var _internal_observable_forkJoin__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(92); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "forkJoin", function() { return _internal_observable_forkJoin__WEBPACK_IMPORTED_MODULE_32__["forkJoin"]; }); /* harmony import */ var _internal_observable_from__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(83); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "from", function() { return _internal_observable_from__WEBPACK_IMPORTED_MODULE_33__["from"]; }); -/* harmony import */ var _internal_observable_fromEvent__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(92); +/* harmony import */ var _internal_observable_fromEvent__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(93); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "fromEvent", function() { return _internal_observable_fromEvent__WEBPACK_IMPORTED_MODULE_34__["fromEvent"]; }); -/* harmony import */ var _internal_observable_fromEventPattern__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(93); +/* harmony import */ var _internal_observable_fromEventPattern__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(94); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "fromEventPattern", function() { return _internal_observable_fromEventPattern__WEBPACK_IMPORTED_MODULE_35__["fromEventPattern"]; }); -/* harmony import */ var _internal_observable_generate__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(94); +/* harmony import */ var _internal_observable_generate__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(95); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "generate", function() { return _internal_observable_generate__WEBPACK_IMPORTED_MODULE_36__["generate"]; }); -/* harmony import */ var _internal_observable_iif__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(95); +/* harmony import */ var _internal_observable_iif__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(96); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "iif", function() { return _internal_observable_iif__WEBPACK_IMPORTED_MODULE_37__["iif"]; }); -/* harmony import */ var _internal_observable_interval__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(96); +/* harmony import */ var _internal_observable_interval__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(97); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "interval", function() { return _internal_observable_interval__WEBPACK_IMPORTED_MODULE_38__["interval"]; }); -/* harmony import */ var _internal_observable_merge__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(98); +/* harmony import */ var _internal_observable_merge__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(99); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "merge", function() { return _internal_observable_merge__WEBPACK_IMPORTED_MODULE_39__["merge"]; }); -/* harmony import */ var _internal_observable_never__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(99); +/* harmony import */ var _internal_observable_never__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(100); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "never", function() { return _internal_observable_never__WEBPACK_IMPORTED_MODULE_40__["never"]; }); /* harmony import */ var _internal_observable_of__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(44); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "of", function() { return _internal_observable_of__WEBPACK_IMPORTED_MODULE_41__["of"]; }); -/* harmony import */ var _internal_observable_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(100); +/* harmony import */ var _internal_observable_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(101); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "onErrorResumeNext", function() { return _internal_observable_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_42__["onErrorResumeNext"]; }); -/* harmony import */ var _internal_observable_pairs__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(101); +/* harmony import */ var _internal_observable_pairs__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(102); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "pairs", function() { return _internal_observable_pairs__WEBPACK_IMPORTED_MODULE_43__["pairs"]; }); -/* harmony import */ var _internal_observable_partition__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(102); +/* harmony import */ var _internal_observable_partition__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(103); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "partition", function() { return _internal_observable_partition__WEBPACK_IMPORTED_MODULE_44__["partition"]; }); -/* harmony import */ var _internal_observable_race__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(105); +/* harmony import */ var _internal_observable_race__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(106); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "race", function() { return _internal_observable_race__WEBPACK_IMPORTED_MODULE_45__["race"]; }); -/* harmony import */ var _internal_observable_range__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(106); +/* harmony import */ var _internal_observable_range__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(107); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "range", function() { return _internal_observable_range__WEBPACK_IMPORTED_MODULE_46__["range"]; }); /* harmony import */ var _internal_observable_throwError__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(49); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throwError", function() { return _internal_observable_throwError__WEBPACK_IMPORTED_MODULE_47__["throwError"]; }); -/* harmony import */ var _internal_observable_timer__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(107); +/* harmony import */ var _internal_observable_timer__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(108); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timer", function() { return _internal_observable_timer__WEBPACK_IMPORTED_MODULE_48__["timer"]; }); -/* harmony import */ var _internal_observable_using__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(108); +/* harmony import */ var _internal_observable_using__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(109); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "using", function() { return _internal_observable_using__WEBPACK_IMPORTED_MODULE_49__["using"]; }); -/* harmony import */ var _internal_observable_zip__WEBPACK_IMPORTED_MODULE_50__ = __webpack_require__(109); +/* harmony import */ var _internal_observable_zip__WEBPACK_IMPORTED_MODULE_50__ = __webpack_require__(110); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "zip", function() { return _internal_observable_zip__WEBPACK_IMPORTED_MODULE_50__["zip"]; }); /* harmony import */ var _internal_scheduled_scheduled__WEBPACK_IMPORTED_MODULE_51__ = __webpack_require__(84); @@ -1916,6 +1924,7 @@ var Subscription = /*@__PURE__*/ (function () { this._parentOrParents = null; this._subscriptions = null; if (unsubscribe) { + this._ctorUnsubscribe = true; this._unsubscribe = unsubscribe; } } @@ -1924,7 +1933,7 @@ var Subscription = /*@__PURE__*/ (function () { if (this.closed) { return; } - var _a = this, _parentOrParents = _a._parentOrParents, _unsubscribe = _a._unsubscribe, _subscriptions = _a._subscriptions; + var _a = this, _parentOrParents = _a._parentOrParents, _ctorUnsubscribe = _a._ctorUnsubscribe, _unsubscribe = _a._unsubscribe, _subscriptions = _a._subscriptions; this.closed = true; this._parentOrParents = null; this._subscriptions = null; @@ -1938,6 +1947,9 @@ var Subscription = /*@__PURE__*/ (function () { } } if (Object(_util_isFunction__WEBPACK_IMPORTED_MODULE_2__["isFunction"])(_unsubscribe)) { + if (_ctorUnsubscribe) { + this._unsubscribe = undefined; + } try { _unsubscribe.call(this); } @@ -3059,13 +3071,15 @@ var ReplayEvent = /*@__PURE__*/ (function () { "use strict"; __webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "queueScheduler", function() { return queueScheduler; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "queue", function() { return queue; }); /* harmony import */ var _QueueAction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(35); /* harmony import */ var _QueueScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(38); /** PURE_IMPORTS_START _QueueAction,_QueueScheduler PURE_IMPORTS_END */ -var queue = /*@__PURE__*/ new _QueueScheduler__WEBPACK_IMPORTED_MODULE_1__["QueueScheduler"](_QueueAction__WEBPACK_IMPORTED_MODULE_0__["QueueAction"]); +var queueScheduler = /*@__PURE__*/ new _QueueScheduler__WEBPACK_IMPORTED_MODULE_1__["QueueScheduler"](_QueueAction__WEBPACK_IMPORTED_MODULE_0__["QueueAction"]); +var queue = queueScheduler; //# sourceMappingURL=queue.js.map @@ -3781,13 +3795,15 @@ var AsyncSubject = /*@__PURE__*/ (function (_super) { "use strict"; __webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "asapScheduler", function() { return asapScheduler; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "asap", function() { return asap; }); /* harmony import */ var _AsapAction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(52); /* harmony import */ var _AsapScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(54); /** PURE_IMPORTS_START _AsapAction,_AsapScheduler PURE_IMPORTS_END */ -var asap = /*@__PURE__*/ new _AsapScheduler__WEBPACK_IMPORTED_MODULE_1__["AsapScheduler"](_AsapAction__WEBPACK_IMPORTED_MODULE_0__["AsapAction"]); +var asapScheduler = /*@__PURE__*/ new _AsapScheduler__WEBPACK_IMPORTED_MODULE_1__["AsapScheduler"](_AsapAction__WEBPACK_IMPORTED_MODULE_0__["AsapAction"]); +var asap = asapScheduler; //# sourceMappingURL=asap.js.map @@ -3930,13 +3946,15 @@ var AsapScheduler = /*@__PURE__*/ (function (_super) { "use strict"; __webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "asyncScheduler", function() { return asyncScheduler; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "async", function() { return async; }); /* harmony import */ var _AsyncAction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36); /* harmony import */ var _AsyncScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(39); /** PURE_IMPORTS_START _AsyncAction,_AsyncScheduler PURE_IMPORTS_END */ -var async = /*@__PURE__*/ new _AsyncScheduler__WEBPACK_IMPORTED_MODULE_1__["AsyncScheduler"](_AsyncAction__WEBPACK_IMPORTED_MODULE_0__["AsyncAction"]); +var asyncScheduler = /*@__PURE__*/ new _AsyncScheduler__WEBPACK_IMPORTED_MODULE_1__["AsyncScheduler"](_AsyncAction__WEBPACK_IMPORTED_MODULE_0__["AsyncAction"]); +var async = asyncScheduler; //# sourceMappingURL=async.js.map @@ -3946,13 +3964,15 @@ var async = /*@__PURE__*/ new _AsyncScheduler__WEBPACK_IMPORTED_MODULE_1__["Asyn "use strict"; __webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "animationFrameScheduler", function() { return animationFrameScheduler; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "animationFrame", function() { return animationFrame; }); /* harmony import */ var _AnimationFrameAction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(57); /* harmony import */ var _AnimationFrameScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(58); /** PURE_IMPORTS_START _AnimationFrameAction,_AnimationFrameScheduler PURE_IMPORTS_END */ -var animationFrame = /*@__PURE__*/ new _AnimationFrameScheduler__WEBPACK_IMPORTED_MODULE_1__["AnimationFrameScheduler"](_AnimationFrameAction__WEBPACK_IMPORTED_MODULE_0__["AnimationFrameAction"]); +var animationFrameScheduler = /*@__PURE__*/ new _AnimationFrameScheduler__WEBPACK_IMPORTED_MODULE_1__["AnimationFrameScheduler"](_AnimationFrameAction__WEBPACK_IMPORTED_MODULE_0__["AnimationFrameAction"]); +var animationFrame = animationFrameScheduler; //# sourceMappingURL=animationFrame.js.map @@ -4599,8 +4619,8 @@ function combineLatest() { for (var _i = 0; _i < arguments.length; _i++) { observables[_i] = arguments[_i]; } - var resultSelector = null; - var scheduler = null; + var resultSelector = undefined; + var scheduler = undefined; if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_1__["isScheduler"])(observables[observables.length - 1])) { scheduler = observables.pop(); } @@ -4647,7 +4667,7 @@ var CombineLatestSubscriber = /*@__PURE__*/ (function (_super) { this.toRespond = len; for (var i = 0; i < len; i++) { var observable = observables[i]; - this.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__["subscribeToResult"])(this, observable, observable, i)); + this.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__["subscribeToResult"])(this, observable, undefined, i)); } } }; @@ -4656,7 +4676,7 @@ var CombineLatestSubscriber = /*@__PURE__*/ (function (_super) { this.destination.complete(); } }; - CombineLatestSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + CombineLatestSubscriber.prototype.notifyNext = function (_outerValue, innerValue, outerIndex) { var values = this.values; var oldVal = values[outerIndex]; var toRespond = !this.toRespond @@ -4877,7 +4897,14 @@ var subscribeToIterable = function (iterable) { return function (subscriber) { var iterator = iterable[_symbol_iterator__WEBPACK_IMPORTED_MODULE_0__["iterator"]](); do { - var item = iterator.next(); + var item = void 0; + try { + item = iterator.next(); + } + catch (err) { + subscriber.error(err); + return subscriber; + } if (item.done) { subscriber.complete(); break; @@ -5039,15 +5066,12 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mergeMap", function() { return mergeMap; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MergeMapOperator", function() { return MergeMapOperator; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MergeMapSubscriber", function() { return MergeMapSubscriber; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "flatMap", function() { return flatMap; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(70); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(69); -/* harmony import */ var _InnerSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(71); -/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(66); -/* harmony import */ var _observable_from__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(83); -/** PURE_IMPORTS_START tslib,_util_subscribeToResult,_OuterSubscriber,_InnerSubscriber,_map,_observable_from PURE_IMPORTS_END */ - - +/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(66); +/* harmony import */ var _observable_from__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(83); +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_map,_observable_from,_innerSubscribe PURE_IMPORTS_END */ @@ -5057,7 +5081,7 @@ function mergeMap(project, resultSelector, concurrent) { concurrent = Number.POSITIVE_INFINITY; } if (typeof resultSelector === 'function') { - return function (source) { return source.pipe(mergeMap(function (a, i) { return Object(_observable_from__WEBPACK_IMPORTED_MODULE_5__["from"])(project(a, i)).pipe(Object(_map__WEBPACK_IMPORTED_MODULE_4__["map"])(function (b, ii) { return resultSelector(a, b, i, ii); })); }, concurrent)); }; + return function (source) { return source.pipe(mergeMap(function (a, i) { return Object(_observable_from__WEBPACK_IMPORTED_MODULE_2__["from"])(project(a, i)).pipe(Object(_map__WEBPACK_IMPORTED_MODULE_1__["map"])(function (b, ii) { return resultSelector(a, b, i, ii); })); }, concurrent)); }; } else if (typeof resultSelector === 'number') { concurrent = resultSelector; @@ -5112,13 +5136,13 @@ var MergeMapSubscriber = /*@__PURE__*/ (function (_super) { return; } this.active++; - this._innerSub(result, value, index); + this._innerSub(result); }; - MergeMapSubscriber.prototype._innerSub = function (ish, value, index) { - var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_3__["InnerSubscriber"](this, value, index); + MergeMapSubscriber.prototype._innerSub = function (ish) { + var innerSubscriber = new _innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["SimpleInnerSubscriber"](this); var destination = this.destination; destination.add(innerSubscriber); - var innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_1__["subscribeToResult"])(this, ish, undefined, undefined, innerSubscriber); + var innerSubscription = Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["innerSubscribe"])(ish, innerSubscriber); if (innerSubscription !== innerSubscriber) { destination.add(innerSubscription); } @@ -5130,12 +5154,11 @@ var MergeMapSubscriber = /*@__PURE__*/ (function (_super) { } this.unsubscribe(); }; - MergeMapSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + MergeMapSubscriber.prototype.notifyNext = function (innerValue) { this.destination.next(innerValue); }; - MergeMapSubscriber.prototype.notifyComplete = function (innerSub) { + MergeMapSubscriber.prototype.notifyComplete = function () { var buffer = this.buffer; - this.remove(innerSub); this.active--; if (buffer.length > 0) { this._next(buffer.shift()); @@ -5145,8 +5168,9 @@ var MergeMapSubscriber = /*@__PURE__*/ (function (_super) { } }; return MergeMapSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["SimpleOuterSubscriber"])); +var flatMap = mergeMap; //# sourceMappingURL=mergeMap.js.map @@ -5378,6 +5402,116 @@ function isIterable(input) { /* 90 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SimpleInnerSubscriber", function() { return SimpleInnerSubscriber; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ComplexInnerSubscriber", function() { return ComplexInnerSubscriber; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SimpleOuterSubscriber", function() { return SimpleOuterSubscriber; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ComplexOuterSubscriber", function() { return ComplexOuterSubscriber; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "innerSubscribe", function() { return innerSubscribe; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(9); +/* harmony import */ var _util_subscribeTo__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(72); +/** PURE_IMPORTS_START tslib,_Subscriber,_Observable,_util_subscribeTo PURE_IMPORTS_END */ + + + + +var SimpleInnerSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SimpleInnerSubscriber, _super); + function SimpleInnerSubscriber(parent) { + var _this = _super.call(this) || this; + _this.parent = parent; + return _this; + } + SimpleInnerSubscriber.prototype._next = function (value) { + this.parent.notifyNext(value); + }; + SimpleInnerSubscriber.prototype._error = function (error) { + this.parent.notifyError(error); + this.unsubscribe(); + }; + SimpleInnerSubscriber.prototype._complete = function () { + this.parent.notifyComplete(); + this.unsubscribe(); + }; + return SimpleInnerSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); + +var ComplexInnerSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ComplexInnerSubscriber, _super); + function ComplexInnerSubscriber(parent, outerValue, outerIndex) { + var _this = _super.call(this) || this; + _this.parent = parent; + _this.outerValue = outerValue; + _this.outerIndex = outerIndex; + return _this; + } + ComplexInnerSubscriber.prototype._next = function (value) { + this.parent.notifyNext(this.outerValue, value, this.outerIndex, this); + }; + ComplexInnerSubscriber.prototype._error = function (error) { + this.parent.notifyError(error); + this.unsubscribe(); + }; + ComplexInnerSubscriber.prototype._complete = function () { + this.parent.notifyComplete(this); + this.unsubscribe(); + }; + return ComplexInnerSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); + +var SimpleOuterSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SimpleOuterSubscriber, _super); + function SimpleOuterSubscriber() { + return _super !== null && _super.apply(this, arguments) || this; + } + SimpleOuterSubscriber.prototype.notifyNext = function (innerValue) { + this.destination.next(innerValue); + }; + SimpleOuterSubscriber.prototype.notifyError = function (err) { + this.destination.error(err); + }; + SimpleOuterSubscriber.prototype.notifyComplete = function () { + this.destination.complete(); + }; + return SimpleOuterSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); + +var ComplexOuterSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ComplexOuterSubscriber, _super); + function ComplexOuterSubscriber() { + return _super !== null && _super.apply(this, arguments) || this; + } + ComplexOuterSubscriber.prototype.notifyNext = function (_outerValue, innerValue, _outerIndex, _innerSub) { + this.destination.next(innerValue); + }; + ComplexOuterSubscriber.prototype.notifyError = function (error) { + this.destination.error(error); + }; + ComplexOuterSubscriber.prototype.notifyComplete = function (_innerSub) { + this.destination.complete(); + }; + return ComplexOuterSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); + +function innerSubscribe(result, innerSubscriber) { + if (innerSubscriber.closed) { + return undefined; + } + if (result instanceof _Observable__WEBPACK_IMPORTED_MODULE_2__["Observable"]) { + return result.subscribe(innerSubscriber); + } + return Object(_util_subscribeTo__WEBPACK_IMPORTED_MODULE_3__["subscribeTo"])(result)(innerSubscriber); +} +//# sourceMappingURL=innerSubscribe.js.map + + +/***/ }), +/* 91 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "defer", function() { return defer; }); @@ -5406,7 +5540,7 @@ function defer(observableFactory) { /***/ }), -/* 91 */ +/* 92 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -5489,7 +5623,7 @@ function forkJoinInternal(sources, keys) { /***/ }), -/* 92 */ +/* 93 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -5565,7 +5699,7 @@ function isEventTarget(sourceObj) { /***/ }), -/* 93 */ +/* 94 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -5610,7 +5744,7 @@ function fromEventPattern(addHandler, removeHandler, resultSelector) { /***/ }), -/* 94 */ +/* 95 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -5747,13 +5881,13 @@ function dispatch(state) { /***/ }), -/* 95 */ +/* 96 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "iif", function() { return iif; }); -/* harmony import */ var _defer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(90); +/* harmony import */ var _defer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(91); /* harmony import */ var _empty__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(43); /** PURE_IMPORTS_START _defer,_empty PURE_IMPORTS_END */ @@ -5771,7 +5905,7 @@ function iif(condition, trueResult, falseResult) { /***/ }), -/* 96 */ +/* 97 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -5779,7 +5913,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "interval", function() { return interval; }); /* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(55); -/* harmony import */ var _util_isNumeric__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(97); +/* harmony import */ var _util_isNumeric__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(98); /** PURE_IMPORTS_START _Observable,_scheduler_async,_util_isNumeric PURE_IMPORTS_END */ @@ -5811,7 +5945,7 @@ function dispatch(state) { /***/ }), -/* 97 */ +/* 98 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -5827,7 +5961,7 @@ function isNumeric(val) { /***/ }), -/* 98 */ +/* 99 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -5868,7 +6002,7 @@ function merge() { /***/ }), -/* 99 */ +/* 100 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -5888,7 +6022,7 @@ function never() { /***/ }), -/* 100 */ +/* 101 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -5928,7 +6062,7 @@ function onErrorResumeNext() { /***/ }), -/* 101 */ +/* 102 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -5979,15 +6113,15 @@ function dispatch(state) { /***/ }), -/* 102 */ +/* 103 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "partition", function() { return partition; }); -/* harmony import */ var _util_not__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(103); +/* harmony import */ var _util_not__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(104); /* harmony import */ var _util_subscribeTo__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(72); -/* harmony import */ var _operators_filter__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(104); +/* harmony import */ var _operators_filter__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(105); /* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(9); /** PURE_IMPORTS_START _util_not,_util_subscribeTo,_operators_filter,_Observable PURE_IMPORTS_END */ @@ -6004,7 +6138,7 @@ function partition(source, predicate, thisArg) { /***/ }), -/* 103 */ +/* 104 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -6023,7 +6157,7 @@ function not(pred, thisArg) { /***/ }), -/* 104 */ +/* 105 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -6077,7 +6211,7 @@ var FilterSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 105 */ +/* 106 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -6141,7 +6275,7 @@ var RaceSubscriber = /*@__PURE__*/ (function (_super) { else { for (var i = 0; i < len && !this.hasFirst; i++) { var observable = observables[i]; - var subscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__["subscribeToResult"])(this, observable, observable, i); + var subscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__["subscribeToResult"])(this, observable, undefined, i); if (this.subscriptions) { this.subscriptions.push(subscription); } @@ -6150,7 +6284,7 @@ var RaceSubscriber = /*@__PURE__*/ (function (_super) { this.observables = null; } }; - RaceSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + RaceSubscriber.prototype.notifyNext = function (_outerValue, innerValue, outerIndex) { if (!this.hasFirst) { this.hasFirst = true; for (var i = 0; i < this.subscriptions.length; i++) { @@ -6171,7 +6305,7 @@ var RaceSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 106 */ +/* 107 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -6230,7 +6364,7 @@ function dispatch(state) { /***/ }), -/* 107 */ +/* 108 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -6238,7 +6372,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timer", function() { return timer; }); /* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(55); -/* harmony import */ var _util_isNumeric__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(97); +/* harmony import */ var _util_isNumeric__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(98); /* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(45); /** PURE_IMPORTS_START _Observable,_scheduler_async,_util_isNumeric,_util_isScheduler PURE_IMPORTS_END */ @@ -6284,7 +6418,7 @@ function dispatch(state) { /***/ }), -/* 108 */ +/* 109 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -6329,7 +6463,7 @@ function using(resourceFactory, observableFactory) { /***/ }), -/* 109 */ +/* 110 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -6341,11 +6475,9 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _fromArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(46); /* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(18); /* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(11); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(69); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(70); -/* harmony import */ var _internal_symbol_iterator__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(75); -/** PURE_IMPORTS_START tslib,_fromArray,_util_isArray,_Subscriber,_OuterSubscriber,_util_subscribeToResult,_.._internal_symbol_iterator PURE_IMPORTS_END */ - +/* harmony import */ var _internal_symbol_iterator__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(75); +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_fromArray,_util_isArray,_Subscriber,_.._internal_symbol_iterator,_innerSubscribe PURE_IMPORTS_END */ @@ -6380,10 +6512,10 @@ var ZipSubscriber = /*@__PURE__*/ (function (_super) { values = Object.create(null); } var _this = _super.call(this, destination) || this; + _this.resultSelector = resultSelector; _this.iterators = []; _this.active = 0; - _this.resultSelector = (typeof resultSelector === 'function') ? resultSelector : null; - _this.values = values; + _this.resultSelector = (typeof resultSelector === 'function') ? resultSelector : undefined; return _this; } ZipSubscriber.prototype._next = function (value) { @@ -6391,8 +6523,8 @@ var ZipSubscriber = /*@__PURE__*/ (function (_super) { if (Object(_util_isArray__WEBPACK_IMPORTED_MODULE_2__["isArray"])(value)) { iterators.push(new StaticArrayIterator(value)); } - else if (typeof value[_internal_symbol_iterator__WEBPACK_IMPORTED_MODULE_6__["iterator"]] === 'function') { - iterators.push(new StaticIterator(value[_internal_symbol_iterator__WEBPACK_IMPORTED_MODULE_6__["iterator"]]())); + else if (typeof value[_internal_symbol_iterator__WEBPACK_IMPORTED_MODULE_4__["iterator"]] === 'function') { + iterators.push(new StaticIterator(value[_internal_symbol_iterator__WEBPACK_IMPORTED_MODULE_4__["iterator"]]())); } else { iterators.push(new ZipBufferIterator(this.destination, this, value)); @@ -6411,7 +6543,7 @@ var ZipSubscriber = /*@__PURE__*/ (function (_super) { var iterator = iterators[i]; if (iterator.stillUnsubscribed) { var destination = this.destination; - destination.add(iterator.subscribe(iterator, i)); + destination.add(iterator.subscribe()); } else { this.active--; @@ -6487,7 +6619,7 @@ var StaticIterator = /*@__PURE__*/ (function () { }; StaticIterator.prototype.hasCompleted = function () { var nextResult = this.nextResult; - return nextResult && nextResult.done; + return Boolean(nextResult && nextResult.done); }; return StaticIterator; }()); @@ -6498,7 +6630,7 @@ var StaticArrayIterator = /*@__PURE__*/ (function () { this.length = 0; this.length = array.length; } - StaticArrayIterator.prototype[_internal_symbol_iterator__WEBPACK_IMPORTED_MODULE_6__["iterator"]] = function () { + StaticArrayIterator.prototype[_internal_symbol_iterator__WEBPACK_IMPORTED_MODULE_4__["iterator"]] = function () { return this; }; StaticArrayIterator.prototype.next = function (value) { @@ -6525,7 +6657,7 @@ var ZipBufferIterator = /*@__PURE__*/ (function (_super) { _this.isComplete = false; return _this; } - ZipBufferIterator.prototype[_internal_symbol_iterator__WEBPACK_IMPORTED_MODULE_6__["iterator"]] = function () { + ZipBufferIterator.prototype[_internal_symbol_iterator__WEBPACK_IMPORTED_MODULE_4__["iterator"]] = function () { return this; }; ZipBufferIterator.prototype.next = function () { @@ -6552,20 +6684,20 @@ var ZipBufferIterator = /*@__PURE__*/ (function (_super) { this.destination.complete(); } }; - ZipBufferIterator.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + ZipBufferIterator.prototype.notifyNext = function (innerValue) { this.buffer.push(innerValue); this.parent.checkIterators(); }; - ZipBufferIterator.prototype.subscribe = function (value, index) { - return Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_5__["subscribeToResult"])(this, this.observable, this, index); + ZipBufferIterator.prototype.subscribe = function () { + return Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_5__["innerSubscribe"])(this.observable, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_5__["SimpleInnerSubscriber"](this)); }; return ZipBufferIterator; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_4__["OuterSubscriber"])); +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_5__["SimpleOuterSubscriber"])); //# sourceMappingURL=zip.js.map /***/ }), -/* 110 */ +/* 111 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -6591,9 +6723,9 @@ var ZipBufferIterator = /*@__PURE__*/ (function (_super) { Object.defineProperty(exports, "__esModule", { value: true }); exports.ToolingLogTextWriter = void 0; const tslib_1 = __webpack_require__(7); -const util_1 = __webpack_require__(111); -const chalk_1 = tslib_1.__importDefault(__webpack_require__(112)); -const log_levels_1 = __webpack_require__(125); +const util_1 = __webpack_require__(112); +const chalk_1 = tslib_1.__importDefault(__webpack_require__(113)); +const log_levels_1 = __webpack_require__(126); const { magentaBright, yellow, red, blue, green, dim } = chalk_1.default; const PREFIX_INDENT = ' '.repeat(6); const MSG_PREFIXES = { @@ -6660,23 +6792,23 @@ exports.ToolingLogTextWriter = ToolingLogTextWriter; /***/ }), -/* 111 */ +/* 112 */ /***/ (function(module, exports) { module.exports = require("util"); /***/ }), -/* 112 */ +/* 113 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const ansiStyles = __webpack_require__(113); -const {stdout: stdoutColor, stderr: stderrColor} = __webpack_require__(119); +const ansiStyles = __webpack_require__(114); +const {stdout: stdoutColor, stderr: stderrColor} = __webpack_require__(120); const { stringReplaceAll, stringEncaseCRLFWithFirstIndex -} = __webpack_require__(123); +} = __webpack_require__(124); const {isArray} = Array; @@ -6885,7 +7017,7 @@ const chalkTag = (chalk, ...strings) => { } if (template === undefined) { - template = __webpack_require__(124); + template = __webpack_require__(125); } return template(chalk, parts.join('')); @@ -6902,7 +7034,7 @@ module.exports = chalk; /***/ }), -/* 113 */ +/* 114 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -6948,7 +7080,7 @@ const setLazyProperty = (object, property, get) => { let colorConvert; const makeDynamicStyles = (wrap, targetSpace, identity, isBackground) => { if (colorConvert === undefined) { - colorConvert = __webpack_require__(115); + colorConvert = __webpack_require__(116); } const offset = isBackground ? 10 : 0; @@ -7070,10 +7202,10 @@ Object.defineProperty(module, 'exports', { get: assembleStyles }); -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(114)(module))) +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(115)(module))) /***/ }), -/* 114 */ +/* 115 */ /***/ (function(module, exports) { module.exports = function(module) { @@ -7101,11 +7233,11 @@ module.exports = function(module) { /***/ }), -/* 115 */ +/* 116 */ /***/ (function(module, exports, __webpack_require__) { -const conversions = __webpack_require__(116); -const route = __webpack_require__(118); +const conversions = __webpack_require__(117); +const route = __webpack_require__(119); const convert = {}; @@ -7188,12 +7320,12 @@ module.exports = convert; /***/ }), -/* 116 */ +/* 117 */ /***/ (function(module, exports, __webpack_require__) { /* MIT license */ /* eslint-disable no-mixed-operators */ -const cssKeywords = __webpack_require__(117); +const cssKeywords = __webpack_require__(118); // NOTE: conversions should only return primitive values (i.e. arrays, or // values that give correct `typeof` results). @@ -8033,7 +8165,7 @@ convert.rgb.gray = function (rgb) { /***/ }), -/* 117 */ +/* 118 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -8192,10 +8324,10 @@ module.exports = { /***/ }), -/* 118 */ +/* 119 */ /***/ (function(module, exports, __webpack_require__) { -const conversions = __webpack_require__(116); +const conversions = __webpack_require__(117); /* This function routes a model to all other models. @@ -8295,14 +8427,14 @@ module.exports = function (fromModel) { /***/ }), -/* 119 */ +/* 120 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const os = __webpack_require__(120); -const tty = __webpack_require__(121); -const hasFlag = __webpack_require__(122); +const os = __webpack_require__(121); +const tty = __webpack_require__(122); +const hasFlag = __webpack_require__(123); const {env} = process; @@ -8441,19 +8573,19 @@ module.exports = { /***/ }), -/* 120 */ +/* 121 */ /***/ (function(module, exports) { module.exports = require("os"); /***/ }), -/* 121 */ +/* 122 */ /***/ (function(module, exports) { module.exports = require("tty"); /***/ }), -/* 122 */ +/* 123 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -8468,7 +8600,7 @@ module.exports = (flag, argv = process.argv) => { /***/ }), -/* 123 */ +/* 124 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -8514,7 +8646,7 @@ module.exports = { /***/ }), -/* 124 */ +/* 125 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -8655,7 +8787,7 @@ module.exports = (chalk, temporary) => { /***/ }), -/* 125 */ +/* 126 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -8712,7 +8844,7 @@ exports.parseLogLevel = parseLogLevel; /***/ }), -/* 126 */ +/* 127 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -8737,7 +8869,7 @@ exports.parseLogLevel = parseLogLevel; */ Object.defineProperty(exports, "__esModule", { value: true }); exports.ToolingLogCollectingWriter = void 0; -const tooling_log_text_writer_1 = __webpack_require__(110); +const tooling_log_text_writer_1 = __webpack_require__(111); class ToolingLogCollectingWriter extends tooling_log_text_writer_1.ToolingLogTextWriter { constructor(level = 'verbose') { super({ @@ -8756,16 +8888,16 @@ exports.ToolingLogCollectingWriter = ToolingLogCollectingWriter; /***/ }), -/* 127 */ +/* 128 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "commands", function() { return commands; }); -/* harmony import */ var _bootstrap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(128); -/* harmony import */ var _clean__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(288); -/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(396); -/* harmony import */ var _watch__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(397); +/* harmony import */ var _bootstrap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(129); +/* harmony import */ var _clean__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(280); +/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(399); +/* harmony import */ var _watch__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(400); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -8796,20 +8928,20 @@ const commands = { }; /***/ }), -/* 128 */ +/* 129 */ /***/ (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 _utils_link_project_executables__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(129); -/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); -/* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(144); -/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(145); -/* harmony import */ var _utils_project_checksums__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(281); -/* harmony import */ var _utils_bootstrap_cache_file__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(286); -/* harmony import */ var _utils_yarn_lock__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(283); -/* harmony import */ var _utils_validate_yarn_lock__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(287); +/* harmony import */ var _utils_link_project_executables__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(130); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(144); +/* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(145); +/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(146); +/* harmony import */ var _utils_project_checksums__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(273); +/* harmony import */ var _utils_bootstrap_cache_file__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(278); +/* harmony import */ var _utils_yarn_lock__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(275); +/* harmony import */ var _utils_validate_yarn_lock__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(279); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -8916,7 +9048,7 @@ const BootstrapCommand = { }; /***/ }), -/* 129 */ +/* 130 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -8924,8 +9056,8 @@ __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__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(130); -/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(143); +/* harmony import */ var _fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(131); +/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(144); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -8987,7 +9119,7 @@ async function linkProjectExecutables(projectsByName, projectGraph) { } /***/ }), -/* 130 */ +/* 131 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -9002,15 +9134,15 @@ __webpack_require__.r(__webpack_exports__); /* 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__(131); +/* harmony import */ var cmd_shim__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(132); /* 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__(133); +/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(134); /* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var ncp__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(142); +/* harmony import */ var ncp__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(143); /* harmony import */ var ncp__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(ncp__WEBPACK_IMPORTED_MODULE_2__); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_3__); -/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(111); +/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(112); /* harmony import */ var util__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_4__); /* * Licensed to Elasticsearch B.V. under one or more contributor @@ -9123,7 +9255,7 @@ async function forceCreate(src, dest, type) { } /***/ }), -/* 131 */ +/* 132 */ /***/ (function(module, exports, __webpack_require__) { // On windows, create a .cmd file. @@ -9139,11 +9271,11 @@ async function forceCreate(src, dest, type) { module.exports = cmdShim cmdShim.ifExists = cmdShimIfExists -var fs = __webpack_require__(132) +var fs = __webpack_require__(133) -var mkdir = __webpack_require__(140) +var mkdir = __webpack_require__(141) , path = __webpack_require__(4) - , toBatchSyntax = __webpack_require__(141) + , toBatchSyntax = __webpack_require__(142) , shebangExpr = /^#\!\s*(?:\/usr\/bin\/env)?\s*([^ \t]+=[^ \t]+\s+)*\s*([^ \t]+)(.*)$/ function cmdShimIfExists (from, to, cb) { @@ -9376,15 +9508,15 @@ function times(n, ok, cb) { /***/ }), -/* 132 */ +/* 133 */ /***/ (function(module, exports, __webpack_require__) { -var fs = __webpack_require__(133) -var polyfills = __webpack_require__(134) -var legacy = __webpack_require__(136) -var clone = __webpack_require__(138) +var fs = __webpack_require__(134) +var polyfills = __webpack_require__(135) +var legacy = __webpack_require__(137) +var clone = __webpack_require__(139) -var util = __webpack_require__(111) +var util = __webpack_require__(112) /* istanbul ignore next - node 0.x polyfill */ var gracefulQueue @@ -9465,7 +9597,7 @@ if (!fs[gracefulQueue]) { if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { process.on('exit', function() { debug(fs[gracefulQueue]) - __webpack_require__(139).equal(fs[gracefulQueue].length, 0) + __webpack_require__(140).equal(fs[gracefulQueue].length, 0) }) } } @@ -9736,16 +9868,16 @@ function retry () { /***/ }), -/* 133 */ +/* 134 */ /***/ (function(module, exports) { module.exports = require("fs"); /***/ }), -/* 134 */ +/* 135 */ /***/ (function(module, exports, __webpack_require__) { -var constants = __webpack_require__(135) +var constants = __webpack_require__(136) var origCwd = process.cwd var cwd = null @@ -10090,16 +10222,16 @@ function patch (fs) { /***/ }), -/* 135 */ +/* 136 */ /***/ (function(module, exports) { module.exports = require("constants"); /***/ }), -/* 136 */ +/* 137 */ /***/ (function(module, exports, __webpack_require__) { -var Stream = __webpack_require__(137).Stream +var Stream = __webpack_require__(138).Stream module.exports = legacy @@ -10220,13 +10352,13 @@ function legacy (fs) { /***/ }), -/* 137 */ +/* 138 */ /***/ (function(module, exports) { module.exports = require("stream"); /***/ }), -/* 138 */ +/* 139 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -10252,17 +10384,17 @@ function clone (obj) { /***/ }), -/* 139 */ +/* 140 */ /***/ (function(module, exports) { module.exports = require("assert"); /***/ }), -/* 140 */ +/* 141 */ /***/ (function(module, exports, __webpack_require__) { var path = __webpack_require__(4); -var fs = __webpack_require__(133); +var fs = __webpack_require__(134); var _0777 = parseInt('0777', 8); module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP; @@ -10363,7 +10495,7 @@ mkdirP.sync = function sync (p, opts, made) { /***/ }), -/* 141 */ +/* 142 */ /***/ (function(module, exports) { exports.replaceDollarWithPercentPair = replaceDollarWithPercentPair @@ -10421,10 +10553,10 @@ function replaceDollarWithPercentPair(value) { /***/ }), -/* 142 */ +/* 143 */ /***/ (function(module, exports, __webpack_require__) { -var fs = __webpack_require__(133), +var fs = __webpack_require__(134), path = __webpack_require__(4); module.exports = ncp; @@ -10688,7 +10820,7 @@ function ncp (source, dest, options, callback) { /***/ }), -/* 143 */ +/* 144 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -10748,7 +10880,7 @@ const log = new Log(); /***/ }), -/* 144 */ +/* 145 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -10814,7 +10946,7 @@ async function parallelize(items, fn, concurrency = 4) { } /***/ }), -/* 145 */ +/* 146 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -10823,15 +10955,15 @@ __webpack_require__.r(__webpack_exports__); /* 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__(146); +/* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(147); /* 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__(4); /* 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__(111); +/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(112); /* 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__(162); -/* harmony import */ var _project__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(163); -/* harmony import */ var _workspaces__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(279); +/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(163); +/* harmony import */ var _project__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(164); +/* harmony import */ var _workspaces__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(271); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -11030,7 +11162,7 @@ function includeTransitiveProjects(subsetOfProjects, allProjects, { } /***/ }), -/* 146 */ +/* 147 */ /***/ (function(module, exports, __webpack_require__) { // Approach: @@ -11075,27 +11207,27 @@ function includeTransitiveProjects(subsetOfProjects, allProjects, { module.exports = glob -var fs = __webpack_require__(133) -var rp = __webpack_require__(147) -var minimatch = __webpack_require__(149) +var fs = __webpack_require__(134) +var rp = __webpack_require__(148) +var minimatch = __webpack_require__(150) var Minimatch = minimatch.Minimatch -var inherits = __webpack_require__(153) -var EE = __webpack_require__(155).EventEmitter +var inherits = __webpack_require__(154) +var EE = __webpack_require__(156).EventEmitter var path = __webpack_require__(4) -var assert = __webpack_require__(139) -var isAbsolute = __webpack_require__(156) -var globSync = __webpack_require__(157) -var common = __webpack_require__(158) +var assert = __webpack_require__(140) +var isAbsolute = __webpack_require__(157) +var globSync = __webpack_require__(158) +var common = __webpack_require__(159) var alphasort = common.alphasort var alphasorti = common.alphasorti var setopts = common.setopts var ownProp = common.ownProp -var inflight = __webpack_require__(159) -var util = __webpack_require__(111) +var inflight = __webpack_require__(160) +var util = __webpack_require__(112) var childrenIgnored = common.childrenIgnored var isIgnored = common.isIgnored -var once = __webpack_require__(161) +var once = __webpack_require__(162) function glob (pattern, options, cb) { if (typeof options === 'function') cb = options, options = {} @@ -11826,7 +11958,7 @@ Glob.prototype._stat2 = function (f, abs, er, stat, cb) { /***/ }), -/* 147 */ +/* 148 */ /***/ (function(module, exports, __webpack_require__) { module.exports = realpath @@ -11836,13 +11968,13 @@ realpath.realpathSync = realpathSync realpath.monkeypatch = monkeypatch realpath.unmonkeypatch = unmonkeypatch -var fs = __webpack_require__(133) +var fs = __webpack_require__(134) var origRealpath = fs.realpath var origRealpathSync = fs.realpathSync var version = process.version var ok = /^v[0-5]\./.test(version) -var old = __webpack_require__(148) +var old = __webpack_require__(149) function newError (er) { return er && er.syscall === 'realpath' && ( @@ -11898,7 +12030,7 @@ function unmonkeypatch () { /***/ }), -/* 148 */ +/* 149 */ /***/ (function(module, exports, __webpack_require__) { // Copyright Joyent, Inc. and other Node contributors. @@ -11924,7 +12056,7 @@ function unmonkeypatch () { var pathModule = __webpack_require__(4); var isWindows = process.platform === 'win32'; -var fs = __webpack_require__(133); +var fs = __webpack_require__(134); // JavaScript implementation of realpath, ported from node pre-v6 @@ -12207,7 +12339,7 @@ exports.realpath = function realpath(p, cache, cb) { /***/ }), -/* 149 */ +/* 150 */ /***/ (function(module, exports, __webpack_require__) { module.exports = minimatch @@ -12219,7 +12351,7 @@ try { } catch (er) {} var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} -var expand = __webpack_require__(150) +var expand = __webpack_require__(151) var plTypes = { '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, @@ -13136,11 +13268,11 @@ function regExpEscape (s) { /***/ }), -/* 150 */ +/* 151 */ /***/ (function(module, exports, __webpack_require__) { -var concatMap = __webpack_require__(151); -var balanced = __webpack_require__(152); +var concatMap = __webpack_require__(152); +var balanced = __webpack_require__(153); module.exports = expandTop; @@ -13343,7 +13475,7 @@ function expand(str, isTop) { /***/ }), -/* 151 */ +/* 152 */ /***/ (function(module, exports) { module.exports = function (xs, fn) { @@ -13362,7 +13494,7 @@ var isArray = Array.isArray || function (xs) { /***/ }), -/* 152 */ +/* 153 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -13428,22 +13560,22 @@ function range(a, b, str) { /***/ }), -/* 153 */ +/* 154 */ /***/ (function(module, exports, __webpack_require__) { try { - var util = __webpack_require__(111); + var util = __webpack_require__(112); /* istanbul ignore next */ if (typeof util.inherits !== 'function') throw ''; module.exports = util.inherits; } catch (e) { /* istanbul ignore next */ - module.exports = __webpack_require__(154); + module.exports = __webpack_require__(155); } /***/ }), -/* 154 */ +/* 155 */ /***/ (function(module, exports) { if (typeof Object.create === 'function') { @@ -13476,13 +13608,13 @@ if (typeof Object.create === 'function') { /***/ }), -/* 155 */ +/* 156 */ /***/ (function(module, exports) { module.exports = require("events"); /***/ }), -/* 156 */ +/* 157 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -13509,22 +13641,22 @@ module.exports.win32 = win32; /***/ }), -/* 157 */ +/* 158 */ /***/ (function(module, exports, __webpack_require__) { module.exports = globSync globSync.GlobSync = GlobSync -var fs = __webpack_require__(133) -var rp = __webpack_require__(147) -var minimatch = __webpack_require__(149) +var fs = __webpack_require__(134) +var rp = __webpack_require__(148) +var minimatch = __webpack_require__(150) var Minimatch = minimatch.Minimatch -var Glob = __webpack_require__(146).Glob -var util = __webpack_require__(111) +var Glob = __webpack_require__(147).Glob +var util = __webpack_require__(112) var path = __webpack_require__(4) -var assert = __webpack_require__(139) -var isAbsolute = __webpack_require__(156) -var common = __webpack_require__(158) +var assert = __webpack_require__(140) +var isAbsolute = __webpack_require__(157) +var common = __webpack_require__(159) var alphasort = common.alphasort var alphasorti = common.alphasorti var setopts = common.setopts @@ -14001,7 +14133,7 @@ GlobSync.prototype._makeAbs = function (f) { /***/ }), -/* 158 */ +/* 159 */ /***/ (function(module, exports, __webpack_require__) { exports.alphasort = alphasort @@ -14019,8 +14151,8 @@ function ownProp (obj, field) { } var path = __webpack_require__(4) -var minimatch = __webpack_require__(149) -var isAbsolute = __webpack_require__(156) +var minimatch = __webpack_require__(150) +var isAbsolute = __webpack_require__(157) var Minimatch = minimatch.Minimatch function alphasorti (a, b) { @@ -14247,12 +14379,12 @@ function childrenIgnored (self, path) { /***/ }), -/* 159 */ +/* 160 */ /***/ (function(module, exports, __webpack_require__) { -var wrappy = __webpack_require__(160) +var wrappy = __webpack_require__(161) var reqs = Object.create(null) -var once = __webpack_require__(161) +var once = __webpack_require__(162) module.exports = wrappy(inflight) @@ -14307,7 +14439,7 @@ function slice (args) { /***/ }), -/* 160 */ +/* 161 */ /***/ (function(module, exports) { // Returns a wrapper function that returns a wrapped callback @@ -14346,10 +14478,10 @@ function wrappy (fn, cb) { /***/ }), -/* 161 */ +/* 162 */ /***/ (function(module, exports, __webpack_require__) { -var wrappy = __webpack_require__(160) +var wrappy = __webpack_require__(161) module.exports = wrappy(once) module.exports.strict = wrappy(onceStrict) @@ -14394,7 +14526,7 @@ function onceStrict (fn) { /***/ }), -/* 162 */ +/* 163 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -14427,22 +14559,22 @@ class CliError extends Error { } /***/ }), -/* 163 */ +/* 164 */ /***/ (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 fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(133); +/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(134); /* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); /* 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__(111); +/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(112); /* 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__(162); -/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(143); -/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(164); -/* harmony import */ var _scripts__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(225); +/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(163); +/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(144); +/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(165); +/* harmony import */ var _scripts__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(226); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } @@ -14679,7 +14811,7 @@ function normalizePath(path) { } /***/ }), -/* 164 */ +/* 165 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -14687,9 +14819,9 @@ __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__(165); +/* harmony import */ var read_pkg__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(166); /* 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__(213); +/* harmony import */ var write_pkg__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(214); /* 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 @@ -14723,15 +14855,15 @@ function writePackageJson(path, json) { const isLinkDependency = depVersion => depVersion.startsWith('link:'); /***/ }), -/* 165 */ +/* 166 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const {promisify} = __webpack_require__(111); -const fs = __webpack_require__(133); +const {promisify} = __webpack_require__(112); +const fs = __webpack_require__(134); const path = __webpack_require__(4); -const parseJson = __webpack_require__(166); +const parseJson = __webpack_require__(167); const readFileAsync = promisify(fs.readFile); @@ -14746,7 +14878,7 @@ module.exports = async options => { const json = parseJson(await readFileAsync(filePath, 'utf8')); if (options.normalize) { - __webpack_require__(187)(json); + __webpack_require__(188)(json); } return json; @@ -14763,7 +14895,7 @@ module.exports.sync = options => { const json = parseJson(fs.readFileSync(filePath, 'utf8')); if (options.normalize) { - __webpack_require__(187)(json); + __webpack_require__(188)(json); } return json; @@ -14771,15 +14903,15 @@ module.exports.sync = options => { /***/ }), -/* 166 */ +/* 167 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const errorEx = __webpack_require__(167); -const fallback = __webpack_require__(169); -const {default: LinesAndColumns} = __webpack_require__(170); -const {codeFrameColumns} = __webpack_require__(171); +const errorEx = __webpack_require__(168); +const fallback = __webpack_require__(170); +const {default: LinesAndColumns} = __webpack_require__(171); +const {codeFrameColumns} = __webpack_require__(172); const JSONError = errorEx('JSONError', { fileName: errorEx.append('in %s'), @@ -14828,14 +14960,14 @@ module.exports = (string, reviver, filename) => { /***/ }), -/* 167 */ +/* 168 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var util = __webpack_require__(111); -var isArrayish = __webpack_require__(168); +var util = __webpack_require__(112); +var isArrayish = __webpack_require__(169); var errorEx = function errorEx(name, properties) { if (!name || name.constructor !== String) { @@ -14968,7 +15100,7 @@ module.exports = errorEx; /***/ }), -/* 168 */ +/* 169 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -14985,7 +15117,7 @@ module.exports = function isArrayish(obj) { /***/ }), -/* 169 */ +/* 170 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -14997,6 +15129,12 @@ function parseJson (txt, reviver, context) { try { return JSON.parse(txt, reviver) } catch (e) { + if (typeof txt !== 'string') { + const isEmptyArray = Array.isArray(txt) && txt.length === 0 + const errorMessage = 'Cannot parse ' + + (isEmptyArray ? 'an empty array' : String(txt)) + throw new TypeError(errorMessage) + } const syntaxErr = e.message.match(/^Unexpected token.*position\s+(\d+)/i) const errIdx = syntaxErr ? +syntaxErr[1] @@ -15024,7 +15162,7 @@ function parseJson (txt, reviver, context) { /***/ }), -/* 170 */ +/* 171 */ /***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) { "use strict"; @@ -15088,7 +15226,7 @@ var LinesAndColumns = (function () { /***/ }), -/* 171 */ +/* 172 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -15100,7 +15238,7 @@ Object.defineProperty(exports, "__esModule", { exports.codeFrameColumns = codeFrameColumns; exports.default = _default; -var _highlight = _interopRequireWildcard(__webpack_require__(172)); +var _highlight = _interopRequireWildcard(__webpack_require__(173)); function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } @@ -15261,7 +15399,7 @@ function _default(rawLines, lineNumber, colNumber, opts = {}) { } /***/ }), -/* 172 */ +/* 173 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -15274,11 +15412,11 @@ exports.shouldHighlight = shouldHighlight; exports.getChalk = getChalk; exports.default = highlight; -var _jsTokens = _interopRequireWildcard(__webpack_require__(173)); +var _jsTokens = _interopRequireWildcard(__webpack_require__(174)); -var _helperValidatorIdentifier = __webpack_require__(174); +var _helperValidatorIdentifier = __webpack_require__(175); -var _chalk = _interopRequireDefault(__webpack_require__(177)); +var _chalk = _interopRequireDefault(__webpack_require__(178)); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } @@ -15374,7 +15512,7 @@ function highlight(code, options = {}) { } /***/ }), -/* 173 */ +/* 174 */ /***/ (function(module, exports) { // Copyright 2014, 2015, 2016, 2017, 2018 Simon Lydell @@ -15403,7 +15541,7 @@ exports.matchToToken = function(match) { /***/ }), -/* 174 */ +/* 175 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -15461,12 +15599,12 @@ Object.defineProperty(exports, "isKeyword", { } }); -var _identifier = __webpack_require__(175); +var _identifier = __webpack_require__(176); -var _keyword = __webpack_require__(176); +var _keyword = __webpack_require__(177); /***/ }), -/* 175 */ +/* 176 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -15549,7 +15687,7 @@ function isIdentifierName(name) { } /***/ }), -/* 176 */ +/* 177 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -15593,16 +15731,16 @@ function isKeyword(word) { } /***/ }), -/* 177 */ +/* 178 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const escapeStringRegexp = __webpack_require__(178); -const ansiStyles = __webpack_require__(179); -const stdoutColor = __webpack_require__(184).stdout; +const escapeStringRegexp = __webpack_require__(179); +const ansiStyles = __webpack_require__(180); +const stdoutColor = __webpack_require__(185).stdout; -const template = __webpack_require__(186); +const template = __webpack_require__(187); const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); @@ -15828,7 +15966,7 @@ module.exports.default = module.exports; // For TypeScript /***/ }), -/* 178 */ +/* 179 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -15846,12 +15984,12 @@ module.exports = function (str) { /***/ }), -/* 179 */ +/* 180 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* WEBPACK VAR INJECTION */(function(module) { -const colorConvert = __webpack_require__(180); +const colorConvert = __webpack_require__(181); const wrapAnsi16 = (fn, offset) => function () { const code = fn.apply(colorConvert, arguments); @@ -16016,14 +16154,14 @@ Object.defineProperty(module, 'exports', { get: assembleStyles }); -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(114)(module))) +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(115)(module))) /***/ }), -/* 180 */ +/* 181 */ /***/ (function(module, exports, __webpack_require__) { -var conversions = __webpack_require__(181); -var route = __webpack_require__(183); +var conversions = __webpack_require__(182); +var route = __webpack_require__(184); var convert = {}; @@ -16103,11 +16241,11 @@ module.exports = convert; /***/ }), -/* 181 */ +/* 182 */ /***/ (function(module, exports, __webpack_require__) { /* MIT license */ -var cssKeywords = __webpack_require__(182); +var cssKeywords = __webpack_require__(183); // NOTE: conversions should only return primitive values (i.e. arrays, or // values that give correct `typeof` results). @@ -16977,7 +17115,7 @@ convert.rgb.gray = function (rgb) { /***/ }), -/* 182 */ +/* 183 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -17136,10 +17274,10 @@ module.exports = { /***/ }), -/* 183 */ +/* 184 */ /***/ (function(module, exports, __webpack_require__) { -var conversions = __webpack_require__(181); +var conversions = __webpack_require__(182); /* this function routes a model to all other models. @@ -17239,13 +17377,13 @@ module.exports = function (fromModel) { /***/ }), -/* 184 */ +/* 185 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const os = __webpack_require__(120); -const hasFlag = __webpack_require__(185); +const os = __webpack_require__(121); +const hasFlag = __webpack_require__(186); const env = process.env; @@ -17377,7 +17515,7 @@ module.exports = { /***/ }), -/* 185 */ +/* 186 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -17392,7 +17530,7 @@ module.exports = (flag, argv) => { /***/ }), -/* 186 */ +/* 187 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -17527,15 +17665,15 @@ module.exports = (chalk, tmp) => { /***/ }), -/* 187 */ +/* 188 */ /***/ (function(module, exports, __webpack_require__) { module.exports = normalize -var fixer = __webpack_require__(188) +var fixer = __webpack_require__(189) normalize.fixer = fixer -var makeWarning = __webpack_require__(211) +var makeWarning = __webpack_require__(212) var fieldsToFix = ['name','version','description','repository','modules','scripts' ,'files','bin','man','bugs','keywords','readme','homepage','license'] @@ -17572,17 +17710,17 @@ function ucFirst (string) { /***/ }), -/* 188 */ +/* 189 */ /***/ (function(module, exports, __webpack_require__) { -var semver = __webpack_require__(189) -var validateLicense = __webpack_require__(190); -var hostedGitInfo = __webpack_require__(195) -var isBuiltinModule = __webpack_require__(199).isCore +var semver = __webpack_require__(190) +var validateLicense = __webpack_require__(191); +var hostedGitInfo = __webpack_require__(196) +var isBuiltinModule = __webpack_require__(200).isCore var depTypes = ["dependencies","devDependencies","optionalDependencies"] -var extractDescription = __webpack_require__(209) -var url = __webpack_require__(196) -var typos = __webpack_require__(210) +var extractDescription = __webpack_require__(210) +var url = __webpack_require__(197) +var typos = __webpack_require__(211) var fixer = module.exports = { // default warning function @@ -17996,7 +18134,7 @@ function bugsTypos(bugs, warn) { /***/ }), -/* 189 */ +/* 190 */ /***/ (function(module, exports) { exports = module.exports = SemVer @@ -19485,11 +19623,11 @@ function coerce (version) { /***/ }), -/* 190 */ +/* 191 */ /***/ (function(module, exports, __webpack_require__) { -var parse = __webpack_require__(191); -var correct = __webpack_require__(193); +var parse = __webpack_require__(192); +var correct = __webpack_require__(194); var genericWarning = ( 'license should be ' + @@ -19575,10 +19713,10 @@ module.exports = function(argument) { /***/ }), -/* 191 */ +/* 192 */ /***/ (function(module, exports, __webpack_require__) { -var parser = __webpack_require__(192).parser +var parser = __webpack_require__(193).parser module.exports = function (argument) { return parser.parse(argument) @@ -19586,7 +19724,7 @@ module.exports = function (argument) { /***/ }), -/* 192 */ +/* 193 */ /***/ (function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(module) {/* parser generated by jison 0.4.17 */ @@ -20939,7 +21077,7 @@ exports.main = function commonjsMain(args) { console.log('Usage: '+args[0]+' FILE'); process.exit(1); } - var source = __webpack_require__(133).readFileSync(__webpack_require__(4).normalize(args[1]), "utf8"); + var source = __webpack_require__(134).readFileSync(__webpack_require__(4).normalize(args[1]), "utf8"); return exports.parser.parse(source); }; if ( true && __webpack_require__.c[__webpack_require__.s] === module) { @@ -20947,13 +21085,13 @@ if ( true && __webpack_require__.c[__webpack_require__.s] === module) { } } -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(114)(module))) +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(115)(module))) /***/ }), -/* 193 */ +/* 194 */ /***/ (function(module, exports, __webpack_require__) { -var licenseIDs = __webpack_require__(194); +var licenseIDs = __webpack_require__(195); function valid(string) { return licenseIDs.indexOf(string) > -1; @@ -21193,20 +21331,20 @@ module.exports = function(identifier) { /***/ }), -/* 194 */ +/* 195 */ /***/ (function(module) { module.exports = JSON.parse("[\"Glide\",\"Abstyles\",\"AFL-1.1\",\"AFL-1.2\",\"AFL-2.0\",\"AFL-2.1\",\"AFL-3.0\",\"AMPAS\",\"APL-1.0\",\"Adobe-Glyph\",\"APAFML\",\"Adobe-2006\",\"AGPL-1.0\",\"Afmparse\",\"Aladdin\",\"ADSL\",\"AMDPLPA\",\"ANTLR-PD\",\"Apache-1.0\",\"Apache-1.1\",\"Apache-2.0\",\"AML\",\"APSL-1.0\",\"APSL-1.1\",\"APSL-1.2\",\"APSL-2.0\",\"Artistic-1.0\",\"Artistic-1.0-Perl\",\"Artistic-1.0-cl8\",\"Artistic-2.0\",\"AAL\",\"Bahyph\",\"Barr\",\"Beerware\",\"BitTorrent-1.0\",\"BitTorrent-1.1\",\"BSL-1.0\",\"Borceux\",\"BSD-2-Clause\",\"BSD-2-Clause-FreeBSD\",\"BSD-2-Clause-NetBSD\",\"BSD-3-Clause\",\"BSD-3-Clause-Clear\",\"BSD-4-Clause\",\"BSD-Protection\",\"BSD-Source-Code\",\"BSD-3-Clause-Attribution\",\"0BSD\",\"BSD-4-Clause-UC\",\"bzip2-1.0.5\",\"bzip2-1.0.6\",\"Caldera\",\"CECILL-1.0\",\"CECILL-1.1\",\"CECILL-2.0\",\"CECILL-2.1\",\"CECILL-B\",\"CECILL-C\",\"ClArtistic\",\"MIT-CMU\",\"CNRI-Jython\",\"CNRI-Python\",\"CNRI-Python-GPL-Compatible\",\"CPOL-1.02\",\"CDDL-1.0\",\"CDDL-1.1\",\"CPAL-1.0\",\"CPL-1.0\",\"CATOSL-1.1\",\"Condor-1.1\",\"CC-BY-1.0\",\"CC-BY-2.0\",\"CC-BY-2.5\",\"CC-BY-3.0\",\"CC-BY-4.0\",\"CC-BY-ND-1.0\",\"CC-BY-ND-2.0\",\"CC-BY-ND-2.5\",\"CC-BY-ND-3.0\",\"CC-BY-ND-4.0\",\"CC-BY-NC-1.0\",\"CC-BY-NC-2.0\",\"CC-BY-NC-2.5\",\"CC-BY-NC-3.0\",\"CC-BY-NC-4.0\",\"CC-BY-NC-ND-1.0\",\"CC-BY-NC-ND-2.0\",\"CC-BY-NC-ND-2.5\",\"CC-BY-NC-ND-3.0\",\"CC-BY-NC-ND-4.0\",\"CC-BY-NC-SA-1.0\",\"CC-BY-NC-SA-2.0\",\"CC-BY-NC-SA-2.5\",\"CC-BY-NC-SA-3.0\",\"CC-BY-NC-SA-4.0\",\"CC-BY-SA-1.0\",\"CC-BY-SA-2.0\",\"CC-BY-SA-2.5\",\"CC-BY-SA-3.0\",\"CC-BY-SA-4.0\",\"CC0-1.0\",\"Crossword\",\"CrystalStacker\",\"CUA-OPL-1.0\",\"Cube\",\"curl\",\"D-FSL-1.0\",\"diffmark\",\"WTFPL\",\"DOC\",\"Dotseqn\",\"DSDP\",\"dvipdfm\",\"EPL-1.0\",\"ECL-1.0\",\"ECL-2.0\",\"eGenix\",\"EFL-1.0\",\"EFL-2.0\",\"MIT-advertising\",\"MIT-enna\",\"Entessa\",\"ErlPL-1.1\",\"EUDatagrid\",\"EUPL-1.0\",\"EUPL-1.1\",\"Eurosym\",\"Fair\",\"MIT-feh\",\"Frameworx-1.0\",\"FreeImage\",\"FTL\",\"FSFAP\",\"FSFUL\",\"FSFULLR\",\"Giftware\",\"GL2PS\",\"Glulxe\",\"AGPL-3.0\",\"GFDL-1.1\",\"GFDL-1.2\",\"GFDL-1.3\",\"GPL-1.0\",\"GPL-2.0\",\"GPL-3.0\",\"LGPL-2.1\",\"LGPL-3.0\",\"LGPL-2.0\",\"gnuplot\",\"gSOAP-1.3b\",\"HaskellReport\",\"HPND\",\"IBM-pibs\",\"IPL-1.0\",\"ICU\",\"ImageMagick\",\"iMatix\",\"Imlib2\",\"IJG\",\"Info-ZIP\",\"Intel-ACPI\",\"Intel\",\"Interbase-1.0\",\"IPA\",\"ISC\",\"JasPer-2.0\",\"JSON\",\"LPPL-1.0\",\"LPPL-1.1\",\"LPPL-1.2\",\"LPPL-1.3a\",\"LPPL-1.3c\",\"Latex2e\",\"BSD-3-Clause-LBNL\",\"Leptonica\",\"LGPLLR\",\"Libpng\",\"libtiff\",\"LAL-1.2\",\"LAL-1.3\",\"LiLiQ-P-1.1\",\"LiLiQ-Rplus-1.1\",\"LiLiQ-R-1.1\",\"LPL-1.02\",\"LPL-1.0\",\"MakeIndex\",\"MTLL\",\"MS-PL\",\"MS-RL\",\"MirOS\",\"MITNFA\",\"MIT\",\"Motosoto\",\"MPL-1.0\",\"MPL-1.1\",\"MPL-2.0\",\"MPL-2.0-no-copyleft-exception\",\"mpich2\",\"Multics\",\"Mup\",\"NASA-1.3\",\"Naumen\",\"NBPL-1.0\",\"NetCDF\",\"NGPL\",\"NOSL\",\"NPL-1.0\",\"NPL-1.1\",\"Newsletr\",\"NLPL\",\"Nokia\",\"NPOSL-3.0\",\"NLOD-1.0\",\"Noweb\",\"NRL\",\"NTP\",\"Nunit\",\"OCLC-2.0\",\"ODbL-1.0\",\"PDDL-1.0\",\"OCCT-PL\",\"OGTSL\",\"OLDAP-2.2.2\",\"OLDAP-1.1\",\"OLDAP-1.2\",\"OLDAP-1.3\",\"OLDAP-1.4\",\"OLDAP-2.0\",\"OLDAP-2.0.1\",\"OLDAP-2.1\",\"OLDAP-2.2\",\"OLDAP-2.2.1\",\"OLDAP-2.3\",\"OLDAP-2.4\",\"OLDAP-2.5\",\"OLDAP-2.6\",\"OLDAP-2.7\",\"OLDAP-2.8\",\"OML\",\"OPL-1.0\",\"OSL-1.0\",\"OSL-1.1\",\"OSL-2.0\",\"OSL-2.1\",\"OSL-3.0\",\"OpenSSL\",\"OSET-PL-2.1\",\"PHP-3.0\",\"PHP-3.01\",\"Plexus\",\"PostgreSQL\",\"psfrag\",\"psutils\",\"Python-2.0\",\"QPL-1.0\",\"Qhull\",\"Rdisc\",\"RPSL-1.0\",\"RPL-1.1\",\"RPL-1.5\",\"RHeCos-1.1\",\"RSCPL\",\"RSA-MD\",\"Ruby\",\"SAX-PD\",\"Saxpath\",\"SCEA\",\"SWL\",\"SMPPL\",\"Sendmail\",\"SGI-B-1.0\",\"SGI-B-1.1\",\"SGI-B-2.0\",\"OFL-1.0\",\"OFL-1.1\",\"SimPL-2.0\",\"Sleepycat\",\"SNIA\",\"Spencer-86\",\"Spencer-94\",\"Spencer-99\",\"SMLNJ\",\"SugarCRM-1.1.3\",\"SISSL\",\"SISSL-1.2\",\"SPL-1.0\",\"Watcom-1.0\",\"TCL\",\"Unlicense\",\"TMate\",\"TORQUE-1.1\",\"TOSL\",\"Unicode-TOU\",\"UPL-1.0\",\"NCSA\",\"Vim\",\"VOSTROM\",\"VSL-1.0\",\"W3C-19980720\",\"W3C\",\"Wsuipa\",\"Xnet\",\"X11\",\"Xerox\",\"XFree86-1.1\",\"xinetd\",\"xpp\",\"XSkat\",\"YPL-1.0\",\"YPL-1.1\",\"Zed\",\"Zend-2.0\",\"Zimbra-1.3\",\"Zimbra-1.4\",\"Zlib\",\"zlib-acknowledgement\",\"ZPL-1.1\",\"ZPL-2.0\",\"ZPL-2.1\",\"BSD-3-Clause-No-Nuclear-License\",\"BSD-3-Clause-No-Nuclear-Warranty\",\"BSD-3-Clause-No-Nuclear-License-2014\",\"eCos-2.0\",\"GPL-2.0-with-autoconf-exception\",\"GPL-2.0-with-bison-exception\",\"GPL-2.0-with-classpath-exception\",\"GPL-2.0-with-font-exception\",\"GPL-2.0-with-GCC-exception\",\"GPL-3.0-with-autoconf-exception\",\"GPL-3.0-with-GCC-exception\",\"StandardML-NJ\",\"WXwindows\"]"); /***/ }), -/* 195 */ +/* 196 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var url = __webpack_require__(196) -var gitHosts = __webpack_require__(197) -var GitHost = module.exports = __webpack_require__(198) +var url = __webpack_require__(197) +var gitHosts = __webpack_require__(198) +var GitHost = module.exports = __webpack_require__(199) var protocolToRepresentationMap = { 'git+ssh': 'sshurl', @@ -21327,13 +21465,13 @@ function parseGitUrl (giturl) { /***/ }), -/* 196 */ +/* 197 */ /***/ (function(module, exports) { module.exports = require("url"); /***/ }), -/* 197 */ +/* 198 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -21408,13 +21546,13 @@ Object.keys(gitHosts).forEach(function (name) { /***/ }), -/* 198 */ +/* 199 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var gitHosts = __webpack_require__(197) -var extend = Object.assign || __webpack_require__(111)._extend +var gitHosts = __webpack_require__(198) +var extend = Object.assign || __webpack_require__(112)._extend var GitHost = module.exports = function (type, user, auth, project, committish, defaultRepresentation, opts) { var gitHostInfo = this @@ -21529,27 +21667,27 @@ GitHost.prototype.toString = function (opts) { /***/ }), -/* 199 */ +/* 200 */ /***/ (function(module, exports, __webpack_require__) { -var async = __webpack_require__(200); -async.core = __webpack_require__(206); -async.isCore = __webpack_require__(205); -async.sync = __webpack_require__(208); +var async = __webpack_require__(201); +async.core = __webpack_require__(207); +async.isCore = __webpack_require__(206); +async.sync = __webpack_require__(209); module.exports = async; /***/ }), -/* 200 */ +/* 201 */ /***/ (function(module, exports, __webpack_require__) { -var fs = __webpack_require__(133); +var fs = __webpack_require__(134); var path = __webpack_require__(4); -var caller = __webpack_require__(201); -var nodeModulesPaths = __webpack_require__(202); -var normalizeOptions = __webpack_require__(204); -var isCore = __webpack_require__(205); +var caller = __webpack_require__(202); +var nodeModulesPaths = __webpack_require__(203); +var normalizeOptions = __webpack_require__(205); +var isCore = __webpack_require__(206); var realpathFS = fs.realpath && typeof fs.realpath.native === 'function' ? fs.realpath.native : fs.realpath; @@ -21845,7 +21983,7 @@ module.exports = function resolve(x, options, callback) { /***/ }), -/* 201 */ +/* 202 */ /***/ (function(module, exports) { module.exports = function () { @@ -21859,11 +21997,11 @@ module.exports = function () { /***/ }), -/* 202 */ +/* 203 */ /***/ (function(module, exports, __webpack_require__) { var path = __webpack_require__(4); -var parse = path.parse || __webpack_require__(203); +var parse = path.parse || __webpack_require__(204); var getNodeModulesDirs = function getNodeModulesDirs(absoluteStart, modules) { var prefix = '/'; @@ -21907,7 +22045,7 @@ module.exports = function nodeModulesPaths(start, opts, request) { /***/ }), -/* 203 */ +/* 204 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -22007,7 +22145,7 @@ module.exports.win32 = win32.parse; /***/ }), -/* 204 */ +/* 205 */ /***/ (function(module, exports) { module.exports = function (x, opts) { @@ -22023,10 +22161,10 @@ module.exports = function (x, opts) { /***/ }), -/* 205 */ +/* 206 */ /***/ (function(module, exports, __webpack_require__) { -var core = __webpack_require__(206); +var core = __webpack_require__(207); module.exports = function isCore(x) { return Object.prototype.hasOwnProperty.call(core, x); @@ -22034,7 +22172,7 @@ module.exports = function isCore(x) { /***/ }), -/* 206 */ +/* 207 */ /***/ (function(module, exports, __webpack_require__) { var current = (process.versions && process.versions.node && process.versions.node.split('.')) || []; @@ -22081,7 +22219,7 @@ function versionIncluded(specifierValue) { return matchesRange(specifierValue); } -var data = __webpack_require__(207); +var data = __webpack_require__(208); var core = {}; for (var mod in data) { // eslint-disable-line no-restricted-syntax @@ -22093,21 +22231,21 @@ module.exports = core; /***/ }), -/* 207 */ +/* 208 */ /***/ (function(module) { module.exports = JSON.parse("{\"assert\":true,\"async_hooks\":\">= 8\",\"buffer_ieee754\":\"< 0.9.7\",\"buffer\":true,\"child_process\":true,\"cluster\":true,\"console\":true,\"constants\":true,\"crypto\":true,\"_debug_agent\":\">= 1 && < 8\",\"_debugger\":\"< 8\",\"dgram\":true,\"dns\":true,\"domain\":true,\"events\":true,\"freelist\":\"< 6\",\"fs\":true,\"fs/promises\":[\">= 10 && < 10.1\",\">= 14\"],\"_http_agent\":\">= 0.11.1\",\"_http_client\":\">= 0.11.1\",\"_http_common\":\">= 0.11.1\",\"_http_incoming\":\">= 0.11.1\",\"_http_outgoing\":\">= 0.11.1\",\"_http_server\":\">= 0.11.1\",\"http\":true,\"http2\":\">= 8.8\",\"https\":true,\"inspector\":\">= 8.0.0\",\"_linklist\":\"< 8\",\"module\":true,\"net\":true,\"node-inspect/lib/_inspect\":\">= 7.6.0 && < 12\",\"node-inspect/lib/internal/inspect_client\":\">= 7.6.0 && < 12\",\"node-inspect/lib/internal/inspect_repl\":\">= 7.6.0 && < 12\",\"os\":true,\"path\":true,\"perf_hooks\":\">= 8.5\",\"process\":\">= 1\",\"punycode\":true,\"querystring\":true,\"readline\":true,\"repl\":true,\"smalloc\":\">= 0.11.5 && < 3\",\"_stream_duplex\":\">= 0.9.4\",\"_stream_transform\":\">= 0.9.4\",\"_stream_wrap\":\">= 1.4.1\",\"_stream_passthrough\":\">= 0.9.4\",\"_stream_readable\":\">= 0.9.4\",\"_stream_writable\":\">= 0.9.4\",\"stream\":true,\"string_decoder\":true,\"sys\":true,\"timers\":true,\"_tls_common\":\">= 0.11.13\",\"_tls_legacy\":\">= 0.11.3 && < 10\",\"_tls_wrap\":\">= 0.11.3\",\"tls\":true,\"trace_events\":\">= 10\",\"tty\":true,\"url\":true,\"util\":true,\"v8/tools/arguments\":\">= 10 && < 12\",\"v8/tools/codemap\":[\">= 4.4.0 && < 5\",\">= 5.2.0 && < 12\"],\"v8/tools/consarray\":[\">= 4.4.0 && < 5\",\">= 5.2.0 && < 12\"],\"v8/tools/csvparser\":[\">= 4.4.0 && < 5\",\">= 5.2.0 && < 12\"],\"v8/tools/logreader\":[\">= 4.4.0 && < 5\",\">= 5.2.0 && < 12\"],\"v8/tools/profile_view\":[\">= 4.4.0 && < 5\",\">= 5.2.0 && < 12\"],\"v8/tools/splaytree\":[\">= 4.4.0 && < 5\",\">= 5.2.0 && < 12\"],\"v8\":\">= 1\",\"vm\":true,\"wasi\":\">= 13.4 && < 13.5\",\"worker_threads\":\">= 11.7\",\"zlib\":true}"); /***/ }), -/* 208 */ +/* 209 */ /***/ (function(module, exports, __webpack_require__) { -var isCore = __webpack_require__(205); -var fs = __webpack_require__(133); +var isCore = __webpack_require__(206); +var fs = __webpack_require__(134); var path = __webpack_require__(4); -var caller = __webpack_require__(201); -var nodeModulesPaths = __webpack_require__(202); -var normalizeOptions = __webpack_require__(204); +var caller = __webpack_require__(202); +var nodeModulesPaths = __webpack_require__(203); +var normalizeOptions = __webpack_require__(205); var realpathFS = fs.realpathSync && typeof fs.realpathSync.native === 'function' ? fs.realpathSync.native : fs.realpathSync; @@ -22296,7 +22434,7 @@ module.exports = function resolveSync(x, options) { /***/ }), -/* 209 */ +/* 210 */ /***/ (function(module, exports) { module.exports = extractDescription @@ -22316,17 +22454,17 @@ function extractDescription (d) { /***/ }), -/* 210 */ +/* 211 */ /***/ (function(module) { module.exports = JSON.parse("{\"topLevel\":{\"dependancies\":\"dependencies\",\"dependecies\":\"dependencies\",\"depdenencies\":\"dependencies\",\"devEependencies\":\"devDependencies\",\"depends\":\"dependencies\",\"dev-dependencies\":\"devDependencies\",\"devDependences\":\"devDependencies\",\"devDepenencies\":\"devDependencies\",\"devdependencies\":\"devDependencies\",\"repostitory\":\"repository\",\"repo\":\"repository\",\"prefereGlobal\":\"preferGlobal\",\"hompage\":\"homepage\",\"hampage\":\"homepage\",\"autohr\":\"author\",\"autor\":\"author\",\"contributers\":\"contributors\",\"publicationConfig\":\"publishConfig\",\"script\":\"scripts\"},\"bugs\":{\"web\":\"url\",\"name\":\"url\"},\"script\":{\"server\":\"start\",\"tests\":\"test\"}}"); /***/ }), -/* 211 */ +/* 212 */ /***/ (function(module, exports, __webpack_require__) { -var util = __webpack_require__(111) -var messages = __webpack_require__(212) +var util = __webpack_require__(112) +var messages = __webpack_require__(213) module.exports = function() { var args = Array.prototype.slice.call(arguments, 0) @@ -22351,20 +22489,20 @@ function makeTypoWarning (providedName, probableName, field) { /***/ }), -/* 212 */ +/* 213 */ /***/ (function(module) { module.exports = JSON.parse("{\"repositories\":\"'repositories' (plural) Not supported. Please pick one as the 'repository' field\",\"missingRepository\":\"No repository field.\",\"brokenGitUrl\":\"Probably broken git url: %s\",\"nonObjectScripts\":\"scripts must be an object\",\"nonStringScript\":\"script values must be string commands\",\"nonArrayFiles\":\"Invalid 'files' member\",\"invalidFilename\":\"Invalid filename in 'files' list: %s\",\"nonArrayBundleDependencies\":\"Invalid 'bundleDependencies' list. Must be array of package names\",\"nonStringBundleDependency\":\"Invalid bundleDependencies member: %s\",\"nonDependencyBundleDependency\":\"Non-dependency in bundleDependencies: %s\",\"nonObjectDependencies\":\"%s field must be an object\",\"nonStringDependency\":\"Invalid dependency: %s %s\",\"deprecatedArrayDependencies\":\"specifying %s as array is deprecated\",\"deprecatedModules\":\"modules field is deprecated\",\"nonArrayKeywords\":\"keywords should be an array of strings\",\"nonStringKeyword\":\"keywords should be an array of strings\",\"conflictingName\":\"%s is also the name of a node core module.\",\"nonStringDescription\":\"'description' field should be a string\",\"missingDescription\":\"No description\",\"missingReadme\":\"No README data\",\"missingLicense\":\"No license field.\",\"nonEmailUrlBugsString\":\"Bug string field must be url, email, or {email,url}\",\"nonUrlBugsUrlField\":\"bugs.url field must be a string url. Deleted.\",\"nonEmailBugsEmailField\":\"bugs.email field must be a string email. Deleted.\",\"emptyNormalizedBugs\":\"Normalized value of bugs field is an empty object. Deleted.\",\"nonUrlHomepage\":\"homepage field must be a string url. Deleted.\",\"invalidLicense\":\"license should be a valid SPDX license expression\",\"typo\":\"%s should probably be %s.\"}"); /***/ }), -/* 213 */ +/* 214 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const writeJsonFile = __webpack_require__(214); -const sortKeys = __webpack_require__(220); +const writeJsonFile = __webpack_require__(215); +const sortKeys = __webpack_require__(221); const dependencyKeys = new Set([ 'dependencies', @@ -22429,18 +22567,18 @@ module.exports.sync = (filePath, data, options) => { /***/ }), -/* 214 */ +/* 215 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const fs = __webpack_require__(132); -const writeFileAtomic = __webpack_require__(215); -const sortKeys = __webpack_require__(220); -const makeDir = __webpack_require__(222); -const pify = __webpack_require__(223); -const detectIndent = __webpack_require__(224); +const fs = __webpack_require__(133); +const writeFileAtomic = __webpack_require__(216); +const sortKeys = __webpack_require__(221); +const makeDir = __webpack_require__(223); +const pify = __webpack_require__(224); +const detectIndent = __webpack_require__(225); const init = (fn, filePath, data, options) => { if (!filePath) { @@ -22512,7 +22650,7 @@ module.exports.sync = (filePath, data, options) => { /***/ }), -/* 215 */ +/* 216 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -22522,9 +22660,9 @@ module.exports.sync = writeFileSync module.exports._getTmpname = getTmpname // for testing module.exports._cleanupOnExit = cleanupOnExit -var fs = __webpack_require__(132) -var MurmurHash3 = __webpack_require__(216) -var onExit = __webpack_require__(217) +var fs = __webpack_require__(133) +var MurmurHash3 = __webpack_require__(217) +var onExit = __webpack_require__(218) var path = __webpack_require__(4) var activeFiles = {} @@ -22532,7 +22670,7 @@ var activeFiles = {} /* istanbul ignore next */ var threadId = (function getId () { try { - var workerThreads = __webpack_require__(219) + var workerThreads = __webpack_require__(220) /// if we are in main thread, this is set to `0` return workerThreads.threadId @@ -22757,7 +22895,7 @@ function writeFileSync (filename, data, options) { /***/ }), -/* 216 */ +/* 217 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -22899,16 +23037,16 @@ function writeFileSync (filename, data, options) { /***/ }), -/* 217 */ +/* 218 */ /***/ (function(module, exports, __webpack_require__) { // Note: since nyc uses this module to output coverage, any lines // that are in the direct sync flow of nyc's outputCoverage are // ignored, since we can never get coverage for them. -var assert = __webpack_require__(139) -var signals = __webpack_require__(218) +var assert = __webpack_require__(140) +var signals = __webpack_require__(219) -var EE = __webpack_require__(155) +var EE = __webpack_require__(156) /* istanbul ignore if */ if (typeof EE !== 'function') { EE = EE.EventEmitter @@ -23062,7 +23200,7 @@ function processEmit (ev, arg) { /***/ }), -/* 218 */ +/* 219 */ /***/ (function(module, exports) { // This is not the set of all possible signals. @@ -23121,18 +23259,18 @@ if (process.platform === 'linux') { /***/ }), -/* 219 */ +/* 220 */ /***/ (function(module, exports) { module.exports = require(undefined); /***/ }), -/* 220 */ +/* 221 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const isPlainObj = __webpack_require__(221); +const isPlainObj = __webpack_require__(222); module.exports = (obj, opts) => { if (!isPlainObj(obj)) { @@ -23189,7 +23327,7 @@ module.exports = (obj, opts) => { /***/ }), -/* 221 */ +/* 222 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -23203,15 +23341,15 @@ module.exports = function (x) { /***/ }), -/* 222 */ +/* 223 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fs = __webpack_require__(133); +const fs = __webpack_require__(134); const path = __webpack_require__(4); -const pify = __webpack_require__(223); -const semver = __webpack_require__(189); +const pify = __webpack_require__(224); +const semver = __webpack_require__(190); const defaults = { mode: 0o777 & (~process.umask()), @@ -23349,7 +23487,7 @@ module.exports.sync = (input, options) => { /***/ }), -/* 223 */ +/* 224 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -23424,7 +23562,7 @@ module.exports = (input, options) => { /***/ }), -/* 224 */ +/* 225 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -23553,7 +23691,7 @@ module.exports = str => { /***/ }), -/* 225 */ +/* 226 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -23562,7 +23700,7 @@ __webpack_require__.r(__webpack_exports__); /* 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 export (binding) */ __webpack_require__.d(__webpack_exports__, "yarnWorkspacesInfo", function() { return yarnWorkspacesInfo; }); -/* harmony import */ var _child_process__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(226); +/* harmony import */ var _child_process__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(227); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -23639,22 +23777,22 @@ async function yarnWorkspacesInfo(directory) { } /***/ }), -/* 226 */ +/* 227 */ /***/ (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 stream__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(137); +/* harmony import */ var stream__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(138); /* harmony import */ var stream__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(stream__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(227); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(113); /* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(chalk__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(236); +/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(228); /* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(execa__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var strong_log_transformer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(271); +/* harmony import */ var strong_log_transformer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(263); /* harmony import */ var strong_log_transformer__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(strong_log_transformer__WEBPACK_IMPORTED_MODULE_3__); -/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(143); +/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(144); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } @@ -23738,5618 +23876,5923 @@ function spawnStreaming(command, args, opts, { } /***/ }), -/* 227 */ +/* 228 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const ansiStyles = __webpack_require__(228); -const {stdout: stdoutColor, stderr: stderrColor} = __webpack_require__(232); -const { - stringReplaceAll, - stringEncaseCRLFWithFirstIndex -} = __webpack_require__(234); - -const {isArray} = Array; +const path = __webpack_require__(4); +const childProcess = __webpack_require__(229); +const crossSpawn = __webpack_require__(230); +const stripFinalNewline = __webpack_require__(243); +const npmRunPath = __webpack_require__(244); +const onetime = __webpack_require__(245); +const makeError = __webpack_require__(247); +const normalizeStdio = __webpack_require__(252); +const {spawnedKill, spawnedCancel, setupTimeout, setExitHandler} = __webpack_require__(253); +const {handleInput, getSpawnedResult, makeAllStream, validateInputSync} = __webpack_require__(254); +const {mergePromise, getSpawnedPromise} = __webpack_require__(261); +const {joinCommand, parseCommand} = __webpack_require__(262); -// `supportsColor.level` → `ansiStyles.color[name]` mapping -const levelMapping = [ - 'ansi', - 'ansi', - 'ansi256', - 'ansi16m' -]; +const DEFAULT_MAX_BUFFER = 1000 * 1000 * 100; -const styles = Object.create(null); +const getEnv = ({env: envOption, extendEnv, preferLocal, localDir, execPath}) => { + const env = extendEnv ? {...process.env, ...envOption} : envOption; -const applyOptions = (object, options = {}) => { - if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) { - throw new Error('The `level` option should be an integer from 0 to 3'); + if (preferLocal) { + return npmRunPath.env({env, cwd: localDir, execPath}); } - // Detect level if not set manually - const colorLevel = stdoutColor ? stdoutColor.level : 0; - object.level = options.level === undefined ? colorLevel : options.level; + return env; }; -class ChalkClass { - constructor(options) { - // eslint-disable-next-line no-constructor-return - return chalkFactory(options); - } -} - -const chalkFactory = options => { - const chalk = {}; - applyOptions(chalk, options); +const handleArguments = (file, args, options = {}) => { + const parsed = crossSpawn._parse(file, args, options); + file = parsed.command; + args = parsed.args; + options = parsed.options; - chalk.template = (...arguments_) => chalkTag(chalk.template, ...arguments_); + options = { + maxBuffer: DEFAULT_MAX_BUFFER, + buffer: true, + stripFinalNewline: true, + extendEnv: true, + preferLocal: false, + localDir: options.cwd || process.cwd(), + execPath: process.execPath, + encoding: 'utf8', + reject: true, + cleanup: true, + all: false, + windowsHide: true, + ...options + }; - Object.setPrototypeOf(chalk, Chalk.prototype); - Object.setPrototypeOf(chalk.template, chalk); + options.env = getEnv(options); - chalk.template.constructor = () => { - throw new Error('`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.'); - }; + options.stdio = normalizeStdio(options); - chalk.template.Instance = ChalkClass; + if (process.platform === 'win32' && path.basename(file, '.exe') === 'cmd') { + // #116 + args.unshift('/q'); + } - return chalk.template; + return {file, args, options, parsed}; }; -function Chalk(options) { - return chalkFactory(options); -} - -for (const [styleName, style] of Object.entries(ansiStyles)) { - styles[styleName] = { - get() { - const builder = createBuilder(this, createStyler(style.open, style.close, this._styler), this._isEmpty); - Object.defineProperty(this, styleName, {value: builder}); - return builder; - } - }; -} +const handleOutput = (options, value, error) => { + if (typeof value !== 'string' && !Buffer.isBuffer(value)) { + // When `execa.sync()` errors, we normalize it to '' to mimic `execa()` + return error === undefined ? undefined : ''; + } -styles.visible = { - get() { - const builder = createBuilder(this, this._styler, true); - Object.defineProperty(this, 'visible', {value: builder}); - return builder; + if (options.stripFinalNewline) { + return stripFinalNewline(value); } + + return value; }; -const usedModels = ['rgb', 'hex', 'keyword', 'hsl', 'hsv', 'hwb', 'ansi', 'ansi256']; +const execa = (file, args, options) => { + const parsed = handleArguments(file, args, options); + const command = joinCommand(file, args); -for (const model of usedModels) { - styles[model] = { - get() { - const {level} = this; - return function (...arguments_) { - const styler = createStyler(ansiStyles.color[levelMapping[level]][model](...arguments_), ansiStyles.color.close, this._styler); - return createBuilder(this, styler, this._isEmpty); - }; - } - }; -} + let spawned; + try { + spawned = childProcess.spawn(parsed.file, parsed.args, parsed.options); + } catch (error) { + // Ensure the returned error is always both a promise and a child process + const dummySpawned = new childProcess.ChildProcess(); + const errorPromise = Promise.reject(makeError({ + error, + stdout: '', + stderr: '', + all: '', + command, + parsed, + timedOut: false, + isCanceled: false, + killed: false + })); + return mergePromise(dummySpawned, errorPromise); + } -for (const model of usedModels) { - const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); - styles[bgModel] = { - get() { - const {level} = this; - return function (...arguments_) { - const styler = createStyler(ansiStyles.bgColor[levelMapping[level]][model](...arguments_), ansiStyles.bgColor.close, this._styler); - return createBuilder(this, styler, this._isEmpty); - }; - } - }; -} + const spawnedPromise = getSpawnedPromise(spawned); + const timedPromise = setupTimeout(spawned, parsed.options, spawnedPromise); + const processDone = setExitHandler(spawned, parsed.options, timedPromise); -const proto = Object.defineProperties(() => {}, { - ...styles, - level: { - enumerable: true, - get() { - return this._generator.level; - }, - set(level) { - this._generator.level = level; - } - } -}); + const context = {isCanceled: false}; -const createStyler = (open, close, parent) => { - let openAll; - let closeAll; - if (parent === undefined) { - openAll = open; - closeAll = close; - } else { - openAll = parent.openAll + open; - closeAll = close + parent.closeAll; - } + spawned.kill = spawnedKill.bind(null, spawned.kill.bind(spawned)); + spawned.cancel = spawnedCancel.bind(null, spawned, context); - return { - open, - close, - openAll, - closeAll, - parent - }; -}; + const handlePromise = async () => { + const [{error, exitCode, signal, timedOut}, stdoutResult, stderrResult, allResult] = await getSpawnedResult(spawned, parsed.options, processDone); + const stdout = handleOutput(parsed.options, stdoutResult); + const stderr = handleOutput(parsed.options, stderrResult); + const all = handleOutput(parsed.options, allResult); -const createBuilder = (self, _styler, _isEmpty) => { - const builder = (...arguments_) => { - if (isArray(arguments_[0]) && isArray(arguments_[0].raw)) { - // Called as a template literal, for example: chalk.red`2 + 3 = {bold ${2+3}}` - return applyStyle(builder, chalkTag(builder, ...arguments_)); + if (error || exitCode !== 0 || signal !== null) { + const returnedError = makeError({ + error, + exitCode, + signal, + stdout, + stderr, + all, + command, + parsed, + timedOut, + isCanceled: context.isCanceled, + killed: spawned.killed + }); + + if (!parsed.options.reject) { + return returnedError; + } + + throw returnedError; } - // Single argument is hot path, implicit coercion is faster than anything - // eslint-disable-next-line no-implicit-coercion - return applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' ')); + return { + command, + exitCode: 0, + stdout, + stderr, + all, + failed: false, + timedOut: false, + isCanceled: false, + killed: false + }; }; - // We alter the prototype because we must return a function, but there is - // no way to create a function with a different prototype - Object.setPrototypeOf(builder, proto); + const handlePromiseOnce = onetime(handlePromise); - builder._generator = self; - builder._styler = _styler; - builder._isEmpty = _isEmpty; + crossSpawn._enoent.hookChildProcess(spawned, parsed.parsed); - return builder; + handleInput(spawned, parsed.options.input); + + spawned.all = makeAllStream(spawned, parsed.options); + + return mergePromise(spawned, handlePromiseOnce); }; -const applyStyle = (self, string) => { - if (self.level <= 0 || !string) { - return self._isEmpty ? '' : string; - } +module.exports = execa; - let styler = self._styler; +module.exports.sync = (file, args, options) => { + const parsed = handleArguments(file, args, options); + const command = joinCommand(file, args); - if (styler === undefined) { - return string; + validateInputSync(parsed.options); + + let result; + try { + result = childProcess.spawnSync(parsed.file, parsed.args, parsed.options); + } catch (error) { + throw makeError({ + error, + stdout: '', + stderr: '', + all: '', + command, + parsed, + timedOut: false, + isCanceled: false, + killed: false + }); } - const {openAll, closeAll} = styler; - if (string.indexOf('\u001B') !== -1) { - while (styler !== undefined) { - // Replace any instances already present with a re-opening code - // otherwise only the part of the string until said closing code - // will be colored, and the rest will simply be 'plain'. - string = stringReplaceAll(string, styler.close, styler.open); + const stdout = handleOutput(parsed.options, result.stdout, result.error); + const stderr = handleOutput(parsed.options, result.stderr, result.error); - styler = styler.parent; + if (result.error || result.status !== 0 || result.signal !== null) { + const error = makeError({ + stdout, + stderr, + error: result.error, + signal: result.signal, + exitCode: result.status, + command, + parsed, + timedOut: result.error && result.error.code === 'ETIMEDOUT', + isCanceled: false, + killed: result.signal !== null + }); + + if (!parsed.options.reject) { + return error; } - } - // We can move both next actions out of loop, because remaining actions in loop won't have - // any/visible effect on parts we add here. Close the styling before a linebreak and reopen - // after next line to fix a bleed issue on macOS: https://github.com/chalk/chalk/pull/92 - const lfIndex = string.indexOf('\n'); - if (lfIndex !== -1) { - string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex); + throw error; } - return openAll + string + closeAll; + return { + command, + exitCode: 0, + stdout, + stderr, + failed: false, + timedOut: false, + isCanceled: false, + killed: false + }; }; -let template; -const chalkTag = (chalk, ...strings) => { - const [firstString] = strings; - - if (!isArray(firstString) || !isArray(firstString.raw)) { - // If chalk() was called by itself or with a string, - // return the string itself as a string. - return strings.join(' '); - } +module.exports.command = (command, options) => { + const [file, ...args] = parseCommand(command); + return execa(file, args, options); +}; - const arguments_ = strings.slice(1); - const parts = [firstString.raw[0]]; +module.exports.commandSync = (command, options) => { + const [file, ...args] = parseCommand(command); + return execa.sync(file, args, options); +}; - for (let i = 1; i < firstString.length; i++) { - parts.push( - String(arguments_[i - 1]).replace(/[{}\\]/g, '\\$&'), - String(firstString.raw[i]) - ); +module.exports.node = (scriptPath, args, options = {}) => { + if (args && !Array.isArray(args) && typeof args === 'object') { + options = args; + args = []; } - if (template === undefined) { - template = __webpack_require__(235); - } + const stdio = normalizeStdio.node(options); - return template(chalk, parts.join('')); -}; + const {nodePath = process.execPath, nodeOptions = process.execArgv} = options; -Object.defineProperties(Chalk.prototype, styles); + return execa( + nodePath, + [ + ...nodeOptions, + scriptPath, + ...(Array.isArray(args) ? args : []) + ], + { + ...options, + stdin: undefined, + stdout: undefined, + stderr: undefined, + stdio, + shell: false + } + ); +}; -const chalk = Chalk(); // eslint-disable-line new-cap -chalk.supportsColor = stdoutColor; -chalk.stderr = Chalk({level: stderrColor ? stderrColor.level : 0}); // eslint-disable-line new-cap -chalk.stderr.supportsColor = stderrColor; -module.exports = chalk; +/***/ }), +/* 229 */ +/***/ (function(module, exports) { +module.exports = require("child_process"); /***/ }), -/* 228 */ +/* 230 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/* WEBPACK VAR INJECTION */(function(module) { - -const wrapAnsi16 = (fn, offset) => (...args) => { - const code = fn(...args); - return `\u001B[${code + offset}m`; -}; -const wrapAnsi256 = (fn, offset) => (...args) => { - const code = fn(...args); - return `\u001B[${38 + offset};5;${code}m`; -}; -const wrapAnsi16m = (fn, offset) => (...args) => { - const rgb = fn(...args); - return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; -}; +const cp = __webpack_require__(229); +const parse = __webpack_require__(231); +const enoent = __webpack_require__(242); -const ansi2ansi = n => n; -const rgb2rgb = (r, g, b) => [r, g, b]; +function spawn(command, args, options) { + // Parse the arguments + const parsed = parse(command, args, options); -const setLazyProperty = (object, property, get) => { - Object.defineProperty(object, property, { - get: () => { - const value = get(); + // Spawn the child process + const spawned = cp.spawn(parsed.command, parsed.args, parsed.options); - Object.defineProperty(object, property, { - value, - enumerable: true, - configurable: true - }); + // Hook into child process "exit" event to emit an error if the command + // does not exists, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 + enoent.hookChildProcess(spawned, parsed); - return value; - }, - enumerable: true, - configurable: true - }); -}; + return spawned; +} -/** @type {typeof import('color-convert')} */ -let colorConvert; -const makeDynamicStyles = (wrap, targetSpace, identity, isBackground) => { - if (colorConvert === undefined) { - colorConvert = __webpack_require__(229); - } +function spawnSync(command, args, options) { + // Parse the arguments + const parsed = parse(command, args, options); - const offset = isBackground ? 10 : 0; - const styles = {}; + // Spawn the child process + const result = cp.spawnSync(parsed.command, parsed.args, parsed.options); - for (const [sourceSpace, suite] of Object.entries(colorConvert)) { - const name = sourceSpace === 'ansi16' ? 'ansi' : sourceSpace; - if (sourceSpace === targetSpace) { - styles[name] = wrap(identity, offset); - } else if (typeof suite === 'object') { - styles[name] = wrap(suite[targetSpace], offset); - } - } + // Analyze if the command does not exist, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 + result.error = result.error || enoent.verifyENOENTSync(result.status, parsed); - return styles; -}; + return result; +} -function assembleStyles() { - const codes = new Map(); - const styles = { - modifier: { - reset: [0, 0], - // 21 isn't widely supported and 22 does the same thing - bold: [1, 22], - dim: [2, 22], - italic: [3, 23], - underline: [4, 24], - inverse: [7, 27], - hidden: [8, 28], - strikethrough: [9, 29] - }, - color: { - black: [30, 39], - red: [31, 39], - green: [32, 39], - yellow: [33, 39], - blue: [34, 39], - magenta: [35, 39], - cyan: [36, 39], - white: [37, 39], +module.exports = spawn; +module.exports.spawn = spawn; +module.exports.sync = spawnSync; - // Bright color - blackBright: [90, 39], - redBright: [91, 39], - greenBright: [92, 39], - yellowBright: [93, 39], - blueBright: [94, 39], - magentaBright: [95, 39], - cyanBright: [96, 39], - whiteBright: [97, 39] - }, - bgColor: { - bgBlack: [40, 49], - bgRed: [41, 49], - bgGreen: [42, 49], - bgYellow: [43, 49], - bgBlue: [44, 49], - bgMagenta: [45, 49], - bgCyan: [46, 49], - bgWhite: [47, 49], +module.exports._parse = parse; +module.exports._enoent = enoent; - // Bright color - bgBlackBright: [100, 49], - bgRedBright: [101, 49], - bgGreenBright: [102, 49], - bgYellowBright: [103, 49], - bgBlueBright: [104, 49], - bgMagentaBright: [105, 49], - bgCyanBright: [106, 49], - bgWhiteBright: [107, 49] - } - }; - // Alias bright black as gray (and grey) - styles.color.gray = styles.color.blackBright; - styles.bgColor.bgGray = styles.bgColor.bgBlackBright; - styles.color.grey = styles.color.blackBright; - styles.bgColor.bgGrey = styles.bgColor.bgBlackBright; +/***/ }), +/* 231 */ +/***/ (function(module, exports, __webpack_require__) { - for (const [groupName, group] of Object.entries(styles)) { - for (const [styleName, style] of Object.entries(group)) { - styles[styleName] = { - open: `\u001B[${style[0]}m`, - close: `\u001B[${style[1]}m` - }; +"use strict"; - group[styleName] = styles[styleName]; - codes.set(style[0], style[1]); - } +const path = __webpack_require__(4); +const resolveCommand = __webpack_require__(232); +const escape = __webpack_require__(238); +const readShebang = __webpack_require__(239); - Object.defineProperty(styles, groupName, { - value: group, - enumerable: false - }); - } +const isWin = process.platform === 'win32'; +const isExecutableRegExp = /\.(?:com|exe)$/i; +const isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i; - Object.defineProperty(styles, 'codes', { - value: codes, - enumerable: false - }); +function detectShebang(parsed) { + parsed.file = resolveCommand(parsed); - styles.color.close = '\u001B[39m'; - styles.bgColor.close = '\u001B[49m'; + const shebang = parsed.file && readShebang(parsed.file); - setLazyProperty(styles.color, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, false)); - setLazyProperty(styles.color, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, false)); - setLazyProperty(styles.color, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, false)); - setLazyProperty(styles.bgColor, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, true)); - setLazyProperty(styles.bgColor, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, true)); - setLazyProperty(styles.bgColor, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, true)); + if (shebang) { + parsed.args.unshift(parsed.file); + parsed.command = shebang; - return styles; + return resolveCommand(parsed); + } + + return parsed.file; } -// Make the export immutable -Object.defineProperty(module, 'exports', { - enumerable: true, - get: assembleStyles -}); +function parseNonShell(parsed) { + if (!isWin) { + return parsed; + } -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(114)(module))) + // Detect & add support for shebangs + const commandFile = detectShebang(parsed); -/***/ }), -/* 229 */ -/***/ (function(module, exports, __webpack_require__) { + // We don't need a shell if the command filename is an executable + const needsShell = !isExecutableRegExp.test(commandFile); -const conversions = __webpack_require__(230); -const route = __webpack_require__(231); + // If a shell is required, use cmd.exe and take care of escaping everything correctly + // Note that `forceShell` is an hidden option used only in tests + if (parsed.options.forceShell || needsShell) { + // Need to double escape meta chars if the command is a cmd-shim located in `node_modules/.bin/` + // The cmd-shim simply calls execute the package bin file with NodeJS, proxying any argument + // Because the escape of metachars with ^ gets interpreted when the cmd.exe is first called, + // we need to double escape them + const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile); -const convert = {}; + // Normalize posix paths into OS compatible paths (e.g.: foo/bar -> foo\bar) + // This is necessary otherwise it will always fail with ENOENT in those cases + parsed.command = path.normalize(parsed.command); -const models = Object.keys(conversions); + // Escape command & arguments + parsed.command = escape.command(parsed.command); + parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars)); -function wrapRaw(fn) { - const wrappedFn = function (...args) { - const arg0 = args[0]; - if (arg0 === undefined || arg0 === null) { - return arg0; - } + const shellCommand = [parsed.command].concat(parsed.args).join(' '); - if (arg0.length > 1) { - args = arg0; - } + parsed.args = ['/d', '/s', '/c', `"${shellCommand}"`]; + parsed.command = process.env.comspec || 'cmd.exe'; + parsed.options.windowsVerbatimArguments = true; // Tell node's spawn that the arguments are already escaped + } - return fn(args); - }; + return parsed; +} - // Preserve .conversion property if there is one - if ('conversion' in fn) { - wrappedFn.conversion = fn.conversion; - } +function parse(command, args, options) { + // Normalize arguments, similar to nodejs + if (args && !Array.isArray(args)) { + options = args; + args = null; + } - return wrappedFn; + args = args ? args.slice(0) : []; // Clone array to avoid changing the original + options = Object.assign({}, options); // Clone object to avoid changing the original + + // Build our parsed object + const parsed = { + command, + args, + options, + file: undefined, + original: { + command, + args, + }, + }; + + // Delegate further parsing to shell or non-shell + return options.shell ? parsed : parseNonShell(parsed); } -function wrapRounded(fn) { - const wrappedFn = function (...args) { - const arg0 = args[0]; +module.exports = parse; - if (arg0 === undefined || arg0 === null) { - return arg0; - } - if (arg0.length > 1) { - args = arg0; - } +/***/ }), +/* 232 */ +/***/ (function(module, exports, __webpack_require__) { - const result = fn(args); +"use strict"; - // We're assuming the result is an array here. - // see notice in conversions.js; don't use box types - // in conversion functions. - if (typeof result === 'object') { - for (let len = result.length, i = 0; i < len; i++) { - result[i] = Math.round(result[i]); - } - } - return result; - }; +const path = __webpack_require__(4); +const which = __webpack_require__(233); +const pathKey = __webpack_require__(237)(); - // Preserve .conversion property if there is one - if ('conversion' in fn) { - wrappedFn.conversion = fn.conversion; - } +function resolveCommandAttempt(parsed, withoutPathExt) { + const cwd = process.cwd(); + const hasCustomCwd = parsed.options.cwd != null; + // Worker threads do not have process.chdir() + const shouldSwitchCwd = hasCustomCwd && process.chdir !== undefined; - return wrappedFn; -} + // If a custom `cwd` was specified, we need to change the process cwd + // because `which` will do stat calls but does not support a custom cwd + if (shouldSwitchCwd) { + try { + process.chdir(parsed.options.cwd); + } catch (err) { + /* Empty */ + } + } -models.forEach(fromModel => { - convert[fromModel] = {}; + let resolved; - Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels}); - Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels}); + try { + resolved = which.sync(parsed.command, { + path: (parsed.options.env || process.env)[pathKey], + pathExt: withoutPathExt ? path.delimiter : undefined, + }); + } catch (e) { + /* Empty */ + } finally { + if (shouldSwitchCwd) { + process.chdir(cwd); + } + } - const routes = route(fromModel); - const routeModels = Object.keys(routes); + // If we successfully resolved, ensure that an absolute path is returned + // Note that when a custom `cwd` was used, we need to resolve to an absolute path based on it + if (resolved) { + resolved = path.resolve(hasCustomCwd ? parsed.options.cwd : '', resolved); + } - routeModels.forEach(toModel => { - const fn = routes[toModel]; + return resolved; +} - convert[fromModel][toModel] = wrapRounded(fn); - convert[fromModel][toModel].raw = wrapRaw(fn); - }); -}); +function resolveCommand(parsed) { + return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true); +} -module.exports = convert; +module.exports = resolveCommand; /***/ }), -/* 230 */ +/* 233 */ /***/ (function(module, exports, __webpack_require__) { -/* MIT license */ -/* eslint-disable no-mixed-operators */ -const cssKeywords = __webpack_require__(117); - -// NOTE: conversions should only return primitive values (i.e. arrays, or -// values that give correct `typeof` results). -// do not use box values types (i.e. Number(), String(), etc.) - -const reverseKeywords = {}; -for (const key of Object.keys(cssKeywords)) { - reverseKeywords[cssKeywords[key]] = key; -} +const isWindows = process.platform === 'win32' || + process.env.OSTYPE === 'cygwin' || + process.env.OSTYPE === 'msys' -const convert = { - rgb: {channels: 3, labels: 'rgb'}, - hsl: {channels: 3, labels: 'hsl'}, - hsv: {channels: 3, labels: 'hsv'}, - hwb: {channels: 3, labels: 'hwb'}, - cmyk: {channels: 4, labels: 'cmyk'}, - xyz: {channels: 3, labels: 'xyz'}, - lab: {channels: 3, labels: 'lab'}, - lch: {channels: 3, labels: 'lch'}, - hex: {channels: 1, labels: ['hex']}, - keyword: {channels: 1, labels: ['keyword']}, - ansi16: {channels: 1, labels: ['ansi16']}, - ansi256: {channels: 1, labels: ['ansi256']}, - hcg: {channels: 3, labels: ['h', 'c', 'g']}, - apple: {channels: 3, labels: ['r16', 'g16', 'b16']}, - gray: {channels: 1, labels: ['gray']} -}; +const path = __webpack_require__(4) +const COLON = isWindows ? ';' : ':' +const isexe = __webpack_require__(234) -module.exports = convert; +const getNotFoundError = (cmd) => + Object.assign(new Error(`not found: ${cmd}`), { code: 'ENOENT' }) -// Hide .channels and .labels properties -for (const model of Object.keys(convert)) { - if (!('channels' in convert[model])) { - throw new Error('missing channels property: ' + model); - } +const getPathInfo = (cmd, opt) => { + const colon = opt.colon || COLON - if (!('labels' in convert[model])) { - throw new Error('missing channel labels property: ' + model); - } + // If it has a slash, then we don't bother searching the pathenv. + // just check the file itself, and that's it. + const pathEnv = cmd.match(/\//) || isWindows && cmd.match(/\\/) ? [''] + : ( + [ + // windows always checks the cwd first + ...(isWindows ? [process.cwd()] : []), + ...(opt.path || process.env.PATH || + /* istanbul ignore next: very unusual */ '').split(colon), + ] + ) + const pathExtExe = isWindows + ? opt.pathExt || process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM' + : '' + const pathExt = isWindows ? pathExtExe.split(colon) : [''] - if (convert[model].labels.length !== convert[model].channels) { - throw new Error('channel and label counts mismatch: ' + model); - } + if (isWindows) { + if (cmd.indexOf('.') !== -1 && pathExt[0] !== '') + pathExt.unshift('') + } - const {channels, labels} = convert[model]; - delete convert[model].channels; - delete convert[model].labels; - Object.defineProperty(convert[model], 'channels', {value: channels}); - Object.defineProperty(convert[model], 'labels', {value: labels}); + return { + pathEnv, + pathExt, + pathExtExe, + } } -convert.rgb.hsl = function (rgb) { - const r = rgb[0] / 255; - const g = rgb[1] / 255; - const b = rgb[2] / 255; - const min = Math.min(r, g, b); - const max = Math.max(r, g, b); - const delta = max - min; - let h; - let s; - - if (max === min) { - h = 0; - } else if (r === max) { - h = (g - b) / delta; - } else if (g === max) { - h = 2 + (b - r) / delta; - } else if (b === max) { - h = 4 + (r - g) / delta; - } +const which = (cmd, opt, cb) => { + if (typeof opt === 'function') { + cb = opt + opt = {} + } + if (!opt) + opt = {} - h = Math.min(h * 60, 360); + const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt) + const found = [] - if (h < 0) { - h += 360; - } + const step = i => new Promise((resolve, reject) => { + if (i === pathEnv.length) + return opt.all && found.length ? resolve(found) + : reject(getNotFoundError(cmd)) - const l = (min + max) / 2; + const ppRaw = pathEnv[i] + const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw - if (max === min) { - s = 0; - } else if (l <= 0.5) { - s = delta / (max + min); - } else { - s = delta / (2 - max - min); - } + const pCmd = path.join(pathPart, cmd) + const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd + : pCmd - return [h, s * 100, l * 100]; -}; + resolve(subStep(p, i, 0)) + }) -convert.rgb.hsv = function (rgb) { - let rdif; - let gdif; - let bdif; - let h; - let s; + const subStep = (p, i, ii) => new Promise((resolve, reject) => { + if (ii === pathExt.length) + return resolve(step(i + 1)) + const ext = pathExt[ii] + isexe(p + ext, { pathExt: pathExtExe }, (er, is) => { + if (!er && is) { + if (opt.all) + found.push(p + ext) + else + return resolve(p + ext) + } + return resolve(subStep(p, i, ii + 1)) + }) + }) - const r = rgb[0] / 255; - const g = rgb[1] / 255; - const b = rgb[2] / 255; - const v = Math.max(r, g, b); - const diff = v - Math.min(r, g, b); - const diffc = function (c) { - return (v - c) / 6 / diff + 1 / 2; - }; + return cb ? step(0).then(res => cb(null, res), cb) : step(0) +} - if (diff === 0) { - h = 0; - s = 0; - } else { - s = diff / v; - rdif = diffc(r); - gdif = diffc(g); - bdif = diffc(b); +const whichSync = (cmd, opt) => { + opt = opt || {} - if (r === v) { - h = bdif - gdif; - } else if (g === v) { - h = (1 / 3) + rdif - bdif; - } else if (b === v) { - h = (2 / 3) + gdif - rdif; - } + const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt) + const found = [] - if (h < 0) { - h += 1; - } else if (h > 1) { - h -= 1; - } - } + for (let i = 0; i < pathEnv.length; i ++) { + const ppRaw = pathEnv[i] + const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw - return [ - h * 360, - s * 100, - v * 100 - ]; -}; + const pCmd = path.join(pathPart, cmd) + const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd + : pCmd -convert.rgb.hwb = function (rgb) { - const r = rgb[0]; - const g = rgb[1]; - let b = rgb[2]; - const h = convert.rgb.hsl(rgb)[0]; - const w = 1 / 255 * Math.min(r, Math.min(g, b)); + for (let j = 0; j < pathExt.length; j ++) { + const cur = p + pathExt[j] + try { + const is = isexe.sync(cur, { pathExt: pathExtExe }) + if (is) { + if (opt.all) + found.push(cur) + else + return cur + } + } catch (ex) {} + } + } - b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); + if (opt.all && found.length) + return found - return [h, w * 100, b * 100]; -}; + if (opt.nothrow) + return null -convert.rgb.cmyk = function (rgb) { - const r = rgb[0] / 255; - const g = rgb[1] / 255; - const b = rgb[2] / 255; + throw getNotFoundError(cmd) +} - const k = Math.min(1 - r, 1 - g, 1 - b); - const c = (1 - r - k) / (1 - k) || 0; - const m = (1 - g - k) / (1 - k) || 0; - const y = (1 - b - k) / (1 - k) || 0; +module.exports = which +which.sync = whichSync - return [c * 100, m * 100, y * 100, k * 100]; -}; -function comparativeDistance(x, y) { - /* - See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance - */ - return ( - ((x[0] - y[0]) ** 2) + - ((x[1] - y[1]) ** 2) + - ((x[2] - y[2]) ** 2) - ); +/***/ }), +/* 234 */ +/***/ (function(module, exports, __webpack_require__) { + +var fs = __webpack_require__(134) +var core +if (process.platform === 'win32' || global.TESTING_WINDOWS) { + core = __webpack_require__(235) +} else { + core = __webpack_require__(236) } -convert.rgb.keyword = function (rgb) { - const reversed = reverseKeywords[rgb]; - if (reversed) { - return reversed; - } +module.exports = isexe +isexe.sync = sync - let currentClosestDistance = Infinity; - let currentClosestKeyword; +function isexe (path, options, cb) { + if (typeof options === 'function') { + cb = options + options = {} + } - for (const keyword of Object.keys(cssKeywords)) { - const value = cssKeywords[keyword]; + if (!cb) { + if (typeof Promise !== 'function') { + throw new TypeError('callback not provided') + } - // Compute comparative distance - const distance = comparativeDistance(rgb, value); + return new Promise(function (resolve, reject) { + isexe(path, options || {}, function (er, is) { + if (er) { + reject(er) + } else { + resolve(is) + } + }) + }) + } - // Check if its less, if so set as closest - if (distance < currentClosestDistance) { - currentClosestDistance = distance; - currentClosestKeyword = keyword; - } - } + core(path, options || {}, function (er, is) { + // ignore EACCES because that just means we aren't allowed to run it + if (er) { + if (er.code === 'EACCES' || options && options.ignoreErrors) { + er = null + is = false + } + } + cb(er, is) + }) +} - return currentClosestKeyword; -}; +function sync (path, options) { + // my kingdom for a filtered catch + try { + return core.sync(path, options || {}) + } catch (er) { + if (options && options.ignoreErrors || er.code === 'EACCES') { + return false + } else { + throw er + } + } +} -convert.keyword.rgb = function (keyword) { - return cssKeywords[keyword]; -}; -convert.rgb.xyz = function (rgb) { - let r = rgb[0] / 255; - let g = rgb[1] / 255; - let b = rgb[2] / 255; +/***/ }), +/* 235 */ +/***/ (function(module, exports, __webpack_require__) { - // Assume sRGB - r = r > 0.04045 ? (((r + 0.055) / 1.055) ** 2.4) : (r / 12.92); - g = g > 0.04045 ? (((g + 0.055) / 1.055) ** 2.4) : (g / 12.92); - b = b > 0.04045 ? (((b + 0.055) / 1.055) ** 2.4) : (b / 12.92); +module.exports = isexe +isexe.sync = sync - const x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); - const y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); - const z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); +var fs = __webpack_require__(134) - return [x * 100, y * 100, z * 100]; -}; +function checkPathExt (path, options) { + var pathext = options.pathExt !== undefined ? + options.pathExt : process.env.PATHEXT -convert.rgb.lab = function (rgb) { - const xyz = convert.rgb.xyz(rgb); - let x = xyz[0]; - let y = xyz[1]; - let z = xyz[2]; + if (!pathext) { + return true + } - x /= 95.047; - y /= 100; - z /= 108.883; + pathext = pathext.split(';') + if (pathext.indexOf('') !== -1) { + return true + } + for (var i = 0; i < pathext.length; i++) { + var p = pathext[i].toLowerCase() + if (p && path.substr(-p.length).toLowerCase() === p) { + return true + } + } + return false +} - x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116); +function checkStat (stat, path, options) { + if (!stat.isSymbolicLink() && !stat.isFile()) { + return false + } + return checkPathExt(path, options) +} - const l = (116 * y) - 16; - const a = 500 * (x - y); - const b = 200 * (y - z); +function isexe (path, options, cb) { + fs.stat(path, function (er, stat) { + cb(er, er ? false : checkStat(stat, path, options)) + }) +} - return [l, a, b]; -}; +function sync (path, options) { + return checkStat(fs.statSync(path), path, options) +} -convert.hsl.rgb = function (hsl) { - const h = hsl[0] / 360; - const s = hsl[1] / 100; - const l = hsl[2] / 100; - let t2; - let t3; - let val; - if (s === 0) { - val = l * 255; - return [val, val, val]; - } +/***/ }), +/* 236 */ +/***/ (function(module, exports, __webpack_require__) { - if (l < 0.5) { - t2 = l * (1 + s); - } else { - t2 = l + s - l * s; - } +module.exports = isexe +isexe.sync = sync - const t1 = 2 * l - t2; +var fs = __webpack_require__(134) - const rgb = [0, 0, 0]; - for (let i = 0; i < 3; i++) { - t3 = h + 1 / 3 * -(i - 1); - if (t3 < 0) { - t3++; - } +function isexe (path, options, cb) { + fs.stat(path, function (er, stat) { + cb(er, er ? false : checkStat(stat, options)) + }) +} - if (t3 > 1) { - t3--; - } +function sync (path, options) { + return checkStat(fs.statSync(path), options) +} - if (6 * t3 < 1) { - val = t1 + (t2 - t1) * 6 * t3; - } else if (2 * t3 < 1) { - val = t2; - } else if (3 * t3 < 2) { - val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; - } else { - val = t1; - } +function checkStat (stat, options) { + return stat.isFile() && checkMode(stat, options) +} - rgb[i] = val * 255; - } +function checkMode (stat, options) { + var mod = stat.mode + var uid = stat.uid + var gid = stat.gid - return rgb; -}; + var myUid = options.uid !== undefined ? + options.uid : process.getuid && process.getuid() + var myGid = options.gid !== undefined ? + options.gid : process.getgid && process.getgid() -convert.hsl.hsv = function (hsl) { - const h = hsl[0]; - let s = hsl[1] / 100; - let l = hsl[2] / 100; - let smin = s; - const lmin = Math.max(l, 0.01); + var u = parseInt('100', 8) + var g = parseInt('010', 8) + var o = parseInt('001', 8) + var ug = u | g - l *= 2; - s *= (l <= 1) ? l : 2 - l; - smin *= lmin <= 1 ? lmin : 2 - lmin; - const v = (l + s) / 2; - const sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s); + var ret = (mod & o) || + (mod & g) && gid === myGid || + (mod & u) && uid === myUid || + (mod & ug) && myUid === 0 - return [h, sv * 100, v * 100]; -}; + return ret +} -convert.hsv.rgb = function (hsv) { - const h = hsv[0] / 60; - const s = hsv[1] / 100; - let v = hsv[2] / 100; - const hi = Math.floor(h) % 6; - const f = h - Math.floor(h); - const p = 255 * v * (1 - s); - const q = 255 * v * (1 - (s * f)); - const t = 255 * v * (1 - (s * (1 - f))); - v *= 255; +/***/ }), +/* 237 */ +/***/ (function(module, exports, __webpack_require__) { - switch (hi) { - case 0: - return [v, t, p]; - case 1: - return [q, v, p]; - case 2: - return [p, v, t]; - case 3: - return [p, q, v]; - case 4: - return [t, p, v]; - case 5: - return [v, p, q]; - } -}; +"use strict"; -convert.hsv.hsl = function (hsv) { - const h = hsv[0]; - const s = hsv[1] / 100; - const v = hsv[2] / 100; - const vmin = Math.max(v, 0.01); - let sl; - let l; - l = (2 - s) * v; - const lmin = (2 - s) * vmin; - sl = s * vmin; - sl /= (lmin <= 1) ? lmin : 2 - lmin; - sl = sl || 0; - l /= 2; +const pathKey = (options = {}) => { + const environment = options.env || process.env; + const platform = options.platform || process.platform; - return [h, sl * 100, l * 100]; + if (platform !== 'win32') { + return 'PATH'; + } + + return Object.keys(environment).find(key => key.toUpperCase() === 'PATH') || 'Path'; }; -// http://dev.w3.org/csswg/css-color/#hwb-to-rgb -convert.hwb.rgb = function (hwb) { - const h = hwb[0] / 360; - let wh = hwb[1] / 100; - let bl = hwb[2] / 100; - const ratio = wh + bl; - let f; +module.exports = pathKey; +// TODO: Remove this for the next major release +module.exports.default = pathKey; - // Wh + bl cant be > 1 - if (ratio > 1) { - wh /= ratio; - bl /= ratio; - } - const i = Math.floor(6 * h); - const v = 1 - bl; - f = 6 * h - i; +/***/ }), +/* 238 */ +/***/ (function(module, exports, __webpack_require__) { - if ((i & 0x01) !== 0) { - f = 1 - f; - } +"use strict"; - const n = wh + f * (v - wh); // Linear interpolation - let r; - let g; - let b; - /* eslint-disable max-statements-per-line,no-multi-spaces */ - switch (i) { - default: - case 6: - case 0: r = v; g = n; b = wh; break; - case 1: r = n; g = v; b = wh; break; - case 2: r = wh; g = v; b = n; break; - case 3: r = wh; g = n; b = v; break; - case 4: r = n; g = wh; b = v; break; - case 5: r = v; g = wh; b = n; break; - } - /* eslint-enable max-statements-per-line,no-multi-spaces */ +// See http://www.robvanderwoude.com/escapechars.php +const metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g; - return [r * 255, g * 255, b * 255]; -}; +function escapeCommand(arg) { + // Escape meta chars + arg = arg.replace(metaCharsRegExp, '^$1'); -convert.cmyk.rgb = function (cmyk) { - const c = cmyk[0] / 100; - const m = cmyk[1] / 100; - const y = cmyk[2] / 100; - const k = cmyk[3] / 100; + return arg; +} - const r = 1 - Math.min(1, c * (1 - k) + k); - const g = 1 - Math.min(1, m * (1 - k) + k); - const b = 1 - Math.min(1, y * (1 - k) + k); +function escapeArgument(arg, doubleEscapeMetaChars) { + // Convert to string + arg = `${arg}`; - return [r * 255, g * 255, b * 255]; -}; + // Algorithm below is based on https://qntm.org/cmd -convert.xyz.rgb = function (xyz) { - const x = xyz[0] / 100; - const y = xyz[1] / 100; - const z = xyz[2] / 100; - let r; - let g; - let b; + // Sequence of backslashes followed by a double quote: + // double up all the backslashes and escape the double quote + arg = arg.replace(/(\\*)"/g, '$1$1\\"'); - r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); - g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); - b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); + // Sequence of backslashes followed by the end of the string + // (which will become a double quote later): + // double up all the backslashes + arg = arg.replace(/(\\*)$/, '$1$1'); - // Assume sRGB - r = r > 0.0031308 - ? ((1.055 * (r ** (1.0 / 2.4))) - 0.055) - : r * 12.92; + // All other backslashes occur literally - g = g > 0.0031308 - ? ((1.055 * (g ** (1.0 / 2.4))) - 0.055) - : g * 12.92; + // Quote the whole thing: + arg = `"${arg}"`; - b = b > 0.0031308 - ? ((1.055 * (b ** (1.0 / 2.4))) - 0.055) - : b * 12.92; + // Escape meta chars + arg = arg.replace(metaCharsRegExp, '^$1'); - r = Math.min(Math.max(0, r), 1); - g = Math.min(Math.max(0, g), 1); - b = Math.min(Math.max(0, b), 1); + // Double escape meta chars if necessary + if (doubleEscapeMetaChars) { + arg = arg.replace(metaCharsRegExp, '^$1'); + } - return [r * 255, g * 255, b * 255]; -}; + return arg; +} -convert.xyz.lab = function (xyz) { - let x = xyz[0]; - let y = xyz[1]; - let z = xyz[2]; +module.exports.command = escapeCommand; +module.exports.argument = escapeArgument; - x /= 95.047; - y /= 100; - z /= 108.883; - x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116); +/***/ }), +/* 239 */ +/***/ (function(module, exports, __webpack_require__) { - const l = (116 * y) - 16; - const a = 500 * (x - y); - const b = 200 * (y - z); +"use strict"; - return [l, a, b]; -}; -convert.lab.xyz = function (lab) { - const l = lab[0]; - const a = lab[1]; - const b = lab[2]; - let x; - let y; - let z; +const fs = __webpack_require__(134); +const shebangCommand = __webpack_require__(240); - y = (l + 16) / 116; - x = a / 500 + y; - z = y - b / 200; +function readShebang(command) { + // Read the first 150 bytes from the file + const size = 150; + const buffer = Buffer.alloc(size); - const y2 = y ** 3; - const x2 = x ** 3; - const z2 = z ** 3; - y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787; - x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787; - z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787; + let fd; - x *= 95.047; - y *= 100; - z *= 108.883; + try { + fd = fs.openSync(command, 'r'); + fs.readSync(fd, buffer, 0, size, 0); + fs.closeSync(fd); + } catch (e) { /* Empty */ } - return [x, y, z]; -}; + // Attempt to extract shebang (null is returned if not a shebang) + return shebangCommand(buffer.toString()); +} -convert.lab.lch = function (lab) { - const l = lab[0]; - const a = lab[1]; - const b = lab[2]; - let h; +module.exports = readShebang; - const hr = Math.atan2(b, a); - h = hr * 360 / 2 / Math.PI; - if (h < 0) { - h += 360; - } +/***/ }), +/* 240 */ +/***/ (function(module, exports, __webpack_require__) { - const c = Math.sqrt(a * a + b * b); +"use strict"; - return [l, c, h]; -}; +const shebangRegex = __webpack_require__(241); -convert.lch.lab = function (lch) { - const l = lch[0]; - const c = lch[1]; - const h = lch[2]; +module.exports = (string = '') => { + const match = string.match(shebangRegex); - const hr = h / 360 * 2 * Math.PI; - const a = c * Math.cos(hr); - const b = c * Math.sin(hr); - - return [l, a, b]; -}; - -convert.rgb.ansi16 = function (args, saturation = null) { - const [r, g, b] = args; - let value = saturation === null ? convert.rgb.hsv(args)[2] : saturation; // Hsv -> ansi16 optimization - - value = Math.round(value / 50); - - if (value === 0) { - return 30; + if (!match) { + return null; } - let ansi = 30 - + ((Math.round(b / 255) << 2) - | (Math.round(g / 255) << 1) - | Math.round(r / 255)); + const [path, argument] = match[0].replace(/#! ?/, '').split(' '); + const binary = path.split('/').pop(); - if (value === 2) { - ansi += 60; + if (binary === 'env') { + return argument; } - return ansi; + return argument ? `${binary} ${argument}` : binary; }; -convert.hsv.ansi16 = function (args) { - // Optimization here; we already know the value and don't need to get - // it converted for us. - return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]); -}; -convert.rgb.ansi256 = function (args) { - const r = args[0]; - const g = args[1]; - const b = args[2]; +/***/ }), +/* 241 */ +/***/ (function(module, exports, __webpack_require__) { - // We use the extended greyscale palette here, with the exception of - // black and white. normal palette only has 4 greyscale shades. - if (r === g && g === b) { - if (r < 8) { - return 16; - } +"use strict"; - if (r > 248) { - return 231; - } +module.exports = /^#!(.*)/; - return Math.round(((r - 8) / 247) * 24) + 232; - } - const ansi = 16 - + (36 * Math.round(r / 255 * 5)) - + (6 * Math.round(g / 255 * 5)) - + Math.round(b / 255 * 5); +/***/ }), +/* 242 */ +/***/ (function(module, exports, __webpack_require__) { - return ansi; -}; +"use strict"; -convert.ansi16.rgb = function (args) { - let color = args % 10; - // Handle greyscale - if (color === 0 || color === 7) { - if (args > 50) { - color += 3.5; - } +const isWin = process.platform === 'win32'; - color = color / 10.5 * 255; +function notFoundError(original, syscall) { + return Object.assign(new Error(`${syscall} ${original.command} ENOENT`), { + code: 'ENOENT', + errno: 'ENOENT', + syscall: `${syscall} ${original.command}`, + path: original.command, + spawnargs: original.args, + }); +} - return [color, color, color]; - } +function hookChildProcess(cp, parsed) { + if (!isWin) { + return; + } - const mult = (~~(args > 50) + 1) * 0.5; - const r = ((color & 1) * mult) * 255; - const g = (((color >> 1) & 1) * mult) * 255; - const b = (((color >> 2) & 1) * mult) * 255; + const originalEmit = cp.emit; - return [r, g, b]; -}; + cp.emit = function (name, arg1) { + // If emitting "exit" event and exit code is 1, we need to check if + // the command exists and emit an "error" instead + // See https://github.com/IndigoUnited/node-cross-spawn/issues/16 + if (name === 'exit') { + const err = verifyENOENT(arg1, parsed, 'spawn'); -convert.ansi256.rgb = function (args) { - // Handle greyscale - if (args >= 232) { - const c = (args - 232) * 10 + 8; - return [c, c, c]; - } + if (err) { + return originalEmit.call(cp, 'error', err); + } + } - args -= 16; + return originalEmit.apply(cp, arguments); // eslint-disable-line prefer-rest-params + }; +} - let rem; - const r = Math.floor(args / 36) / 5 * 255; - const g = Math.floor((rem = args % 36) / 6) / 5 * 255; - const b = (rem % 6) / 5 * 255; +function verifyENOENT(status, parsed) { + if (isWin && status === 1 && !parsed.file) { + return notFoundError(parsed.original, 'spawn'); + } - return [r, g, b]; -}; + return null; +} -convert.rgb.hex = function (args) { - const integer = ((Math.round(args[0]) & 0xFF) << 16) - + ((Math.round(args[1]) & 0xFF) << 8) - + (Math.round(args[2]) & 0xFF); +function verifyENOENTSync(status, parsed) { + if (isWin && status === 1 && !parsed.file) { + return notFoundError(parsed.original, 'spawnSync'); + } - const string = integer.toString(16).toUpperCase(); - return '000000'.substring(string.length) + string; -}; + return null; +} -convert.hex.rgb = function (args) { - const match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); - if (!match) { - return [0, 0, 0]; - } +module.exports = { + hookChildProcess, + verifyENOENT, + verifyENOENTSync, + notFoundError, +}; - let colorString = match[0]; - if (match[0].length === 3) { - colorString = colorString.split('').map(char => { - return char + char; - }).join(''); - } +/***/ }), +/* 243 */ +/***/ (function(module, exports, __webpack_require__) { - const integer = parseInt(colorString, 16); - const r = (integer >> 16) & 0xFF; - const g = (integer >> 8) & 0xFF; - const b = integer & 0xFF; +"use strict"; - return [r, g, b]; -}; -convert.rgb.hcg = function (rgb) { - const r = rgb[0] / 255; - const g = rgb[1] / 255; - const b = rgb[2] / 255; - const max = Math.max(Math.max(r, g), b); - const min = Math.min(Math.min(r, g), b); - const chroma = (max - min); - let grayscale; - let hue; +module.exports = input => { + const LF = typeof input === 'string' ? '\n' : '\n'.charCodeAt(); + const CR = typeof input === 'string' ? '\r' : '\r'.charCodeAt(); - if (chroma < 1) { - grayscale = min / (1 - chroma); - } else { - grayscale = 0; + if (input[input.length - 1] === LF) { + input = input.slice(0, input.length - 1); } - if (chroma <= 0) { - hue = 0; - } else - if (max === r) { - hue = ((g - b) / chroma) % 6; - } else - if (max === g) { - hue = 2 + (b - r) / chroma; - } else { - hue = 4 + (r - g) / chroma; + if (input[input.length - 1] === CR) { + input = input.slice(0, input.length - 1); } - hue /= 6; - hue %= 1; - - return [hue * 360, chroma * 100, grayscale * 100]; + return input; }; -convert.hsl.hcg = function (hsl) { - const s = hsl[1] / 100; - const l = hsl[2] / 100; - const c = l < 0.5 ? (2.0 * s * l) : (2.0 * s * (1.0 - l)); +/***/ }), +/* 244 */ +/***/ (function(module, exports, __webpack_require__) { - let f = 0; - if (c < 1.0) { - f = (l - 0.5 * c) / (1.0 - c); - } +"use strict"; - return [hsl[0], c * 100, f * 100]; -}; +const path = __webpack_require__(4); +const pathKey = __webpack_require__(237); -convert.hsv.hcg = function (hsv) { - const s = hsv[1] / 100; - const v = hsv[2] / 100; +const npmRunPath = options => { + options = { + cwd: process.cwd(), + path: process.env[pathKey()], + execPath: process.execPath, + ...options + }; - const c = s * v; - let f = 0; + let previous; + let cwdPath = path.resolve(options.cwd); + const result = []; - if (c < 1.0) { - f = (v - c) / (1 - c); + while (previous !== cwdPath) { + result.push(path.join(cwdPath, 'node_modules/.bin')); + previous = cwdPath; + cwdPath = path.resolve(cwdPath, '..'); } - return [hsv[0], c * 100, f * 100]; -}; + // Ensure the running `node` binary is used + const execPathDir = path.resolve(options.cwd, options.execPath, '..'); + result.push(execPathDir); -convert.hcg.rgb = function (hcg) { - const h = hcg[0] / 360; - const c = hcg[1] / 100; - const g = hcg[2] / 100; + return result.concat(options.path).join(path.delimiter); +}; - if (c === 0.0) { - return [g * 255, g * 255, g * 255]; - } +module.exports = npmRunPath; +// TODO: Remove this for the next major release +module.exports.default = npmRunPath; - const pure = [0, 0, 0]; - const hi = (h % 1) * 6; - const v = hi % 1; - const w = 1 - v; - let mg = 0; +module.exports.env = options => { + options = { + env: process.env, + ...options + }; - /* eslint-disable max-statements-per-line */ - switch (Math.floor(hi)) { - case 0: - pure[0] = 1; pure[1] = v; pure[2] = 0; break; - case 1: - pure[0] = w; pure[1] = 1; pure[2] = 0; break; - case 2: - pure[0] = 0; pure[1] = 1; pure[2] = v; break; - case 3: - pure[0] = 0; pure[1] = w; pure[2] = 1; break; - case 4: - pure[0] = v; pure[1] = 0; pure[2] = 1; break; - default: - pure[0] = 1; pure[1] = 0; pure[2] = w; - } - /* eslint-enable max-statements-per-line */ + const env = {...options.env}; + const path = pathKey({env}); - mg = (1.0 - c) * g; + options.path = env[path]; + env[path] = module.exports(options); - return [ - (c * pure[0] + mg) * 255, - (c * pure[1] + mg) * 255, - (c * pure[2] + mg) * 255 - ]; + return env; }; -convert.hcg.hsv = function (hcg) { - const c = hcg[1] / 100; - const g = hcg[2] / 100; - - const v = c + g * (1.0 - c); - let f = 0; - if (v > 0.0) { - f = c / v; - } +/***/ }), +/* 245 */ +/***/ (function(module, exports, __webpack_require__) { - return [hcg[0], f * 100, v * 100]; -}; +"use strict"; -convert.hcg.hsl = function (hcg) { - const c = hcg[1] / 100; - const g = hcg[2] / 100; +const mimicFn = __webpack_require__(246); - const l = g * (1.0 - c) + 0.5 * c; - let s = 0; +const calledFunctions = new WeakMap(); - if (l > 0.0 && l < 0.5) { - s = c / (2 * l); - } else - if (l >= 0.5 && l < 1.0) { - s = c / (2 * (1 - l)); +const oneTime = (fn, options = {}) => { + if (typeof fn !== 'function') { + throw new TypeError('Expected a function'); } - return [hcg[0], s * 100, l * 100]; -}; + let ret; + let isCalled = false; + let callCount = 0; + const functionName = fn.displayName || fn.name || ''; -convert.hcg.hwb = function (hcg) { - const c = hcg[1] / 100; - const g = hcg[2] / 100; - const v = c + g * (1.0 - c); - return [hcg[0], (v - c) * 100, (1 - v) * 100]; -}; + const onetime = function (...args) { + calledFunctions.set(onetime, ++callCount); -convert.hwb.hcg = function (hwb) { - const w = hwb[1] / 100; - const b = hwb[2] / 100; - const v = 1 - b; - const c = v - w; - let g = 0; + if (isCalled) { + if (options.throw === true) { + throw new Error(`Function \`${functionName}\` can only be called once`); + } - if (c < 1) { - g = (v - c) / (1 - c); - } + return ret; + } - return [hwb[0], c * 100, g * 100]; -}; + isCalled = true; + ret = fn.apply(this, args); + fn = null; -convert.apple.rgb = function (apple) { - return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255]; -}; + return ret; + }; -convert.rgb.apple = function (rgb) { - return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535]; -}; + mimicFn(onetime, fn); + calledFunctions.set(onetime, callCount); -convert.gray.rgb = function (args) { - return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; + return onetime; }; -convert.gray.hsl = function (args) { - return [0, 0, args[0]]; -}; +module.exports = oneTime; +// TODO: Remove this for the next major release +module.exports.default = oneTime; -convert.gray.hsv = convert.gray.hsl; +module.exports.callCount = fn => { + if (!calledFunctions.has(fn)) { + throw new Error(`The given function \`${fn.name}\` is not wrapped by the \`onetime\` package`); + } -convert.gray.hwb = function (gray) { - return [0, 100, gray[0]]; + return calledFunctions.get(fn); }; -convert.gray.cmyk = function (gray) { - return [0, 0, 0, gray[0]]; -}; -convert.gray.lab = function (gray) { - return [gray[0], 0, 0]; -}; +/***/ }), +/* 246 */ +/***/ (function(module, exports, __webpack_require__) { -convert.gray.hex = function (gray) { - const val = Math.round(gray[0] / 100 * 255) & 0xFF; - const integer = (val << 16) + (val << 8) + val; +"use strict"; - const string = integer.toString(16).toUpperCase(); - return '000000'.substring(string.length) + string; -}; -convert.rgb.gray = function (rgb) { - const val = (rgb[0] + rgb[1] + rgb[2]) / 3; - return [val / 255 * 100]; +const mimicFn = (to, from) => { + for (const prop of Reflect.ownKeys(from)) { + Object.defineProperty(to, prop, Object.getOwnPropertyDescriptor(from, prop)); + } + + return to; }; +module.exports = mimicFn; +// TODO: Remove this for the next major release +module.exports.default = mimicFn; + /***/ }), -/* 231 */ +/* 247 */ /***/ (function(module, exports, __webpack_require__) { -const conversions = __webpack_require__(230); +"use strict"; -/* - This function routes a model to all other models. +const {signalsByName} = __webpack_require__(248); - all functions that are routed have a property `.conversion` attached - to the returned synthetic function. This property is an array - of strings, each with the steps in between the 'from' and 'to' - color models (inclusive). +const getErrorPrefix = ({timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled}) => { + if (timedOut) { + return `timed out after ${timeout} milliseconds`; + } - conversions that are not possible simply are not included. -*/ + if (isCanceled) { + return 'was canceled'; + } -function buildGraph() { - const graph = {}; - // https://jsperf.com/object-keys-vs-for-in-with-closure/3 - const models = Object.keys(conversions); + if (errorCode !== undefined) { + return `failed with ${errorCode}`; + } - for (let len = models.length, i = 0; i < len; i++) { - graph[models[i]] = { - // http://jsperf.com/1-vs-infinity - // micro-opt, but this is simple. - distance: -1, - parent: null - }; + if (signal !== undefined) { + return `was killed with ${signal} (${signalDescription})`; } - return graph; -} + if (exitCode !== undefined) { + return `failed with exit code ${exitCode}`; + } -// https://en.wikipedia.org/wiki/Breadth-first_search -function deriveBFS(fromModel) { - const graph = buildGraph(); - const queue = [fromModel]; // Unshift -> queue -> pop + return 'failed'; +}; - graph[fromModel].distance = 0; +const makeError = ({ + stdout, + stderr, + all, + error, + signal, + exitCode, + command, + timedOut, + isCanceled, + killed, + parsed: {options: {timeout}} +}) => { + // `signal` and `exitCode` emitted on `spawned.on('exit')` event can be `null`. + // We normalize them to `undefined` + exitCode = exitCode === null ? undefined : exitCode; + signal = signal === null ? undefined : signal; + const signalDescription = signal === undefined ? undefined : signalsByName[signal].description; - while (queue.length) { - const current = queue.pop(); - const adjacents = Object.keys(conversions[current]); + const errorCode = error && error.code; - for (let len = adjacents.length, i = 0; i < len; i++) { - const adjacent = adjacents[i]; - const node = graph[adjacent]; + const prefix = getErrorPrefix({timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled}); + const execaMessage = `Command ${prefix}: ${command}`; + const isError = Object.prototype.toString.call(error) === '[object Error]'; + const shortMessage = isError ? `${execaMessage}\n${error.message}` : execaMessage; + const message = [shortMessage, stderr, stdout].filter(Boolean).join('\n'); - if (node.distance === -1) { - node.distance = graph[current].distance + 1; - node.parent = current; - queue.unshift(adjacent); - } - } + if (isError) { + error.originalMessage = error.message; + error.message = message; + } else { + error = new Error(message); } - return graph; -} + error.shortMessage = shortMessage; + error.command = command; + error.exitCode = exitCode; + error.signal = signal; + error.signalDescription = signalDescription; + error.stdout = stdout; + error.stderr = stderr; -function link(from, to) { - return function (args) { - return to(from(args)); - }; -} + if (all !== undefined) { + error.all = all; + } -function wrapConversion(toModel, graph) { - const path = [graph[toModel].parent, toModel]; - let fn = conversions[graph[toModel].parent][toModel]; - - let cur = graph[toModel].parent; - while (graph[cur].parent) { - path.unshift(graph[cur].parent); - fn = link(conversions[graph[cur].parent][cur], fn); - cur = graph[cur].parent; + if ('bufferedData' in error) { + delete error.bufferedData; } - fn.conversion = path; - return fn; -} - -module.exports = function (fromModel) { - const graph = deriveBFS(fromModel); - const conversion = {}; - - const models = Object.keys(graph); - for (let len = models.length, i = 0; i < len; i++) { - const toModel = models[i]; - const node = graph[toModel]; - - if (node.parent === null) { - // No possible conversion, or this node is the source model. - continue; - } - - conversion[toModel] = wrapConversion(toModel, graph); - } + error.failed = true; + error.timedOut = Boolean(timedOut); + error.isCanceled = isCanceled; + error.killed = killed && !timedOut; - return conversion; + return error; }; +module.exports = makeError; /***/ }), -/* 232 */ +/* 248 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +Object.defineProperty(exports,"__esModule",{value:true});exports.signalsByNumber=exports.signalsByName=void 0;var _os=__webpack_require__(121); -const os = __webpack_require__(120); -const tty = __webpack_require__(121); -const hasFlag = __webpack_require__(233); - -const {env} = process; - -let forceColor; -if (hasFlag('no-color') || - hasFlag('no-colors') || - hasFlag('color=false') || - hasFlag('color=never')) { - forceColor = 0; -} else if (hasFlag('color') || - hasFlag('colors') || - hasFlag('color=true') || - hasFlag('color=always')) { - forceColor = 1; -} - -if ('FORCE_COLOR' in env) { - if (env.FORCE_COLOR === 'true') { - forceColor = 1; - } else if (env.FORCE_COLOR === 'false') { - forceColor = 0; - } else { - forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3); - } -} - -function translateLevel(level) { - if (level === 0) { - return false; - } - - return { - level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3 - }; -} +var _signals=__webpack_require__(249); +var _realtime=__webpack_require__(251); -function supportsColor(haveStream, streamIsTTY) { - if (forceColor === 0) { - return 0; - } - if (hasFlag('color=16m') || - hasFlag('color=full') || - hasFlag('color=truecolor')) { - return 3; - } - if (hasFlag('color=256')) { - return 2; - } +const getSignalsByName=function(){ +const signals=(0,_signals.getSignals)(); +return signals.reduce(getSignalByName,{}); +}; - if (haveStream && !streamIsTTY && forceColor === undefined) { - return 0; - } +const getSignalByName=function( +signalByNameMemo, +{name,number,description,supported,action,forced,standard}) +{ +return{ +...signalByNameMemo, +[name]:{name,number,description,supported,action,forced,standard}}; - const min = forceColor || 0; +}; - if (env.TERM === 'dumb') { - return min; - } +const signalsByName=getSignalsByName();exports.signalsByName=signalsByName; - if (process.platform === 'win32') { - // Windows 10 build 10586 is the first Windows release that supports 256 colors. - // Windows 10 build 14931 is the first release that supports 16m/TrueColor. - const osRelease = os.release().split('.'); - if ( - Number(osRelease[0]) >= 10 && - Number(osRelease[2]) >= 10586 - ) { - return Number(osRelease[2]) >= 14931 ? 3 : 2; - } - return 1; - } - if ('CI' in env) { - if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') { - return 1; - } - return min; - } +const getSignalsByNumber=function(){ +const signals=(0,_signals.getSignals)(); +const length=_realtime.SIGRTMAX+1; +const signalsA=Array.from({length},(value,number)=> +getSignalByNumber(number,signals)); - if ('TEAMCITY_VERSION' in env) { - return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; - } +return Object.assign({},...signalsA); +}; - if ('GITHUB_ACTIONS' in env) { - return 1; - } +const getSignalByNumber=function(number,signals){ +const signal=findSignalByNumber(number,signals); - if (env.COLORTERM === 'truecolor') { - return 3; - } +if(signal===undefined){ +return{}; +} - if ('TERM_PROGRAM' in env) { - const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); +const{name,description,supported,action,forced,standard}=signal; +return{ +[number]:{ +name, +number, +description, +supported, +action, +forced, +standard}}; - switch (env.TERM_PROGRAM) { - case 'iTerm.app': - return version >= 3 ? 3 : 2; - case 'Apple_Terminal': - return 2; - // No default - } - } - if (/-256(color)?$/i.test(env.TERM)) { - return 2; - } +}; - if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { - return 1; - } - if ('COLORTERM' in env) { - return 1; - } - return min; -} +const findSignalByNumber=function(number,signals){ +const signal=signals.find(({name})=>_os.constants.signals[name]===number); -function getSupportLevel(stream) { - const level = supportsColor(stream, stream && stream.isTTY); - return translateLevel(level); +if(signal!==undefined){ +return signal; } -module.exports = { - supportsColor: getSupportLevel, - stdout: translateLevel(supportsColor(true, tty.isatty(1))), - stderr: translateLevel(supportsColor(true, tty.isatty(2))) +return signals.find(signalA=>signalA.number===number); }; +const signalsByNumber=getSignalsByNumber();exports.signalsByNumber=signalsByNumber; +//# sourceMappingURL=main.js.map /***/ }), -/* 233 */ +/* 249 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +Object.defineProperty(exports,"__esModule",{value:true});exports.getSignals=void 0;var _os=__webpack_require__(121); - -module.exports = (flag, argv = process.argv) => { - const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); - const position = argv.indexOf(prefix + flag); - const terminatorPosition = argv.indexOf('--'); - return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition); -}; +var _core=__webpack_require__(250); +var _realtime=__webpack_require__(251); -/***/ }), -/* 234 */ -/***/ (function(module, exports, __webpack_require__) { -"use strict"; +const getSignals=function(){ +const realtimeSignals=(0,_realtime.getRealtimeSignals)(); +const signals=[..._core.SIGNALS,...realtimeSignals].map(normalizeSignal); +return signals; +};exports.getSignals=getSignals; -const stringReplaceAll = (string, substring, replacer) => { - let index = string.indexOf(substring); - if (index === -1) { - return string; - } - const substringLength = substring.length; - let endIndex = 0; - let returnValue = ''; - do { - returnValue += string.substr(endIndex, index - endIndex) + substring + replacer; - endIndex = index + substringLength; - index = string.indexOf(substring, endIndex); - } while (index !== -1); - returnValue += string.substr(endIndex); - return returnValue; -}; -const stringEncaseCRLFWithFirstIndex = (string, prefix, postfix, index) => { - let endIndex = 0; - let returnValue = ''; - do { - const gotCR = string[index - 1] === '\r'; - returnValue += string.substr(endIndex, (gotCR ? index - 1 : index) - endIndex) + prefix + (gotCR ? '\r\n' : '\n') + postfix; - endIndex = index + 1; - index = string.indexOf('\n', endIndex); - } while (index !== -1); - returnValue += string.substr(endIndex); - return returnValue; -}; -module.exports = { - stringReplaceAll, - stringEncaseCRLFWithFirstIndex +const normalizeSignal=function({ +name, +number:defaultNumber, +description, +action, +forced=false, +standard}) +{ +const{ +signals:{[name]:constantSignal}}= +_os.constants; +const supported=constantSignal!==undefined; +const number=supported?constantSignal:defaultNumber; +return{name,number,description,supported,action,forced,standard}; }; - +//# sourceMappingURL=signals.js.map /***/ }), -/* 235 */ +/* 250 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +Object.defineProperty(exports,"__esModule",{value:true});exports.SIGNALS=void 0; -const TEMPLATE_REGEX = /(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; -const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; -const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; -const ESCAPE_REGEX = /\\(u(?:[a-f\d]{4}|{[a-f\d]{1,6}})|x[a-f\d]{2}|.)|([^\\])/gi; - -const ESCAPES = new Map([ - ['n', '\n'], - ['r', '\r'], - ['t', '\t'], - ['b', '\b'], - ['f', '\f'], - ['v', '\v'], - ['0', '\0'], - ['\\', '\\'], - ['e', '\u001B'], - ['a', '\u0007'] -]); +const SIGNALS=[ +{ +name:"SIGHUP", +number:1, +action:"terminate", +description:"Terminal closed", +standard:"posix"}, -function unescape(c) { - const u = c[0] === 'u'; - const bracket = c[1] === '{'; +{ +name:"SIGINT", +number:2, +action:"terminate", +description:"User interruption with CTRL-C", +standard:"ansi"}, - if ((u && !bracket && c.length === 5) || (c[0] === 'x' && c.length === 3)) { - return String.fromCharCode(parseInt(c.slice(1), 16)); - } +{ +name:"SIGQUIT", +number:3, +action:"core", +description:"User interruption with CTRL-\\", +standard:"posix"}, - if (u && bracket) { - return String.fromCodePoint(parseInt(c.slice(2, -1), 16)); - } +{ +name:"SIGILL", +number:4, +action:"core", +description:"Invalid machine instruction", +standard:"ansi"}, - return ESCAPES.get(c) || c; -} +{ +name:"SIGTRAP", +number:5, +action:"core", +description:"Debugger breakpoint", +standard:"posix"}, -function parseArguments(name, arguments_) { - const results = []; - const chunks = arguments_.trim().split(/\s*,\s*/g); - let matches; +{ +name:"SIGABRT", +number:6, +action:"core", +description:"Aborted", +standard:"ansi"}, - for (const chunk of chunks) { - const number = Number(chunk); - if (!Number.isNaN(number)) { - results.push(number); - } else if ((matches = chunk.match(STRING_REGEX))) { - results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, character) => escape ? unescape(escape) : character)); - } else { - throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); - } - } +{ +name:"SIGIOT", +number:6, +action:"core", +description:"Aborted", +standard:"bsd"}, - return results; -} +{ +name:"SIGBUS", +number:7, +action:"core", +description: +"Bus error due to misaligned, non-existing address or paging error", +standard:"bsd"}, -function parseStyle(style) { - STYLE_REGEX.lastIndex = 0; +{ +name:"SIGEMT", +number:7, +action:"terminate", +description:"Command should be emulated but is not implemented", +standard:"other"}, - const results = []; - let matches; +{ +name:"SIGFPE", +number:8, +action:"core", +description:"Floating point arithmetic error", +standard:"ansi"}, - while ((matches = STYLE_REGEX.exec(style)) !== null) { - const name = matches[1]; +{ +name:"SIGKILL", +number:9, +action:"terminate", +description:"Forced termination", +standard:"posix", +forced:true}, - if (matches[2]) { - const args = parseArguments(name, matches[2]); - results.push([name].concat(args)); - } else { - results.push([name]); - } - } +{ +name:"SIGUSR1", +number:10, +action:"terminate", +description:"Application-specific signal", +standard:"posix"}, - return results; -} +{ +name:"SIGSEGV", +number:11, +action:"core", +description:"Segmentation fault", +standard:"ansi"}, -function buildStyle(chalk, styles) { - const enabled = {}; +{ +name:"SIGUSR2", +number:12, +action:"terminate", +description:"Application-specific signal", +standard:"posix"}, - for (const layer of styles) { - for (const style of layer.styles) { - enabled[style[0]] = layer.inverse ? null : style.slice(1); - } - } +{ +name:"SIGPIPE", +number:13, +action:"terminate", +description:"Broken pipe or socket", +standard:"posix"}, - let current = chalk; - for (const [styleName, styles] of Object.entries(enabled)) { - if (!Array.isArray(styles)) { - continue; - } +{ +name:"SIGALRM", +number:14, +action:"terminate", +description:"Timeout or timer", +standard:"posix"}, - if (!(styleName in current)) { - throw new Error(`Unknown Chalk style: ${styleName}`); - } +{ +name:"SIGTERM", +number:15, +action:"terminate", +description:"Termination", +standard:"ansi"}, - current = styles.length > 0 ? current[styleName](...styles) : current[styleName]; - } +{ +name:"SIGSTKFLT", +number:16, +action:"terminate", +description:"Stack is empty or overflowed", +standard:"other"}, - return current; -} +{ +name:"SIGCHLD", +number:17, +action:"ignore", +description:"Child process terminated, paused or unpaused", +standard:"posix"}, -module.exports = (chalk, temporary) => { - const styles = []; - const chunks = []; - let chunk = []; +{ +name:"SIGCLD", +number:17, +action:"ignore", +description:"Child process terminated, paused or unpaused", +standard:"other"}, - // eslint-disable-next-line max-params - temporary.replace(TEMPLATE_REGEX, (m, escapeCharacter, inverse, style, close, character) => { - if (escapeCharacter) { - chunk.push(unescape(escapeCharacter)); - } else if (style) { - const string = chunk.join(''); - chunk = []; - chunks.push(styles.length === 0 ? string : buildStyle(chalk, styles)(string)); - styles.push({inverse, styles: parseStyle(style)}); - } else if (close) { - if (styles.length === 0) { - throw new Error('Found extraneous } in Chalk template literal'); - } +{ +name:"SIGCONT", +number:18, +action:"unpause", +description:"Unpaused", +standard:"posix", +forced:true}, - chunks.push(buildStyle(chalk, styles)(chunk.join(''))); - chunk = []; - styles.pop(); - } else { - chunk.push(character); - } - }); +{ +name:"SIGSTOP", +number:19, +action:"pause", +description:"Paused", +standard:"posix", +forced:true}, - chunks.push(chunk.join('')); +{ +name:"SIGTSTP", +number:20, +action:"pause", +description:"Paused using CTRL-Z or \"suspend\"", +standard:"posix"}, - if (styles.length > 0) { - const errMessage = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; - throw new Error(errMessage); - } +{ +name:"SIGTTIN", +number:21, +action:"pause", +description:"Background process cannot read terminal input", +standard:"posix"}, - return chunks.join(''); -}; +{ +name:"SIGBREAK", +number:21, +action:"terminate", +description:"User interruption with CTRL-BREAK", +standard:"other"}, + +{ +name:"SIGTTOU", +number:22, +action:"pause", +description:"Background process cannot write to terminal output", +standard:"posix"}, + +{ +name:"SIGURG", +number:23, +action:"ignore", +description:"Socket received out-of-band data", +standard:"bsd"}, + +{ +name:"SIGXCPU", +number:24, +action:"core", +description:"Process timed out", +standard:"bsd"}, + +{ +name:"SIGXFSZ", +number:25, +action:"core", +description:"File too big", +standard:"bsd"}, + +{ +name:"SIGVTALRM", +number:26, +action:"terminate", +description:"Timeout or timer", +standard:"bsd"}, + +{ +name:"SIGPROF", +number:27, +action:"terminate", +description:"Timeout or timer", +standard:"bsd"}, + +{ +name:"SIGWINCH", +number:28, +action:"ignore", +description:"Terminal window size changed", +standard:"bsd"}, +{ +name:"SIGIO", +number:29, +action:"terminate", +description:"I/O is available", +standard:"other"}, + +{ +name:"SIGPOLL", +number:29, +action:"terminate", +description:"Watched event", +standard:"other"}, + +{ +name:"SIGINFO", +number:29, +action:"ignore", +description:"Request for process information", +standard:"other"}, + +{ +name:"SIGPWR", +number:30, +action:"terminate", +description:"Device running out of power", +standard:"systemv"}, + +{ +name:"SIGSYS", +number:31, +action:"core", +description:"Invalid system call", +standard:"other"}, + +{ +name:"SIGUNUSED", +number:31, +action:"terminate", +description:"Invalid system call", +standard:"other"}];exports.SIGNALS=SIGNALS; +//# sourceMappingURL=core.js.map /***/ }), -/* 236 */ +/* 251 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +Object.defineProperty(exports,"__esModule",{value:true});exports.SIGRTMAX=exports.getRealtimeSignals=void 0; +const getRealtimeSignals=function(){ +const length=SIGRTMAX-SIGRTMIN+1; +return Array.from({length},getRealtimeSignal); +};exports.getRealtimeSignals=getRealtimeSignals; -const path = __webpack_require__(4); -const childProcess = __webpack_require__(237); -const crossSpawn = __webpack_require__(238); -const stripFinalNewline = __webpack_require__(251); -const npmRunPath = __webpack_require__(252); -const onetime = __webpack_require__(253); -const makeError = __webpack_require__(255); -const normalizeStdio = __webpack_require__(260); -const {spawnedKill, spawnedCancel, setupTimeout, setExitHandler} = __webpack_require__(261); -const {handleInput, getSpawnedResult, makeAllStream, validateInputSync} = __webpack_require__(262); -const {mergePromise, getSpawnedPromise} = __webpack_require__(269); -const {joinCommand, parseCommand} = __webpack_require__(270); +const getRealtimeSignal=function(value,index){ +return{ +name:`SIGRT${index+1}`, +number:SIGRTMIN+index, +action:"terminate", +description:"Application-specific signal (realtime)", +standard:"posix"}; -const DEFAULT_MAX_BUFFER = 1000 * 1000 * 100; +}; -const getEnv = ({env: envOption, extendEnv, preferLocal, localDir, execPath}) => { - const env = extendEnv ? {...process.env, ...envOption} : envOption; +const SIGRTMIN=34; +const SIGRTMAX=64;exports.SIGRTMAX=SIGRTMAX; +//# sourceMappingURL=realtime.js.map - if (preferLocal) { - return npmRunPath.env({env, cwd: localDir, execPath}); - } +/***/ }), +/* 252 */ +/***/ (function(module, exports, __webpack_require__) { - return env; -}; +"use strict"; -const handleArgs = (file, args, options = {}) => { - const parsed = crossSpawn._parse(file, args, options); - file = parsed.command; - args = parsed.args; - options = parsed.options; +const aliases = ['stdin', 'stdout', 'stderr']; - options = { - maxBuffer: DEFAULT_MAX_BUFFER, - buffer: true, - stripFinalNewline: true, - extendEnv: true, - preferLocal: false, - localDir: options.cwd || process.cwd(), - execPath: process.execPath, - encoding: 'utf8', - reject: true, - cleanup: true, - all: false, - windowsHide: true, - ...options - }; +const hasAlias = opts => aliases.some(alias => opts[alias] !== undefined); - options.env = getEnv(options); +const normalizeStdio = opts => { + if (!opts) { + return; + } - options.stdio = normalizeStdio(options); + const {stdio} = opts; - if (process.platform === 'win32' && path.basename(file, '.exe') === 'cmd') { - // #116 - args.unshift('/q'); + if (stdio === undefined) { + return aliases.map(alias => opts[alias]); } - return {file, args, options, parsed}; -}; + if (hasAlias(opts)) { + throw new Error(`It's not possible to provide \`stdio\` in combination with one of ${aliases.map(alias => `\`${alias}\``).join(', ')}`); + } -const handleOutput = (options, value, error) => { - if (typeof value !== 'string' && !Buffer.isBuffer(value)) { - // When `execa.sync()` errors, we normalize it to '' to mimic `execa()` - return error === undefined ? undefined : ''; + if (typeof stdio === 'string') { + return stdio; } - if (options.stripFinalNewline) { - return stripFinalNewline(value); + if (!Array.isArray(stdio)) { + throw new TypeError(`Expected \`stdio\` to be of type \`string\` or \`Array\`, got \`${typeof stdio}\``); } - return value; + const length = Math.max(stdio.length, aliases.length); + return Array.from({length}, (value, index) => stdio[index]); }; -const execa = (file, args, options) => { - const parsed = handleArgs(file, args, options); - const command = joinCommand(file, args); +module.exports = normalizeStdio; - let spawned; - try { - spawned = childProcess.spawn(parsed.file, parsed.args, parsed.options); - } catch (error) { - // Ensure the returned error is always both a promise and a child process - const dummySpawned = new childProcess.ChildProcess(); - const errorPromise = Promise.reject(makeError({ - error, - stdout: '', - stderr: '', - all: '', - command, - parsed, - timedOut: false, - isCanceled: false, - killed: false - })); - return mergePromise(dummySpawned, errorPromise); - } +// `ipc` is pushed unless it is already present +module.exports.node = opts => { + const stdio = normalizeStdio(opts); - const spawnedPromise = getSpawnedPromise(spawned); - const timedPromise = setupTimeout(spawned, parsed.options, spawnedPromise); - const processDone = setExitHandler(spawned, parsed.options, timedPromise); + if (stdio === 'ipc') { + return 'ipc'; + } - const context = {isCanceled: false}; + if (stdio === undefined || typeof stdio === 'string') { + return [stdio, stdio, stdio, 'ipc']; + } - spawned.kill = spawnedKill.bind(null, spawned.kill.bind(spawned)); - spawned.cancel = spawnedCancel.bind(null, spawned, context); + if (stdio.includes('ipc')) { + return stdio; + } - const handlePromise = async () => { - const [{error, exitCode, signal, timedOut}, stdoutResult, stderrResult, allResult] = await getSpawnedResult(spawned, parsed.options, processDone); - const stdout = handleOutput(parsed.options, stdoutResult); - const stderr = handleOutput(parsed.options, stderrResult); - const all = handleOutput(parsed.options, allResult); + return [...stdio, 'ipc']; +}; - if (error || exitCode !== 0 || signal !== null) { - const returnedError = makeError({ - error, - exitCode, - signal, - stdout, - stderr, - all, - command, - parsed, - timedOut, - isCanceled: context.isCanceled, - killed: spawned.killed - }); - if (!parsed.options.reject) { - return returnedError; - } +/***/ }), +/* 253 */ +/***/ (function(module, exports, __webpack_require__) { - throw returnedError; - } +"use strict"; - return { - command, - exitCode: 0, - stdout, - stderr, - all, - failed: false, - timedOut: false, - isCanceled: false, - killed: false - }; - }; +const os = __webpack_require__(121); +const onExit = __webpack_require__(218); - const handlePromiseOnce = onetime(handlePromise); +const DEFAULT_FORCE_KILL_TIMEOUT = 1000 * 5; - crossSpawn._enoent.hookChildProcess(spawned, parsed.parsed); +// Monkey-patches `childProcess.kill()` to add `forceKillAfterTimeout` behavior +const spawnedKill = (kill, signal = 'SIGTERM', options = {}) => { + const killResult = kill(signal); + setKillTimeout(kill, signal, options, killResult); + return killResult; +}; - handleInput(spawned, parsed.options.input); +const setKillTimeout = (kill, signal, options, killResult) => { + if (!shouldForceKill(signal, options, killResult)) { + return; + } - spawned.all = makeAllStream(spawned, parsed.options); + const timeout = getForceKillAfterTimeout(options); + const t = setTimeout(() => { + kill('SIGKILL'); + }, timeout); - return mergePromise(spawned, handlePromiseOnce); + // Guarded because there's no `.unref()` when `execa` is used in the renderer + // process in Electron. This cannot be tested since we don't run tests in + // Electron. + // istanbul ignore else + if (t.unref) { + t.unref(); + } }; -module.exports = execa; - -module.exports.sync = (file, args, options) => { - const parsed = handleArgs(file, args, options); - const command = joinCommand(file, args); +const shouldForceKill = (signal, {forceKillAfterTimeout}, killResult) => { + return isSigterm(signal) && forceKillAfterTimeout !== false && killResult; +}; - validateInputSync(parsed.options); +const isSigterm = signal => { + return signal === os.constants.signals.SIGTERM || + (typeof signal === 'string' && signal.toUpperCase() === 'SIGTERM'); +}; - let result; - try { - result = childProcess.spawnSync(parsed.file, parsed.args, parsed.options); - } catch (error) { - throw makeError({ - error, - stdout: '', - stderr: '', - all: '', - command, - parsed, - timedOut: false, - isCanceled: false, - killed: false - }); +const getForceKillAfterTimeout = ({forceKillAfterTimeout = true}) => { + if (forceKillAfterTimeout === true) { + return DEFAULT_FORCE_KILL_TIMEOUT; } - const stdout = handleOutput(parsed.options, result.stdout, result.error); - const stderr = handleOutput(parsed.options, result.stderr, result.error); + if (!Number.isFinite(forceKillAfterTimeout) || forceKillAfterTimeout < 0) { + throw new TypeError(`Expected the \`forceKillAfterTimeout\` option to be a non-negative integer, got \`${forceKillAfterTimeout}\` (${typeof forceKillAfterTimeout})`); + } - if (result.error || result.status !== 0 || result.signal !== null) { - const error = makeError({ - stdout, - stderr, - error: result.error, - signal: result.signal, - exitCode: result.status, - command, - parsed, - timedOut: result.error && result.error.code === 'ETIMEDOUT', - isCanceled: false, - killed: result.signal !== null - }); + return forceKillAfterTimeout; +}; - if (!parsed.options.reject) { - return error; - } +// `childProcess.cancel()` +const spawnedCancel = (spawned, context) => { + const killResult = spawned.kill(); - throw error; + if (killResult) { + context.isCanceled = true; } - - return { - command, - exitCode: 0, - stdout, - stderr, - failed: false, - timedOut: false, - isCanceled: false, - killed: false - }; }; -module.exports.command = (command, options) => { - const [file, ...args] = parseCommand(command); - return execa(file, args, options); +const timeoutKill = (spawned, signal, reject) => { + spawned.kill(signal); + reject(Object.assign(new Error('Timed out'), {timedOut: true, signal})); }; -module.exports.commandSync = (command, options) => { - const [file, ...args] = parseCommand(command); - return execa.sync(file, args, options); -}; +// `timeout` option handling +const setupTimeout = (spawned, {timeout, killSignal = 'SIGTERM'}, spawnedPromise) => { + if (timeout === 0 || timeout === undefined) { + return spawnedPromise; + } -module.exports.node = (scriptPath, args, options = {}) => { - if (args && !Array.isArray(args) && typeof args === 'object') { - options = args; - args = []; + if (!Number.isFinite(timeout) || timeout < 0) { + throw new TypeError(`Expected the \`timeout\` option to be a non-negative integer, got \`${timeout}\` (${typeof timeout})`); } - const stdio = normalizeStdio.node(options); + let timeoutId; + const timeoutPromise = new Promise((resolve, reject) => { + timeoutId = setTimeout(() => { + timeoutKill(spawned, killSignal, reject); + }, timeout); + }); - const {nodePath = process.execPath, nodeOptions = process.execArgv} = options; + const safeSpawnedPromise = spawnedPromise.finally(() => { + clearTimeout(timeoutId); + }); - return execa( - nodePath, - [ - ...nodeOptions, - scriptPath, - ...(Array.isArray(args) ? args : []) - ], - { - ...options, - stdin: undefined, - stdout: undefined, - stderr: undefined, - stdio, - shell: false - } - ); + return Promise.race([timeoutPromise, safeSpawnedPromise]); }; +// `cleanup` option handling +const setExitHandler = async (spawned, {cleanup, detached}, timedPromise) => { + if (!cleanup || detached) { + return timedPromise; + } + + const removeExitHandler = onExit(() => { + spawned.kill(); + }); -/***/ }), -/* 237 */ -/***/ (function(module, exports) { + return timedPromise.finally(() => { + removeExitHandler(); + }); +}; + +module.exports = { + spawnedKill, + spawnedCancel, + setupTimeout, + setExitHandler +}; -module.exports = require("child_process"); /***/ }), -/* 238 */ +/* 254 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +const isStream = __webpack_require__(255); +const getStream = __webpack_require__(256); +const mergeStream = __webpack_require__(260); -const cp = __webpack_require__(237); -const parse = __webpack_require__(239); -const enoent = __webpack_require__(250); +// `input` option +const handleInput = (spawned, input) => { + // Checking for stdin is workaround for https://github.com/nodejs/node/issues/26852 + // TODO: Remove `|| spawned.stdin === undefined` once we drop support for Node.js <=12.2.0 + if (input === undefined || spawned.stdin === undefined) { + return; + } -function spawn(command, args, options) { - // Parse the arguments - const parsed = parse(command, args, options); + if (isStream(input)) { + input.pipe(spawned.stdin); + } else { + spawned.stdin.end(input); + } +}; - // Spawn the child process - const spawned = cp.spawn(parsed.command, parsed.args, parsed.options); +// `all` interleaves `stdout` and `stderr` +const makeAllStream = (spawned, {all}) => { + if (!all || (!spawned.stdout && !spawned.stderr)) { + return; + } - // Hook into child process "exit" event to emit an error if the command - // does not exists, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 - enoent.hookChildProcess(spawned, parsed); + const mixed = mergeStream(); - return spawned; -} + if (spawned.stdout) { + mixed.add(spawned.stdout); + } -function spawnSync(command, args, options) { - // Parse the arguments - const parsed = parse(command, args, options); + if (spawned.stderr) { + mixed.add(spawned.stderr); + } - // Spawn the child process - const result = cp.spawnSync(parsed.command, parsed.args, parsed.options); + return mixed; +}; - // Analyze if the command does not exist, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 - result.error = result.error || enoent.verifyENOENTSync(result.status, parsed); +// On failure, `result.stdout|stderr|all` should contain the currently buffered stream +const getBufferedData = async (stream, streamPromise) => { + if (!stream) { + return; + } - return result; -} + stream.destroy(); -module.exports = spawn; -module.exports.spawn = spawn; -module.exports.sync = spawnSync; + try { + return await streamPromise; + } catch (error) { + return error.bufferedData; + } +}; -module.exports._parse = parse; -module.exports._enoent = enoent; +const getStreamPromise = (stream, {encoding, buffer, maxBuffer}) => { + if (!stream || !buffer) { + return; + } + if (encoding) { + return getStream(stream, {encoding, maxBuffer}); + } -/***/ }), -/* 239 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -const path = __webpack_require__(4); -const resolveCommand = __webpack_require__(240); -const escape = __webpack_require__(246); -const readShebang = __webpack_require__(247); - -const isWin = process.platform === 'win32'; -const isExecutableRegExp = /\.(?:com|exe)$/i; -const isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i; - -function detectShebang(parsed) { - parsed.file = resolveCommand(parsed); - - const shebang = parsed.file && readShebang(parsed.file); - - if (shebang) { - parsed.args.unshift(parsed.file); - parsed.command = shebang; - - return resolveCommand(parsed); - } + return getStream.buffer(stream, {maxBuffer}); +}; - return parsed.file; -} +// Retrieve result of child process: exit code, signal, error, streams (stdout/stderr/all) +const getSpawnedResult = async ({stdout, stderr, all}, {encoding, buffer, maxBuffer}, processDone) => { + const stdoutPromise = getStreamPromise(stdout, {encoding, buffer, maxBuffer}); + const stderrPromise = getStreamPromise(stderr, {encoding, buffer, maxBuffer}); + const allPromise = getStreamPromise(all, {encoding, buffer, maxBuffer: maxBuffer * 2}); -function parseNonShell(parsed) { - if (!isWin) { - return parsed; - } + try { + return await Promise.all([processDone, stdoutPromise, stderrPromise, allPromise]); + } catch (error) { + return Promise.all([ + {error, signal: error.signal, timedOut: error.timedOut}, + getBufferedData(stdout, stdoutPromise), + getBufferedData(stderr, stderrPromise), + getBufferedData(all, allPromise) + ]); + } +}; - // Detect & add support for shebangs - const commandFile = detectShebang(parsed); +const validateInputSync = ({input}) => { + if (isStream(input)) { + throw new TypeError('The `input` option cannot be a stream in sync mode'); + } +}; - // We don't need a shell if the command filename is an executable - const needsShell = !isExecutableRegExp.test(commandFile); +module.exports = { + handleInput, + makeAllStream, + getSpawnedResult, + validateInputSync +}; - // If a shell is required, use cmd.exe and take care of escaping everything correctly - // Note that `forceShell` is an hidden option used only in tests - if (parsed.options.forceShell || needsShell) { - // Need to double escape meta chars if the command is a cmd-shim located in `node_modules/.bin/` - // The cmd-shim simply calls execute the package bin file with NodeJS, proxying any argument - // Because the escape of metachars with ^ gets interpreted when the cmd.exe is first called, - // we need to double escape them - const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile); - // Normalize posix paths into OS compatible paths (e.g.: foo/bar -> foo\bar) - // This is necessary otherwise it will always fail with ENOENT in those cases - parsed.command = path.normalize(parsed.command); - // Escape command & arguments - parsed.command = escape.command(parsed.command); - parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars)); +/***/ }), +/* 255 */ +/***/ (function(module, exports, __webpack_require__) { - const shellCommand = [parsed.command].concat(parsed.args).join(' '); +"use strict"; - parsed.args = ['/d', '/s', '/c', `"${shellCommand}"`]; - parsed.command = process.env.comspec || 'cmd.exe'; - parsed.options.windowsVerbatimArguments = true; // Tell node's spawn that the arguments are already escaped - } - return parsed; -} +const isStream = stream => + stream !== null && + typeof stream === 'object' && + typeof stream.pipe === 'function'; -function parse(command, args, options) { - // Normalize arguments, similar to nodejs - if (args && !Array.isArray(args)) { - options = args; - args = null; - } +isStream.writable = stream => + isStream(stream) && + stream.writable !== false && + typeof stream._write === 'function' && + typeof stream._writableState === 'object'; - args = args ? args.slice(0) : []; // Clone array to avoid changing the original - options = Object.assign({}, options); // Clone object to avoid changing the original +isStream.readable = stream => + isStream(stream) && + stream.readable !== false && + typeof stream._read === 'function' && + typeof stream._readableState === 'object'; - // Build our parsed object - const parsed = { - command, - args, - options, - file: undefined, - original: { - command, - args, - }, - }; +isStream.duplex = stream => + isStream.writable(stream) && + isStream.readable(stream); - // Delegate further parsing to shell or non-shell - return options.shell ? parsed : parseNonShell(parsed); -} +isStream.transform = stream => + isStream.duplex(stream) && + typeof stream._transform === 'function' && + typeof stream._transformState === 'object'; -module.exports = parse; +module.exports = isStream; /***/ }), -/* 240 */ +/* 256 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +const pump = __webpack_require__(257); +const bufferStream = __webpack_require__(259); -const path = __webpack_require__(4); -const which = __webpack_require__(241); -const pathKey = __webpack_require__(245)(); +class MaxBufferError extends Error { + constructor() { + super('maxBuffer exceeded'); + this.name = 'MaxBufferError'; + } +} -function resolveCommandAttempt(parsed, withoutPathExt) { - const cwd = process.cwd(); - const hasCustomCwd = parsed.options.cwd != null; - // Worker threads do not have process.chdir() - const shouldSwitchCwd = hasCustomCwd && process.chdir !== undefined; +async function getStream(inputStream, options) { + if (!inputStream) { + return Promise.reject(new Error('Expected a stream')); + } - // If a custom `cwd` was specified, we need to change the process cwd - // because `which` will do stat calls but does not support a custom cwd - if (shouldSwitchCwd) { - try { - process.chdir(parsed.options.cwd); - } catch (err) { - /* Empty */ - } - } + options = { + maxBuffer: Infinity, + ...options + }; - let resolved; + const {maxBuffer} = options; - try { - resolved = which.sync(parsed.command, { - path: (parsed.options.env || process.env)[pathKey], - pathExt: withoutPathExt ? path.delimiter : undefined, - }); - } catch (e) { - /* Empty */ - } finally { - if (shouldSwitchCwd) { - process.chdir(cwd); - } - } + let stream; + await new Promise((resolve, reject) => { + const rejectPromise = error => { + if (error) { // A null check + error.bufferedData = stream.getBufferedValue(); + } - // If we successfully resolved, ensure that an absolute path is returned - // Note that when a custom `cwd` was used, we need to resolve to an absolute path based on it - if (resolved) { - resolved = path.resolve(hasCustomCwd ? parsed.options.cwd : '', resolved); - } + reject(error); + }; - return resolved; -} + stream = pump(inputStream, bufferStream(options), error => { + if (error) { + rejectPromise(error); + return; + } -function resolveCommand(parsed) { - return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true); + resolve(); + }); + + stream.on('data', () => { + if (stream.getBufferedLength() > maxBuffer) { + rejectPromise(new MaxBufferError()); + } + }); + }); + + return stream.getBufferedValue(); } -module.exports = resolveCommand; +module.exports = getStream; +// TODO: Remove this for the next major release +module.exports.default = getStream; +module.exports.buffer = (stream, options) => getStream(stream, {...options, encoding: 'buffer'}); +module.exports.array = (stream, options) => getStream(stream, {...options, array: true}); +module.exports.MaxBufferError = MaxBufferError; /***/ }), -/* 241 */ +/* 257 */ /***/ (function(module, exports, __webpack_require__) { -const isWindows = process.platform === 'win32' || - process.env.OSTYPE === 'cygwin' || - process.env.OSTYPE === 'msys' - -const path = __webpack_require__(4) -const COLON = isWindows ? ';' : ':' -const isexe = __webpack_require__(242) - -const getNotFoundError = (cmd) => - Object.assign(new Error(`not found: ${cmd}`), { code: 'ENOENT' }) - -const getPathInfo = (cmd, opt) => { - const colon = opt.colon || COLON - - // If it has a slash, then we don't bother searching the pathenv. - // just check the file itself, and that's it. - const pathEnv = cmd.match(/\//) || isWindows && cmd.match(/\\/) ? [''] - : ( - [ - // windows always checks the cwd first - ...(isWindows ? [process.cwd()] : []), - ...(opt.path || process.env.PATH || - /* istanbul ignore next: very unusual */ '').split(colon), - ] - ) - const pathExtExe = isWindows - ? opt.pathExt || process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM' - : '' - const pathExt = isWindows ? pathExtExe.split(colon) : [''] +var once = __webpack_require__(162) +var eos = __webpack_require__(258) +var fs = __webpack_require__(134) // we only need fs to get the ReadStream and WriteStream prototypes - if (isWindows) { - if (cmd.indexOf('.') !== -1 && pathExt[0] !== '') - pathExt.unshift('') - } +var noop = function () {} +var ancient = /^v?\.0/.test(process.version) - return { - pathEnv, - pathExt, - pathExtExe, - } +var isFn = function (fn) { + return typeof fn === 'function' } -const which = (cmd, opt, cb) => { - if (typeof opt === 'function') { - cb = opt - opt = {} - } - if (!opt) - opt = {} - - const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt) - const found = [] - - const step = i => new Promise((resolve, reject) => { - if (i === pathEnv.length) - return opt.all && found.length ? resolve(found) - : reject(getNotFoundError(cmd)) +var isFS = function (stream) { + if (!ancient) return false // newer node version do not need to care about fs is a special way + if (!fs) return false // browser + return (stream instanceof (fs.ReadStream || noop) || stream instanceof (fs.WriteStream || noop)) && isFn(stream.close) +} - const ppRaw = pathEnv[i] - const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw +var isRequest = function (stream) { + return stream.setHeader && isFn(stream.abort) +} - const pCmd = path.join(pathPart, cmd) - const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd - : pCmd +var destroyer = function (stream, reading, writing, callback) { + callback = once(callback) - resolve(subStep(p, i, 0)) + var closed = false + stream.on('close', function () { + closed = true }) - const subStep = (p, i, ii) => new Promise((resolve, reject) => { - if (ii === pathExt.length) - return resolve(step(i + 1)) - const ext = pathExt[ii] - isexe(p + ext, { pathExt: pathExtExe }, (er, is) => { - if (!er && is) { - if (opt.all) - found.push(p + ext) - else - return resolve(p + ext) - } - return resolve(subStep(p, i, ii + 1)) - }) + eos(stream, {readable: reading, writable: writing}, function (err) { + if (err) return callback(err) + closed = true + callback() }) - return cb ? step(0).then(res => cb(null, res), cb) : step(0) -} - -const whichSync = (cmd, opt) => { - opt = opt || {} - - const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt) - const found = [] + var destroyed = false + return function (err) { + if (closed) return + if (destroyed) return + destroyed = true - for (let i = 0; i < pathEnv.length; i ++) { - const ppRaw = pathEnv[i] - const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw + if (isFS(stream)) return stream.close(noop) // use close for fs streams to avoid fd leaks + if (isRequest(stream)) return stream.abort() // request.destroy just do .end - .abort is what we want - const pCmd = path.join(pathPart, cmd) - const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd - : pCmd + if (isFn(stream.destroy)) return stream.destroy() - for (let j = 0; j < pathExt.length; j ++) { - const cur = p + pathExt[j] - try { - const is = isexe.sync(cur, { pathExt: pathExtExe }) - if (is) { - if (opt.all) - found.push(cur) - else - return cur - } - } catch (ex) {} - } + callback(err || new Error('stream was destroyed')) } - - if (opt.all && found.length) - return found - - if (opt.nothrow) - return null - - throw getNotFoundError(cmd) } -module.exports = which -which.sync = whichSync - - -/***/ }), -/* 242 */ -/***/ (function(module, exports, __webpack_require__) { - -var fs = __webpack_require__(133) -var core -if (process.platform === 'win32' || global.TESTING_WINDOWS) { - core = __webpack_require__(243) -} else { - core = __webpack_require__(244) +var call = function (fn) { + fn() } -module.exports = isexe -isexe.sync = sync +var pipe = function (from, to) { + return from.pipe(to) +} -function isexe (path, options, cb) { - if (typeof options === 'function') { - cb = options - options = {} - } +var pump = function () { + var streams = Array.prototype.slice.call(arguments) + var callback = isFn(streams[streams.length - 1] || noop) && streams.pop() || noop - if (!cb) { - if (typeof Promise !== 'function') { - throw new TypeError('callback not provided') - } + if (Array.isArray(streams[0])) streams = streams[0] + if (streams.length < 2) throw new Error('pump requires two streams per minimum') - return new Promise(function (resolve, reject) { - isexe(path, options || {}, function (er, is) { - if (er) { - reject(er) - } else { - resolve(is) - } - }) + var error + var destroys = streams.map(function (stream, i) { + var reading = i < streams.length - 1 + var writing = i > 0 + return destroyer(stream, reading, writing, function (err) { + if (!error) error = err + if (err) destroys.forEach(call) + if (reading) return + destroys.forEach(call) + callback(error) }) - } - - core(path, options || {}, function (er, is) { - // ignore EACCES because that just means we aren't allowed to run it - if (er) { - if (er.code === 'EACCES' || options && options.ignoreErrors) { - er = null - is = false - } - } - cb(er, is) }) -} -function sync (path, options) { - // my kingdom for a filtered catch - try { - return core.sync(path, options || {}) - } catch (er) { - if (options && options.ignoreErrors || er.code === 'EACCES') { - return false - } else { - throw er - } - } + return streams.reduce(pipe) } +module.exports = pump + /***/ }), -/* 243 */ +/* 258 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = isexe -isexe.sync = sync - -var fs = __webpack_require__(133) +var once = __webpack_require__(162); -function checkPathExt (path, options) { - var pathext = options.pathExt !== undefined ? - options.pathExt : process.env.PATHEXT +var noop = function() {}; - if (!pathext) { - return true - } +var isRequest = function(stream) { + return stream.setHeader && typeof stream.abort === 'function'; +}; - pathext = pathext.split(';') - if (pathext.indexOf('') !== -1) { - return true - } - for (var i = 0; i < pathext.length; i++) { - var p = pathext[i].toLowerCase() - if (p && path.substr(-p.length).toLowerCase() === p) { - return true - } - } - return false -} +var isChildProcess = function(stream) { + return stream.stdio && Array.isArray(stream.stdio) && stream.stdio.length === 3 +}; -function checkStat (stat, path, options) { - if (!stat.isSymbolicLink() && !stat.isFile()) { - return false - } - return checkPathExt(path, options) -} +var eos = function(stream, opts, callback) { + if (typeof opts === 'function') return eos(stream, null, opts); + if (!opts) opts = {}; -function isexe (path, options, cb) { - fs.stat(path, function (er, stat) { - cb(er, er ? false : checkStat(stat, path, options)) - }) -} + callback = once(callback || noop); -function sync (path, options) { - return checkStat(fs.statSync(path), path, options) -} + var ws = stream._writableState; + var rs = stream._readableState; + var readable = opts.readable || (opts.readable !== false && stream.readable); + var writable = opts.writable || (opts.writable !== false && stream.writable); + var cancelled = false; + var onlegacyfinish = function() { + if (!stream.writable) onfinish(); + }; -/***/ }), -/* 244 */ -/***/ (function(module, exports, __webpack_require__) { + var onfinish = function() { + writable = false; + if (!readable) callback.call(stream); + }; -module.exports = isexe -isexe.sync = sync + var onend = function() { + readable = false; + if (!writable) callback.call(stream); + }; -var fs = __webpack_require__(133) + var onexit = function(exitCode) { + callback.call(stream, exitCode ? new Error('exited with error code: ' + exitCode) : null); + }; -function isexe (path, options, cb) { - fs.stat(path, function (er, stat) { - cb(er, er ? false : checkStat(stat, options)) - }) -} + var onerror = function(err) { + callback.call(stream, err); + }; -function sync (path, options) { - return checkStat(fs.statSync(path), options) -} + var onclose = function() { + process.nextTick(onclosenexttick); + }; -function checkStat (stat, options) { - return stat.isFile() && checkMode(stat, options) -} + var onclosenexttick = function() { + if (cancelled) return; + if (readable && !(rs && (rs.ended && !rs.destroyed))) return callback.call(stream, new Error('premature close')); + if (writable && !(ws && (ws.ended && !ws.destroyed))) return callback.call(stream, new Error('premature close')); + }; -function checkMode (stat, options) { - var mod = stat.mode - var uid = stat.uid - var gid = stat.gid + var onrequest = function() { + stream.req.on('finish', onfinish); + }; - var myUid = options.uid !== undefined ? - options.uid : process.getuid && process.getuid() - var myGid = options.gid !== undefined ? - options.gid : process.getgid && process.getgid() + if (isRequest(stream)) { + stream.on('complete', onfinish); + stream.on('abort', onclose); + if (stream.req) onrequest(); + else stream.on('request', onrequest); + } else if (writable && !ws) { // legacy streams + stream.on('end', onlegacyfinish); + stream.on('close', onlegacyfinish); + } - var u = parseInt('100', 8) - var g = parseInt('010', 8) - var o = parseInt('001', 8) - var ug = u | g + if (isChildProcess(stream)) stream.on('exit', onexit); - var ret = (mod & o) || - (mod & g) && gid === myGid || - (mod & u) && uid === myUid || - (mod & ug) && myUid === 0 + stream.on('end', onend); + stream.on('finish', onfinish); + if (opts.error !== false) stream.on('error', onerror); + stream.on('close', onclose); - return ret -} + return function() { + cancelled = true; + stream.removeListener('complete', onfinish); + stream.removeListener('abort', onclose); + stream.removeListener('request', onrequest); + if (stream.req) stream.req.removeListener('finish', onfinish); + stream.removeListener('end', onlegacyfinish); + stream.removeListener('close', onlegacyfinish); + stream.removeListener('finish', onfinish); + stream.removeListener('exit', onexit); + stream.removeListener('end', onend); + stream.removeListener('error', onerror); + stream.removeListener('close', onclose); + }; +}; + +module.exports = eos; /***/ }), -/* 245 */ +/* 259 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +const {PassThrough: PassThroughStream} = __webpack_require__(138); -const pathKey = (options = {}) => { - const environment = options.env || process.env; - const platform = options.platform || process.platform; - - if (platform !== 'win32') { - return 'PATH'; - } - - return Object.keys(environment).find(key => key.toUpperCase() === 'PATH') || 'Path'; -}; +module.exports = options => { + options = {...options}; -module.exports = pathKey; -// TODO: Remove this for the next major release -module.exports.default = pathKey; + const {array} = options; + let {encoding} = options; + const isBuffer = encoding === 'buffer'; + let objectMode = false; + if (array) { + objectMode = !(encoding || isBuffer); + } else { + encoding = encoding || 'utf8'; + } -/***/ }), -/* 246 */ -/***/ (function(module, exports, __webpack_require__) { + if (isBuffer) { + encoding = null; + } -"use strict"; + const stream = new PassThroughStream({objectMode}); + if (encoding) { + stream.setEncoding(encoding); + } -// See http://www.robvanderwoude.com/escapechars.php -const metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g; + let length = 0; + const chunks = []; -function escapeCommand(arg) { - // Escape meta chars - arg = arg.replace(metaCharsRegExp, '^$1'); + stream.on('data', chunk => { + chunks.push(chunk); - return arg; -} + if (objectMode) { + length = chunks.length; + } else { + length += chunk.length; + } + }); -function escapeArgument(arg, doubleEscapeMetaChars) { - // Convert to string - arg = `${arg}`; + stream.getBufferedValue = () => { + if (array) { + return chunks; + } - // Algorithm below is based on https://qntm.org/cmd + return isBuffer ? Buffer.concat(chunks, length) : chunks.join(''); + }; - // Sequence of backslashes followed by a double quote: - // double up all the backslashes and escape the double quote - arg = arg.replace(/(\\*)"/g, '$1$1\\"'); + stream.getBufferedLength = () => length; - // Sequence of backslashes followed by the end of the string - // (which will become a double quote later): - // double up all the backslashes - arg = arg.replace(/(\\*)$/, '$1$1'); + return stream; +}; - // All other backslashes occur literally - // Quote the whole thing: - arg = `"${arg}"`; +/***/ }), +/* 260 */ +/***/ (function(module, exports, __webpack_require__) { - // Escape meta chars - arg = arg.replace(metaCharsRegExp, '^$1'); +"use strict"; - // Double escape meta chars if necessary - if (doubleEscapeMetaChars) { - arg = arg.replace(metaCharsRegExp, '^$1'); - } - return arg; -} +const { PassThrough } = __webpack_require__(138); -module.exports.command = escapeCommand; -module.exports.argument = escapeArgument; +module.exports = function (/*streams...*/) { + var sources = [] + var output = new PassThrough({objectMode: true}) + output.setMaxListeners(0) -/***/ }), -/* 247 */ -/***/ (function(module, exports, __webpack_require__) { + output.add = add + output.isEmpty = isEmpty -"use strict"; + output.on('unpipe', remove) + Array.prototype.slice.call(arguments).forEach(add) -const fs = __webpack_require__(133); -const shebangCommand = __webpack_require__(248); + return output -function readShebang(command) { - // Read the first 150 bytes from the file - const size = 150; - const buffer = Buffer.alloc(size); + function add (source) { + if (Array.isArray(source)) { + source.forEach(add) + return this + } - let fd; + sources.push(source); + source.once('end', remove.bind(null, source)) + source.once('error', output.emit.bind(output, 'error')) + source.pipe(output, {end: false}) + return this + } - try { - fd = fs.openSync(command, 'r'); - fs.readSync(fd, buffer, 0, size, 0); - fs.closeSync(fd); - } catch (e) { /* Empty */ } + function isEmpty () { + return sources.length == 0; + } - // Attempt to extract shebang (null is returned if not a shebang) - return shebangCommand(buffer.toString()); + function remove (source) { + sources = sources.filter(function (it) { return it !== source }) + if (!sources.length && output.readable) { output.end() } + } } -module.exports = readShebang; - /***/ }), -/* 248 */ +/* 261 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const shebangRegex = __webpack_require__(249); - -module.exports = (string = '') => { - const match = string.match(shebangRegex); - if (!match) { - return null; - } +const nativePromisePrototype = (async () => {})().constructor.prototype; +const descriptors = ['then', 'catch', 'finally'].map(property => [ + property, + Reflect.getOwnPropertyDescriptor(nativePromisePrototype, property) +]); - const [path, argument] = match[0].replace(/#! ?/, '').split(' '); - const binary = path.split('/').pop(); +// The return value is a mixin of `childProcess` and `Promise` +const mergePromise = (spawned, promise) => { + for (const [property, descriptor] of descriptors) { + // Starting the main `promise` is deferred to avoid consuming streams + const value = typeof promise === 'function' ? + (...args) => Reflect.apply(descriptor.value, promise(), args) : + descriptor.value.bind(promise); - if (binary === 'env') { - return argument; + Reflect.defineProperty(spawned, property, {...descriptor, value}); } - return argument ? `${binary} ${argument}` : binary; + return spawned; }; +// Use promises instead of `child_process` events +const getSpawnedPromise = spawned => { + return new Promise((resolve, reject) => { + spawned.on('exit', (exitCode, signal) => { + resolve({exitCode, signal}); + }); -/***/ }), -/* 249 */ -/***/ (function(module, exports, __webpack_require__) { + spawned.on('error', error => { + reject(error); + }); -"use strict"; + if (spawned.stdin) { + spawned.stdin.on('error', error => { + reject(error); + }); + } + }); +}; + +module.exports = { + mergePromise, + getSpawnedPromise +}; -module.exports = /^#!(.*)/; /***/ }), -/* 250 */ +/* 262 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +const SPACES_REGEXP = / +/g; -const isWin = process.platform === 'win32'; - -function notFoundError(original, syscall) { - return Object.assign(new Error(`${syscall} ${original.command} ENOENT`), { - code: 'ENOENT', - errno: 'ENOENT', - syscall: `${syscall} ${original.command}`, - path: original.command, - spawnargs: original.args, - }); -} - -function hookChildProcess(cp, parsed) { - if (!isWin) { - return; - } - - const originalEmit = cp.emit; - - cp.emit = function (name, arg1) { - // If emitting "exit" event and exit code is 1, we need to check if - // the command exists and emit an "error" instead - // See https://github.com/IndigoUnited/node-cross-spawn/issues/16 - if (name === 'exit') { - const err = verifyENOENT(arg1, parsed, 'spawn'); +const joinCommand = (file, args = []) => { + if (!Array.isArray(args)) { + return file; + } - if (err) { - return originalEmit.call(cp, 'error', err); - } - } + return [file, ...args].join(' '); +}; - return originalEmit.apply(cp, arguments); // eslint-disable-line prefer-rest-params - }; -} +// Allow spaces to be escaped by a backslash if not meant as a delimiter +const handleEscaping = (tokens, token, index) => { + if (index === 0) { + return [token]; + } -function verifyENOENT(status, parsed) { - if (isWin && status === 1 && !parsed.file) { - return notFoundError(parsed.original, 'spawn'); - } + const previousToken = tokens[tokens.length - 1]; - return null; -} + if (previousToken.endsWith('\\')) { + return [...tokens.slice(0, -1), `${previousToken.slice(0, -1)} ${token}`]; + } -function verifyENOENTSync(status, parsed) { - if (isWin && status === 1 && !parsed.file) { - return notFoundError(parsed.original, 'spawnSync'); - } + return [...tokens, token]; +}; - return null; -} +// Handle `execa.command()` +const parseCommand = command => { + return command + .trim() + .split(SPACES_REGEXP) + .reduce(handleEscaping, []); +}; module.exports = { - hookChildProcess, - verifyENOENT, - verifyENOENTSync, - notFoundError, + joinCommand, + parseCommand }; /***/ }), -/* 251 */ +/* 263 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - - -module.exports = input => { - const LF = typeof input === 'string' ? '\n' : '\n'.charCodeAt(); - const CR = typeof input === 'string' ? '\r' : '\r'.charCodeAt(); - - if (input[input.length - 1] === LF) { - input = input.slice(0, input.length - 1); - } - - if (input[input.length - 1] === CR) { - input = input.slice(0, input.length - 1); - } +// Copyright IBM Corp. 2014,2018. All Rights Reserved. +// Node module: strong-log-transformer +// This file is licensed under the Apache License 2.0. +// License text available at https://opensource.org/licenses/Apache-2.0 - return input; -}; +module.exports = __webpack_require__(264); +module.exports.cli = __webpack_require__(268); /***/ }), -/* 252 */ +/* 264 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +// Copyright IBM Corp. 2014,2018. All Rights Reserved. +// Node module: strong-log-transformer +// This file is licensed under the Apache License 2.0. +// License text available at https://opensource.org/licenses/Apache-2.0 -const path = __webpack_require__(4); -const pathKey = __webpack_require__(245); -const npmRunPath = options => { - options = { - cwd: process.cwd(), - path: process.env[pathKey()], - execPath: process.execPath, - ...options - }; - let previous; - let cwdPath = path.resolve(options.cwd); - const result = []; +var stream = __webpack_require__(138); +var util = __webpack_require__(112); +var fs = __webpack_require__(134); - while (previous !== cwdPath) { - result.push(path.join(cwdPath, 'node_modules/.bin')); - previous = cwdPath; - cwdPath = path.resolve(cwdPath, '..'); - } +var through = __webpack_require__(265); +var duplexer = __webpack_require__(266); +var StringDecoder = __webpack_require__(267).StringDecoder; - // Ensure the running `node` binary is used - const execPathDir = path.resolve(options.cwd, options.execPath, '..'); - result.push(execPathDir); +module.exports = Logger; - return result.concat(options.path).join(path.delimiter); +Logger.DEFAULTS = { + format: 'text', + tag: '', + mergeMultiline: false, + timeStamp: false, }; -module.exports = npmRunPath; -// TODO: Remove this for the next major release -module.exports.default = npmRunPath; +var formatters = { + text: textFormatter, + json: jsonFormatter, +} -module.exports.env = options => { - options = { - env: process.env, - ...options - }; +function Logger(options) { + var defaults = JSON.parse(JSON.stringify(Logger.DEFAULTS)); + options = util._extend(defaults, options || {}); + var catcher = deLiner(); + var emitter = catcher; + var transforms = [ + objectifier(), + ]; - const env = {...options.env}; - const path = pathKey({env}); + if (options.tag) { + transforms.push(staticTagger(options.tag)); + } - options.path = env[path]; - env[path] = module.exports(options); + if (options.mergeMultiline) { + transforms.push(lineMerger()); + } - return env; -}; + // TODO + // if (options.pidStamp) { + // transforms.push(pidStamper(options.pid)); + // } + // TODO + // if (options.workerStamp) { + // transforms.push(workerStamper(options.worker)); + // } -/***/ }), -/* 253 */ -/***/ (function(module, exports, __webpack_require__) { + transforms.push(formatters[options.format](options)); -"use strict"; + // restore line endings that were removed by line splitting + transforms.push(reLiner()); -const mimicFn = __webpack_require__(254); + for (var t in transforms) { + emitter = emitter.pipe(transforms[t]); + } -const calledFunctions = new WeakMap(); + return duplexer(catcher, emitter); +} -const oneTime = (fn, options = {}) => { - if (typeof fn !== 'function') { - throw new TypeError('Expected a function'); - } +function deLiner() { + var decoder = new StringDecoder('utf8'); + var last = ''; - let ret; - let isCalled = false; - let callCount = 0; - const functionName = fn.displayName || fn.name || ''; + return new stream.Transform({ + transform(chunk, _enc, callback) { + last += decoder.write(chunk); + var list = last.split(/\r\n|[\n\v\f\r\x85\u2028\u2029]/g); + last = list.pop(); + for (var i = 0; i < list.length; i++) { + // swallow empty lines + if (list[i]) { + this.push(list[i]); + } + } + callback(); + }, + flush(callback) { + // incomplete UTF8 sequences become UTF8 replacement characters + last += decoder.end(); + if (last) { + this.push(last); + } + callback(); + }, + }); +} - const onetime = function (...args) { - calledFunctions.set(onetime, ++callCount); +function reLiner() { + return through(appendNewline); - if (isCalled) { - if (options.throw === true) { - throw new Error(`Function \`${functionName}\` can only be called once`); - } + function appendNewline(line) { + this.emit('data', line + '\n'); + } +} - return ret; - } +function objectifier() { + return through(objectify, null, {autoDestroy: false}); - isCalled = true; - ret = fn.apply(this, args); - fn = null; + function objectify(line) { + this.emit('data', { + msg: line, + time: Date.now(), + }); + } +} - return ret; - }; +function staticTagger(tag) { + return through(tagger); - mimicFn(onetime, fn); - calledFunctions.set(onetime, callCount); + function tagger(logEvent) { + logEvent.tag = tag; + this.emit('data', logEvent); + } +} - return onetime; -}; - -module.exports = oneTime; -// TODO: Remove this for the next major release -module.exports.default = oneTime; +function textFormatter(options) { + return through(textify); -module.exports.callCount = fn => { - if (!calledFunctions.has(fn)) { - throw new Error(`The given function \`${fn.name}\` is not wrapped by the \`onetime\` package`); - } + function textify(logEvent) { + var line = util.format('%s%s', textifyTags(logEvent.tag), + logEvent.msg.toString()); + if (options.timeStamp) { + line = util.format('%s %s', new Date(logEvent.time).toISOString(), line); + } + this.emit('data', line.replace(/\n/g, '\\n')); + } - return calledFunctions.get(fn); -}; + function textifyTags(tags) { + var str = ''; + if (typeof tags === 'string') { + str = tags + ' '; + } else if (typeof tags === 'object') { + for (var t in tags) { + str += t + ':' + tags[t] + ' '; + } + } + return str; + } +} +function jsonFormatter(options) { + return through(jsonify); -/***/ }), -/* 254 */ -/***/ (function(module, exports, __webpack_require__) { + function jsonify(logEvent) { + if (options.timeStamp) { + logEvent.time = new Date(logEvent.time).toISOString(); + } else { + delete logEvent.time; + } + logEvent.msg = logEvent.msg.toString(); + this.emit('data', JSON.stringify(logEvent)); + } +} -"use strict"; +function lineMerger(host) { + var previousLine = null; + var flushTimer = null; + var stream = through(lineMergerWrite, lineMergerEnd); + var flush = _flush.bind(stream); + return stream; -const mimicFn = (to, from) => { - for (const prop of Reflect.ownKeys(from)) { - Object.defineProperty(to, prop, Object.getOwnPropertyDescriptor(from, prop)); - } + function lineMergerWrite(line) { + if (/^\s+/.test(line.msg)) { + if (previousLine) { + previousLine.msg += '\n' + line.msg; + } else { + previousLine = line; + } + } else { + flush(); + previousLine = line; + } + // rolling timeout + clearTimeout(flushTimer); + flushTimer = setTimeout(flush.bind(this), 10); + } - return to; -}; + function _flush() { + if (previousLine) { + this.emit('data', previousLine); + previousLine = null; + } + } -module.exports = mimicFn; -// TODO: Remove this for the next major release -module.exports.default = mimicFn; + function lineMergerEnd() { + flush.call(this); + this.emit('end'); + } +} /***/ }), -/* 255 */ +/* 265 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +var Stream = __webpack_require__(138) -const {signalsByName} = __webpack_require__(256); +// through +// +// a stream that does nothing but re-emit the input. +// useful for aggregating a series of changing but not ending streams into one stream) -const getErrorPrefix = ({timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled}) => { - if (timedOut) { - return `timed out after ${timeout} milliseconds`; - } +exports = module.exports = through +through.through = through - if (isCanceled) { - return 'was canceled'; - } +//create a readable writable stream. - if (errorCode !== undefined) { - return `failed with ${errorCode}`; - } +function through (write, end, opts) { + write = write || function (data) { this.queue(data) } + end = end || function () { this.queue(null) } - if (signal !== undefined) { - return `was killed with ${signal} (${signalDescription})`; - } + var ended = false, destroyed = false, buffer = [], _ended = false + var stream = new Stream() + stream.readable = stream.writable = true + stream.paused = false - if (exitCode !== undefined) { - return `failed with exit code ${exitCode}`; - } +// stream.autoPause = !(opts && opts.autoPause === false) + stream.autoDestroy = !(opts && opts.autoDestroy === false) - return 'failed'; -}; + stream.write = function (data) { + write.call(this, data) + return !stream.paused + } -const makeError = ({ - stdout, - stderr, - all, - error, - signal, - exitCode, - command, - timedOut, - isCanceled, - killed, - parsed: {options: {timeout}} -}) => { - // `signal` and `exitCode` emitted on `spawned.on('exit')` event can be `null`. - // We normalize them to `undefined` - exitCode = exitCode === null ? undefined : exitCode; - signal = signal === null ? undefined : signal; - const signalDescription = signal === undefined ? undefined : signalsByName[signal].description; + function drain() { + while(buffer.length && !stream.paused) { + var data = buffer.shift() + if(null === data) + return stream.emit('end') + else + stream.emit('data', data) + } + } - const errorCode = error && error.code; + stream.queue = stream.push = function (data) { +// console.error(ended) + if(_ended) return stream + if(data === null) _ended = true + buffer.push(data) + drain() + return stream + } - const prefix = getErrorPrefix({timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled}); - const execaMessage = `Command ${prefix}: ${command}`; - const isError = Object.prototype.toString.call(error) === '[object Error]'; - const shortMessage = isError ? `${execaMessage}\n${error.message}` : execaMessage; - const message = [shortMessage, stderr, stdout].filter(Boolean).join('\n'); + //this will be registered as the first 'end' listener + //must call destroy next tick, to make sure we're after any + //stream piped from here. + //this is only a problem if end is not emitted synchronously. + //a nicer way to do this is to make sure this is the last listener for 'end' - if (isError) { - error.originalMessage = error.message; - error.message = message; - } else { - error = new Error(message); - } + stream.on('end', function () { + stream.readable = false + if(!stream.writable && stream.autoDestroy) + process.nextTick(function () { + stream.destroy() + }) + }) - error.shortMessage = shortMessage; - error.command = command; - error.exitCode = exitCode; - error.signal = signal; - error.signalDescription = signalDescription; - error.stdout = stdout; - error.stderr = stderr; + function _end () { + stream.writable = false + end.call(stream) + if(!stream.readable && stream.autoDestroy) + stream.destroy() + } - if (all !== undefined) { - error.all = all; - } + stream.end = function (data) { + if(ended) return + ended = true + if(arguments.length) stream.write(data) + _end() // will emit or queue + return stream + } - if ('bufferedData' in error) { - delete error.bufferedData; - } + stream.destroy = function () { + if(destroyed) return + destroyed = true + ended = true + buffer.length = 0 + stream.writable = stream.readable = false + stream.emit('close') + return stream + } - error.failed = true; - error.timedOut = Boolean(timedOut); - error.isCanceled = isCanceled; - error.killed = killed && !timedOut; + stream.pause = function () { + if(stream.paused) return + stream.paused = true + return stream + } - return error; -}; + stream.resume = function () { + if(stream.paused) { + stream.paused = false + stream.emit('resume') + } + drain() + //may have become paused again, + //as drain emits 'data'. + if(!stream.paused) + stream.emit('drain') + return stream + } + return stream +} -module.exports = makeError; /***/ }), -/* 256 */ +/* 266 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; -Object.defineProperty(exports,"__esModule",{value:true});exports.signalsByNumber=exports.signalsByName=void 0;var _os=__webpack_require__(120); - -var _signals=__webpack_require__(257); -var _realtime=__webpack_require__(259); +var Stream = __webpack_require__(138) +var writeMethods = ["write", "end", "destroy"] +var readMethods = ["resume", "pause"] +var readEvents = ["data", "close"] +var slice = Array.prototype.slice +module.exports = duplex +function forEach (arr, fn) { + if (arr.forEach) { + return arr.forEach(fn) + } -const getSignalsByName=function(){ -const signals=(0,_signals.getSignals)(); -return signals.reduce(getSignalByName,{}); -}; + for (var i = 0; i < arr.length; i++) { + fn(arr[i], i) + } +} -const getSignalByName=function( -signalByNameMemo, -{name,number,description,supported,action,forced,standard}) -{ -return{ -...signalByNameMemo, -[name]:{name,number,description,supported,action,forced,standard}}; +function duplex(writer, reader) { + var stream = new Stream() + var ended = false -}; + forEach(writeMethods, proxyWriter) -const signalsByName=getSignalsByName();exports.signalsByName=signalsByName; + forEach(readMethods, proxyReader) + forEach(readEvents, proxyStream) + reader.on("end", handleEnd) + writer.on("drain", function() { + stream.emit("drain") + }) -const getSignalsByNumber=function(){ -const signals=(0,_signals.getSignals)(); -const length=_realtime.SIGRTMAX+1; -const signalsA=Array.from({length},(value,number)=> -getSignalByNumber(number,signals)); + writer.on("error", reemit) + reader.on("error", reemit) -return Object.assign({},...signalsA); -}; + stream.writable = writer.writable + stream.readable = reader.readable -const getSignalByNumber=function(number,signals){ -const signal=findSignalByNumber(number,signals); + return stream -if(signal===undefined){ -return{}; -} + function proxyWriter(methodName) { + stream[methodName] = method -const{name,description,supported,action,forced,standard}=signal; -return{ -[number]:{ -name, -number, -description, -supported, -action, -forced, -standard}}; + function method() { + return writer[methodName].apply(writer, arguments) + } + } + function proxyReader(methodName) { + stream[methodName] = method -}; + function method() { + stream.emit(methodName) + var func = reader[methodName] + if (func) { + return func.apply(reader, arguments) + } + reader.emit(methodName) + } + } + function proxyStream(methodName) { + reader.on(methodName, reemit) + function reemit() { + var args = slice.call(arguments) + args.unshift(methodName) + stream.emit.apply(stream, args) + } + } -const findSignalByNumber=function(number,signals){ -const signal=signals.find(({name})=>_os.constants.signals[name]===number); + function handleEnd() { + if (ended) { + return + } + ended = true + var args = slice.call(arguments) + args.unshift("end") + stream.emit.apply(stream, args) + } -if(signal!==undefined){ -return signal; + function reemit(err) { + stream.emit("error", err) + } } -return signals.find(signalA=>signalA.number===number); -}; -const signalsByNumber=getSignalsByNumber();exports.signalsByNumber=signalsByNumber; -//# sourceMappingURL=main.js.map +/***/ }), +/* 267 */ +/***/ (function(module, exports) { + +module.exports = require("string_decoder"); /***/ }), -/* 257 */ +/* 268 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -Object.defineProperty(exports,"__esModule",{value:true});exports.getSignals=void 0;var _os=__webpack_require__(120); +// Copyright IBM Corp. 2014,2018. All Rights Reserved. +// Node module: strong-log-transformer +// This file is licensed under the Apache License 2.0. +// License text available at https://opensource.org/licenses/Apache-2.0 -var _core=__webpack_require__(258); -var _realtime=__webpack_require__(259); +var minimist = __webpack_require__(269); +var path = __webpack_require__(4); -const getSignals=function(){ -const realtimeSignals=(0,_realtime.getRealtimeSignals)(); -const signals=[..._core.SIGNALS,...realtimeSignals].map(normalizeSignal); -return signals; -};exports.getSignals=getSignals; +var Logger = __webpack_require__(264); +var pkg = __webpack_require__(270); +module.exports = cli; +function cli(args) { + var opts = minimist(args.slice(2)); + var $0 = path.basename(args[1]); + var p = console.log.bind(console); + if (opts.v || opts.version) { + version($0, p); + } else if (opts.h || opts.help) { + usage($0, p); + } else if (args.length < 3) { + process.stdin.pipe(Logger()).pipe(process.stdout); + } else { + process.stdin.pipe(Logger(opts)).pipe(process.stdout); + } +} +function version($0, p) { + p('%s v%s', pkg.name, pkg.version); +} +function usage($0, p) { + var PADDING = ' '; + var opt, def; + p('Usage: %s [options]', $0); + p(''); + p('%s', pkg.description); + p(''); + p('OPTIONS:'); + for (opt in Logger.DEFAULTS) { + def = Logger.DEFAULTS[opt]; + if (typeof def === 'boolean') + boolOpt(opt, Logger.DEFAULTS[opt]); + else + stdOpt(opt, Logger.DEFAULTS[opt]); + } + p(''); + function boolOpt(name, def) { + name = name + PADDING.slice(0, 20-name.length); + p(' --%s default: %s', name, def); + } + function stdOpt(name, def) { + var value = name.toUpperCase() + + PADDING.slice(0, 19 - name.length*2); + p(' --%s %s default: %j', name, value, def); + } +} -const normalizeSignal=function({ -name, -number:defaultNumber, -description, -action, -forced=false, -standard}) -{ -const{ -signals:{[name]:constantSignal}}= -_os.constants; -const supported=constantSignal!==undefined; -const number=supported?constantSignal:defaultNumber; -return{name,number,description,supported,action,forced,standard}; -}; -//# sourceMappingURL=signals.js.map /***/ }), -/* 258 */ -/***/ (function(module, exports, __webpack_require__) { +/* 269 */ +/***/ (function(module, exports) { -"use strict"; -Object.defineProperty(exports,"__esModule",{value:true});exports.SIGNALS=void 0; +module.exports = function (args, opts) { + if (!opts) opts = {}; + + var flags = { bools : {}, strings : {}, unknownFn: null }; -const SIGNALS=[ -{ -name:"SIGHUP", -number:1, -action:"terminate", -description:"Terminal closed", -standard:"posix"}, + if (typeof opts['unknown'] === 'function') { + flags.unknownFn = opts['unknown']; + } -{ -name:"SIGINT", -number:2, -action:"terminate", -description:"User interruption with CTRL-C", -standard:"ansi"}, + if (typeof opts['boolean'] === 'boolean' && opts['boolean']) { + flags.allBools = true; + } else { + [].concat(opts['boolean']).filter(Boolean).forEach(function (key) { + flags.bools[key] = true; + }); + } + + var aliases = {}; + Object.keys(opts.alias || {}).forEach(function (key) { + aliases[key] = [].concat(opts.alias[key]); + aliases[key].forEach(function (x) { + aliases[x] = [key].concat(aliases[key].filter(function (y) { + return x !== y; + })); + }); + }); -{ -name:"SIGQUIT", -number:3, -action:"core", -description:"User interruption with CTRL-\\", -standard:"posix"}, + [].concat(opts.string).filter(Boolean).forEach(function (key) { + flags.strings[key] = true; + if (aliases[key]) { + flags.strings[aliases[key]] = true; + } + }); -{ -name:"SIGILL", -number:4, -action:"core", -description:"Invalid machine instruction", -standard:"ansi"}, + var defaults = opts['default'] || {}; + + var argv = { _ : [] }; + Object.keys(flags.bools).forEach(function (key) { + setArg(key, defaults[key] === undefined ? false : defaults[key]); + }); + + var notFlags = []; -{ -name:"SIGTRAP", -number:5, -action:"core", -description:"Debugger breakpoint", -standard:"posix"}, - -{ -name:"SIGABRT", -number:6, -action:"core", -description:"Aborted", -standard:"ansi"}, - -{ -name:"SIGIOT", -number:6, -action:"core", -description:"Aborted", -standard:"bsd"}, - -{ -name:"SIGBUS", -number:7, -action:"core", -description: -"Bus error due to misaligned, non-existing address or paging error", -standard:"bsd"}, + if (args.indexOf('--') !== -1) { + notFlags = args.slice(args.indexOf('--')+1); + args = args.slice(0, args.indexOf('--')); + } -{ -name:"SIGEMT", -number:7, -action:"terminate", -description:"Command should be emulated but is not implemented", -standard:"other"}, + function argDefined(key, arg) { + return (flags.allBools && /^--[^=]+$/.test(arg)) || + flags.strings[key] || flags.bools[key] || aliases[key]; + } -{ -name:"SIGFPE", -number:8, -action:"core", -description:"Floating point arithmetic error", -standard:"ansi"}, + function setArg (key, val, arg) { + if (arg && flags.unknownFn && !argDefined(key, arg)) { + if (flags.unknownFn(arg) === false) return; + } -{ -name:"SIGKILL", -number:9, -action:"terminate", -description:"Forced termination", -standard:"posix", -forced:true}, + var value = !flags.strings[key] && isNumber(val) + ? Number(val) : val + ; + setKey(argv, key.split('.'), value); + + (aliases[key] || []).forEach(function (x) { + setKey(argv, x.split('.'), value); + }); + } -{ -name:"SIGUSR1", -number:10, -action:"terminate", -description:"Application-specific signal", -standard:"posix"}, + function setKey (obj, keys, value) { + var o = obj; + for (var i = 0; i < keys.length-1; i++) { + var key = keys[i]; + if (key === '__proto__') return; + if (o[key] === undefined) o[key] = {}; + if (o[key] === Object.prototype || o[key] === Number.prototype + || o[key] === String.prototype) o[key] = {}; + if (o[key] === Array.prototype) o[key] = []; + o = o[key]; + } -{ -name:"SIGSEGV", -number:11, -action:"core", -description:"Segmentation fault", -standard:"ansi"}, + var key = keys[keys.length - 1]; + if (key === '__proto__') return; + if (o === Object.prototype || o === Number.prototype + || o === String.prototype) o = {}; + if (o === Array.prototype) o = []; + if (o[key] === undefined || flags.bools[key] || typeof o[key] === 'boolean') { + o[key] = value; + } + else if (Array.isArray(o[key])) { + o[key].push(value); + } + else { + o[key] = [ o[key], value ]; + } + } + + function aliasIsBoolean(key) { + return aliases[key].some(function (x) { + return flags.bools[x]; + }); + } -{ -name:"SIGUSR2", -number:12, -action:"terminate", -description:"Application-specific signal", -standard:"posix"}, + for (var i = 0; i < args.length; i++) { + var arg = args[i]; + + if (/^--.+=/.test(arg)) { + // Using [\s\S] instead of . because js doesn't support the + // 'dotall' regex modifier. See: + // http://stackoverflow.com/a/1068308/13216 + var m = arg.match(/^--([^=]+)=([\s\S]*)$/); + var key = m[1]; + var value = m[2]; + if (flags.bools[key]) { + value = value !== 'false'; + } + setArg(key, value, arg); + } + else if (/^--no-.+/.test(arg)) { + var key = arg.match(/^--no-(.+)/)[1]; + setArg(key, false, arg); + } + else if (/^--.+/.test(arg)) { + var key = arg.match(/^--(.+)/)[1]; + var next = args[i + 1]; + if (next !== undefined && !/^-/.test(next) + && !flags.bools[key] + && !flags.allBools + && (aliases[key] ? !aliasIsBoolean(key) : true)) { + setArg(key, next, arg); + i++; + } + else if (/^(true|false)$/.test(next)) { + setArg(key, next === 'true', arg); + i++; + } + else { + setArg(key, flags.strings[key] ? '' : true, arg); + } + } + else if (/^-[^-]+/.test(arg)) { + var letters = arg.slice(1,-1).split(''); + + var broken = false; + for (var j = 0; j < letters.length; j++) { + var next = arg.slice(j+2); + + if (next === '-') { + setArg(letters[j], next, arg) + continue; + } + + if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) { + setArg(letters[j], next.split('=')[1], arg); + broken = true; + break; + } + + if (/[A-Za-z]/.test(letters[j]) + && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) { + setArg(letters[j], next, arg); + broken = true; + break; + } + + if (letters[j+1] && letters[j+1].match(/\W/)) { + setArg(letters[j], arg.slice(j+2), arg); + broken = true; + break; + } + else { + setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg); + } + } + + var key = arg.slice(-1)[0]; + if (!broken && key !== '-') { + if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1]) + && !flags.bools[key] + && (aliases[key] ? !aliasIsBoolean(key) : true)) { + setArg(key, args[i+1], arg); + i++; + } + else if (args[i+1] && /^(true|false)$/.test(args[i+1])) { + setArg(key, args[i+1] === 'true', arg); + i++; + } + else { + setArg(key, flags.strings[key] ? '' : true, arg); + } + } + } + else { + if (!flags.unknownFn || flags.unknownFn(arg) !== false) { + argv._.push( + flags.strings['_'] || !isNumber(arg) ? arg : Number(arg) + ); + } + if (opts.stopEarly) { + argv._.push.apply(argv._, args.slice(i + 1)); + break; + } + } + } + + Object.keys(defaults).forEach(function (key) { + if (!hasKey(argv, key.split('.'))) { + setKey(argv, key.split('.'), defaults[key]); + + (aliases[key] || []).forEach(function (x) { + setKey(argv, x.split('.'), defaults[key]); + }); + } + }); + + if (opts['--']) { + argv['--'] = new Array(); + notFlags.forEach(function(key) { + argv['--'].push(key); + }); + } + else { + notFlags.forEach(function(key) { + argv._.push(key); + }); + } -{ -name:"SIGPIPE", -number:13, -action:"terminate", -description:"Broken pipe or socket", -standard:"posix"}, + return argv; +}; -{ -name:"SIGALRM", -number:14, -action:"terminate", -description:"Timeout or timer", -standard:"posix"}, +function hasKey (obj, keys) { + var o = obj; + keys.slice(0,-1).forEach(function (key) { + o = (o[key] || {}); + }); -{ -name:"SIGTERM", -number:15, -action:"terminate", -description:"Termination", -standard:"ansi"}, + var key = keys[keys.length - 1]; + return key in o; +} -{ -name:"SIGSTKFLT", -number:16, -action:"terminate", -description:"Stack is empty or overflowed", -standard:"other"}, +function isNumber (x) { + if (typeof x === 'number') return true; + if (/^0x[0-9a-f]+$/i.test(x)) return true; + return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x); +} -{ -name:"SIGCHLD", -number:17, -action:"ignore", -description:"Child process terminated, paused or unpaused", -standard:"posix"}, -{ -name:"SIGCLD", -number:17, -action:"ignore", -description:"Child process terminated, paused or unpaused", -standard:"other"}, -{ -name:"SIGCONT", -number:18, -action:"unpause", -description:"Unpaused", -standard:"posix", -forced:true}, +/***/ }), +/* 270 */ +/***/ (function(module) { -{ -name:"SIGSTOP", -number:19, -action:"pause", -description:"Paused", -standard:"posix", -forced:true}, +module.exports = JSON.parse("{\"name\":\"strong-log-transformer\",\"version\":\"2.1.0\",\"description\":\"Stream transformer that prefixes lines with timestamps and other things.\",\"author\":\"Ryan Graham \",\"license\":\"Apache-2.0\",\"repository\":{\"type\":\"git\",\"url\":\"git://github.com/strongloop/strong-log-transformer\"},\"keywords\":[\"logging\",\"streams\"],\"bugs\":{\"url\":\"https://github.com/strongloop/strong-log-transformer/issues\"},\"homepage\":\"https://github.com/strongloop/strong-log-transformer\",\"directories\":{\"test\":\"test\"},\"bin\":{\"sl-log-transformer\":\"bin/sl-log-transformer.js\"},\"main\":\"index.js\",\"scripts\":{\"test\":\"tap --100 test/test-*\"},\"dependencies\":{\"duplexer\":\"^0.1.1\",\"minimist\":\"^1.2.0\",\"through\":\"^2.3.4\"},\"devDependencies\":{\"tap\":\"^12.0.1\"},\"engines\":{\"node\":\">=4\"}}"); -{ -name:"SIGTSTP", -number:20, -action:"pause", -description:"Paused using CTRL-Z or \"suspend\"", -standard:"posix"}, +/***/ }), +/* 271 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -{ -name:"SIGTTIN", -number:21, -action:"pause", -description:"Background process cannot read terminal input", -standard:"posix"}, +"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__(147); +/* 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__(4); +/* 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__(112); +/* 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__(272); +/* harmony import */ var _fs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(131); +/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(165); +/* harmony import */ var _projects__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(146); +/* + * 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. + */ -{ -name:"SIGBREAK", -number:21, -action:"terminate", -description:"User interruption with CTRL-BREAK", -standard:"other"}, -{ -name:"SIGTTOU", -number:22, -action:"pause", -description:"Background process cannot write to terminal output", -standard:"posix"}, -{ -name:"SIGURG", -number:23, -action:"ignore", -description:"Socket received out-of-band data", -standard:"bsd"}, -{ -name:"SIGXCPU", -number:24, -action:"core", -description:"Process timed out", -standard:"bsd"}, -{ -name:"SIGXFSZ", -number:25, -action:"core", -description:"File too big", -standard:"bsd"}, -{ -name:"SIGVTALRM", -number:26, -action:"terminate", -description:"Timeout or timer", -standard:"bsd"}, -{ -name:"SIGPROF", -number:27, -action:"terminate", -description:"Timeout or timer", -standard:"bsd"}, +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"])(rootPath); -{ -name:"SIGWINCH", -number:28, -action:"ignore", -description:"Terminal window size changed", -standard:"bsd"}, + if (!rootPkgJson.workspaces) { + return []; + } -{ -name:"SIGIO", -number:29, -action:"terminate", -description:"I/O is available", -standard:"other"}, + const workspacesPathsPatterns = rootPkgJson.workspaces.packages; + let workspaceProjectsPaths = []; -{ -name:"SIGPOLL", -number:29, -action:"terminate", -description:"Watched event", -standard:"other"}, + for (const pattern of workspacesPathsPatterns) { + workspaceProjectsPaths = workspaceProjectsPaths.concat(await packagesFromGlobPattern({ + pattern, + rootPath + })); + } // Filter out exclude glob patterns -{ -name:"SIGINFO", -number:29, -action:"ignore", -description:"Request for process information", -standard:"other"}, -{ -name:"SIGPWR", -number:30, -action:"terminate", -description:"Device running out of power", -standard:"systemv"}, + 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); + } + } -{ -name:"SIGSYS", -number:31, -action:"core", -description:"Invalid system call", -standard:"other"}, + return workspaceProjectsPaths; +} +async function copyWorkspacePackages(rootPath) { + const projectPaths = Object(_config__WEBPACK_IMPORTED_MODULE_3__["getProjectPaths"])({ + rootPath + }); + const projects = await Object(_projects__WEBPACK_IMPORTED_MODULE_6__["getProjects"])(rootPath, projectPaths); -{ -name:"SIGUNUSED", -number:31, -action:"terminate", -description:"Invalid system call", -standard:"other"}];exports.SIGNALS=SIGNALS; -//# sourceMappingURL=core.js.map + for (const project of projects.values()) { + const dest = path__WEBPACK_IMPORTED_MODULE_1___default.a.resolve(rootPath, 'node_modules', project.name); -/***/ }), -/* 259 */ -/***/ (function(module, exports, __webpack_require__) { + if ((await Object(_fs__WEBPACK_IMPORTED_MODULE_4__["isSymlink"])(dest)) === false) { + continue; + } // Remove the symlink -"use strict"; -Object.defineProperty(exports,"__esModule",{value:true});exports.SIGRTMAX=exports.getRealtimeSignals=void 0; -const getRealtimeSignals=function(){ -const length=SIGRTMAX-SIGRTMIN+1; -return Array.from({length},getRealtimeSignal); -};exports.getRealtimeSignals=getRealtimeSignals; -const getRealtimeSignal=function(value,index){ -return{ -name:`SIGRT${index+1}`, -number:SIGRTMIN+index, -action:"terminate", -description:"Application-specific signal (realtime)", -standard:"posix"}; + await Object(_fs__WEBPACK_IMPORTED_MODULE_4__["unlink"])(dest); // Copy in the package -}; + await Object(_fs__WEBPACK_IMPORTED_MODULE_4__["copyDirectory"])(project.path, dest); + } +} -const SIGRTMIN=34; -const SIGRTMAX=64;exports.SIGRTMAX=SIGRTMAX; -//# sourceMappingURL=realtime.js.map +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); +} /***/ }), -/* 260 */ -/***/ (function(module, exports, __webpack_require__) { +/* 272 */ +/***/ (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__(4); +/* 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. + */ -const aliases = ['stdin', 'stdout', 'stderr']; - -const hasAlias = opts => aliases.some(alias => opts[alias] !== undefined); - -const normalizeStdio = opts => { - if (!opts) { - return; - } - const {stdio} = opts; +/** + * Returns all the paths where plugins are located + */ +function getProjectPaths({ + rootPath, + ossOnly, + skipKibanaPlugins +}) { + 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. - if (stdio === undefined) { - return aliases.map(alias => opts[alias]); - } + 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/*')); + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'examples/*')); - if (hasAlias(opts)) { - throw new Error(`It's not possible to provide \`stdio\` in combination with one of ${aliases.map(alias => `\`${alias}\``).join(', ')}`); - } + 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/*')); + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'x-pack/legacy/plugins/*')); + projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'x-pack/test/functional_with_es_ssl/fixtures/plugins/*')); + } - if (typeof stdio === 'string') { - return stdio; - } + 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/*')); + } - if (!Array.isArray(stdio)) { - throw new TypeError(`Expected \`stdio\` to be of type \`string\` or \`Array\`, got \`${typeof stdio}\``); - } + return projectPaths; +} - const length = Math.max(stdio.length, aliases.length); - return Array.from({length}, (value, index) => stdio[index]); -}; +/***/ }), +/* 273 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -module.exports = normalizeStdio; +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getAllChecksums", function() { return getAllChecksums; }); +/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(134); +/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(274); +/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(crypto__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(112); +/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(228); +/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(execa__WEBPACK_IMPORTED_MODULE_3__); +/* harmony import */ var _yarn_lock__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(275); +/* + * 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. + */ -// `ipc` is pushed unless it is already present -module.exports.node = opts => { - const stdio = normalizeStdio(opts); - if (stdio === 'ipc') { - return 'ipc'; - } - if (stdio === undefined || typeof stdio === 'string') { - return [stdio, stdio, stdio, 'ipc']; - } - if (stdio.includes('ipc')) { - return stdio; - } - return [...stdio, 'ipc']; -}; +const statAsync = Object(util__WEBPACK_IMPORTED_MODULE_2__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_0___default.a.stat); +const projectBySpecificitySorter = (a, b) => b.path.length - a.path.length; +/** Get the changed files for a set of projects */ -/***/ }), -/* 261 */ -/***/ (function(module, exports, __webpack_require__) { -"use strict"; +async function getChangesForProjects(projects, kbn, log) { + log.verbose('getting changed files'); + const { + stdout + } = await execa__WEBPACK_IMPORTED_MODULE_3___default()('git', ['ls-files', '-dmto', '--exclude-standard', '--', ...Array.from(projects.values()).filter(p => kbn.isPartOfRepo(p)).map(p => p.path)], { + cwd: kbn.getAbsolute() + }); + const output = stdout.trim(); + const unassignedChanges = new Map(); -const os = __webpack_require__(120); -const onExit = __webpack_require__(217); + if (output) { + for (const line of output.split('\n')) { + const [tag, ...pathParts] = line.trim().split(' '); + const path = pathParts.join(' '); -const DEFAULT_FORCE_KILL_TIMEOUT = 1000 * 5; + switch (tag) { + case 'M': + case 'C': + // for some reason ls-files returns deleted files as both deleted + // and modified, so make sure not to overwrite changes already + // tracked as "deleted" + if (unassignedChanges.get(path) !== 'deleted') { + unassignedChanges.set(path, 'modified'); + } -// Monkey-patches `childProcess.kill()` to add `forceKillAfterTimeout` behavior -const spawnedKill = (kill, signal = 'SIGTERM', options = {}) => { - const killResult = kill(signal); - setKillTimeout(kill, signal, options, killResult); - return killResult; -}; + break; -const setKillTimeout = (kill, signal, options, killResult) => { - if (!shouldForceKill(signal, options, killResult)) { - return; - } + case 'R': + unassignedChanges.set(path, 'deleted'); + break; - const timeout = getForceKillAfterTimeout(options); - const t = setTimeout(() => { - kill('SIGKILL'); - }, timeout); + case '?': + unassignedChanges.set(path, 'untracked'); + break; - // Guarded because there's no `.unref()` when `execa` is used in the renderer - // process in Electron. This cannot be tested since we don't run tests in - // Electron. - // istanbul ignore else - if (t.unref) { - t.unref(); - } -}; + case 'H': + case 'S': + case 'K': + default: + log.warning(`unexpected modification status "${tag}" for ${path}, please report this!`); + unassignedChanges.set(path, 'invalid'); + break; + } + } + } -const shouldForceKill = (signal, {forceKillAfterTimeout}, killResult) => { - return isSigterm(signal) && forceKillAfterTimeout !== false && killResult; -}; + const sortedRelevantProjects = Array.from(projects.values()).sort(projectBySpecificitySorter); + const changesByProject = new Map(); -const isSigterm = signal => { - return signal === os.constants.signals.SIGTERM || - (typeof signal === 'string' && signal.toUpperCase() === 'SIGTERM'); -}; + for (const project of sortedRelevantProjects) { + if (kbn.isOutsideRepo(project)) { + changesByProject.set(project, undefined); + continue; + } -const getForceKillAfterTimeout = ({forceKillAfterTimeout = true}) => { - if (forceKillAfterTimeout === true) { - return DEFAULT_FORCE_KILL_TIMEOUT; - } + const ownChanges = new Map(); + const prefix = kbn.getRelative(project.path); - if (!Number.isInteger(forceKillAfterTimeout) || forceKillAfterTimeout < 0) { - throw new TypeError(`Expected the \`forceKillAfterTimeout\` option to be a non-negative integer, got \`${forceKillAfterTimeout}\` (${typeof forceKillAfterTimeout})`); - } + for (const [path, type] of unassignedChanges) { + if (path.startsWith(prefix)) { + ownChanges.set(path, type); + unassignedChanges.delete(path); + } + } - return forceKillAfterTimeout; -}; + log.verbose(`[${project.name}] found ${ownChanges.size} changes`); + changesByProject.set(project, ownChanges); + } -// `childProcess.cancel()` -const spawnedCancel = (spawned, context) => { - const killResult = spawned.kill(); + if (unassignedChanges.size) { + throw new Error(`unable to assign all change paths to a project: ${JSON.stringify(Array.from(unassignedChanges.entries()))}`); + } - if (killResult) { - context.isCanceled = true; - } -}; + return changesByProject; +} +/** Get the latest commit sha for a project */ -const timeoutKill = (spawned, signal, reject) => { - spawned.kill(signal); - reject(Object.assign(new Error('Timed out'), {timedOut: true, signal})); -}; -// `timeout` option handling -const setupTimeout = (spawned, {timeout, killSignal = 'SIGTERM'}, spawnedPromise) => { - if (timeout === 0 || timeout === undefined) { - return spawnedPromise; - } +async function getLatestSha(project, kbn) { + if (kbn.isOutsideRepo(project)) { + return; + } - if (!Number.isInteger(timeout) || timeout < 0) { - throw new TypeError(`Expected the \`timeout\` option to be a non-negative integer, got \`${timeout}\` (${typeof timeout})`); - } + const { + stdout + } = await execa__WEBPACK_IMPORTED_MODULE_3___default()('git', ['log', '-n', '1', '--pretty=format:%H', '--', project.path], { + cwd: kbn.getAbsolute() + }); + return stdout.trim() || undefined; +} +/** + * Get the checksum for a specific project in the workspace + */ - let timeoutId; - const timeoutPromise = new Promise((resolve, reject) => { - timeoutId = setTimeout(() => { - timeoutKill(spawned, killSignal, reject); - }, timeout); - }); - const safeSpawnedPromise = spawnedPromise.finally(() => { - clearTimeout(timeoutId); - }); +async function getChecksum(project, changes, yarnLock, kbn, log) { + const sha = await getLatestSha(project, kbn); - return Promise.race([timeoutPromise, safeSpawnedPromise]); -}; + if (sha) { + log.verbose(`[${project.name}] local sha:`, sha); + } -// `cleanup` option handling -const setExitHandler = async (spawned, {cleanup, detached}, timedPromise) => { - if (!cleanup || detached) { - return timedPromise; - } + if (!changes || Array.from(changes.values()).includes('invalid')) { + log.warning(`[${project.name}] unable to determine local changes, caching disabled`); + return; + } - const removeExitHandler = onExit(() => { - spawned.kill(); - }); + const changesSummary = await Promise.all(Array.from(changes).sort((a, b) => a[0].localeCompare(b[0])).map(async ([path, type]) => { + if (type === 'deleted') { + return `${path}:deleted`; + } - return timedPromise.finally(() => { - removeExitHandler(); - }); -}; + const stats = await statAsync(kbn.getAbsolute(path)); + log.verbose(`[${project.name}] modified time ${stats.mtimeMs} for ${path}`); + return `${path}:${stats.mtimeMs}`; + })); + const depMap = Object(_yarn_lock__WEBPACK_IMPORTED_MODULE_4__["resolveDepsForProject"])({ + project, + yarnLock, + kbn, + log, + includeDependentProject: false, + productionDepsOnly: false + }); -module.exports = { - spawnedKill, - spawnedCancel, - setupTimeout, - setExitHandler -}; + if (!depMap) { + return; + } + const deps = Array.from(depMap.values()).map(({ + name, + version + }) => `${name}@${version}`).sort((a, b) => a.localeCompare(b)); + log.verbose(`[${project.name}] resolved %d deps`, deps.length); + const checksum = JSON.stringify({ + sha, + changes: changesSummary, + deps + }, null, 2); -/***/ }), -/* 262 */ -/***/ (function(module, exports, __webpack_require__) { + if (process.env.BOOTSTRAP_CACHE_DEBUG_CHECKSUM) { + return checksum; + } -"use strict"; + const hash = crypto__WEBPACK_IMPORTED_MODULE_1___default.a.createHash('sha1'); + hash.update(checksum); + return hash.digest('hex'); +} +/** + * Calculate checksums for all projects in the workspace based on + * - last git commit to project directory + * - un-committed changes + * - resolved dependencies from yarn.lock referenced by project package.json + */ -const isStream = __webpack_require__(263); -const getStream = __webpack_require__(264); -const mergeStream = __webpack_require__(268); -// `input` option -const handleInput = (spawned, input) => { - // Checking for stdin is workaround for https://github.com/nodejs/node/issues/26852 - // TODO: Remove `|| spawned.stdin === undefined` once we drop support for Node.js <=12.2.0 - if (input === undefined || spawned.stdin === undefined) { - return; - } +async function getAllChecksums(kbn, log, yarnLock) { + const projects = kbn.getAllProjects(); + const changesByProject = await getChangesForProjects(projects, kbn, log); + /** map of [project.name, cacheKey] */ - if (isStream(input)) { - input.pipe(spawned.stdin); - } else { - spawned.stdin.end(input); - } -}; + const cacheKeys = new Map(); + await Promise.all(Array.from(projects.values()).map(async project => { + cacheKeys.set(project.name, await getChecksum(project, changesByProject.get(project), yarnLock, kbn, log)); + })); + return cacheKeys; +} -// `all` interleaves `stdout` and `stderr` -const makeAllStream = (spawned, {all}) => { - if (!all || (!spawned.stdout && !spawned.stderr)) { - return; - } +/***/ }), +/* 274 */ +/***/ (function(module, exports) { - const mixed = mergeStream(); +module.exports = require("crypto"); - if (spawned.stdout) { - mixed.add(spawned.stdout); - } +/***/ }), +/* 275 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - if (spawned.stderr) { - mixed.add(spawned.stderr); - } +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "readYarnLock", function() { return readYarnLock; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "resolveDepsForProject", function() { return resolveDepsForProject; }); +/* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(276); +/* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(131); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +// @ts-expect-error published types are worthless - return mixed; -}; -// On failure, `result.stdout|stderr|all` should contain the currently buffered stream -const getBufferedData = async (stream, streamPromise) => { - if (!stream) { - return; - } +async function readYarnLock(kbn) { + try { + const contents = await Object(_utils_fs__WEBPACK_IMPORTED_MODULE_1__["readFile"])(kbn.getAbsolute('yarn.lock'), 'utf8'); + const yarnLock = Object(_yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__["parse"])(contents); - stream.destroy(); + if (yarnLock.type === 'success') { + return yarnLock.object; + } - try { - return await streamPromise; - } catch (error) { - return error.bufferedData; - } -}; + throw new Error('unable to read yarn.lock file, please run `yarn kbn bootstrap`'); + } catch (error) { + if (error.code !== 'ENOENT') { + throw error; + } + } -const getStreamPromise = (stream, {encoding, buffer, maxBuffer}) => { - if (!stream || !buffer) { - return; - } + return {}; +} +/** + * Get a list of the absolute dependencies of this project, as resolved + * in the yarn.lock file, does not include other projects in the workspace + * or their dependencies + */ - if (encoding) { - return getStream(stream, {encoding, maxBuffer}); - } +function resolveDepsForProject({ + project: rootProject, + yarnLock, + kbn, + log, + productionDepsOnly, + includeDependentProject +}) { + /** map of [name@range, { name, version }] */ + const resolved = new Map(); + const seenProjects = new Set(); + const projectQueue = [rootProject]; + const depQueue = []; - return getStream.buffer(stream, {maxBuffer}); -}; + while (projectQueue.length) { + const project = projectQueue.shift(); -// Retrieve result of child process: exit code, signal, error, streams (stdout/stderr/all) -const getSpawnedResult = async ({stdout, stderr, all}, {encoding, buffer, maxBuffer}, processDone) => { - const stdoutPromise = getStreamPromise(stdout, {encoding, buffer, maxBuffer}); - const stderrPromise = getStreamPromise(stderr, {encoding, buffer, maxBuffer}); - const allPromise = getStreamPromise(all, {encoding, buffer, maxBuffer: maxBuffer * 2}); + if (seenProjects.has(project)) { + continue; + } - try { - return await Promise.all([processDone, stdoutPromise, stderrPromise, allPromise]); - } catch (error) { - return Promise.all([ - {error, signal: error.signal, timedOut: error.timedOut}, - getBufferedData(stdout, stdoutPromise), - getBufferedData(stderr, stderrPromise), - getBufferedData(all, allPromise) - ]); - } -}; + seenProjects.add(project); + const projectDeps = Object.entries(productionDepsOnly ? project.productionDependencies : project.allDependencies); -const validateInputSync = ({input}) => { - if (isStream(input)) { - throw new TypeError('The `input` option cannot be a stream in sync mode'); - } -}; + for (const [name, versionRange] of projectDeps) { + depQueue.push([name, versionRange]); + } -module.exports = { - handleInput, - makeAllStream, - getSpawnedResult, - validateInputSync -}; + while (depQueue.length) { + const [name, versionRange] = depQueue.shift(); + const req = `${name}@${versionRange}`; + if (resolved.has(req)) { + continue; + } + if (includeDependentProject && kbn.hasProject(name)) { + projectQueue.push(kbn.getProject(name)); + } -/***/ }), -/* 263 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - + if (!kbn.hasProject(name)) { + const pkg = yarnLock[req]; -const isStream = stream => - stream !== null && - typeof stream === 'object' && - typeof stream.pipe === 'function'; + if (!pkg) { + log.warning('yarn.lock file is out of date, please run `yarn kbn bootstrap` to re-enable caching'); + return; + } -isStream.writable = stream => - isStream(stream) && - stream.writable !== false && - typeof stream._write === 'function' && - typeof stream._writableState === 'object'; + resolved.set(req, { + name, + version: pkg.version + }); + const allDepsEntries = [...Object.entries(pkg.dependencies || {}), ...Object.entries(pkg.optionalDependencies || {})]; -isStream.readable = stream => - isStream(stream) && - stream.readable !== false && - typeof stream._read === 'function' && - typeof stream._readableState === 'object'; + for (const [childName, childVersionRange] of allDepsEntries) { + depQueue.push([childName, childVersionRange]); + } + } + } + } -isStream.duplex = stream => - isStream.writable(stream) && - isStream.readable(stream); + return resolved; +} -isStream.transform = stream => - isStream.duplex(stream) && - typeof stream._transform === 'function' && - typeof stream._transformState === 'object'; +/***/ }), +/* 276 */ +/***/ (function(module, exports, __webpack_require__) { -module.exports = isStream; +module.exports = +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // identity function for calling harmony imports with the correct context +/******/ __webpack_require__.i = function(value) { return value; }; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 14); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports) { +module.exports = __webpack_require__(4); /***/ }), -/* 264 */ +/* 1 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pump = __webpack_require__(265); -const bufferStream = __webpack_require__(267); -class MaxBufferError extends Error { - constructor() { - super('maxBuffer exceeded'); - this.name = 'MaxBufferError'; - } -} - -async function getStream(inputStream, options) { - if (!inputStream) { - return Promise.reject(new Error('Expected a stream')); - } +exports.__esModule = true; - options = { - maxBuffer: Infinity, - ...options - }; +var _promise = __webpack_require__(173); - const {maxBuffer} = options; +var _promise2 = _interopRequireDefault(_promise); - let stream; - await new Promise((resolve, reject) => { - const rejectPromise = error => { - if (error) { // A null check - error.bufferedData = stream.getBufferedValue(); - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - reject(error); - }; +exports.default = function (fn) { + return function () { + var gen = fn.apply(this, arguments); + return new _promise2.default(function (resolve, reject) { + function step(key, arg) { + try { + var info = gen[key](arg); + var value = info.value; + } catch (error) { + reject(error); + return; + } - stream = pump(inputStream, bufferStream(options), error => { - if (error) { - rejectPromise(error); - return; - } + if (info.done) { + resolve(value); + } else { + return _promise2.default.resolve(value).then(function (value) { + step("next", value); + }, function (err) { + step("throw", err); + }); + } + } - resolve(); - }); + return step("next"); + }); + }; +}; - stream.on('data', () => { - if (stream.getBufferedLength() > maxBuffer) { - rejectPromise(new MaxBufferError()); - } - }); - }); +/***/ }), +/* 2 */ +/***/ (function(module, exports) { - return stream.getBufferedValue(); -} +module.exports = __webpack_require__(112); -module.exports = getStream; -// TODO: Remove this for the next major release -module.exports.default = getStream; -module.exports.buffer = (stream, options) => getStream(stream, {...options, encoding: 'buffer'}); -module.exports.array = (stream, options) => getStream(stream, {...options, array: true}); -module.exports.MaxBufferError = MaxBufferError; +/***/ }), +/* 3 */ +/***/ (function(module, exports) { +module.exports = __webpack_require__(134); /***/ }), -/* 265 */ +/* 4 */ /***/ (function(module, exports, __webpack_require__) { -var once = __webpack_require__(161) -var eos = __webpack_require__(266) -var fs = __webpack_require__(133) // we only need fs to get the ReadStream and WriteStream prototypes - -var noop = function () {} -var ancient = /^v?\.0/.test(process.version) +"use strict"; -var isFn = function (fn) { - return typeof fn === 'function' -} -var isFS = function (stream) { - if (!ancient) return false // newer node version do not need to care about fs is a special way - if (!fs) return false // browser - return (stream instanceof (fs.ReadStream || noop) || stream instanceof (fs.WriteStream || noop)) && isFn(stream.close) -} +Object.defineProperty(exports, "__esModule", { + value: true +}); +class MessageError extends Error { + constructor(msg, code) { + super(msg); + this.code = code; + } -var isRequest = function (stream) { - return stream.setHeader && isFn(stream.abort) } -var destroyer = function (stream, reading, writing, callback) { - callback = once(callback) - - var closed = false - stream.on('close', function () { - closed = true - }) - - eos(stream, {readable: reading, writable: writing}, function (err) { - if (err) return callback(err) - closed = true - callback() - }) - - var destroyed = false - return function (err) { - if (closed) return - if (destroyed) return - destroyed = true - - if (isFS(stream)) return stream.close(noop) // use close for fs streams to avoid fd leaks - if (isRequest(stream)) return stream.abort() // request.destroy just do .end - .abort is what we want - - if (isFn(stream.destroy)) return stream.destroy() - - callback(err || new Error('stream was destroyed')) +exports.MessageError = MessageError; +class ProcessSpawnError extends MessageError { + constructor(msg, code, process) { + super(msg, code); + this.process = process; } -} - -var call = function (fn) { - fn() -} -var pipe = function (from, to) { - return from.pipe(to) } -var pump = function () { - var streams = Array.prototype.slice.call(arguments) - var callback = isFn(streams[streams.length - 1] || noop) && streams.pop() || noop +exports.ProcessSpawnError = ProcessSpawnError; +class SecurityError extends MessageError {} - if (Array.isArray(streams[0])) streams = streams[0] - if (streams.length < 2) throw new Error('pump requires two streams per minimum') +exports.SecurityError = SecurityError; +class ProcessTermError extends MessageError {} - var error - var destroys = streams.map(function (stream, i) { - var reading = i < streams.length - 1 - var writing = i > 0 - return destroyer(stream, reading, writing, function (err) { - if (!error) error = err - if (err) destroys.forEach(call) - if (reading) return - destroys.forEach(call) - callback(error) - }) - }) +exports.ProcessTermError = ProcessTermError; +class ResponseError extends Error { + constructor(msg, responseCode) { + super(msg); + this.responseCode = responseCode; + } - return streams.reduce(pipe) } - -module.exports = pump - +exports.ResponseError = ResponseError; /***/ }), -/* 266 */ +/* 5 */ /***/ (function(module, exports, __webpack_require__) { -var once = __webpack_require__(161); +"use strict"; -var noop = function() {}; -var isRequest = function(stream) { - return stream.setHeader && typeof stream.abort === 'function'; -}; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getFirstSuitableFolder = exports.readFirstAvailableStream = exports.makeTempDir = exports.hardlinksWork = exports.writeFilePreservingEol = exports.getFileSizeOnDisk = exports.walk = exports.symlink = exports.find = exports.readJsonAndFile = exports.readJson = exports.readFileAny = exports.hardlinkBulk = exports.copyBulk = exports.unlink = exports.glob = exports.link = exports.chmod = exports.lstat = exports.exists = exports.mkdirp = exports.stat = exports.access = exports.rename = exports.readdir = exports.realpath = exports.readlink = exports.writeFile = exports.open = exports.readFileBuffer = exports.lockQueue = exports.constants = undefined; -var isChildProcess = function(stream) { - return stream.stdio && Array.isArray(stream.stdio) && stream.stdio.length === 3 -}; +var _asyncToGenerator2; -var eos = function(stream, opts, callback) { - if (typeof opts === 'function') return eos(stream, null, opts); - if (!opts) opts = {}; +function _load_asyncToGenerator() { + return _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(1)); +} - callback = once(callback || noop); +let buildActionsForCopy = (() => { + var _ref = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, events, possibleExtraneous, reporter) { - var ws = stream._writableState; - var rs = stream._readableState; - var readable = opts.readable || (opts.readable !== false && stream.readable); - var writable = opts.writable || (opts.writable !== false && stream.writable); - var cancelled = false; + // + let build = (() => { + var _ref5 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { + const src = data.src, + dest = data.dest, + type = data.type; - var onlegacyfinish = function() { - if (!stream.writable) onfinish(); - }; + const onFresh = data.onFresh || noop; + const onDone = data.onDone || noop; - var onfinish = function() { - writable = false; - if (!readable) callback.call(stream); - }; + // TODO https://github.com/yarnpkg/yarn/issues/3751 + // related to bundled dependencies handling + if (files.has(dest.toLowerCase())) { + reporter.verbose(`The case-insensitive file ${dest} shouldn't be copied twice in one bulk copy`); + } else { + files.add(dest.toLowerCase()); + } - var onend = function() { - readable = false; - if (!writable) callback.call(stream); - }; + if (type === 'symlink') { + yield mkdirp((_path || _load_path()).default.dirname(dest)); + onFresh(); + actions.symlink.push({ + dest, + linkname: src + }); + onDone(); + return; + } - var onexit = function(exitCode) { - callback.call(stream, exitCode ? new Error('exited with error code: ' + exitCode) : null); - }; + if (events.ignoreBasenames.indexOf((_path || _load_path()).default.basename(src)) >= 0) { + // ignored file + return; + } - var onerror = function(err) { - callback.call(stream, err); - }; + const srcStat = yield lstat(src); + let srcFiles; - var onclose = function() { - process.nextTick(onclosenexttick); - }; + if (srcStat.isDirectory()) { + srcFiles = yield readdir(src); + } - var onclosenexttick = function() { - if (cancelled) return; - if (readable && !(rs && (rs.ended && !rs.destroyed))) return callback.call(stream, new Error('premature close')); - if (writable && !(ws && (ws.ended && !ws.destroyed))) return callback.call(stream, new Error('premature close')); - }; + let destStat; + try { + // try accessing the destination + destStat = yield lstat(dest); + } catch (e) { + // proceed if destination doesn't exist, otherwise error + if (e.code !== 'ENOENT') { + throw e; + } + } - var onrequest = function() { - stream.req.on('finish', onfinish); - }; + // if destination exists + if (destStat) { + const bothSymlinks = srcStat.isSymbolicLink() && destStat.isSymbolicLink(); + const bothFolders = srcStat.isDirectory() && destStat.isDirectory(); + const bothFiles = srcStat.isFile() && destStat.isFile(); - if (isRequest(stream)) { - stream.on('complete', onfinish); - stream.on('abort', onclose); - if (stream.req) onrequest(); - else stream.on('request', onrequest); - } else if (writable && !ws) { // legacy streams - stream.on('end', onlegacyfinish); - stream.on('close', onlegacyfinish); - } + // EINVAL access errors sometimes happen which shouldn't because node shouldn't be giving + // us modes that aren't valid. investigate this, it's generally safe to proceed. - if (isChildProcess(stream)) stream.on('exit', onexit); + /* if (srcStat.mode !== destStat.mode) { + try { + await access(dest, srcStat.mode); + } catch (err) {} + } */ - stream.on('end', onend); - stream.on('finish', onfinish); - if (opts.error !== false) stream.on('error', onerror); - stream.on('close', onclose); + if (bothFiles && artifactFiles.has(dest)) { + // this file gets changed during build, likely by a custom install script. Don't bother checking it. + onDone(); + reporter.verbose(reporter.lang('verboseFileSkipArtifact', src)); + return; + } - return function() { - cancelled = true; - stream.removeListener('complete', onfinish); - stream.removeListener('abort', onclose); - stream.removeListener('request', onrequest); - if (stream.req) stream.req.removeListener('finish', onfinish); - stream.removeListener('end', onlegacyfinish); - stream.removeListener('close', onlegacyfinish); - stream.removeListener('finish', onfinish); - stream.removeListener('exit', onexit); - stream.removeListener('end', onend); - stream.removeListener('error', onerror); - stream.removeListener('close', onclose); - }; -}; + if (bothFiles && srcStat.size === destStat.size && (0, (_fsNormalized || _load_fsNormalized()).fileDatesEqual)(srcStat.mtime, destStat.mtime)) { + // we can safely assume this is the same file + onDone(); + reporter.verbose(reporter.lang('verboseFileSkip', src, dest, srcStat.size, +srcStat.mtime)); + return; + } -module.exports = eos; + if (bothSymlinks) { + const srcReallink = yield readlink(src); + if (srcReallink === (yield readlink(dest))) { + // if both symlinks are the same then we can continue on + onDone(); + reporter.verbose(reporter.lang('verboseFileSkipSymlink', src, dest, srcReallink)); + return; + } + } + if (bothFolders) { + // mark files that aren't in this folder as possibly extraneous + const destFiles = yield readdir(dest); + invariant(srcFiles, 'src files not initialised'); -/***/ }), -/* 267 */ -/***/ (function(module, exports, __webpack_require__) { + for (var _iterator4 = destFiles, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) { + var _ref6; -"use strict"; + if (_isArray4) { + if (_i4 >= _iterator4.length) break; + _ref6 = _iterator4[_i4++]; + } else { + _i4 = _iterator4.next(); + if (_i4.done) break; + _ref6 = _i4.value; + } -const {PassThrough: PassThroughStream} = __webpack_require__(137); + const file = _ref6; -module.exports = options => { - options = {...options}; + if (srcFiles.indexOf(file) < 0) { + const loc = (_path || _load_path()).default.join(dest, file); + possibleExtraneous.add(loc); - const {array} = options; - let {encoding} = options; - const isBuffer = encoding === 'buffer'; - let objectMode = false; + if ((yield lstat(loc)).isDirectory()) { + for (var _iterator5 = yield readdir(loc), _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) { + var _ref7; - if (array) { - objectMode = !(encoding || isBuffer); - } else { - encoding = encoding || 'utf8'; - } + if (_isArray5) { + if (_i5 >= _iterator5.length) break; + _ref7 = _iterator5[_i5++]; + } else { + _i5 = _iterator5.next(); + if (_i5.done) break; + _ref7 = _i5.value; + } - if (isBuffer) { - encoding = null; - } + const file = _ref7; - const stream = new PassThroughStream({objectMode}); + possibleExtraneous.add((_path || _load_path()).default.join(loc, file)); + } + } + } + } + } + } - if (encoding) { - stream.setEncoding(encoding); - } + if (destStat && destStat.isSymbolicLink()) { + yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(dest); + destStat = null; + } - let length = 0; - const chunks = []; + if (srcStat.isSymbolicLink()) { + onFresh(); + const linkname = yield readlink(src); + actions.symlink.push({ + dest, + linkname + }); + onDone(); + } else if (srcStat.isDirectory()) { + if (!destStat) { + reporter.verbose(reporter.lang('verboseFileFolder', dest)); + yield mkdirp(dest); + } - stream.on('data', chunk => { - chunks.push(chunk); + const destParts = dest.split((_path || _load_path()).default.sep); + while (destParts.length) { + files.add(destParts.join((_path || _load_path()).default.sep).toLowerCase()); + destParts.pop(); + } - if (objectMode) { - length = chunks.length; - } else { - length += chunk.length; - } - }); + // push all files to queue + invariant(srcFiles, 'src files not initialised'); + let remaining = srcFiles.length; + if (!remaining) { + onDone(); + } + for (var _iterator6 = srcFiles, _isArray6 = Array.isArray(_iterator6), _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : _iterator6[Symbol.iterator]();;) { + var _ref8; - stream.getBufferedValue = () => { - if (array) { - return chunks; - } + if (_isArray6) { + if (_i6 >= _iterator6.length) break; + _ref8 = _iterator6[_i6++]; + } else { + _i6 = _iterator6.next(); + if (_i6.done) break; + _ref8 = _i6.value; + } - return isBuffer ? Buffer.concat(chunks, length) : chunks.join(''); - }; + const file = _ref8; - stream.getBufferedLength = () => length; + queue.push({ + dest: (_path || _load_path()).default.join(dest, file), + onFresh, + onDone: function (_onDone) { + function onDone() { + return _onDone.apply(this, arguments); + } - return stream; -}; + onDone.toString = function () { + return _onDone.toString(); + }; + return onDone; + }(function () { + if (--remaining === 0) { + onDone(); + } + }), + src: (_path || _load_path()).default.join(src, file) + }); + } + } else if (srcStat.isFile()) { + onFresh(); + actions.file.push({ + src, + dest, + atime: srcStat.atime, + mtime: srcStat.mtime, + mode: srcStat.mode + }); + onDone(); + } else { + throw new Error(`unsure how to copy this: ${src}`); + } + }); -/***/ }), -/* 268 */ -/***/ (function(module, exports, __webpack_require__) { + return function build(_x5) { + return _ref5.apply(this, arguments); + }; + })(); -"use strict"; + const artifactFiles = new Set(events.artifactFiles || []); + const files = new Set(); + // initialise events + for (var _iterator = queue, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { + var _ref2; -const { PassThrough } = __webpack_require__(137); + if (_isArray) { + if (_i >= _iterator.length) break; + _ref2 = _iterator[_i++]; + } else { + _i = _iterator.next(); + if (_i.done) break; + _ref2 = _i.value; + } -module.exports = function (/*streams...*/) { - var sources = [] - var output = new PassThrough({objectMode: true}) + const item = _ref2; - output.setMaxListeners(0) + const onDone = item.onDone; + item.onDone = function () { + events.onProgress(item.dest); + if (onDone) { + onDone(); + } + }; + } + events.onStart(queue.length); - output.add = add - output.isEmpty = isEmpty + // start building actions + const actions = { + file: [], + symlink: [], + link: [] + }; - output.on('unpipe', remove) + // custom concurrency logic as we're always executing stacks of CONCURRENT_QUEUE_ITEMS queue items + // at a time due to the requirement to push items onto the queue + while (queue.length) { + const items = queue.splice(0, CONCURRENT_QUEUE_ITEMS); + yield Promise.all(items.map(build)); + } - Array.prototype.slice.call(arguments).forEach(add) + // simulate the existence of some files to prevent considering them extraneous + for (var _iterator2 = artifactFiles, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { + var _ref3; - return output + if (_isArray2) { + if (_i2 >= _iterator2.length) break; + _ref3 = _iterator2[_i2++]; + } else { + _i2 = _iterator2.next(); + if (_i2.done) break; + _ref3 = _i2.value; + } - function add (source) { - if (Array.isArray(source)) { - source.forEach(add) - return this + const file = _ref3; + + if (possibleExtraneous.has(file)) { + reporter.verbose(reporter.lang('verboseFilePhantomExtraneous', file)); + possibleExtraneous.delete(file); + } } - sources.push(source); - source.once('end', remove.bind(null, source)) - source.once('error', output.emit.bind(output, 'error')) - source.pipe(output, {end: false}) - return this - } + for (var _iterator3 = possibleExtraneous, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) { + var _ref4; - function isEmpty () { - return sources.length == 0; - } + if (_isArray3) { + if (_i3 >= _iterator3.length) break; + _ref4 = _iterator3[_i3++]; + } else { + _i3 = _iterator3.next(); + if (_i3.done) break; + _ref4 = _i3.value; + } - function remove (source) { - sources = sources.filter(function (it) { return it !== source }) - if (!sources.length && output.readable) { output.end() } - } -} + const loc = _ref4; + if (files.has(loc.toLowerCase())) { + possibleExtraneous.delete(loc); + } + } -/***/ }), -/* 269 */ -/***/ (function(module, exports, __webpack_require__) { + return actions; + }); -"use strict"; + return function buildActionsForCopy(_x, _x2, _x3, _x4) { + return _ref.apply(this, arguments); + }; +})(); +let buildActionsForHardlink = (() => { + var _ref9 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, events, possibleExtraneous, reporter) { -const nativePromisePrototype = (async () => {})().constructor.prototype; -const descriptors = ['then', 'catch', 'finally'].map(property => [ - property, - Reflect.getOwnPropertyDescriptor(nativePromisePrototype, property) -]); + // + let build = (() => { + var _ref13 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { + const src = data.src, + dest = data.dest; -// The return value is a mixin of `childProcess` and `Promise` -const mergePromise = (spawned, promise) => { - for (const [property, descriptor] of descriptors) { - // Starting the main `promise` is deferred to avoid consuming streams - const value = typeof promise === 'function' ? - (...args) => Reflect.apply(descriptor.value, promise(), args) : - descriptor.value.bind(promise); + const onFresh = data.onFresh || noop; + const onDone = data.onDone || noop; + if (files.has(dest.toLowerCase())) { + // Fixes issue https://github.com/yarnpkg/yarn/issues/2734 + // When bulk hardlinking we have A -> B structure that we want to hardlink to A1 -> B1, + // package-linker passes that modules A1 and B1 need to be hardlinked, + // the recursive linking algorithm of A1 ends up scheduling files in B1 to be linked twice which will case + // an exception. + onDone(); + return; + } + files.add(dest.toLowerCase()); - Reflect.defineProperty(spawned, property, {...descriptor, value}); - } + if (events.ignoreBasenames.indexOf((_path || _load_path()).default.basename(src)) >= 0) { + // ignored file + return; + } - return spawned; -}; + const srcStat = yield lstat(src); + let srcFiles; -// Use promises instead of `child_process` events -const getSpawnedPromise = spawned => { - return new Promise((resolve, reject) => { - spawned.on('exit', (exitCode, signal) => { - resolve({exitCode, signal}); - }); + if (srcStat.isDirectory()) { + srcFiles = yield readdir(src); + } - spawned.on('error', error => { - reject(error); - }); + const destExists = yield exists(dest); + if (destExists) { + const destStat = yield lstat(dest); - if (spawned.stdin) { - spawned.stdin.on('error', error => { - reject(error); - }); - } - }); -}; + const bothSymlinks = srcStat.isSymbolicLink() && destStat.isSymbolicLink(); + const bothFolders = srcStat.isDirectory() && destStat.isDirectory(); + const bothFiles = srcStat.isFile() && destStat.isFile(); -module.exports = { - mergePromise, - getSpawnedPromise -}; + if (srcStat.mode !== destStat.mode) { + try { + yield access(dest, srcStat.mode); + } catch (err) { + // EINVAL access errors sometimes happen which shouldn't because node shouldn't be giving + // us modes that aren't valid. investigate this, it's generally safe to proceed. + reporter.verbose(err); + } + } + if (bothFiles && artifactFiles.has(dest)) { + // this file gets changed during build, likely by a custom install script. Don't bother checking it. + onDone(); + reporter.verbose(reporter.lang('verboseFileSkipArtifact', src)); + return; + } + // correct hardlink + if (bothFiles && srcStat.ino !== null && srcStat.ino === destStat.ino) { + onDone(); + reporter.verbose(reporter.lang('verboseFileSkip', src, dest, srcStat.ino)); + return; + } -/***/ }), -/* 270 */ -/***/ (function(module, exports, __webpack_require__) { + if (bothSymlinks) { + const srcReallink = yield readlink(src); + if (srcReallink === (yield readlink(dest))) { + // if both symlinks are the same then we can continue on + onDone(); + reporter.verbose(reporter.lang('verboseFileSkipSymlink', src, dest, srcReallink)); + return; + } + } -"use strict"; + if (bothFolders) { + // mark files that aren't in this folder as possibly extraneous + const destFiles = yield readdir(dest); + invariant(srcFiles, 'src files not initialised'); -const SPACES_REGEXP = / +/g; + for (var _iterator10 = destFiles, _isArray10 = Array.isArray(_iterator10), _i10 = 0, _iterator10 = _isArray10 ? _iterator10 : _iterator10[Symbol.iterator]();;) { + var _ref14; -const joinCommand = (file, args = []) => { - if (!Array.isArray(args)) { - return file; - } + if (_isArray10) { + if (_i10 >= _iterator10.length) break; + _ref14 = _iterator10[_i10++]; + } else { + _i10 = _iterator10.next(); + if (_i10.done) break; + _ref14 = _i10.value; + } - return [file, ...args].join(' '); -}; + const file = _ref14; -// Allow spaces to be escaped by a backslash if not meant as a delimiter -const handleEscaping = (tokens, token, index) => { - if (index === 0) { - return [token]; - } + if (srcFiles.indexOf(file) < 0) { + const loc = (_path || _load_path()).default.join(dest, file); + possibleExtraneous.add(loc); - const previousToken = tokens[tokens.length - 1]; + if ((yield lstat(loc)).isDirectory()) { + for (var _iterator11 = yield readdir(loc), _isArray11 = Array.isArray(_iterator11), _i11 = 0, _iterator11 = _isArray11 ? _iterator11 : _iterator11[Symbol.iterator]();;) { + var _ref15; - if (previousToken.endsWith('\\')) { - return [...tokens.slice(0, -1), `${previousToken.slice(0, -1)} ${token}`]; - } + if (_isArray11) { + if (_i11 >= _iterator11.length) break; + _ref15 = _iterator11[_i11++]; + } else { + _i11 = _iterator11.next(); + if (_i11.done) break; + _ref15 = _i11.value; + } - return [...tokens, token]; -}; + const file = _ref15; -// Handle `execa.command()` -const parseCommand = command => { - return command - .trim() - .split(SPACES_REGEXP) - .reduce(handleEscaping, []); -}; + possibleExtraneous.add((_path || _load_path()).default.join(loc, file)); + } + } + } + } + } + } -module.exports = { - joinCommand, - parseCommand -}; + if (srcStat.isSymbolicLink()) { + onFresh(); + const linkname = yield readlink(src); + actions.symlink.push({ + dest, + linkname + }); + onDone(); + } else if (srcStat.isDirectory()) { + reporter.verbose(reporter.lang('verboseFileFolder', dest)); + yield mkdirp(dest); + const destParts = dest.split((_path || _load_path()).default.sep); + while (destParts.length) { + files.add(destParts.join((_path || _load_path()).default.sep).toLowerCase()); + destParts.pop(); + } -/***/ }), -/* 271 */ -/***/ (function(module, exports, __webpack_require__) { + // push all files to queue + invariant(srcFiles, 'src files not initialised'); + let remaining = srcFiles.length; + if (!remaining) { + onDone(); + } + for (var _iterator12 = srcFiles, _isArray12 = Array.isArray(_iterator12), _i12 = 0, _iterator12 = _isArray12 ? _iterator12 : _iterator12[Symbol.iterator]();;) { + var _ref16; -// Copyright IBM Corp. 2014,2018. All Rights Reserved. -// Node module: strong-log-transformer -// This file is licensed under the Apache License 2.0. -// License text available at https://opensource.org/licenses/Apache-2.0 + if (_isArray12) { + if (_i12 >= _iterator12.length) break; + _ref16 = _iterator12[_i12++]; + } else { + _i12 = _iterator12.next(); + if (_i12.done) break; + _ref16 = _i12.value; + } -module.exports = __webpack_require__(272); -module.exports.cli = __webpack_require__(276); + const file = _ref16; + queue.push({ + onFresh, + src: (_path || _load_path()).default.join(src, file), + dest: (_path || _load_path()).default.join(dest, file), + onDone: function (_onDone2) { + function onDone() { + return _onDone2.apply(this, arguments); + } -/***/ }), -/* 272 */ -/***/ (function(module, exports, __webpack_require__) { + onDone.toString = function () { + return _onDone2.toString(); + }; -"use strict"; -// Copyright IBM Corp. 2014,2018. All Rights Reserved. -// Node module: strong-log-transformer -// This file is licensed under the Apache License 2.0. -// License text available at https://opensource.org/licenses/Apache-2.0 + return onDone; + }(function () { + if (--remaining === 0) { + onDone(); + } + }) + }); + } + } else if (srcStat.isFile()) { + onFresh(); + actions.link.push({ + src, + dest, + removeDest: destExists + }); + onDone(); + } else { + throw new Error(`unsure how to copy this: ${src}`); + } + }); + return function build(_x10) { + return _ref13.apply(this, arguments); + }; + })(); + const artifactFiles = new Set(events.artifactFiles || []); + const files = new Set(); -var stream = __webpack_require__(137); -var util = __webpack_require__(111); -var fs = __webpack_require__(133); + // initialise events + for (var _iterator7 = queue, _isArray7 = Array.isArray(_iterator7), _i7 = 0, _iterator7 = _isArray7 ? _iterator7 : _iterator7[Symbol.iterator]();;) { + var _ref10; -var through = __webpack_require__(273); -var duplexer = __webpack_require__(274); -var StringDecoder = __webpack_require__(275).StringDecoder; + if (_isArray7) { + if (_i7 >= _iterator7.length) break; + _ref10 = _iterator7[_i7++]; + } else { + _i7 = _iterator7.next(); + if (_i7.done) break; + _ref10 = _i7.value; + } -module.exports = Logger; + const item = _ref10; -Logger.DEFAULTS = { - format: 'text', - tag: '', - mergeMultiline: false, - timeStamp: false, -}; + const onDone = item.onDone || noop; + item.onDone = function () { + events.onProgress(item.dest); + onDone(); + }; + } + events.onStart(queue.length); -var formatters = { - text: textFormatter, - json: jsonFormatter, -} + // start building actions + const actions = { + file: [], + symlink: [], + link: [] + }; -function Logger(options) { - var defaults = JSON.parse(JSON.stringify(Logger.DEFAULTS)); - options = util._extend(defaults, options || {}); - var catcher = deLiner(); - var emitter = catcher; - var transforms = [ - objectifier(), - ]; - - if (options.tag) { - transforms.push(staticTagger(options.tag)); - } - - if (options.mergeMultiline) { - transforms.push(lineMerger()); - } + // custom concurrency logic as we're always executing stacks of CONCURRENT_QUEUE_ITEMS queue items + // at a time due to the requirement to push items onto the queue + while (queue.length) { + const items = queue.splice(0, CONCURRENT_QUEUE_ITEMS); + yield Promise.all(items.map(build)); + } - // TODO - // if (options.pidStamp) { - // transforms.push(pidStamper(options.pid)); - // } + // simulate the existence of some files to prevent considering them extraneous + for (var _iterator8 = artifactFiles, _isArray8 = Array.isArray(_iterator8), _i8 = 0, _iterator8 = _isArray8 ? _iterator8 : _iterator8[Symbol.iterator]();;) { + var _ref11; - // TODO - // if (options.workerStamp) { - // transforms.push(workerStamper(options.worker)); - // } + if (_isArray8) { + if (_i8 >= _iterator8.length) break; + _ref11 = _iterator8[_i8++]; + } else { + _i8 = _iterator8.next(); + if (_i8.done) break; + _ref11 = _i8.value; + } - transforms.push(formatters[options.format](options)); + const file = _ref11; - // restore line endings that were removed by line splitting - transforms.push(reLiner()); + if (possibleExtraneous.has(file)) { + reporter.verbose(reporter.lang('verboseFilePhantomExtraneous', file)); + possibleExtraneous.delete(file); + } + } - for (var t in transforms) { - emitter = emitter.pipe(transforms[t]); - } + for (var _iterator9 = possibleExtraneous, _isArray9 = Array.isArray(_iterator9), _i9 = 0, _iterator9 = _isArray9 ? _iterator9 : _iterator9[Symbol.iterator]();;) { + var _ref12; - return duplexer(catcher, emitter); -} + if (_isArray9) { + if (_i9 >= _iterator9.length) break; + _ref12 = _iterator9[_i9++]; + } else { + _i9 = _iterator9.next(); + if (_i9.done) break; + _ref12 = _i9.value; + } -function deLiner() { - var decoder = new StringDecoder('utf8'); - var last = ''; + const loc = _ref12; - return new stream.Transform({ - transform(chunk, _enc, callback) { - last += decoder.write(chunk); - var list = last.split(/\r\n|[\n\v\f\r\x85\u2028\u2029]/g); - last = list.pop(); - for (var i = 0; i < list.length; i++) { - // swallow empty lines - if (list[i]) { - this.push(list[i]); - } - } - callback(); - }, - flush(callback) { - // incomplete UTF8 sequences become UTF8 replacement characters - last += decoder.end(); - if (last) { - this.push(last); + if (files.has(loc.toLowerCase())) { + possibleExtraneous.delete(loc); } - callback(); - }, + } + + return actions; }); -} -function reLiner() { - return through(appendNewline); + return function buildActionsForHardlink(_x6, _x7, _x8, _x9) { + return _ref9.apply(this, arguments); + }; +})(); - function appendNewline(line) { - this.emit('data', line + '\n'); - } -} +let copyBulk = exports.copyBulk = (() => { + var _ref17 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, reporter, _events) { + const events = { + onStart: _events && _events.onStart || noop, + onProgress: _events && _events.onProgress || noop, + possibleExtraneous: _events ? _events.possibleExtraneous : new Set(), + ignoreBasenames: _events && _events.ignoreBasenames || [], + artifactFiles: _events && _events.artifactFiles || [] + }; -function objectifier() { - return through(objectify, null, {autoDestroy: false}); + const actions = yield buildActionsForCopy(queue, events, events.possibleExtraneous, reporter); + events.onStart(actions.file.length + actions.symlink.length + actions.link.length); - function objectify(line) { - this.emit('data', { - msg: line, - time: Date.now(), + const fileActions = actions.file; + + const currentlyWriting = new Map(); + + yield (_promise || _load_promise()).queue(fileActions, (() => { + var _ref18 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { + let writePromise; + while (writePromise = currentlyWriting.get(data.dest)) { + yield writePromise; + } + + reporter.verbose(reporter.lang('verboseFileCopy', data.src, data.dest)); + const copier = (0, (_fsNormalized || _load_fsNormalized()).copyFile)(data, function () { + return currentlyWriting.delete(data.dest); + }); + currentlyWriting.set(data.dest, copier); + events.onProgress(data.dest); + return copier; + }); + + return function (_x14) { + return _ref18.apply(this, arguments); + }; + })(), CONCURRENT_QUEUE_ITEMS); + + // we need to copy symlinks last as they could reference files we were copying + const symlinkActions = actions.symlink; + yield (_promise || _load_promise()).queue(symlinkActions, function (data) { + const linkname = (_path || _load_path()).default.resolve((_path || _load_path()).default.dirname(data.dest), data.linkname); + reporter.verbose(reporter.lang('verboseFileSymlink', data.dest, linkname)); + return symlink(linkname, data.dest); }); - } -} + }); -function staticTagger(tag) { - return through(tagger); + return function copyBulk(_x11, _x12, _x13) { + return _ref17.apply(this, arguments); + }; +})(); - function tagger(logEvent) { - logEvent.tag = tag; - this.emit('data', logEvent); - } -} +let hardlinkBulk = exports.hardlinkBulk = (() => { + var _ref19 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, reporter, _events) { + const events = { + onStart: _events && _events.onStart || noop, + onProgress: _events && _events.onProgress || noop, + possibleExtraneous: _events ? _events.possibleExtraneous : new Set(), + artifactFiles: _events && _events.artifactFiles || [], + ignoreBasenames: [] + }; -function textFormatter(options) { - return through(textify); + const actions = yield buildActionsForHardlink(queue, events, events.possibleExtraneous, reporter); + events.onStart(actions.file.length + actions.symlink.length + actions.link.length); - function textify(logEvent) { - var line = util.format('%s%s', textifyTags(logEvent.tag), - logEvent.msg.toString()); - if (options.timeStamp) { - line = util.format('%s %s', new Date(logEvent.time).toISOString(), line); - } - this.emit('data', line.replace(/\n/g, '\\n')); - } + const fileActions = actions.link; - function textifyTags(tags) { - var str = ''; - if (typeof tags === 'string') { - str = tags + ' '; - } else if (typeof tags === 'object') { - for (var t in tags) { - str += t + ':' + tags[t] + ' '; - } - } - return str; - } -} + yield (_promise || _load_promise()).queue(fileActions, (() => { + var _ref20 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { + reporter.verbose(reporter.lang('verboseFileLink', data.src, data.dest)); + if (data.removeDest) { + yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(data.dest); + } + yield link(data.src, data.dest); + }); -function jsonFormatter(options) { - return through(jsonify); + return function (_x18) { + return _ref20.apply(this, arguments); + }; + })(), CONCURRENT_QUEUE_ITEMS); - function jsonify(logEvent) { - if (options.timeStamp) { - logEvent.time = new Date(logEvent.time).toISOString(); - } else { - delete logEvent.time; - } - logEvent.msg = logEvent.msg.toString(); - this.emit('data', JSON.stringify(logEvent)); - } -} + // we need to copy symlinks last as they could reference files we were copying + const symlinkActions = actions.symlink; + yield (_promise || _load_promise()).queue(symlinkActions, function (data) { + const linkname = (_path || _load_path()).default.resolve((_path || _load_path()).default.dirname(data.dest), data.linkname); + reporter.verbose(reporter.lang('verboseFileSymlink', data.dest, linkname)); + return symlink(linkname, data.dest); + }); + }); -function lineMerger(host) { - var previousLine = null; - var flushTimer = null; - var stream = through(lineMergerWrite, lineMergerEnd); - var flush = _flush.bind(stream); + return function hardlinkBulk(_x15, _x16, _x17) { + return _ref19.apply(this, arguments); + }; +})(); - return stream; +let readFileAny = exports.readFileAny = (() => { + var _ref21 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (files) { + for (var _iterator13 = files, _isArray13 = Array.isArray(_iterator13), _i13 = 0, _iterator13 = _isArray13 ? _iterator13 : _iterator13[Symbol.iterator]();;) { + var _ref22; - function lineMergerWrite(line) { - if (/^\s+/.test(line.msg)) { - if (previousLine) { - previousLine.msg += '\n' + line.msg; + if (_isArray13) { + if (_i13 >= _iterator13.length) break; + _ref22 = _iterator13[_i13++]; } else { - previousLine = line; + _i13 = _iterator13.next(); + if (_i13.done) break; + _ref22 = _i13.value; } - } else { - flush(); - previousLine = line; - } - // rolling timeout - clearTimeout(flushTimer); - flushTimer = setTimeout(flush.bind(this), 10); - } - function _flush() { - if (previousLine) { - this.emit('data', previousLine); - previousLine = null; + const file = _ref22; + + if (yield exists(file)) { + return readFile(file); + } } - } + return null; + }); - function lineMergerEnd() { - flush.call(this); - this.emit('end'); - } -} + return function readFileAny(_x19) { + return _ref21.apply(this, arguments); + }; +})(); +let readJson = exports.readJson = (() => { + var _ref23 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (loc) { + return (yield readJsonAndFile(loc)).object; + }); -/***/ }), -/* 273 */ -/***/ (function(module, exports, __webpack_require__) { + return function readJson(_x20) { + return _ref23.apply(this, arguments); + }; +})(); -var Stream = __webpack_require__(137) +let readJsonAndFile = exports.readJsonAndFile = (() => { + var _ref24 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (loc) { + const file = yield readFile(loc); + try { + return { + object: (0, (_map || _load_map()).default)(JSON.parse(stripBOM(file))), + content: file + }; + } catch (err) { + err.message = `${loc}: ${err.message}`; + throw err; + } + }); -// through -// -// a stream that does nothing but re-emit the input. -// useful for aggregating a series of changing but not ending streams into one stream) + return function readJsonAndFile(_x21) { + return _ref24.apply(this, arguments); + }; +})(); -exports = module.exports = through -through.through = through +let find = exports.find = (() => { + var _ref25 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (filename, dir) { + const parts = dir.split((_path || _load_path()).default.sep); -//create a readable writable stream. + while (parts.length) { + const loc = parts.concat(filename).join((_path || _load_path()).default.sep); -function through (write, end, opts) { - write = write || function (data) { this.queue(data) } - end = end || function () { this.queue(null) } + if (yield exists(loc)) { + return loc; + } else { + parts.pop(); + } + } - var ended = false, destroyed = false, buffer = [], _ended = false - var stream = new Stream() - stream.readable = stream.writable = true - stream.paused = false + return false; + }); -// stream.autoPause = !(opts && opts.autoPause === false) - stream.autoDestroy = !(opts && opts.autoDestroy === false) + return function find(_x22, _x23) { + return _ref25.apply(this, arguments); + }; +})(); - stream.write = function (data) { - write.call(this, data) - return !stream.paused - } +let symlink = exports.symlink = (() => { + var _ref26 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (src, dest) { + try { + const stats = yield lstat(dest); + if (stats.isSymbolicLink()) { + const resolved = yield realpath(dest); + if (resolved === src) { + return; + } + } + } catch (err) { + if (err.code !== 'ENOENT') { + throw err; + } + } + // We use rimraf for unlink which never throws an ENOENT on missing target + yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(dest); - function drain() { - while(buffer.length && !stream.paused) { - var data = buffer.shift() - if(null === data) - return stream.emit('end') - else - stream.emit('data', data) + if (process.platform === 'win32') { + // use directory junctions if possible on win32, this requires absolute paths + yield fsSymlink(src, dest, 'junction'); + } else { + // use relative paths otherwise which will be retained if the directory is moved + let relative; + try { + relative = (_path || _load_path()).default.relative((_fs || _load_fs()).default.realpathSync((_path || _load_path()).default.dirname(dest)), (_fs || _load_fs()).default.realpathSync(src)); + } catch (err) { + if (err.code !== 'ENOENT') { + throw err; + } + relative = (_path || _load_path()).default.relative((_path || _load_path()).default.dirname(dest), src); + } + // When path.relative returns an empty string for the current directory, we should instead use + // '.', which is a valid fs.symlink target. + yield fsSymlink(relative || '.', dest); } - } + }); - stream.queue = stream.push = function (data) { -// console.error(ended) - if(_ended) return stream - if(data === null) _ended = true - buffer.push(data) - drain() - return stream - } + return function symlink(_x24, _x25) { + return _ref26.apply(this, arguments); + }; +})(); - //this will be registered as the first 'end' listener - //must call destroy next tick, to make sure we're after any - //stream piped from here. - //this is only a problem if end is not emitted synchronously. - //a nicer way to do this is to make sure this is the last listener for 'end' +let walk = exports.walk = (() => { + var _ref27 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (dir, relativeDir, ignoreBasenames = new Set()) { + let files = []; - stream.on('end', function () { - stream.readable = false - if(!stream.writable && stream.autoDestroy) - process.nextTick(function () { - stream.destroy() - }) - }) + let filenames = yield readdir(dir); + if (ignoreBasenames.size) { + filenames = filenames.filter(function (name) { + return !ignoreBasenames.has(name); + }); + } - function _end () { - stream.writable = false - end.call(stream) - if(!stream.readable && stream.autoDestroy) - stream.destroy() - } + for (var _iterator14 = filenames, _isArray14 = Array.isArray(_iterator14), _i14 = 0, _iterator14 = _isArray14 ? _iterator14 : _iterator14[Symbol.iterator]();;) { + var _ref28; - stream.end = function (data) { - if(ended) return - ended = true - if(arguments.length) stream.write(data) - _end() // will emit or queue - return stream - } + if (_isArray14) { + if (_i14 >= _iterator14.length) break; + _ref28 = _iterator14[_i14++]; + } else { + _i14 = _iterator14.next(); + if (_i14.done) break; + _ref28 = _i14.value; + } - stream.destroy = function () { - if(destroyed) return - destroyed = true - ended = true - buffer.length = 0 - stream.writable = stream.readable = false - stream.emit('close') - return stream - } + const name = _ref28; - stream.pause = function () { - if(stream.paused) return - stream.paused = true - return stream - } + const relative = relativeDir ? (_path || _load_path()).default.join(relativeDir, name) : name; + const loc = (_path || _load_path()).default.join(dir, name); + const stat = yield lstat(loc); - stream.resume = function () { - if(stream.paused) { - stream.paused = false - stream.emit('resume') + files.push({ + relative, + basename: name, + absolute: loc, + mtime: +stat.mtime + }); + + if (stat.isDirectory()) { + files = files.concat((yield walk(loc, relative, ignoreBasenames))); + } } - drain() - //may have become paused again, - //as drain emits 'data'. - if(!stream.paused) - stream.emit('drain') - return stream - } - return stream -} + return files; + }); + return function walk(_x26, _x27) { + return _ref27.apply(this, arguments); + }; +})(); -/***/ }), -/* 274 */ -/***/ (function(module, exports, __webpack_require__) { +let getFileSizeOnDisk = exports.getFileSizeOnDisk = (() => { + var _ref29 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (loc) { + const stat = yield lstat(loc); + const size = stat.size, + blockSize = stat.blksize; -var Stream = __webpack_require__(137) -var writeMethods = ["write", "end", "destroy"] -var readMethods = ["resume", "pause"] -var readEvents = ["data", "close"] -var slice = Array.prototype.slice -module.exports = duplex + return Math.ceil(size / blockSize) * blockSize; + }); -function forEach (arr, fn) { - if (arr.forEach) { - return arr.forEach(fn) + return function getFileSizeOnDisk(_x28) { + return _ref29.apply(this, arguments); + }; +})(); + +let getEolFromFile = (() => { + var _ref30 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (path) { + if (!(yield exists(path))) { + return undefined; } - for (var i = 0; i < arr.length; i++) { - fn(arr[i], i) + const buffer = yield readFileBuffer(path); + + for (let i = 0; i < buffer.length; ++i) { + if (buffer[i] === cr) { + return '\r\n'; + } + if (buffer[i] === lf) { + return '\n'; + } } -} + return undefined; + }); -function duplex(writer, reader) { - var stream = new Stream() - var ended = false + return function getEolFromFile(_x29) { + return _ref30.apply(this, arguments); + }; +})(); - forEach(writeMethods, proxyWriter) +let writeFilePreservingEol = exports.writeFilePreservingEol = (() => { + var _ref31 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (path, data) { + const eol = (yield getEolFromFile(path)) || (_os || _load_os()).default.EOL; + if (eol !== '\n') { + data = data.replace(/\n/g, eol); + } + yield writeFile(path, data); + }); - forEach(readMethods, proxyReader) + return function writeFilePreservingEol(_x30, _x31) { + return _ref31.apply(this, arguments); + }; +})(); - forEach(readEvents, proxyStream) +let hardlinksWork = exports.hardlinksWork = (() => { + var _ref32 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (dir) { + const filename = 'test-file' + Math.random(); + const file = (_path || _load_path()).default.join(dir, filename); + const fileLink = (_path || _load_path()).default.join(dir, filename + '-link'); + try { + yield writeFile(file, 'test'); + yield link(file, fileLink); + } catch (err) { + return false; + } finally { + yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(file); + yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(fileLink); + } + return true; + }); - reader.on("end", handleEnd) + return function hardlinksWork(_x32) { + return _ref32.apply(this, arguments); + }; +})(); - writer.on("drain", function() { - stream.emit("drain") - }) +// not a strict polyfill for Node's fs.mkdtemp - writer.on("error", reemit) - reader.on("error", reemit) - stream.writable = writer.writable - stream.readable = reader.readable +let makeTempDir = exports.makeTempDir = (() => { + var _ref33 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (prefix) { + const dir = (_path || _load_path()).default.join((_os || _load_os()).default.tmpdir(), `yarn-${prefix || ''}-${Date.now()}-${Math.random()}`); + yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(dir); + yield mkdirp(dir); + return dir; + }); - return stream + return function makeTempDir(_x33) { + return _ref33.apply(this, arguments); + }; +})(); - function proxyWriter(methodName) { - stream[methodName] = method +let readFirstAvailableStream = exports.readFirstAvailableStream = (() => { + var _ref34 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (paths) { + for (var _iterator15 = paths, _isArray15 = Array.isArray(_iterator15), _i15 = 0, _iterator15 = _isArray15 ? _iterator15 : _iterator15[Symbol.iterator]();;) { + var _ref35; - function method() { - return writer[methodName].apply(writer, arguments) - } - } + if (_isArray15) { + if (_i15 >= _iterator15.length) break; + _ref35 = _iterator15[_i15++]; + } else { + _i15 = _iterator15.next(); + if (_i15.done) break; + _ref35 = _i15.value; + } - function proxyReader(methodName) { - stream[methodName] = method + const path = _ref35; - function method() { - stream.emit(methodName) - var func = reader[methodName] - if (func) { - return func.apply(reader, arguments) - } - reader.emit(methodName) - } + try { + const fd = yield open(path, 'r'); + return (_fs || _load_fs()).default.createReadStream(path, { fd }); + } catch (err) { + // Try the next one + } } + return null; + }); - function proxyStream(methodName) { - reader.on(methodName, reemit) + return function readFirstAvailableStream(_x34) { + return _ref34.apply(this, arguments); + }; +})(); - function reemit() { - var args = slice.call(arguments) - args.unshift(methodName) - stream.emit.apply(stream, args) - } - } +let getFirstSuitableFolder = exports.getFirstSuitableFolder = (() => { + var _ref36 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (paths, mode = constants.W_OK | constants.X_OK) { + const result = { + skipped: [], + folder: null + }; - function handleEnd() { - if (ended) { - return - } - ended = true - var args = slice.call(arguments) - args.unshift("end") - stream.emit.apply(stream, args) - } + for (var _iterator16 = paths, _isArray16 = Array.isArray(_iterator16), _i16 = 0, _iterator16 = _isArray16 ? _iterator16 : _iterator16[Symbol.iterator]();;) { + var _ref37; - function reemit(err) { - stream.emit("error", err) + if (_isArray16) { + if (_i16 >= _iterator16.length) break; + _ref37 = _iterator16[_i16++]; + } else { + _i16 = _iterator16.next(); + if (_i16.done) break; + _ref37 = _i16.value; + } + + const folder = _ref37; + + try { + yield mkdirp(folder); + yield access(folder, mode); + + result.folder = folder; + + return result; + } catch (error) { + result.skipped.push({ + error, + folder + }); + } } + return result; + }); + + return function getFirstSuitableFolder(_x35) { + return _ref36.apply(this, arguments); + }; +})(); + +exports.copy = copy; +exports.readFile = readFile; +exports.readFileRaw = readFileRaw; +exports.normalizeOS = normalizeOS; + +var _fs; + +function _load_fs() { + return _fs = _interopRequireDefault(__webpack_require__(3)); } +var _glob; -/***/ }), -/* 275 */ -/***/ (function(module, exports) { +function _load_glob() { + return _glob = _interopRequireDefault(__webpack_require__(75)); +} -module.exports = require("string_decoder"); +var _os; + +function _load_os() { + return _os = _interopRequireDefault(__webpack_require__(36)); +} + +var _path; + +function _load_path() { + return _path = _interopRequireDefault(__webpack_require__(0)); +} + +var _blockingQueue; + +function _load_blockingQueue() { + return _blockingQueue = _interopRequireDefault(__webpack_require__(84)); +} + +var _promise; + +function _load_promise() { + return _promise = _interopRequireWildcard(__webpack_require__(40)); +} + +var _promise2; + +function _load_promise2() { + return _promise2 = __webpack_require__(40); +} + +var _map; + +function _load_map() { + return _map = _interopRequireDefault(__webpack_require__(20)); +} + +var _fsNormalized; + +function _load_fsNormalized() { + return _fsNormalized = __webpack_require__(164); +} + +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; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const constants = exports.constants = typeof (_fs || _load_fs()).default.constants !== 'undefined' ? (_fs || _load_fs()).default.constants : { + R_OK: (_fs || _load_fs()).default.R_OK, + W_OK: (_fs || _load_fs()).default.W_OK, + X_OK: (_fs || _load_fs()).default.X_OK +}; + +const lockQueue = exports.lockQueue = new (_blockingQueue || _load_blockingQueue()).default('fs lock'); + +const readFileBuffer = exports.readFileBuffer = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.readFile); +const open = exports.open = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.open); +const writeFile = exports.writeFile = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.writeFile); +const readlink = exports.readlink = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.readlink); +const realpath = exports.realpath = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.realpath); +const readdir = exports.readdir = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.readdir); +const rename = exports.rename = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.rename); +const access = exports.access = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.access); +const stat = exports.stat = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.stat); +const mkdirp = exports.mkdirp = (0, (_promise2 || _load_promise2()).promisify)(__webpack_require__(116)); +const exists = exports.exists = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.exists, true); +const lstat = exports.lstat = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.lstat); +const chmod = exports.chmod = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.chmod); +const link = exports.link = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.link); +const glob = exports.glob = (0, (_promise2 || _load_promise2()).promisify)((_glob || _load_glob()).default); +exports.unlink = (_fsNormalized || _load_fsNormalized()).unlink; + +// fs.copyFile uses the native file copying instructions on the system, performing much better +// than any JS-based solution and consumes fewer resources. Repeated testing to fine tune the +// concurrency level revealed 128 as the sweet spot on a quad-core, 16 CPU Intel system with SSD. + +const CONCURRENT_QUEUE_ITEMS = (_fs || _load_fs()).default.copyFile ? 128 : 4; + +const fsSymlink = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.symlink); +const invariant = __webpack_require__(7); +const stripBOM = __webpack_require__(122); + +const noop = () => {}; + +function copy(src, dest, reporter) { + return copyBulk([{ src, dest }], reporter); +} + +function _readFile(loc, encoding) { + return new Promise((resolve, reject) => { + (_fs || _load_fs()).default.readFile(loc, encoding, function (err, content) { + if (err) { + reject(err); + } else { + resolve(content); + } + }); + }); +} + +function readFile(loc) { + return _readFile(loc, 'utf8').then(normalizeOS); +} + +function readFileRaw(loc) { + return _readFile(loc, 'binary'); +} + +function normalizeOS(body) { + return body.replace(/\r\n/g, '\n'); +} + +const cr = '\r'.charCodeAt(0); +const lf = '\n'.charCodeAt(0); /***/ }), -/* 276 */ +/* 6 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -// Copyright IBM Corp. 2014,2018. All Rights Reserved. -// Node module: strong-log-transformer -// This file is licensed under the Apache License 2.0. -// License text available at https://opensource.org/licenses/Apache-2.0 +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getPathKey = getPathKey; +const os = __webpack_require__(36); +const path = __webpack_require__(0); +const userHome = __webpack_require__(45).default; -var minimist = __webpack_require__(277); -var path = __webpack_require__(4); +var _require = __webpack_require__(171); -var Logger = __webpack_require__(272); -var pkg = __webpack_require__(278); +const getCacheDir = _require.getCacheDir, + getConfigDir = _require.getConfigDir, + getDataDir = _require.getDataDir; -module.exports = cli; +const isWebpackBundle = __webpack_require__(227); -function cli(args) { - var opts = minimist(args.slice(2)); - var $0 = path.basename(args[1]); - var p = console.log.bind(console); - if (opts.v || opts.version) { - version($0, p); - } else if (opts.h || opts.help) { - usage($0, p); - } else if (args.length < 3) { - process.stdin.pipe(Logger()).pipe(process.stdout); - } else { - process.stdin.pipe(Logger(opts)).pipe(process.stdout); +const DEPENDENCY_TYPES = exports.DEPENDENCY_TYPES = ['devDependencies', 'dependencies', 'optionalDependencies', 'peerDependencies']; +const RESOLUTIONS = exports.RESOLUTIONS = 'resolutions'; +const MANIFEST_FIELDS = exports.MANIFEST_FIELDS = [RESOLUTIONS, ...DEPENDENCY_TYPES]; + +const SUPPORTED_NODE_VERSIONS = exports.SUPPORTED_NODE_VERSIONS = '^4.8.0 || ^5.7.0 || ^6.2.2 || >=8.0.0'; + +const YARN_REGISTRY = exports.YARN_REGISTRY = 'https://registry.yarnpkg.com'; + +const YARN_DOCS = exports.YARN_DOCS = 'https://yarnpkg.com/en/docs/cli/'; +const YARN_INSTALLER_SH = exports.YARN_INSTALLER_SH = 'https://yarnpkg.com/install.sh'; +const YARN_INSTALLER_MSI = exports.YARN_INSTALLER_MSI = 'https://yarnpkg.com/latest.msi'; + +const SELF_UPDATE_VERSION_URL = exports.SELF_UPDATE_VERSION_URL = 'https://yarnpkg.com/latest-version'; + +// cache version, bump whenever we make backwards incompatible changes +const CACHE_VERSION = exports.CACHE_VERSION = 2; + +// lockfile version, bump whenever we make backwards incompatible changes +const LOCKFILE_VERSION = exports.LOCKFILE_VERSION = 1; + +// max amount of network requests to perform concurrently +const NETWORK_CONCURRENCY = exports.NETWORK_CONCURRENCY = 8; + +// HTTP timeout used when downloading packages +const NETWORK_TIMEOUT = exports.NETWORK_TIMEOUT = 30 * 1000; // in milliseconds + +// max amount of child processes to execute concurrently +const CHILD_CONCURRENCY = exports.CHILD_CONCURRENCY = 5; + +const REQUIRED_PACKAGE_KEYS = exports.REQUIRED_PACKAGE_KEYS = ['name', 'version', '_uid']; + +function getPreferredCacheDirectories() { + const preferredCacheDirectories = [getCacheDir()]; + + if (process.getuid) { + // $FlowFixMe: process.getuid exists, dammit + preferredCacheDirectories.push(path.join(os.tmpdir(), `.yarn-cache-${process.getuid()}`)); } -} -function version($0, p) { - p('%s v%s', pkg.name, pkg.version); + preferredCacheDirectories.push(path.join(os.tmpdir(), `.yarn-cache`)); + + return preferredCacheDirectories; } -function usage($0, p) { - var PADDING = ' '; - var opt, def; - p('Usage: %s [options]', $0); - p(''); - p('%s', pkg.description); - p(''); - p('OPTIONS:'); - for (opt in Logger.DEFAULTS) { - def = Logger.DEFAULTS[opt]; - if (typeof def === 'boolean') - boolOpt(opt, Logger.DEFAULTS[opt]); - else - stdOpt(opt, Logger.DEFAULTS[opt]); - } - p(''); +const PREFERRED_MODULE_CACHE_DIRECTORIES = exports.PREFERRED_MODULE_CACHE_DIRECTORIES = getPreferredCacheDirectories(); +const CONFIG_DIRECTORY = exports.CONFIG_DIRECTORY = getConfigDir(); +const DATA_DIRECTORY = exports.DATA_DIRECTORY = getDataDir(); +const LINK_REGISTRY_DIRECTORY = exports.LINK_REGISTRY_DIRECTORY = path.join(DATA_DIRECTORY, 'link'); +const GLOBAL_MODULE_DIRECTORY = exports.GLOBAL_MODULE_DIRECTORY = path.join(DATA_DIRECTORY, 'global'); - function boolOpt(name, def) { - name = name + PADDING.slice(0, 20-name.length); - p(' --%s default: %s', name, def); - } +const NODE_BIN_PATH = exports.NODE_BIN_PATH = process.execPath; +const YARN_BIN_PATH = exports.YARN_BIN_PATH = getYarnBinPath(); - function stdOpt(name, def) { - var value = name.toUpperCase() + - PADDING.slice(0, 19 - name.length*2); - p(' --%s %s default: %j', name, value, def); +// Webpack needs to be configured with node.__dirname/__filename = false +function getYarnBinPath() { + if (isWebpackBundle) { + return __filename; + } else { + return path.join(__dirname, '..', 'bin', 'yarn.js'); } } +const NODE_MODULES_FOLDER = exports.NODE_MODULES_FOLDER = 'node_modules'; +const NODE_PACKAGE_JSON = exports.NODE_PACKAGE_JSON = 'package.json'; -/***/ }), -/* 277 */ -/***/ (function(module, exports) { +const POSIX_GLOBAL_PREFIX = exports.POSIX_GLOBAL_PREFIX = `${process.env.DESTDIR || ''}/usr/local`; +const FALLBACK_GLOBAL_PREFIX = exports.FALLBACK_GLOBAL_PREFIX = path.join(userHome, '.yarn'); -module.exports = function (args, opts) { - if (!opts) opts = {}; - - var flags = { bools : {}, strings : {}, unknownFn: null }; +const META_FOLDER = exports.META_FOLDER = '.yarn-meta'; +const INTEGRITY_FILENAME = exports.INTEGRITY_FILENAME = '.yarn-integrity'; +const LOCKFILE_FILENAME = exports.LOCKFILE_FILENAME = 'yarn.lock'; +const METADATA_FILENAME = exports.METADATA_FILENAME = '.yarn-metadata.json'; +const TARBALL_FILENAME = exports.TARBALL_FILENAME = '.yarn-tarball.tgz'; +const CLEAN_FILENAME = exports.CLEAN_FILENAME = '.yarnclean'; - if (typeof opts['unknown'] === 'function') { - flags.unknownFn = opts['unknown']; - } +const NPM_LOCK_FILENAME = exports.NPM_LOCK_FILENAME = 'package-lock.json'; +const NPM_SHRINKWRAP_FILENAME = exports.NPM_SHRINKWRAP_FILENAME = 'npm-shrinkwrap.json'; - if (typeof opts['boolean'] === 'boolean' && opts['boolean']) { - flags.allBools = true; - } else { - [].concat(opts['boolean']).filter(Boolean).forEach(function (key) { - flags.bools[key] = true; - }); - } - - var aliases = {}; - Object.keys(opts.alias || {}).forEach(function (key) { - aliases[key] = [].concat(opts.alias[key]); - aliases[key].forEach(function (x) { - aliases[x] = [key].concat(aliases[key].filter(function (y) { - return x !== y; - })); - }); - }); +const DEFAULT_INDENT = exports.DEFAULT_INDENT = ' '; +const SINGLE_INSTANCE_PORT = exports.SINGLE_INSTANCE_PORT = 31997; +const SINGLE_INSTANCE_FILENAME = exports.SINGLE_INSTANCE_FILENAME = '.yarn-single-instance'; - [].concat(opts.string).filter(Boolean).forEach(function (key) { - flags.strings[key] = true; - if (aliases[key]) { - flags.strings[aliases[key]] = true; - } - }); +const ENV_PATH_KEY = exports.ENV_PATH_KEY = getPathKey(process.platform, process.env); - var defaults = opts['default'] || {}; - - var argv = { _ : [] }; - Object.keys(flags.bools).forEach(function (key) { - setArg(key, defaults[key] === undefined ? false : defaults[key]); - }); - - var notFlags = []; +function getPathKey(platform, env) { + let pathKey = 'PATH'; - if (args.indexOf('--') !== -1) { - notFlags = args.slice(args.indexOf('--')+1); - args = args.slice(0, args.indexOf('--')); - } + // windows calls its path "Path" usually, but this is not guaranteed. + if (platform === 'win32') { + pathKey = 'Path'; - function argDefined(key, arg) { - return (flags.allBools && /^--[^=]+$/.test(arg)) || - flags.strings[key] || flags.bools[key] || aliases[key]; + for (const key in env) { + if (key.toLowerCase() === 'path') { + pathKey = key; + } } + } - function setArg (key, val, arg) { - if (arg && flags.unknownFn && !argDefined(key, arg)) { - if (flags.unknownFn(arg) === false) return; - } + return pathKey; +} - var value = !flags.strings[key] && isNumber(val) - ? Number(val) : val - ; - setKey(argv, key.split('.'), value); - - (aliases[key] || []).forEach(function (x) { - setKey(argv, x.split('.'), value); - }); - } +const VERSION_COLOR_SCHEME = exports.VERSION_COLOR_SCHEME = { + major: 'red', + premajor: 'red', + minor: 'yellow', + preminor: 'yellow', + patch: 'green', + prepatch: 'green', + prerelease: 'red', + unchanged: 'white', + unknown: 'red' +}; - function setKey (obj, keys, value) { - var o = obj; - for (var i = 0; i < keys.length-1; i++) { - var key = keys[i]; - if (key === '__proto__') return; - if (o[key] === undefined) o[key] = {}; - if (o[key] === Object.prototype || o[key] === Number.prototype - || o[key] === String.prototype) o[key] = {}; - if (o[key] === Array.prototype) o[key] = []; - o = o[key]; - } +/***/ }), +/* 7 */ +/***/ (function(module, exports, __webpack_require__) { - var key = keys[keys.length - 1]; - if (key === '__proto__') return; - if (o === Object.prototype || o === Number.prototype - || o === String.prototype) o = {}; - if (o === Array.prototype) o = []; - if (o[key] === undefined || flags.bools[key] || typeof o[key] === 'boolean') { - o[key] = value; - } - else if (Array.isArray(o[key])) { - o[key].push(value); - } - else { - o[key] = [ o[key], value ]; - } - } - - function aliasIsBoolean(key) { - return aliases[key].some(function (x) { - return flags.bools[x]; - }); - } +"use strict"; +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ - for (var i = 0; i < args.length; i++) { - var arg = args[i]; - - if (/^--.+=/.test(arg)) { - // Using [\s\S] instead of . because js doesn't support the - // 'dotall' regex modifier. See: - // http://stackoverflow.com/a/1068308/13216 - var m = arg.match(/^--([^=]+)=([\s\S]*)$/); - var key = m[1]; - var value = m[2]; - if (flags.bools[key]) { - value = value !== 'false'; - } - setArg(key, value, arg); - } - else if (/^--no-.+/.test(arg)) { - var key = arg.match(/^--no-(.+)/)[1]; - setArg(key, false, arg); - } - else if (/^--.+/.test(arg)) { - var key = arg.match(/^--(.+)/)[1]; - var next = args[i + 1]; - if (next !== undefined && !/^-/.test(next) - && !flags.bools[key] - && !flags.allBools - && (aliases[key] ? !aliasIsBoolean(key) : true)) { - setArg(key, next, arg); - i++; - } - else if (/^(true|false)$/.test(next)) { - setArg(key, next === 'true', arg); - i++; - } - else { - setArg(key, flags.strings[key] ? '' : true, arg); - } - } - else if (/^-[^-]+/.test(arg)) { - var letters = arg.slice(1,-1).split(''); - - var broken = false; - for (var j = 0; j < letters.length; j++) { - var next = arg.slice(j+2); - - if (next === '-') { - setArg(letters[j], next, arg) - continue; - } - - if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) { - setArg(letters[j], next.split('=')[1], arg); - broken = true; - break; - } - - if (/[A-Za-z]/.test(letters[j]) - && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) { - setArg(letters[j], next, arg); - broken = true; - break; - } - - if (letters[j+1] && letters[j+1].match(/\W/)) { - setArg(letters[j], arg.slice(j+2), arg); - broken = true; - break; - } - else { - setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg); - } - } - - var key = arg.slice(-1)[0]; - if (!broken && key !== '-') { - if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1]) - && !flags.bools[key] - && (aliases[key] ? !aliasIsBoolean(key) : true)) { - setArg(key, args[i+1], arg); - i++; - } - else if (args[i+1] && /^(true|false)$/.test(args[i+1])) { - setArg(key, args[i+1] === 'true', arg); - i++; - } - else { - setArg(key, flags.strings[key] ? '' : true, arg); - } - } - } - else { - if (!flags.unknownFn || flags.unknownFn(arg) !== false) { - argv._.push( - flags.strings['_'] || !isNumber(arg) ? arg : Number(arg) - ); - } - if (opts.stopEarly) { - argv._.push.apply(argv._, args.slice(i + 1)); - break; - } - } - } - - Object.keys(defaults).forEach(function (key) { - if (!hasKey(argv, key.split('.'))) { - setKey(argv, key.split('.'), defaults[key]); - - (aliases[key] || []).forEach(function (x) { - setKey(argv, x.split('.'), defaults[key]); - }); - } - }); - - if (opts['--']) { - argv['--'] = new Array(); - notFlags.forEach(function(key) { - argv['--'].push(key); - }); + + +/** + * Use invariant() to assert state which your program assumes to be true. + * + * Provide sprintf-style format (only %s is supported) and arguments + * to provide information about what broke and what you were + * expecting. + * + * The invariant message will be stripped in production, but the invariant + * will remain to ensure logic does not differ in production. + */ + +var NODE_ENV = "none"; + +var invariant = function(condition, format, a, b, c, d, e, f) { + if (NODE_ENV !== 'production') { + if (format === undefined) { + throw new Error('invariant requires an error message argument'); } - else { - notFlags.forEach(function(key) { - argv._.push(key); - }); + } + + if (!condition) { + var error; + if (format === undefined) { + error = new Error( + 'Minified exception occurred; use the non-minified dev environment ' + + 'for the full error message and additional helpful warnings.' + ); + } else { + var args = [a, b, c, d, e, f]; + var argIndex = 0; + error = new Error( + format.replace(/%s/g, function() { return args[argIndex++]; }) + ); + error.name = 'Invariant Violation'; } - return argv; + error.framesToPop = 1; // we don't care about invariant's own frame + throw error; + } }; -function hasKey (obj, keys) { - var o = obj; - keys.slice(0,-1).forEach(function (key) { - o = (o[key] || {}); - }); - - var key = keys[keys.length - 1]; - return key in o; -} +module.exports = invariant; -function isNumber (x) { - if (typeof x === 'number') return true; - if (/^0x[0-9a-f]+$/i.test(x)) return true; - return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x); -} +/***/ }), +/* 8 */, +/* 9 */ +/***/ (function(module, exports) { +module.exports = __webpack_require__(274); /***/ }), -/* 278 */ -/***/ (function(module) { +/* 10 */, +/* 11 */ +/***/ (function(module, exports) { + +// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 +var global = module.exports = typeof window != 'undefined' && window.Math == Math + ? window : typeof self != 'undefined' && self.Math == Math ? self + // eslint-disable-next-line no-new-func + : Function('return this')(); +if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef -module.exports = JSON.parse("{\"name\":\"strong-log-transformer\",\"version\":\"2.1.0\",\"description\":\"Stream transformer that prefixes lines with timestamps and other things.\",\"author\":\"Ryan Graham \",\"license\":\"Apache-2.0\",\"repository\":{\"type\":\"git\",\"url\":\"git://github.com/strongloop/strong-log-transformer\"},\"keywords\":[\"logging\",\"streams\"],\"bugs\":{\"url\":\"https://github.com/strongloop/strong-log-transformer/issues\"},\"homepage\":\"https://github.com/strongloop/strong-log-transformer\",\"directories\":{\"test\":\"test\"},\"bin\":{\"sl-log-transformer\":\"bin/sl-log-transformer.js\"},\"main\":\"index.js\",\"scripts\":{\"test\":\"tap --100 test/test-*\"},\"dependencies\":{\"duplexer\":\"^0.1.1\",\"minimist\":\"^1.2.0\",\"through\":\"^2.3.4\"},\"devDependencies\":{\"tap\":\"^12.0.1\"},\"engines\":{\"node\":\">=4\"}}"); /***/ }), -/* 279 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 12 */ +/***/ (function(module, 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__(146); -/* 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__(4); -/* 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__(111); -/* 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__(280); -/* harmony import */ var _fs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(130); -/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(164); -/* harmony import */ var _projects__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(145); -/* - * 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.sortAlpha = sortAlpha; +exports.entries = entries; +exports.removePrefix = removePrefix; +exports.removeSuffix = removeSuffix; +exports.addSuffix = addSuffix; +exports.hyphenate = hyphenate; +exports.camelCase = camelCase; +exports.compareSortedArrays = compareSortedArrays; +exports.sleep = sleep; +const _camelCase = __webpack_require__(176); +function sortAlpha(a, b) { + // sort alphabetically in a deterministic way + const shortLen = Math.min(a.length, b.length); + for (let i = 0; i < shortLen; i++) { + const aChar = a.charCodeAt(i); + const bChar = b.charCodeAt(i); + if (aChar !== bChar) { + return aChar - bChar; + } + } + return a.length - b.length; +} +function entries(obj) { + const entries = []; + if (obj) { + for (const key in obj) { + entries.push([key, obj[key]]); + } + } + return entries; +} +function removePrefix(pattern, prefix) { + if (pattern.startsWith(prefix)) { + pattern = pattern.slice(prefix.length); + } + return pattern; +} -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"])(rootPath); +function removeSuffix(pattern, suffix) { + if (pattern.endsWith(suffix)) { + return pattern.slice(0, -suffix.length); + } - if (!rootPkgJson.workspaces) { - return []; + return pattern; +} + +function addSuffix(pattern, suffix) { + if (!pattern.endsWith(suffix)) { + return pattern + suffix; } - const workspacesPathsPatterns = rootPkgJson.workspaces.packages; - let workspaceProjectsPaths = []; + return pattern; +} - for (const pattern of workspacesPathsPatterns) { - workspaceProjectsPaths = workspaceProjectsPaths.concat(await packagesFromGlobPattern({ - pattern, - rootPath - })); - } // Filter out exclude glob patterns +function hyphenate(str) { + return str.replace(/[A-Z]/g, match => { + return '-' + match.charAt(0).toLowerCase(); + }); +} +function camelCase(str) { + if (/[A-Z]/.test(str)) { + return null; + } else { + return _camelCase(str); + } +} - 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); +function compareSortedArrays(array1, array2) { + if (array1.length !== array2.length) { + return false; + } + for (let i = 0, len = array1.length; i < len; i++) { + if (array1[i] !== array2[i]) { + return false; } } - - return workspaceProjectsPaths; + return true; } -async function copyWorkspacePackages(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 project of projects.values()) { - const dest = path__WEBPACK_IMPORTED_MODULE_1___default.a.resolve(rootPath, 'node_modules', project.name); +function sleep(ms) { + return new Promise(resolve => { + setTimeout(resolve, ms); + }); +} - if ((await Object(_fs__WEBPACK_IMPORTED_MODULE_4__["isSymlink"])(dest)) === false) { - continue; - } // Remove the symlink +/***/ }), +/* 13 */ +/***/ (function(module, exports, __webpack_require__) { +var store = __webpack_require__(107)('wks'); +var uid = __webpack_require__(111); +var Symbol = __webpack_require__(11).Symbol; +var USE_SYMBOL = typeof Symbol == 'function'; - await Object(_fs__WEBPACK_IMPORTED_MODULE_4__["unlink"])(dest); // Copy in the package +var $exports = module.exports = function (name) { + return store[name] || (store[name] = + USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name)); +}; - await Object(_fs__WEBPACK_IMPORTED_MODULE_4__["copyDirectory"])(project.path, dest); - } -} +$exports.store = store; -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); -} /***/ }), -/* 280 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 14 */ +/***/ (function(module, 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__(4); -/* 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. - */ -/** - * Returns all the paths where plugins are located - */ -function getProjectPaths({ - rootPath, - ossOnly, - skipKibanaPlugins -}) { - 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. +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.stringify = exports.parse = undefined; - 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/*')); - projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'examples/*')); +var _asyncToGenerator2; - 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/*')); - projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'x-pack/legacy/plugins/*')); - projectPaths.push(Object(path__WEBPACK_IMPORTED_MODULE_0__["resolve"])(rootPath, 'x-pack/test/functional_with_es_ssl/fixtures/plugins/*')); - } +function _load_asyncToGenerator() { + return _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(1)); +} - 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/*')); +var _parse; + +function _load_parse() { + return _parse = __webpack_require__(81); +} + +Object.defineProperty(exports, 'parse', { + enumerable: true, + get: function get() { + return _interopRequireDefault(_parse || _load_parse()).default; } +}); - return projectPaths; +var _stringify; + +function _load_stringify() { + return _stringify = __webpack_require__(150); } -/***/ }), -/* 281 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +Object.defineProperty(exports, 'stringify', { + enumerable: true, + get: function get() { + return _interopRequireDefault(_stringify || _load_stringify()).default; + } +}); +exports.implodeEntry = implodeEntry; +exports.explodeEntry = explodeEntry; -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getAllChecksums", function() { return getAllChecksums; }); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(133); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(282); -/* harmony import */ var crypto__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(crypto__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(111); -/* harmony import */ var util__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(util__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(236); -/* harmony import */ var execa__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(execa__WEBPACK_IMPORTED_MODULE_3__); -/* harmony import */ var _yarn_lock__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(283); -/* - * 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 _misc; +function _load_misc() { + return _misc = __webpack_require__(12); +} +var _normalizePattern; +function _load_normalizePattern() { + return _normalizePattern = __webpack_require__(29); +} +var _parse2; -const statAsync = Object(util__WEBPACK_IMPORTED_MODULE_2__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_0___default.a.stat); +function _load_parse2() { + return _parse2 = _interopRequireDefault(__webpack_require__(81)); +} -const projectBySpecificitySorter = (a, b) => b.path.length - a.path.length; -/** Get the changed files for a set of projects */ +var _constants; +function _load_constants() { + return _constants = __webpack_require__(6); +} -async function getChangesForProjects(projects, kbn, log) { - log.verbose('getting changed files'); - const { - stdout - } = await execa__WEBPACK_IMPORTED_MODULE_3___default()('git', ['ls-files', '-dmto', '--exclude-standard', '--', ...Array.from(projects.values()).filter(p => kbn.isPartOfRepo(p)).map(p => p.path)], { - cwd: kbn.getAbsolute() - }); - const output = stdout.trim(); - const unassignedChanges = new Map(); +var _fs; - if (output) { - for (const line of output.split('\n')) { - const [tag, ...pathParts] = line.trim().split(' '); - const path = pathParts.join(' '); +function _load_fs() { + return _fs = _interopRequireWildcard(__webpack_require__(5)); +} - switch (tag) { - case 'M': - case 'C': - // for some reason ls-files returns deleted files as both deleted - // and modified, so make sure not to overwrite changes already - // tracked as "deleted" - if (unassignedChanges.get(path) !== 'deleted') { - unassignedChanges.set(path, 'modified'); - } +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; } } - break; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - case 'R': - unassignedChanges.set(path, 'deleted'); - break; +const invariant = __webpack_require__(7); - case '?': - unassignedChanges.set(path, 'untracked'); - break; +const path = __webpack_require__(0); +const ssri = __webpack_require__(55); - case 'H': - case 'S': - case 'K': - default: - log.warning(`unexpected modification status "${tag}" for ${path}, please report this!`); - unassignedChanges.set(path, 'invalid'); - break; - } - } +function getName(pattern) { + return (0, (_normalizePattern || _load_normalizePattern()).normalizePattern)(pattern).name; +} + +function blankObjectUndefined(obj) { + return obj && Object.keys(obj).length ? obj : undefined; +} + +function keyForRemote(remote) { + return remote.resolved || (remote.reference && remote.hash ? `${remote.reference}#${remote.hash}` : null); +} + +function serializeIntegrity(integrity) { + // We need this because `Integrity.toString()` does not use sorting to ensure a stable string output + // See https://git.io/vx2Hy + return integrity.toString().split(' ').sort().join(' '); +} + +function implodeEntry(pattern, obj) { + const inferredName = getName(pattern); + const integrity = obj.integrity ? serializeIntegrity(obj.integrity) : ''; + const imploded = { + name: inferredName === obj.name ? undefined : obj.name, + version: obj.version, + uid: obj.uid === obj.version ? undefined : obj.uid, + resolved: obj.resolved, + registry: obj.registry === 'npm' ? undefined : obj.registry, + dependencies: blankObjectUndefined(obj.dependencies), + optionalDependencies: blankObjectUndefined(obj.optionalDependencies), + permissions: blankObjectUndefined(obj.permissions), + prebuiltVariants: blankObjectUndefined(obj.prebuiltVariants) + }; + if (integrity) { + imploded.integrity = integrity; } + return imploded; +} - const sortedRelevantProjects = Array.from(projects.values()).sort(projectBySpecificitySorter); - const changesByProject = new Map(); +function explodeEntry(pattern, obj) { + obj.optionalDependencies = obj.optionalDependencies || {}; + obj.dependencies = obj.dependencies || {}; + obj.uid = obj.uid || obj.version; + obj.permissions = obj.permissions || {}; + obj.registry = obj.registry || 'npm'; + obj.name = obj.name || getName(pattern); + const integrity = obj.integrity; + if (integrity && integrity.isIntegrity) { + obj.integrity = ssri.parse(integrity); + } + return obj; +} - for (const project of sortedRelevantProjects) { - if (kbn.isOutsideRepo(project)) { - changesByProject.set(project, undefined); - continue; - } +class Lockfile { + constructor({ cache, source, parseResultType } = {}) { + this.source = source || ''; + this.cache = cache; + this.parseResultType = parseResultType; + } - const ownChanges = new Map(); - const prefix = kbn.getRelative(project.path); + // source string if the `cache` was parsed - for (const [path, type] of unassignedChanges) { - if (path.startsWith(prefix)) { - ownChanges.set(path, type); - unassignedChanges.delete(path); + + // if true, we're parsing an old yarn file and need to update integrity fields + hasEntriesExistWithoutIntegrity() { + if (!this.cache) { + return false; + } + + for (const key in this.cache) { + // $FlowFixMe - `this.cache` is clearly defined at this point + if (!/^.*@(file:|http)/.test(key) && this.cache[key] && !this.cache[key].integrity) { + return true; } } - log.verbose(`[${project.name}] found ${ownChanges.size} changes`); - changesByProject.set(project, ownChanges); + return false; } - if (unassignedChanges.size) { - throw new Error(`unable to assign all change paths to a project: ${JSON.stringify(Array.from(unassignedChanges.entries()))}`); - } + static fromDirectory(dir, reporter) { + return (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { + // read the manifest in this directory + const lockfileLoc = path.join(dir, (_constants || _load_constants()).LOCKFILE_FILENAME); - return changesByProject; -} -/** Get the latest commit sha for a project */ + let lockfile; + let rawLockfile = ''; + let parseResult; + if (yield (_fs || _load_fs()).exists(lockfileLoc)) { + rawLockfile = yield (_fs || _load_fs()).readFile(lockfileLoc); + parseResult = (0, (_parse2 || _load_parse2()).default)(rawLockfile, lockfileLoc); -async function getLatestSha(project, kbn) { - if (kbn.isOutsideRepo(project)) { - return; + if (reporter) { + if (parseResult.type === 'merge') { + reporter.info(reporter.lang('lockfileMerged')); + } else if (parseResult.type === 'conflict') { + reporter.warn(reporter.lang('lockfileConflict')); + } + } + + lockfile = parseResult.object; + } else if (reporter) { + reporter.info(reporter.lang('noLockfileFound')); + } + + return new Lockfile({ cache: lockfile, source: rawLockfile, parseResultType: parseResult && parseResult.type }); + })(); } - const { - stdout - } = await execa__WEBPACK_IMPORTED_MODULE_3___default()('git', ['log', '-n', '1', '--pretty=format:%H', '--', project.path], { - cwd: kbn.getAbsolute() - }); - return stdout.trim() || undefined; -} -/** - * Get the checksum for a specific project in the workspace - */ + getLocked(pattern) { + const cache = this.cache; + if (!cache) { + return undefined; + } + const shrunk = pattern in cache && cache[pattern]; -async function getChecksum(project, changes, yarnLock, kbn, log) { - const sha = await getLatestSha(project, kbn); + if (typeof shrunk === 'string') { + return this.getLocked(shrunk); + } else if (shrunk) { + explodeEntry(pattern, shrunk); + return shrunk; + } - if (sha) { - log.verbose(`[${project.name}] local sha:`, sha); + return undefined; } - if (!changes || Array.from(changes.values()).includes('invalid')) { - log.warning(`[${project.name}] unable to determine local changes, caching disabled`); - return; + removePattern(pattern) { + const cache = this.cache; + if (!cache) { + return; + } + delete cache[pattern]; } - const changesSummary = await Promise.all(Array.from(changes).sort((a, b) => a[0].localeCompare(b[0])).map(async ([path, type]) => { - if (type === 'deleted') { - return `${path}:deleted`; - } + getLockfile(patterns) { + const lockfile = {}; + const seen = new Map(); - const stats = await statAsync(kbn.getAbsolute(path)); - log.verbose(`[${project.name}] modified time ${stats.mtimeMs} for ${path}`); - return `${path}:${stats.mtimeMs}`; - })); - const depMap = Object(_yarn_lock__WEBPACK_IMPORTED_MODULE_4__["resolveDepsForProject"])({ - project, - yarnLock, - kbn, - log, - includeDependentProject: false, - productionDepsOnly: false - }); + // order by name so that lockfile manifest is assigned to the first dependency with this manifest + // the others that have the same remoteKey will just refer to the first + // ordering allows for consistency in lockfile when it is serialized + const sortedPatternsKeys = Object.keys(patterns).sort((_misc || _load_misc()).sortAlpha); - if (!depMap) { - return; - } + for (var _iterator = sortedPatternsKeys, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { + var _ref; - const deps = Array.from(depMap.values()).map(({ - name, - version - }) => `${name}@${version}`).sort((a, b) => a.localeCompare(b)); - log.verbose(`[${project.name}] resolved %d deps`, deps.length); - const checksum = JSON.stringify({ - sha, - changes: changesSummary, - deps - }, null, 2); + if (_isArray) { + if (_i >= _iterator.length) break; + _ref = _iterator[_i++]; + } else { + _i = _iterator.next(); + if (_i.done) break; + _ref = _i.value; + } - if (process.env.BOOTSTRAP_CACHE_DEBUG_CHECKSUM) { - return checksum; - } + const pattern = _ref; - const hash = crypto__WEBPACK_IMPORTED_MODULE_1___default.a.createHash('sha1'); - hash.update(checksum); - return hash.digest('hex'); -} -/** - * Calculate checksums for all projects in the workspace based on - * - last git commit to project directory - * - un-committed changes - * - resolved dependencies from yarn.lock referenced by project package.json - */ + const pkg = patterns[pattern]; + const remote = pkg._remote, + ref = pkg._reference; + invariant(ref, 'Package is missing a reference'); + invariant(remote, 'Package is missing a remote'); -async function getAllChecksums(kbn, log, yarnLock) { - const projects = kbn.getAllProjects(); - const changesByProject = await getChangesForProjects(projects, kbn, log); - /** map of [project.name, cacheKey] */ + const remoteKey = keyForRemote(remote); + const seenPattern = remoteKey && seen.get(remoteKey); + if (seenPattern) { + // no point in duplicating it + lockfile[pattern] = seenPattern; - const cacheKeys = new Map(); - await Promise.all(Array.from(projects.values()).map(async project => { - cacheKeys.set(project.name, await getChecksum(project, changesByProject.get(project), yarnLock, kbn, log)); - })); - return cacheKeys; + // if we're relying on our name being inferred and two of the patterns have + // different inferred names then we need to set it + if (!seenPattern.name && getName(pattern) !== pkg.name) { + seenPattern.name = pkg.name; + } + continue; + } + const obj = implodeEntry(pattern, { + name: pkg.name, + version: pkg.version, + uid: pkg._uid, + resolved: remote.resolved, + integrity: remote.integrity, + registry: remote.registry, + dependencies: pkg.dependencies, + peerDependencies: pkg.peerDependencies, + optionalDependencies: pkg.optionalDependencies, + permissions: ref.permissions, + prebuiltVariants: pkg.prebuiltVariants + }); + + lockfile[pattern] = obj; + + if (remoteKey) { + seen.set(remoteKey, obj); + } + } + + return lockfile; + } } +exports.default = Lockfile; /***/ }), -/* 282 */ +/* 15 */, +/* 16 */, +/* 17 */ /***/ (function(module, exports) { -module.exports = require("crypto"); +module.exports = __webpack_require__(138); /***/ }), -/* 283 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 18 */, +/* 19 */, +/* 20 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "readYarnLock", function() { return readYarnLock; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "resolveDepsForProject", function() { return resolveDepsForProject; }); -/* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(284); -/* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(130); -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -// @ts-expect-error published types are worthless -async function readYarnLock(kbn) { - try { - const contents = await Object(_utils_fs__WEBPACK_IMPORTED_MODULE_1__["readFile"])(kbn.getAbsolute('yarn.lock'), 'utf8'); - const yarnLock = Object(_yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__["parse"])(contents); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = nullify; +function nullify(obj = {}) { + if (Array.isArray(obj)) { + for (var _iterator = obj, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { + var _ref; - if (yarnLock.type === 'success') { - return yarnLock.object; + if (_isArray) { + if (_i >= _iterator.length) break; + _ref = _iterator[_i++]; + } else { + _i = _iterator.next(); + if (_i.done) break; + _ref = _i.value; + } + + const item = _ref; + + nullify(item); } + } else if (obj !== null && typeof obj === 'object' || typeof obj === 'function') { + Object.setPrototypeOf(obj, null); - throw new Error('unable to read yarn.lock file, please run `yarn kbn bootstrap`'); - } catch (error) { - if (error.code !== 'ENOENT') { - throw error; + // for..in can only be applied to 'object', not 'function' + if (typeof obj === 'object') { + for (const key in obj) { + nullify(obj[key]); + } } } - return {}; + return obj; } -/** - * Get a list of the absolute dependencies of this project, as resolved - * in the yarn.lock file, does not include other projects in the workspace - * or their dependencies - */ - -function resolveDepsForProject({ - project: rootProject, - yarnLock, - kbn, - log, - productionDepsOnly, - includeDependentProject -}) { - /** map of [name@range, { name, version }] */ - const resolved = new Map(); - const seenProjects = new Set(); - const projectQueue = [rootProject]; - const depQueue = []; - while (projectQueue.length) { - const project = projectQueue.shift(); +/***/ }), +/* 21 */, +/* 22 */ +/***/ (function(module, exports) { - if (seenProjects.has(project)) { - continue; - } +module.exports = __webpack_require__(140); - seenProjects.add(project); - const projectDeps = Object.entries(productionDepsOnly ? project.productionDependencies : project.allDependencies); +/***/ }), +/* 23 */ +/***/ (function(module, exports) { - for (const [name, versionRange] of projectDeps) { - depQueue.push([name, versionRange]); - } +var core = module.exports = { version: '2.5.7' }; +if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef - while (depQueue.length) { - const [name, versionRange] = depQueue.shift(); - const req = `${name}@${versionRange}`; - if (resolved.has(req)) { - continue; - } +/***/ }), +/* 24 */, +/* 25 */, +/* 26 */, +/* 27 */ +/***/ (function(module, exports, __webpack_require__) { - if (includeDependentProject && kbn.hasProject(name)) { - projectQueue.push(kbn.getProject(name)); - } +var isObject = __webpack_require__(34); +module.exports = function (it) { + if (!isObject(it)) throw TypeError(it + ' is not an object!'); + return it; +}; - if (!kbn.hasProject(name)) { - const pkg = yarnLock[req]; - if (!pkg) { - log.warning('yarn.lock file is out of date, please run `yarn kbn bootstrap` to re-enable caching'); - return; - } +/***/ }), +/* 28 */, +/* 29 */ +/***/ (function(module, exports, __webpack_require__) { - resolved.set(req, { - name, - version: pkg.version - }); - const allDepsEntries = [...Object.entries(pkg.dependencies || {}), ...Object.entries(pkg.optionalDependencies || {})]; +"use strict"; - for (const [childName, childVersionRange] of allDepsEntries) { - depQueue.push([childName, childVersionRange]); - } - } - } - } - return resolved; -} +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.normalizePattern = normalizePattern; + +/** + * Explode and normalize a pattern into its name and range. + */ + +function normalizePattern(pattern) { + let hasVersion = false; + let range = 'latest'; + let name = pattern; + + // if we're a scope then remove the @ and add it back later + let isScoped = false; + if (name[0] === '@') { + isScoped = true; + name = name.slice(1); + } + + // take first part as the name + const parts = name.split('@'); + if (parts.length > 1) { + name = parts.shift(); + range = parts.join('@'); + + if (range) { + hasVersion = true; + } else { + range = '*'; + } + } + + // add back @ scope suffix + if (isScoped) { + name = `@${name}`; + } + + return { name, range, hasVersion }; +} /***/ }), -/* 284 */ +/* 30 */, +/* 31 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = -/******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // identity function for calling harmony imports with the correct context -/******/ __webpack_require__.i = function(value) { return value; }; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 14); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports) { +var dP = __webpack_require__(50); +var createDesc = __webpack_require__(106); +module.exports = __webpack_require__(33) ? function (object, key, value) { + return dP.f(object, key, createDesc(1, value)); +} : function (object, key, value) { + object[key] = value; + return object; +}; -module.exports = __webpack_require__(4); /***/ }), -/* 1 */ +/* 32 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +/* eslint-disable node/no-deprecated-api */ +var buffer = __webpack_require__(63) +var Buffer = buffer.Buffer + +// alternative to using Object.keys for old browsers +function copyProps (src, dst) { + for (var key in src) { + dst[key] = src[key] + } +} +if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { + module.exports = buffer +} else { + // Copy properties from require('buffer') + copyProps(buffer, exports) + exports.Buffer = SafeBuffer +} +function SafeBuffer (arg, encodingOrOffset, length) { + return Buffer(arg, encodingOrOffset, length) +} -exports.__esModule = true; +// Copy static methods from Buffer +copyProps(Buffer, SafeBuffer) -var _promise = __webpack_require__(173); +SafeBuffer.from = function (arg, encodingOrOffset, length) { + if (typeof arg === 'number') { + throw new TypeError('Argument must not be a number') + } + return Buffer(arg, encodingOrOffset, length) +} -var _promise2 = _interopRequireDefault(_promise); +SafeBuffer.alloc = function (size, fill, encoding) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + var buf = Buffer(size) + if (fill !== undefined) { + if (typeof encoding === 'string') { + buf.fill(fill, encoding) + } else { + buf.fill(fill) + } + } else { + buf.fill(0) + } + return buf +} -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +SafeBuffer.allocUnsafe = function (size) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + return Buffer(size) +} -exports.default = function (fn) { - return function () { - var gen = fn.apply(this, arguments); - return new _promise2.default(function (resolve, reject) { - function step(key, arg) { - try { - var info = gen[key](arg); - var value = info.value; - } catch (error) { - reject(error); - return; - } +SafeBuffer.allocUnsafeSlow = function (size) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + return buffer.SlowBuffer(size) +} - if (info.done) { - resolve(value); - } else { - return _promise2.default.resolve(value).then(function (value) { - step("next", value); - }, function (err) { - step("throw", err); - }); - } - } - return step("next"); - }); - }; +/***/ }), +/* 33 */ +/***/ (function(module, exports, __webpack_require__) { + +// Thank's IE8 for his funny defineProperty +module.exports = !__webpack_require__(85)(function () { + return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7; +}); + + +/***/ }), +/* 34 */ +/***/ (function(module, exports) { + +module.exports = function (it) { + return typeof it === 'object' ? it !== null : typeof it === 'function'; }; + /***/ }), -/* 2 */ +/* 35 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(111); +module.exports = {}; + /***/ }), -/* 3 */ +/* 36 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(133); +module.exports = __webpack_require__(121); /***/ }), -/* 4 */ +/* 37 */, +/* 38 */, +/* 39 */, +/* 40 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -29358,41 +29801,164 @@ module.exports = __webpack_require__(133); Object.defineProperty(exports, "__esModule", { value: true }); -class MessageError extends Error { - constructor(msg, code) { - super(msg); - this.code = code; - } +exports.wait = wait; +exports.promisify = promisify; +exports.queue = queue; +function wait(delay) { + return new Promise(resolve => { + setTimeout(resolve, delay); + }); +} + +function promisify(fn, firstData) { + return function (...args) { + return new Promise(function (resolve, reject) { + args.push(function (err, ...result) { + let res = result; + + if (result.length <= 1) { + res = result[0]; + } + + if (firstData) { + res = err; + err = null; + } + + if (err) { + reject(err); + } else { + resolve(res); + } + }); + fn.apply(null, args); + }); + }; } -exports.MessageError = MessageError; -class ProcessSpawnError extends MessageError { - constructor(msg, code, process) { - super(msg, code); - this.process = process; +function queue(arr, promiseProducer, concurrency = Infinity) { + concurrency = Math.min(concurrency, arr.length); + + // clone + arr = arr.slice(); + + const results = []; + let total = arr.length; + if (!total) { + return Promise.resolve(results); } + return new Promise((resolve, reject) => { + for (let i = 0; i < concurrency; i++) { + next(); + } + + function next() { + const item = arr.shift(); + const promise = promiseProducer(item); + + promise.then(function (result) { + results.push(result); + + total--; + if (total === 0) { + resolve(results); + } else { + if (arr.length) { + next(); + } + } + }, reject); + } + }); } -exports.ProcessSpawnError = ProcessSpawnError; -class SecurityError extends MessageError {} +/***/ }), +/* 41 */ +/***/ (function(module, exports, __webpack_require__) { -exports.SecurityError = SecurityError; -class ProcessTermError extends MessageError {} +var global = __webpack_require__(11); +var core = __webpack_require__(23); +var ctx = __webpack_require__(48); +var hide = __webpack_require__(31); +var has = __webpack_require__(49); +var PROTOTYPE = 'prototype'; -exports.ProcessTermError = ProcessTermError; -class ResponseError extends Error { - constructor(msg, responseCode) { - super(msg); - this.responseCode = responseCode; +var $export = function (type, name, source) { + var IS_FORCED = type & $export.F; + var IS_GLOBAL = type & $export.G; + var IS_STATIC = type & $export.S; + var IS_PROTO = type & $export.P; + var IS_BIND = type & $export.B; + var IS_WRAP = type & $export.W; + var exports = IS_GLOBAL ? core : core[name] || (core[name] = {}); + var expProto = exports[PROTOTYPE]; + var target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE]; + var key, own, out; + if (IS_GLOBAL) source = name; + for (key in source) { + // contains in native + own = !IS_FORCED && target && target[key] !== undefined; + if (own && has(exports, key)) continue; + // export native or passed + out = own ? target[key] : source[key]; + // prevent global pollution for namespaces + exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key] + // bind timers to global for call from export context + : IS_BIND && own ? ctx(out, global) + // wrap global constructors for prevent change them in library + : IS_WRAP && target[key] == out ? (function (C) { + var F = function (a, b, c) { + if (this instanceof C) { + switch (arguments.length) { + case 0: return new C(); + case 1: return new C(a); + case 2: return new C(a, b); + } return new C(a, b, c); + } return C.apply(this, arguments); + }; + F[PROTOTYPE] = C[PROTOTYPE]; + return F; + // make static versions for prototype methods + })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out; + // export proto methods to core.%CONSTRUCTOR%.methods.%NAME% + if (IS_PROTO) { + (exports.virtual || (exports.virtual = {}))[key] = out; + // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME% + if (type & $export.R && expProto && !expProto[key]) hide(expProto, key, out); + } } +}; +// type bitmap +$export.F = 1; // forced +$export.G = 2; // global +$export.S = 4; // static +$export.P = 8; // proto +$export.B = 16; // bind +$export.W = 32; // wrap +$export.U = 64; // safe +$export.R = 128; // real proto method for `library` +module.exports = $export; + + +/***/ }), +/* 42 */ +/***/ (function(module, exports, __webpack_require__) { +try { + var util = __webpack_require__(2); + if (typeof util.inherits !== 'function') throw ''; + module.exports = util.inherits; +} catch (e) { + module.exports = __webpack_require__(224); } -exports.ResponseError = ResponseError; + /***/ }), -/* 5 */ +/* 43 */, +/* 44 */, +/* 45 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -29401,2050 +29967,2427 @@ exports.ResponseError = ResponseError; Object.defineProperty(exports, "__esModule", { value: true }); -exports.getFirstSuitableFolder = exports.readFirstAvailableStream = exports.makeTempDir = exports.hardlinksWork = exports.writeFilePreservingEol = exports.getFileSizeOnDisk = exports.walk = exports.symlink = exports.find = exports.readJsonAndFile = exports.readJson = exports.readFileAny = exports.hardlinkBulk = exports.copyBulk = exports.unlink = exports.glob = exports.link = exports.chmod = exports.lstat = exports.exists = exports.mkdirp = exports.stat = exports.access = exports.rename = exports.readdir = exports.realpath = exports.readlink = exports.writeFile = exports.open = exports.readFileBuffer = exports.lockQueue = exports.constants = undefined; +exports.home = undefined; -var _asyncToGenerator2; +var _rootUser; -function _load_asyncToGenerator() { - return _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(1)); +function _load_rootUser() { + return _rootUser = _interopRequireDefault(__webpack_require__(169)); } -let buildActionsForCopy = (() => { - var _ref = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, events, possibleExtraneous, reporter) { - - // - let build = (() => { - var _ref5 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { - const src = data.src, - dest = data.dest, - type = data.type; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - const onFresh = data.onFresh || noop; - const onDone = data.onDone || noop; +const path = __webpack_require__(0); - // TODO https://github.com/yarnpkg/yarn/issues/3751 - // related to bundled dependencies handling - if (files.has(dest.toLowerCase())) { - reporter.verbose(`The case-insensitive file ${dest} shouldn't be copied twice in one bulk copy`); - } else { - files.add(dest.toLowerCase()); - } +const home = exports.home = __webpack_require__(36).homedir(); - if (type === 'symlink') { - yield mkdirp((_path || _load_path()).default.dirname(dest)); - onFresh(); - actions.symlink.push({ - dest, - linkname: src - }); - onDone(); - return; - } +const userHomeDir = (_rootUser || _load_rootUser()).default ? path.resolve('/usr/local/share') : home; - if (events.ignoreBasenames.indexOf((_path || _load_path()).default.basename(src)) >= 0) { - // ignored file - return; - } +exports.default = userHomeDir; - const srcStat = yield lstat(src); - let srcFiles; +/***/ }), +/* 46 */ +/***/ (function(module, exports) { - if (srcStat.isDirectory()) { - srcFiles = yield readdir(src); - } +module.exports = function (it) { + if (typeof it != 'function') throw TypeError(it + ' is not a function!'); + return it; +}; - let destStat; - try { - // try accessing the destination - destStat = yield lstat(dest); - } catch (e) { - // proceed if destination doesn't exist, otherwise error - if (e.code !== 'ENOENT') { - throw e; - } - } - // if destination exists - if (destStat) { - const bothSymlinks = srcStat.isSymbolicLink() && destStat.isSymbolicLink(); - const bothFolders = srcStat.isDirectory() && destStat.isDirectory(); - const bothFiles = srcStat.isFile() && destStat.isFile(); +/***/ }), +/* 47 */ +/***/ (function(module, exports) { - // EINVAL access errors sometimes happen which shouldn't because node shouldn't be giving - // us modes that aren't valid. investigate this, it's generally safe to proceed. +var toString = {}.toString; - /* if (srcStat.mode !== destStat.mode) { - try { - await access(dest, srcStat.mode); - } catch (err) {} - } */ +module.exports = function (it) { + return toString.call(it).slice(8, -1); +}; - if (bothFiles && artifactFiles.has(dest)) { - // this file gets changed during build, likely by a custom install script. Don't bother checking it. - onDone(); - reporter.verbose(reporter.lang('verboseFileSkipArtifact', src)); - return; - } - if (bothFiles && srcStat.size === destStat.size && (0, (_fsNormalized || _load_fsNormalized()).fileDatesEqual)(srcStat.mtime, destStat.mtime)) { - // we can safely assume this is the same file - onDone(); - reporter.verbose(reporter.lang('verboseFileSkip', src, dest, srcStat.size, +srcStat.mtime)); - return; - } +/***/ }), +/* 48 */ +/***/ (function(module, exports, __webpack_require__) { - if (bothSymlinks) { - const srcReallink = yield readlink(src); - if (srcReallink === (yield readlink(dest))) { - // if both symlinks are the same then we can continue on - onDone(); - reporter.verbose(reporter.lang('verboseFileSkipSymlink', src, dest, srcReallink)); - return; - } - } - - if (bothFolders) { - // mark files that aren't in this folder as possibly extraneous - const destFiles = yield readdir(dest); - invariant(srcFiles, 'src files not initialised'); - - for (var _iterator4 = destFiles, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) { - var _ref6; - - if (_isArray4) { - if (_i4 >= _iterator4.length) break; - _ref6 = _iterator4[_i4++]; - } else { - _i4 = _iterator4.next(); - if (_i4.done) break; - _ref6 = _i4.value; - } +// optional / simple context binding +var aFunction = __webpack_require__(46); +module.exports = function (fn, that, length) { + aFunction(fn); + if (that === undefined) return fn; + switch (length) { + case 1: return function (a) { + return fn.call(that, a); + }; + case 2: return function (a, b) { + return fn.call(that, a, b); + }; + case 3: return function (a, b, c) { + return fn.call(that, a, b, c); + }; + } + return function (/* ...args */) { + return fn.apply(that, arguments); + }; +}; - const file = _ref6; - if (srcFiles.indexOf(file) < 0) { - const loc = (_path || _load_path()).default.join(dest, file); - possibleExtraneous.add(loc); +/***/ }), +/* 49 */ +/***/ (function(module, exports) { - if ((yield lstat(loc)).isDirectory()) { - for (var _iterator5 = yield readdir(loc), _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) { - var _ref7; +var hasOwnProperty = {}.hasOwnProperty; +module.exports = function (it, key) { + return hasOwnProperty.call(it, key); +}; - if (_isArray5) { - if (_i5 >= _iterator5.length) break; - _ref7 = _iterator5[_i5++]; - } else { - _i5 = _iterator5.next(); - if (_i5.done) break; - _ref7 = _i5.value; - } - const file = _ref7; +/***/ }), +/* 50 */ +/***/ (function(module, exports, __webpack_require__) { - possibleExtraneous.add((_path || _load_path()).default.join(loc, file)); - } - } - } - } - } - } +var anObject = __webpack_require__(27); +var IE8_DOM_DEFINE = __webpack_require__(184); +var toPrimitive = __webpack_require__(201); +var dP = Object.defineProperty; - if (destStat && destStat.isSymbolicLink()) { - yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(dest); - destStat = null; - } +exports.f = __webpack_require__(33) ? Object.defineProperty : function defineProperty(O, P, Attributes) { + anObject(O); + P = toPrimitive(P, true); + anObject(Attributes); + if (IE8_DOM_DEFINE) try { + return dP(O, P, Attributes); + } catch (e) { /* empty */ } + if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!'); + if ('value' in Attributes) O[P] = Attributes.value; + return O; +}; - if (srcStat.isSymbolicLink()) { - onFresh(); - const linkname = yield readlink(src); - actions.symlink.push({ - dest, - linkname - }); - onDone(); - } else if (srcStat.isDirectory()) { - if (!destStat) { - reporter.verbose(reporter.lang('verboseFileFolder', dest)); - yield mkdirp(dest); - } - const destParts = dest.split((_path || _load_path()).default.sep); - while (destParts.length) { - files.add(destParts.join((_path || _load_path()).default.sep).toLowerCase()); - destParts.pop(); - } +/***/ }), +/* 51 */, +/* 52 */, +/* 53 */, +/* 54 */ +/***/ (function(module, exports) { - // push all files to queue - invariant(srcFiles, 'src files not initialised'); - let remaining = srcFiles.length; - if (!remaining) { - onDone(); - } - for (var _iterator6 = srcFiles, _isArray6 = Array.isArray(_iterator6), _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : _iterator6[Symbol.iterator]();;) { - var _ref8; +module.exports = __webpack_require__(156); - if (_isArray6) { - if (_i6 >= _iterator6.length) break; - _ref8 = _iterator6[_i6++]; - } else { - _i6 = _iterator6.next(); - if (_i6.done) break; - _ref8 = _i6.value; - } +/***/ }), +/* 55 */ +/***/ (function(module, exports, __webpack_require__) { - const file = _ref8; +"use strict"; - queue.push({ - dest: (_path || _load_path()).default.join(dest, file), - onFresh, - onDone: function (_onDone) { - function onDone() { - return _onDone.apply(this, arguments); - } - onDone.toString = function () { - return _onDone.toString(); - }; +const Buffer = __webpack_require__(32).Buffer - return onDone; - }(function () { - if (--remaining === 0) { - onDone(); - } - }), - src: (_path || _load_path()).default.join(src, file) - }); - } - } else if (srcStat.isFile()) { - onFresh(); - actions.file.push({ - src, - dest, - atime: srcStat.atime, - mtime: srcStat.mtime, - mode: srcStat.mode - }); - onDone(); - } else { - throw new Error(`unsure how to copy this: ${src}`); - } - }); +const crypto = __webpack_require__(9) +const Transform = __webpack_require__(17).Transform - return function build(_x5) { - return _ref5.apply(this, arguments); - }; - })(); +const SPEC_ALGORITHMS = ['sha256', 'sha384', 'sha512'] - const artifactFiles = new Set(events.artifactFiles || []); - const files = new Set(); +const BASE64_REGEX = /^[a-z0-9+/]+(?:=?=?)$/i +const SRI_REGEX = /^([^-]+)-([^?]+)([?\S*]*)$/ +const STRICT_SRI_REGEX = /^([^-]+)-([A-Za-z0-9+/=]{44,88})(\?[\x21-\x7E]*)*$/ +const VCHAR_REGEX = /^[\x21-\x7E]+$/ - // initialise events - for (var _iterator = queue, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { - var _ref2; +class Hash { + get isHash () { return true } + constructor (hash, opts) { + const strict = !!(opts && opts.strict) + this.source = hash.trim() + // 3.1. Integrity metadata (called "Hash" by ssri) + // https://w3c.github.io/webappsec-subresource-integrity/#integrity-metadata-description + const match = this.source.match( + strict + ? STRICT_SRI_REGEX + : SRI_REGEX + ) + if (!match) { return } + if (strict && !SPEC_ALGORITHMS.some(a => a === match[1])) { return } + this.algorithm = match[1] + this.digest = match[2] - if (_isArray) { - if (_i >= _iterator.length) break; - _ref2 = _iterator[_i++]; - } else { - _i = _iterator.next(); - if (_i.done) break; - _ref2 = _i.value; + const rawOpts = match[3] + this.options = rawOpts ? rawOpts.slice(1).split('?') : [] + } + hexDigest () { + return this.digest && Buffer.from(this.digest, 'base64').toString('hex') + } + toJSON () { + return this.toString() + } + toString (opts) { + if (opts && opts.strict) { + // Strict mode enforces the standard as close to the foot of the + // letter as it can. + if (!( + // The spec has very restricted productions for algorithms. + // https://www.w3.org/TR/CSP2/#source-list-syntax + SPEC_ALGORITHMS.some(x => x === this.algorithm) && + // Usually, if someone insists on using a "different" base64, we + // leave it as-is, since there's multiple standards, and the + // specified is not a URL-safe variant. + // https://www.w3.org/TR/CSP2/#base64_value + this.digest.match(BASE64_REGEX) && + // Option syntax is strictly visual chars. + // https://w3c.github.io/webappsec-subresource-integrity/#grammardef-option-expression + // https://tools.ietf.org/html/rfc5234#appendix-B.1 + (this.options || []).every(opt => opt.match(VCHAR_REGEX)) + )) { + return '' } - - const item = _ref2; - - const onDone = item.onDone; - item.onDone = function () { - events.onProgress(item.dest); - if (onDone) { - onDone(); - } - }; } - events.onStart(queue.length); - - // start building actions - const actions = { - file: [], - symlink: [], - link: [] - }; + const options = this.options && this.options.length + ? `?${this.options.join('?')}` + : '' + return `${this.algorithm}-${this.digest}${options}` + } +} - // custom concurrency logic as we're always executing stacks of CONCURRENT_QUEUE_ITEMS queue items - // at a time due to the requirement to push items onto the queue - while (queue.length) { - const items = queue.splice(0, CONCURRENT_QUEUE_ITEMS); - yield Promise.all(items.map(build)); +class Integrity { + get isIntegrity () { return true } + toJSON () { + return this.toString() + } + toString (opts) { + opts = opts || {} + let sep = opts.sep || ' ' + if (opts.strict) { + // Entries must be separated by whitespace, according to spec. + sep = sep.replace(/\S+/g, ' ') } - - // simulate the existence of some files to prevent considering them extraneous - for (var _iterator2 = artifactFiles, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { - var _ref3; - - if (_isArray2) { - if (_i2 >= _iterator2.length) break; - _ref3 = _iterator2[_i2++]; - } else { - _i2 = _iterator2.next(); - if (_i2.done) break; - _ref3 = _i2.value; - } - - const file = _ref3; - - if (possibleExtraneous.has(file)) { - reporter.verbose(reporter.lang('verboseFilePhantomExtraneous', file)); - possibleExtraneous.delete(file); - } + return Object.keys(this).map(k => { + return this[k].map(hash => { + return Hash.prototype.toString.call(hash, opts) + }).filter(x => x.length).join(sep) + }).filter(x => x.length).join(sep) + } + concat (integrity, opts) { + const other = typeof integrity === 'string' + ? integrity + : stringify(integrity, opts) + return parse(`${this.toString(opts)} ${other}`, opts) + } + hexDigest () { + return parse(this, {single: true}).hexDigest() + } + match (integrity, opts) { + const other = parse(integrity, opts) + const algo = other.pickAlgorithm(opts) + return ( + this[algo] && + other[algo] && + this[algo].find(hash => + other[algo].find(otherhash => + hash.digest === otherhash.digest + ) + ) + ) || false + } + pickAlgorithm (opts) { + const pickAlgorithm = (opts && opts.pickAlgorithm) || getPrioritizedHash + const keys = Object.keys(this) + if (!keys.length) { + throw new Error(`No algorithms available for ${ + JSON.stringify(this.toString()) + }`) } + return keys.reduce((acc, algo) => { + return pickAlgorithm(acc, algo) || acc + }) + } +} - for (var _iterator3 = possibleExtraneous, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) { - var _ref4; - - if (_isArray3) { - if (_i3 >= _iterator3.length) break; - _ref4 = _iterator3[_i3++]; - } else { - _i3 = _iterator3.next(); - if (_i3.done) break; - _ref4 = _i3.value; - } - - const loc = _ref4; +module.exports.parse = parse +function parse (sri, opts) { + opts = opts || {} + if (typeof sri === 'string') { + return _parse(sri, opts) + } else if (sri.algorithm && sri.digest) { + const fullSri = new Integrity() + fullSri[sri.algorithm] = [sri] + return _parse(stringify(fullSri, opts), opts) + } else { + return _parse(stringify(sri, opts), opts) + } +} - if (files.has(loc.toLowerCase())) { - possibleExtraneous.delete(loc); - } +function _parse (integrity, opts) { + // 3.4.3. Parse metadata + // https://w3c.github.io/webappsec-subresource-integrity/#parse-metadata + if (opts.single) { + return new Hash(integrity, opts) + } + return integrity.trim().split(/\s+/).reduce((acc, string) => { + const hash = new Hash(string, opts) + if (hash.algorithm && hash.digest) { + const algo = hash.algorithm + if (!acc[algo]) { acc[algo] = [] } + acc[algo].push(hash) } + return acc + }, new Integrity()) +} - return actions; - }); - - return function buildActionsForCopy(_x, _x2, _x3, _x4) { - return _ref.apply(this, arguments); - }; -})(); - -let buildActionsForHardlink = (() => { - var _ref9 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, events, possibleExtraneous, reporter) { - - // - let build = (() => { - var _ref13 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { - const src = data.src, - dest = data.dest; +module.exports.stringify = stringify +function stringify (obj, opts) { + if (obj.algorithm && obj.digest) { + return Hash.prototype.toString.call(obj, opts) + } else if (typeof obj === 'string') { + return stringify(parse(obj, opts), opts) + } else { + return Integrity.prototype.toString.call(obj, opts) + } +} - const onFresh = data.onFresh || noop; - const onDone = data.onDone || noop; - if (files.has(dest.toLowerCase())) { - // Fixes issue https://github.com/yarnpkg/yarn/issues/2734 - // When bulk hardlinking we have A -> B structure that we want to hardlink to A1 -> B1, - // package-linker passes that modules A1 and B1 need to be hardlinked, - // the recursive linking algorithm of A1 ends up scheduling files in B1 to be linked twice which will case - // an exception. - onDone(); - return; - } - files.add(dest.toLowerCase()); +module.exports.fromHex = fromHex +function fromHex (hexDigest, algorithm, opts) { + const optString = (opts && opts.options && opts.options.length) + ? `?${opts.options.join('?')}` + : '' + return parse( + `${algorithm}-${ + Buffer.from(hexDigest, 'hex').toString('base64') + }${optString}`, opts + ) +} - if (events.ignoreBasenames.indexOf((_path || _load_path()).default.basename(src)) >= 0) { - // ignored file - return; - } +module.exports.fromData = fromData +function fromData (data, opts) { + opts = opts || {} + const algorithms = opts.algorithms || ['sha512'] + const optString = opts.options && opts.options.length + ? `?${opts.options.join('?')}` + : '' + return algorithms.reduce((acc, algo) => { + const digest = crypto.createHash(algo).update(data).digest('base64') + const hash = new Hash( + `${algo}-${digest}${optString}`, + opts + ) + if (hash.algorithm && hash.digest) { + const algo = hash.algorithm + if (!acc[algo]) { acc[algo] = [] } + acc[algo].push(hash) + } + return acc + }, new Integrity()) +} - const srcStat = yield lstat(src); - let srcFiles; +module.exports.fromStream = fromStream +function fromStream (stream, opts) { + opts = opts || {} + const P = opts.Promise || Promise + const istream = integrityStream(opts) + return new P((resolve, reject) => { + stream.pipe(istream) + stream.on('error', reject) + istream.on('error', reject) + let sri + istream.on('integrity', s => { sri = s }) + istream.on('end', () => resolve(sri)) + istream.on('data', () => {}) + }) +} - if (srcStat.isDirectory()) { - srcFiles = yield readdir(src); +module.exports.checkData = checkData +function checkData (data, sri, opts) { + opts = opts || {} + sri = parse(sri, opts) + if (!Object.keys(sri).length) { + if (opts.error) { + throw Object.assign( + new Error('No valid integrity hashes to check against'), { + code: 'EINTEGRITY' } + ) + } else { + return false + } + } + const algorithm = sri.pickAlgorithm(opts) + const digest = crypto.createHash(algorithm).update(data).digest('base64') + const newSri = parse({algorithm, digest}) + const match = newSri.match(sri, opts) + if (match || !opts.error) { + return match + } else if (typeof opts.size === 'number' && (data.length !== opts.size)) { + const err = new Error(`data size mismatch when checking ${sri}.\n Wanted: ${opts.size}\n Found: ${data.length}`) + err.code = 'EBADSIZE' + err.found = data.length + err.expected = opts.size + err.sri = sri + throw err + } else { + const err = new Error(`Integrity checksum failed when using ${algorithm}: Wanted ${sri}, but got ${newSri}. (${data.length} bytes)`) + err.code = 'EINTEGRITY' + err.found = newSri + err.expected = sri + err.algorithm = algorithm + err.sri = sri + throw err + } +} - const destExists = yield exists(dest); - if (destExists) { - const destStat = yield lstat(dest); - - const bothSymlinks = srcStat.isSymbolicLink() && destStat.isSymbolicLink(); - const bothFolders = srcStat.isDirectory() && destStat.isDirectory(); - const bothFiles = srcStat.isFile() && destStat.isFile(); +module.exports.checkStream = checkStream +function checkStream (stream, sri, opts) { + opts = opts || {} + const P = opts.Promise || Promise + const checker = integrityStream(Object.assign({}, opts, { + integrity: sri + })) + return new P((resolve, reject) => { + stream.pipe(checker) + stream.on('error', reject) + checker.on('error', reject) + let sri + checker.on('verified', s => { sri = s }) + checker.on('end', () => resolve(sri)) + checker.on('data', () => {}) + }) +} - if (srcStat.mode !== destStat.mode) { - try { - yield access(dest, srcStat.mode); - } catch (err) { - // EINVAL access errors sometimes happen which shouldn't because node shouldn't be giving - // us modes that aren't valid. investigate this, it's generally safe to proceed. - reporter.verbose(err); - } - } +module.exports.integrityStream = integrityStream +function integrityStream (opts) { + opts = opts || {} + // For verification + const sri = opts.integrity && parse(opts.integrity, opts) + const goodSri = sri && Object.keys(sri).length + const algorithm = goodSri && sri.pickAlgorithm(opts) + const digests = goodSri && sri[algorithm] + // Calculating stream + const algorithms = Array.from( + new Set( + (opts.algorithms || ['sha512']) + .concat(algorithm ? [algorithm] : []) + ) + ) + const hashes = algorithms.map(crypto.createHash) + let streamSize = 0 + const stream = new Transform({ + transform (chunk, enc, cb) { + streamSize += chunk.length + hashes.forEach(h => h.update(chunk, enc)) + cb(null, chunk, enc) + } + }).on('end', () => { + const optString = (opts.options && opts.options.length) + ? `?${opts.options.join('?')}` + : '' + const newSri = parse(hashes.map((h, i) => { + return `${algorithms[i]}-${h.digest('base64')}${optString}` + }).join(' '), opts) + // Integrity verification mode + const match = goodSri && newSri.match(sri, opts) + if (typeof opts.size === 'number' && streamSize !== opts.size) { + const err = new Error(`stream size mismatch when checking ${sri}.\n Wanted: ${opts.size}\n Found: ${streamSize}`) + err.code = 'EBADSIZE' + err.found = streamSize + err.expected = opts.size + err.sri = sri + stream.emit('error', err) + } else if (opts.integrity && !match) { + const err = new Error(`${sri} integrity checksum failed when using ${algorithm}: wanted ${digests} but got ${newSri}. (${streamSize} bytes)`) + err.code = 'EINTEGRITY' + err.found = newSri + err.expected = digests + err.algorithm = algorithm + err.sri = sri + stream.emit('error', err) + } else { + stream.emit('size', streamSize) + stream.emit('integrity', newSri) + match && stream.emit('verified', match) + } + }) + return stream +} - if (bothFiles && artifactFiles.has(dest)) { - // this file gets changed during build, likely by a custom install script. Don't bother checking it. - onDone(); - reporter.verbose(reporter.lang('verboseFileSkipArtifact', src)); - return; - } +module.exports.create = createIntegrity +function createIntegrity (opts) { + opts = opts || {} + const algorithms = opts.algorithms || ['sha512'] + const optString = opts.options && opts.options.length + ? `?${opts.options.join('?')}` + : '' - // correct hardlink - if (bothFiles && srcStat.ino !== null && srcStat.ino === destStat.ino) { - onDone(); - reporter.verbose(reporter.lang('verboseFileSkip', src, dest, srcStat.ino)); - return; - } + const hashes = algorithms.map(crypto.createHash) - if (bothSymlinks) { - const srcReallink = yield readlink(src); - if (srcReallink === (yield readlink(dest))) { - // if both symlinks are the same then we can continue on - onDone(); - reporter.verbose(reporter.lang('verboseFileSkipSymlink', src, dest, srcReallink)); - return; - } - } + return { + update: function (chunk, enc) { + hashes.forEach(h => h.update(chunk, enc)) + return this + }, + digest: function (enc) { + const integrity = algorithms.reduce((acc, algo) => { + const digest = hashes.shift().digest('base64') + const hash = new Hash( + `${algo}-${digest}${optString}`, + opts + ) + if (hash.algorithm && hash.digest) { + const algo = hash.algorithm + if (!acc[algo]) { acc[algo] = [] } + acc[algo].push(hash) + } + return acc + }, new Integrity()) - if (bothFolders) { - // mark files that aren't in this folder as possibly extraneous - const destFiles = yield readdir(dest); - invariant(srcFiles, 'src files not initialised'); + return integrity + } + } +} - for (var _iterator10 = destFiles, _isArray10 = Array.isArray(_iterator10), _i10 = 0, _iterator10 = _isArray10 ? _iterator10 : _iterator10[Symbol.iterator]();;) { - var _ref14; +const NODE_HASHES = new Set(crypto.getHashes()) - if (_isArray10) { - if (_i10 >= _iterator10.length) break; - _ref14 = _iterator10[_i10++]; - } else { - _i10 = _iterator10.next(); - if (_i10.done) break; - _ref14 = _i10.value; - } +// This is a Best Effort™ at a reasonable priority for hash algos +const DEFAULT_PRIORITY = [ + 'md5', 'whirlpool', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512', + // TODO - it's unclear _which_ of these Node will actually use as its name + // for the algorithm, so we guesswork it based on the OpenSSL names. + 'sha3', + 'sha3-256', 'sha3-384', 'sha3-512', + 'sha3_256', 'sha3_384', 'sha3_512' +].filter(algo => NODE_HASHES.has(algo)) - const file = _ref14; +function getPrioritizedHash (algo1, algo2) { + return DEFAULT_PRIORITY.indexOf(algo1.toLowerCase()) >= DEFAULT_PRIORITY.indexOf(algo2.toLowerCase()) + ? algo1 + : algo2 +} - if (srcFiles.indexOf(file) < 0) { - const loc = (_path || _load_path()).default.join(dest, file); - possibleExtraneous.add(loc); - if ((yield lstat(loc)).isDirectory()) { - for (var _iterator11 = yield readdir(loc), _isArray11 = Array.isArray(_iterator11), _i11 = 0, _iterator11 = _isArray11 ? _iterator11 : _iterator11[Symbol.iterator]();;) { - var _ref15; +/***/ }), +/* 56 */, +/* 57 */, +/* 58 */, +/* 59 */, +/* 60 */ +/***/ (function(module, exports, __webpack_require__) { - if (_isArray11) { - if (_i11 >= _iterator11.length) break; - _ref15 = _iterator11[_i11++]; - } else { - _i11 = _iterator11.next(); - if (_i11.done) break; - _ref15 = _i11.value; - } +module.exports = minimatch +minimatch.Minimatch = Minimatch - const file = _ref15; +var path = { sep: '/' } +try { + path = __webpack_require__(0) +} catch (er) {} - possibleExtraneous.add((_path || _load_path()).default.join(loc, file)); - } - } - } - } - } - } +var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} +var expand = __webpack_require__(175) - if (srcStat.isSymbolicLink()) { - onFresh(); - const linkname = yield readlink(src); - actions.symlink.push({ - dest, - linkname - }); - onDone(); - } else if (srcStat.isDirectory()) { - reporter.verbose(reporter.lang('verboseFileFolder', dest)); - yield mkdirp(dest); +var plTypes = { + '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, + '?': { open: '(?:', close: ')?' }, + '+': { open: '(?:', close: ')+' }, + '*': { open: '(?:', close: ')*' }, + '@': { open: '(?:', close: ')' } +} - const destParts = dest.split((_path || _load_path()).default.sep); - while (destParts.length) { - files.add(destParts.join((_path || _load_path()).default.sep).toLowerCase()); - destParts.pop(); - } +// any single thing other than / +// don't need to escape / when using new RegExp() +var qmark = '[^/]' - // push all files to queue - invariant(srcFiles, 'src files not initialised'); - let remaining = srcFiles.length; - if (!remaining) { - onDone(); - } - for (var _iterator12 = srcFiles, _isArray12 = Array.isArray(_iterator12), _i12 = 0, _iterator12 = _isArray12 ? _iterator12 : _iterator12[Symbol.iterator]();;) { - var _ref16; +// * => any number of characters +var star = qmark + '*?' - if (_isArray12) { - if (_i12 >= _iterator12.length) break; - _ref16 = _iterator12[_i12++]; - } else { - _i12 = _iterator12.next(); - if (_i12.done) break; - _ref16 = _i12.value; - } +// ** when dots are allowed. Anything goes, except .. and . +// not (^ or / followed by one or two dots followed by $ or /), +// followed by anything, any number of times. +var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' - const file = _ref16; +// not a ^ or / followed by a dot, +// followed by anything, any number of times. +var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' - queue.push({ - onFresh, - src: (_path || _load_path()).default.join(src, file), - dest: (_path || _load_path()).default.join(dest, file), - onDone: function (_onDone2) { - function onDone() { - return _onDone2.apply(this, arguments); - } +// characters that need to be escaped in RegExp. +var reSpecials = charSet('().*{}+?[]^$\\!') - onDone.toString = function () { - return _onDone2.toString(); - }; +// "abc" -> { a:true, b:true, c:true } +function charSet (s) { + return s.split('').reduce(function (set, c) { + set[c] = true + return set + }, {}) +} - return onDone; - }(function () { - if (--remaining === 0) { - onDone(); - } - }) - }); - } - } else if (srcStat.isFile()) { - onFresh(); - actions.link.push({ - src, - dest, - removeDest: destExists - }); - onDone(); - } else { - throw new Error(`unsure how to copy this: ${src}`); - } - }); +// normalizes slashes. +var slashSplit = /\/+/ - return function build(_x10) { - return _ref13.apply(this, arguments); - }; - })(); +minimatch.filter = filter +function filter (pattern, options) { + options = options || {} + return function (p, i, list) { + return minimatch(p, pattern, options) + } +} - const artifactFiles = new Set(events.artifactFiles || []); - const files = new Set(); +function ext (a, b) { + a = a || {} + b = b || {} + var t = {} + Object.keys(b).forEach(function (k) { + t[k] = b[k] + }) + Object.keys(a).forEach(function (k) { + t[k] = a[k] + }) + return t +} - // initialise events - for (var _iterator7 = queue, _isArray7 = Array.isArray(_iterator7), _i7 = 0, _iterator7 = _isArray7 ? _iterator7 : _iterator7[Symbol.iterator]();;) { - var _ref10; +minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return minimatch - if (_isArray7) { - if (_i7 >= _iterator7.length) break; - _ref10 = _iterator7[_i7++]; - } else { - _i7 = _iterator7.next(); - if (_i7.done) break; - _ref10 = _i7.value; - } + var orig = minimatch - const item = _ref10; + var m = function minimatch (p, pattern, options) { + return orig.minimatch(p, pattern, ext(def, options)) + } - const onDone = item.onDone || noop; - item.onDone = function () { - events.onProgress(item.dest); - onDone(); - }; - } - events.onStart(queue.length); + m.Minimatch = function Minimatch (pattern, options) { + return new orig.Minimatch(pattern, ext(def, options)) + } - // start building actions - const actions = { - file: [], - symlink: [], - link: [] - }; + return m +} - // custom concurrency logic as we're always executing stacks of CONCURRENT_QUEUE_ITEMS queue items - // at a time due to the requirement to push items onto the queue - while (queue.length) { - const items = queue.splice(0, CONCURRENT_QUEUE_ITEMS); - yield Promise.all(items.map(build)); - } +Minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return Minimatch + return minimatch.defaults(def).Minimatch +} - // simulate the existence of some files to prevent considering them extraneous - for (var _iterator8 = artifactFiles, _isArray8 = Array.isArray(_iterator8), _i8 = 0, _iterator8 = _isArray8 ? _iterator8 : _iterator8[Symbol.iterator]();;) { - var _ref11; +function minimatch (p, pattern, options) { + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') + } - if (_isArray8) { - if (_i8 >= _iterator8.length) break; - _ref11 = _iterator8[_i8++]; - } else { - _i8 = _iterator8.next(); - if (_i8.done) break; - _ref11 = _i8.value; - } + if (!options) options = {} - const file = _ref11; + // shortcut: comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + return false + } - if (possibleExtraneous.has(file)) { - reporter.verbose(reporter.lang('verboseFilePhantomExtraneous', file)); - possibleExtraneous.delete(file); - } - } + // "" only matches "" + if (pattern.trim() === '') return p === '' - for (var _iterator9 = possibleExtraneous, _isArray9 = Array.isArray(_iterator9), _i9 = 0, _iterator9 = _isArray9 ? _iterator9 : _iterator9[Symbol.iterator]();;) { - var _ref12; + return new Minimatch(pattern, options).match(p) +} - if (_isArray9) { - if (_i9 >= _iterator9.length) break; - _ref12 = _iterator9[_i9++]; - } else { - _i9 = _iterator9.next(); - if (_i9.done) break; - _ref12 = _i9.value; - } +function Minimatch (pattern, options) { + if (!(this instanceof Minimatch)) { + return new Minimatch(pattern, options) + } - const loc = _ref12; + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') + } - if (files.has(loc.toLowerCase())) { - possibleExtraneous.delete(loc); - } - } + if (!options) options = {} + pattern = pattern.trim() - return actions; - }); + // windows support: need to use /, not \ + if (path.sep !== '/') { + pattern = pattern.split(path.sep).join('/') + } - return function buildActionsForHardlink(_x6, _x7, _x8, _x9) { - return _ref9.apply(this, arguments); - }; -})(); + this.options = options + this.set = [] + this.pattern = pattern + this.regexp = null + this.negate = false + this.comment = false + this.empty = false -let copyBulk = exports.copyBulk = (() => { - var _ref17 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, reporter, _events) { - const events = { - onStart: _events && _events.onStart || noop, - onProgress: _events && _events.onProgress || noop, - possibleExtraneous: _events ? _events.possibleExtraneous : new Set(), - ignoreBasenames: _events && _events.ignoreBasenames || [], - artifactFiles: _events && _events.artifactFiles || [] - }; + // make the set of regexps etc. + this.make() +} - const actions = yield buildActionsForCopy(queue, events, events.possibleExtraneous, reporter); - events.onStart(actions.file.length + actions.symlink.length + actions.link.length); +Minimatch.prototype.debug = function () {} - const fileActions = actions.file; +Minimatch.prototype.make = make +function make () { + // don't do it more than once. + if (this._made) return - const currentlyWriting = new Map(); + var pattern = this.pattern + var options = this.options - yield (_promise || _load_promise()).queue(fileActions, (() => { - var _ref18 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { - let writePromise; - while (writePromise = currentlyWriting.get(data.dest)) { - yield writePromise; - } + // empty patterns and comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + this.comment = true + return + } + if (!pattern) { + this.empty = true + return + } - reporter.verbose(reporter.lang('verboseFileCopy', data.src, data.dest)); - const copier = (0, (_fsNormalized || _load_fsNormalized()).copyFile)(data, function () { - return currentlyWriting.delete(data.dest); - }); - currentlyWriting.set(data.dest, copier); - events.onProgress(data.dest); - return copier; - }); + // step 1: figure out negation, etc. + this.parseNegate() - return function (_x14) { - return _ref18.apply(this, arguments); - }; - })(), CONCURRENT_QUEUE_ITEMS); + // step 2: expand braces + var set = this.globSet = this.braceExpand() - // we need to copy symlinks last as they could reference files we were copying - const symlinkActions = actions.symlink; - yield (_promise || _load_promise()).queue(symlinkActions, function (data) { - const linkname = (_path || _load_path()).default.resolve((_path || _load_path()).default.dirname(data.dest), data.linkname); - reporter.verbose(reporter.lang('verboseFileSymlink', data.dest, linkname)); - return symlink(linkname, data.dest); - }); - }); + if (options.debug) this.debug = console.error - return function copyBulk(_x11, _x12, _x13) { - return _ref17.apply(this, arguments); - }; -})(); + this.debug(this.pattern, set) -let hardlinkBulk = exports.hardlinkBulk = (() => { - var _ref19 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (queue, reporter, _events) { - const events = { - onStart: _events && _events.onStart || noop, - onProgress: _events && _events.onProgress || noop, - possibleExtraneous: _events ? _events.possibleExtraneous : new Set(), - artifactFiles: _events && _events.artifactFiles || [], - ignoreBasenames: [] - }; - - const actions = yield buildActionsForHardlink(queue, events, events.possibleExtraneous, reporter); - events.onStart(actions.file.length + actions.symlink.length + actions.link.length); + // step 3: now we have a set, so turn each one into a series of path-portion + // matching patterns. + // These will be regexps, except in the case of "**", which is + // set to the GLOBSTAR object for globstar behavior, + // and will not contain any / characters + set = this.globParts = set.map(function (s) { + return s.split(slashSplit) + }) - const fileActions = actions.link; + this.debug(this.pattern, set) - yield (_promise || _load_promise()).queue(fileActions, (() => { - var _ref20 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data) { - reporter.verbose(reporter.lang('verboseFileLink', data.src, data.dest)); - if (data.removeDest) { - yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(data.dest); - } - yield link(data.src, data.dest); - }); + // glob --> regexps + set = set.map(function (s, si, set) { + return s.map(this.parse, this) + }, this) - return function (_x18) { - return _ref20.apply(this, arguments); - }; - })(), CONCURRENT_QUEUE_ITEMS); + this.debug(this.pattern, set) - // we need to copy symlinks last as they could reference files we were copying - const symlinkActions = actions.symlink; - yield (_promise || _load_promise()).queue(symlinkActions, function (data) { - const linkname = (_path || _load_path()).default.resolve((_path || _load_path()).default.dirname(data.dest), data.linkname); - reporter.verbose(reporter.lang('verboseFileSymlink', data.dest, linkname)); - return symlink(linkname, data.dest); - }); - }); + // filter out everything that didn't compile properly. + set = set.filter(function (s) { + return s.indexOf(false) === -1 + }) - return function hardlinkBulk(_x15, _x16, _x17) { - return _ref19.apply(this, arguments); - }; -})(); + this.debug(this.pattern, set) -let readFileAny = exports.readFileAny = (() => { - var _ref21 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (files) { - for (var _iterator13 = files, _isArray13 = Array.isArray(_iterator13), _i13 = 0, _iterator13 = _isArray13 ? _iterator13 : _iterator13[Symbol.iterator]();;) { - var _ref22; + this.set = set +} - if (_isArray13) { - if (_i13 >= _iterator13.length) break; - _ref22 = _iterator13[_i13++]; - } else { - _i13 = _iterator13.next(); - if (_i13.done) break; - _ref22 = _i13.value; - } +Minimatch.prototype.parseNegate = parseNegate +function parseNegate () { + var pattern = this.pattern + var negate = false + var options = this.options + var negateOffset = 0 - const file = _ref22; + if (options.nonegate) return - if (yield exists(file)) { - return readFile(file); - } - } - return null; - }); + for (var i = 0, l = pattern.length + ; i < l && pattern.charAt(i) === '!' + ; i++) { + negate = !negate + negateOffset++ + } - return function readFileAny(_x19) { - return _ref21.apply(this, arguments); - }; -})(); + if (negateOffset) this.pattern = pattern.substr(negateOffset) + this.negate = negate +} -let readJson = exports.readJson = (() => { - var _ref23 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (loc) { - return (yield readJsonAndFile(loc)).object; - }); +// Brace expansion: +// a{b,c}d -> abd acd +// a{b,}c -> abc ac +// a{0..3}d -> a0d a1d a2d a3d +// a{b,c{d,e}f}g -> abg acdfg acefg +// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg +// +// Invalid sets are not expanded. +// a{2..}b -> a{2..}b +// a{b}c -> a{b}c +minimatch.braceExpand = function (pattern, options) { + return braceExpand(pattern, options) +} - return function readJson(_x20) { - return _ref23.apply(this, arguments); - }; -})(); +Minimatch.prototype.braceExpand = braceExpand -let readJsonAndFile = exports.readJsonAndFile = (() => { - var _ref24 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (loc) { - const file = yield readFile(loc); - try { - return { - object: (0, (_map || _load_map()).default)(JSON.parse(stripBOM(file))), - content: file - }; - } catch (err) { - err.message = `${loc}: ${err.message}`; - throw err; +function braceExpand (pattern, options) { + if (!options) { + if (this instanceof Minimatch) { + options = this.options + } else { + options = {} } - }); + } - return function readJsonAndFile(_x21) { - return _ref24.apply(this, arguments); - }; -})(); + pattern = typeof pattern === 'undefined' + ? this.pattern : pattern -let find = exports.find = (() => { - var _ref25 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (filename, dir) { - const parts = dir.split((_path || _load_path()).default.sep); + if (typeof pattern === 'undefined') { + throw new TypeError('undefined pattern') + } - while (parts.length) { - const loc = parts.concat(filename).join((_path || _load_path()).default.sep); + if (options.nobrace || + !pattern.match(/\{.*\}/)) { + // shortcut. no need to expand. + return [pattern] + } - if (yield exists(loc)) { - return loc; - } else { - parts.pop(); - } - } + return expand(pattern) +} - return false; - }); +// parse a component of the expanded set. +// At this point, no pattern may contain "/" in it +// so we're going to return a 2d array, where each entry is the full +// pattern, split on '/', and then turned into a regular expression. +// A regexp is made at the end which joins each array with an +// escaped /, and another full one which joins each regexp with |. +// +// Following the lead of Bash 4.1, note that "**" only has special meaning +// when it is the *only* thing in a path portion. Otherwise, any series +// of * is equivalent to a single *. Globstar behavior is enabled by +// default, and can be disabled by setting options.noglobstar. +Minimatch.prototype.parse = parse +var SUBPARSE = {} +function parse (pattern, isSub) { + if (pattern.length > 1024 * 64) { + throw new TypeError('pattern is too long') + } - return function find(_x22, _x23) { - return _ref25.apply(this, arguments); - }; -})(); + var options = this.options -let symlink = exports.symlink = (() => { - var _ref26 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (src, dest) { - try { - const stats = yield lstat(dest); - if (stats.isSymbolicLink()) { - const resolved = yield realpath(dest); - if (resolved === src) { - return; - } - } - } catch (err) { - if (err.code !== 'ENOENT') { - throw err; - } - } - // We use rimraf for unlink which never throws an ENOENT on missing target - yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(dest); + // shortcuts + if (!options.noglobstar && pattern === '**') return GLOBSTAR + if (pattern === '') return '' - if (process.platform === 'win32') { - // use directory junctions if possible on win32, this requires absolute paths - yield fsSymlink(src, dest, 'junction'); - } else { - // use relative paths otherwise which will be retained if the directory is moved - let relative; - try { - relative = (_path || _load_path()).default.relative((_fs || _load_fs()).default.realpathSync((_path || _load_path()).default.dirname(dest)), (_fs || _load_fs()).default.realpathSync(src)); - } catch (err) { - if (err.code !== 'ENOENT') { - throw err; - } - relative = (_path || _load_path()).default.relative((_path || _load_path()).default.dirname(dest), src); + var re = '' + var hasMagic = !!options.nocase + var escaping = false + // ? => one single character + var patternListStack = [] + var negativeLists = [] + var stateChar + var inClass = false + var reClassStart = -1 + var classStart = -1 + // . and .. never match anything that doesn't start with ., + // even when options.dot is set. + var patternStart = pattern.charAt(0) === '.' ? '' // anything + // not (start or / followed by . or .. followed by / or end) + : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' + : '(?!\\.)' + var self = this + + function clearStateChar () { + if (stateChar) { + // we had some state-tracking character + // that wasn't consumed by this pass. + switch (stateChar) { + case '*': + re += star + hasMagic = true + break + case '?': + re += qmark + hasMagic = true + break + default: + re += '\\' + stateChar + break } - // When path.relative returns an empty string for the current directory, we should instead use - // '.', which is a valid fs.symlink target. - yield fsSymlink(relative || '.', dest); + self.debug('clearStateChar %j %j', stateChar, re) + stateChar = false } - }); - - return function symlink(_x24, _x25) { - return _ref26.apply(this, arguments); - }; -})(); + } -let walk = exports.walk = (() => { - var _ref27 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (dir, relativeDir, ignoreBasenames = new Set()) { - let files = []; + for (var i = 0, len = pattern.length, c + ; (i < len) && (c = pattern.charAt(i)) + ; i++) { + this.debug('%s\t%s %s %j', pattern, i, re, c) - let filenames = yield readdir(dir); - if (ignoreBasenames.size) { - filenames = filenames.filter(function (name) { - return !ignoreBasenames.has(name); - }); + // skip over any that are escaped. + if (escaping && reSpecials[c]) { + re += '\\' + c + escaping = false + continue } - for (var _iterator14 = filenames, _isArray14 = Array.isArray(_iterator14), _i14 = 0, _iterator14 = _isArray14 ? _iterator14 : _iterator14[Symbol.iterator]();;) { - var _ref28; - - if (_isArray14) { - if (_i14 >= _iterator14.length) break; - _ref28 = _iterator14[_i14++]; - } else { - _i14 = _iterator14.next(); - if (_i14.done) break; - _ref28 = _i14.value; - } + switch (c) { + case '/': + // completely not allowed, even escaped. + // Should already be path-split by now. + return false - const name = _ref28; + case '\\': + clearStateChar() + escaping = true + continue - const relative = relativeDir ? (_path || _load_path()).default.join(relativeDir, name) : name; - const loc = (_path || _load_path()).default.join(dir, name); - const stat = yield lstat(loc); + // the various stateChar values + // for the "extglob" stuff. + case '?': + case '*': + case '+': + case '@': + case '!': + this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) - files.push({ - relative, - basename: name, - absolute: loc, - mtime: +stat.mtime - }); + // all of those are literals inside a class, except that + // the glob [!a] means [^a] in regexp + if (inClass) { + this.debug(' in class') + if (c === '!' && i === classStart + 1) c = '^' + re += c + continue + } - if (stat.isDirectory()) { - files = files.concat((yield walk(loc, relative, ignoreBasenames))); - } - } + // if we already have a stateChar, then it means + // that there was something like ** or +? in there. + // Handle the stateChar, then proceed with this one. + self.debug('call clearStateChar %j', stateChar) + clearStateChar() + stateChar = c + // if extglob is disabled, then +(asdf|foo) isn't a thing. + // just clear the statechar *now*, rather than even diving into + // the patternList stuff. + if (options.noext) clearStateChar() + continue - return files; - }); + case '(': + if (inClass) { + re += '(' + continue + } - return function walk(_x26, _x27) { - return _ref27.apply(this, arguments); - }; -})(); + if (!stateChar) { + re += '\\(' + continue + } -let getFileSizeOnDisk = exports.getFileSizeOnDisk = (() => { - var _ref29 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (loc) { - const stat = yield lstat(loc); - const size = stat.size, - blockSize = stat.blksize; + patternListStack.push({ + type: stateChar, + start: i - 1, + reStart: re.length, + open: plTypes[stateChar].open, + close: plTypes[stateChar].close + }) + // negation is (?:(?!js)[^/]*) + re += stateChar === '!' ? '(?:(?!(?:' : '(?:' + this.debug('plType %j %j', stateChar, re) + stateChar = false + continue + case ')': + if (inClass || !patternListStack.length) { + re += '\\)' + continue + } - return Math.ceil(size / blockSize) * blockSize; - }); + clearStateChar() + hasMagic = true + var pl = patternListStack.pop() + // negation is (?:(?!js)[^/]*) + // The others are (?:) + re += pl.close + if (pl.type === '!') { + negativeLists.push(pl) + } + pl.reEnd = re.length + continue - return function getFileSizeOnDisk(_x28) { - return _ref29.apply(this, arguments); - }; -})(); + case '|': + if (inClass || !patternListStack.length || escaping) { + re += '\\|' + escaping = false + continue + } -let getEolFromFile = (() => { - var _ref30 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (path) { - if (!(yield exists(path))) { - return undefined; - } + clearStateChar() + re += '|' + continue - const buffer = yield readFileBuffer(path); + // these are mostly the same in regexp and glob + case '[': + // swallow any state-tracking char before the [ + clearStateChar() - for (let i = 0; i < buffer.length; ++i) { - if (buffer[i] === cr) { - return '\r\n'; - } - if (buffer[i] === lf) { - return '\n'; - } - } - return undefined; - }); + if (inClass) { + re += '\\' + c + continue + } - return function getEolFromFile(_x29) { - return _ref30.apply(this, arguments); - }; -})(); + inClass = true + classStart = i + reClassStart = re.length + re += c + continue -let writeFilePreservingEol = exports.writeFilePreservingEol = (() => { - var _ref31 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (path, data) { - const eol = (yield getEolFromFile(path)) || (_os || _load_os()).default.EOL; - if (eol !== '\n') { - data = data.replace(/\n/g, eol); - } - yield writeFile(path, data); - }); + case ']': + // a right bracket shall lose its special + // meaning and represent itself in + // a bracket expression if it occurs + // first in the list. -- POSIX.2 2.8.3.2 + if (i === classStart + 1 || !inClass) { + re += '\\' + c + escaping = false + continue + } - return function writeFilePreservingEol(_x30, _x31) { - return _ref31.apply(this, arguments); - }; -})(); + // handle the case where we left a class open. + // "[z-a]" is valid, equivalent to "\[z-a\]" + if (inClass) { + // split where the last [ was, make sure we don't have + // an invalid re. if so, re-walk the contents of the + // would-be class to re-translate any characters that + // were passed through as-is + // TODO: It would probably be faster to determine this + // without a try/catch and a new RegExp, but it's tricky + // to do safely. For now, this is safe and works. + var cs = pattern.substring(classStart + 1, i) + try { + RegExp('[' + cs + ']') + } catch (er) { + // not a valid class! + var sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' + hasMagic = hasMagic || sp[1] + inClass = false + continue + } + } -let hardlinksWork = exports.hardlinksWork = (() => { - var _ref32 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (dir) { - const filename = 'test-file' + Math.random(); - const file = (_path || _load_path()).default.join(dir, filename); - const fileLink = (_path || _load_path()).default.join(dir, filename + '-link'); - try { - yield writeFile(file, 'test'); - yield link(file, fileLink); - } catch (err) { - return false; - } finally { - yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(file); - yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(fileLink); - } - return true; - }); + // finish up the class. + hasMagic = true + inClass = false + re += c + continue - return function hardlinksWork(_x32) { - return _ref32.apply(this, arguments); - }; -})(); - -// not a strict polyfill for Node's fs.mkdtemp + default: + // swallow any state char that wasn't consumed + clearStateChar() + if (escaping) { + // no need + escaping = false + } else if (reSpecials[c] + && !(c === '^' && inClass)) { + re += '\\' + } -let makeTempDir = exports.makeTempDir = (() => { - var _ref33 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (prefix) { - const dir = (_path || _load_path()).default.join((_os || _load_os()).default.tmpdir(), `yarn-${prefix || ''}-${Date.now()}-${Math.random()}`); - yield (0, (_fsNormalized || _load_fsNormalized()).unlink)(dir); - yield mkdirp(dir); - return dir; - }); + re += c - return function makeTempDir(_x33) { - return _ref33.apply(this, arguments); - }; -})(); + } // switch + } // for -let readFirstAvailableStream = exports.readFirstAvailableStream = (() => { - var _ref34 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (paths) { - for (var _iterator15 = paths, _isArray15 = Array.isArray(_iterator15), _i15 = 0, _iterator15 = _isArray15 ? _iterator15 : _iterator15[Symbol.iterator]();;) { - var _ref35; + // handle the case where we left a class open. + // "[abc" is valid, equivalent to "\[abc" + if (inClass) { + // split where the last [ was, and escape it + // this is a huge pita. We now have to re-walk + // the contents of the would-be class to re-translate + // any characters that were passed through as-is + cs = pattern.substr(classStart + 1) + sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + hasMagic = hasMagic || sp[1] + } - if (_isArray15) { - if (_i15 >= _iterator15.length) break; - _ref35 = _iterator15[_i15++]; - } else { - _i15 = _iterator15.next(); - if (_i15.done) break; - _ref35 = _i15.value; + // handle the case where we had a +( thing at the *end* + // of the pattern. + // each pattern list stack adds 3 chars, and we need to go through + // and escape any | chars that were passed through as-is for the regexp. + // Go through and escape them, taking care not to double-escape any + // | chars that were already escaped. + for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { + var tail = re.slice(pl.reStart + pl.open.length) + this.debug('setting tail', re, pl) + // maybe some even number of \, then maybe 1 \, followed by a | + tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { + if (!$2) { + // the | isn't already escaped, so escape it. + $2 = '\\' } - const path = _ref35; - - try { - const fd = yield open(path, 'r'); - return (_fs || _load_fs()).default.createReadStream(path, { fd }); - } catch (err) { - // Try the next one - } - } - return null; - }); + // need to escape all those slashes *again*, without escaping the + // one that we need for escaping the | character. As it works out, + // escaping an even number of slashes can be done by simply repeating + // it exactly after itself. That's why this trick works. + // + // I am sorry that you have to see this. + return $1 + $1 + $2 + '|' + }) - return function readFirstAvailableStream(_x34) { - return _ref34.apply(this, arguments); - }; -})(); + this.debug('tail=%j\n %s', tail, tail, pl, re) + var t = pl.type === '*' ? star + : pl.type === '?' ? qmark + : '\\' + pl.type -let getFirstSuitableFolder = exports.getFirstSuitableFolder = (() => { - var _ref36 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (paths, mode = constants.W_OK | constants.X_OK) { - const result = { - skipped: [], - folder: null - }; + hasMagic = true + re = re.slice(0, pl.reStart) + t + '\\(' + tail + } - for (var _iterator16 = paths, _isArray16 = Array.isArray(_iterator16), _i16 = 0, _iterator16 = _isArray16 ? _iterator16 : _iterator16[Symbol.iterator]();;) { - var _ref37; + // handle trailing things that only matter at the very end. + clearStateChar() + if (escaping) { + // trailing \\ + re += '\\\\' + } - if (_isArray16) { - if (_i16 >= _iterator16.length) break; - _ref37 = _iterator16[_i16++]; - } else { - _i16 = _iterator16.next(); - if (_i16.done) break; - _ref37 = _i16.value; - } + // only need to apply the nodot start if the re starts with + // something that could conceivably capture a dot + var addPatternStart = false + switch (re.charAt(0)) { + case '.': + case '[': + case '(': addPatternStart = true + } - const folder = _ref37; + // Hack to work around lack of negative lookbehind in JS + // A pattern like: *.!(x).!(y|z) needs to ensure that a name + // like 'a.xyz.yz' doesn't match. So, the first negative + // lookahead, has to look ALL the way ahead, to the end of + // the pattern. + for (var n = negativeLists.length - 1; n > -1; n--) { + var nl = negativeLists[n] - try { - yield mkdirp(folder); - yield access(folder, mode); + var nlBefore = re.slice(0, nl.reStart) + var nlFirst = re.slice(nl.reStart, nl.reEnd - 8) + var nlLast = re.slice(nl.reEnd - 8, nl.reEnd) + var nlAfter = re.slice(nl.reEnd) - result.folder = folder; + nlLast += nlAfter - return result; - } catch (error) { - result.skipped.push({ - error, - folder - }); - } + // Handle nested stuff like *(*.js|!(*.json)), where open parens + // mean that we should *not* include the ) in the bit that is considered + // "after" the negated section. + var openParensBefore = nlBefore.split('(').length - 1 + var cleanAfter = nlAfter + for (i = 0; i < openParensBefore; i++) { + cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') } - return result; - }); + nlAfter = cleanAfter - return function getFirstSuitableFolder(_x35) { - return _ref36.apply(this, arguments); - }; -})(); + var dollar = '' + if (nlAfter === '' && isSub !== SUBPARSE) { + dollar = '$' + } + var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast + re = newRe + } -exports.copy = copy; -exports.readFile = readFile; -exports.readFileRaw = readFileRaw; -exports.normalizeOS = normalizeOS; + // if the re is not "" at this point, then we need to make sure + // it doesn't match against an empty path part. + // Otherwise a/* will match a/, which it should not. + if (re !== '' && hasMagic) { + re = '(?=.)' + re + } -var _fs; + if (addPatternStart) { + re = patternStart + re + } -function _load_fs() { - return _fs = _interopRequireDefault(__webpack_require__(3)); -} + // parsing just a piece of a larger pattern. + if (isSub === SUBPARSE) { + return [re, hasMagic] + } -var _glob; + // skip the regexp for non-magical patterns + // unescape anything in it, though, so that it'll be + // an exact match against a file etc. + if (!hasMagic) { + return globUnescape(pattern) + } -function _load_glob() { - return _glob = _interopRequireDefault(__webpack_require__(75)); -} + var flags = options.nocase ? 'i' : '' + try { + var regExp = new RegExp('^' + re + '$', flags) + } catch (er) { + // If it was an invalid regular expression, then it can't match + // anything. This trick looks for a character after the end of + // the string, which is of course impossible, except in multi-line + // mode, but it's not a /m regex. + return new RegExp('$.') + } -var _os; + regExp._glob = pattern + regExp._src = re -function _load_os() { - return _os = _interopRequireDefault(__webpack_require__(36)); + return regExp } -var _path; - -function _load_path() { - return _path = _interopRequireDefault(__webpack_require__(0)); +minimatch.makeRe = function (pattern, options) { + return new Minimatch(pattern, options || {}).makeRe() } -var _blockingQueue; +Minimatch.prototype.makeRe = makeRe +function makeRe () { + if (this.regexp || this.regexp === false) return this.regexp -function _load_blockingQueue() { - return _blockingQueue = _interopRequireDefault(__webpack_require__(84)); -} + // at this point, this.set is a 2d array of partial + // pattern strings, or "**". + // + // It's better to use .match(). This function shouldn't + // be used, really, but it's pretty convenient sometimes, + // when you just want to work with a regex. + var set = this.set -var _promise; + if (!set.length) { + this.regexp = false + return this.regexp + } + var options = this.options -function _load_promise() { - return _promise = _interopRequireWildcard(__webpack_require__(40)); -} + var twoStar = options.noglobstar ? star + : options.dot ? twoStarDot + : twoStarNoDot + var flags = options.nocase ? 'i' : '' -var _promise2; + var re = set.map(function (pattern) { + return pattern.map(function (p) { + return (p === GLOBSTAR) ? twoStar + : (typeof p === 'string') ? regExpEscape(p) + : p._src + }).join('\\\/') + }).join('|') -function _load_promise2() { - return _promise2 = __webpack_require__(40); -} + // must match entire pattern + // ending in a * or ** will make it less strict. + re = '^(?:' + re + ')$' -var _map; + // can match anything, as long as it's not this. + if (this.negate) re = '^(?!' + re + ').*$' -function _load_map() { - return _map = _interopRequireDefault(__webpack_require__(20)); + try { + this.regexp = new RegExp(re, flags) + } catch (ex) { + this.regexp = false + } + return this.regexp } -var _fsNormalized; - -function _load_fsNormalized() { - return _fsNormalized = __webpack_require__(164); +minimatch.match = function (list, pattern, options) { + options = options || {} + var mm = new Minimatch(pattern, options) + list = list.filter(function (f) { + return mm.match(f) + }) + if (mm.options.nonull && !list.length) { + list.push(pattern) + } + return list } -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; } } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const constants = exports.constants = typeof (_fs || _load_fs()).default.constants !== 'undefined' ? (_fs || _load_fs()).default.constants : { - R_OK: (_fs || _load_fs()).default.R_OK, - W_OK: (_fs || _load_fs()).default.W_OK, - X_OK: (_fs || _load_fs()).default.X_OK -}; - -const lockQueue = exports.lockQueue = new (_blockingQueue || _load_blockingQueue()).default('fs lock'); - -const readFileBuffer = exports.readFileBuffer = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.readFile); -const open = exports.open = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.open); -const writeFile = exports.writeFile = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.writeFile); -const readlink = exports.readlink = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.readlink); -const realpath = exports.realpath = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.realpath); -const readdir = exports.readdir = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.readdir); -const rename = exports.rename = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.rename); -const access = exports.access = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.access); -const stat = exports.stat = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.stat); -const mkdirp = exports.mkdirp = (0, (_promise2 || _load_promise2()).promisify)(__webpack_require__(116)); -const exists = exports.exists = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.exists, true); -const lstat = exports.lstat = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.lstat); -const chmod = exports.chmod = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.chmod); -const link = exports.link = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.link); -const glob = exports.glob = (0, (_promise2 || _load_promise2()).promisify)((_glob || _load_glob()).default); -exports.unlink = (_fsNormalized || _load_fsNormalized()).unlink; +Minimatch.prototype.match = match +function match (f, partial) { + this.debug('match', f, this.pattern) + // short-circuit in the case of busted things. + // comments, etc. + if (this.comment) return false + if (this.empty) return f === '' -// fs.copyFile uses the native file copying instructions on the system, performing much better -// than any JS-based solution and consumes fewer resources. Repeated testing to fine tune the -// concurrency level revealed 128 as the sweet spot on a quad-core, 16 CPU Intel system with SSD. + if (f === '/' && partial) return true -const CONCURRENT_QUEUE_ITEMS = (_fs || _load_fs()).default.copyFile ? 128 : 4; + var options = this.options -const fsSymlink = (0, (_promise2 || _load_promise2()).promisify)((_fs || _load_fs()).default.symlink); -const invariant = __webpack_require__(7); -const stripBOM = __webpack_require__(122); + // windows: need to use /, not \ + if (path.sep !== '/') { + f = f.split(path.sep).join('/') + } -const noop = () => {}; + // treat the test path as a set of pathparts. + f = f.split(slashSplit) + this.debug(this.pattern, 'split', f) -function copy(src, dest, reporter) { - return copyBulk([{ src, dest }], reporter); -} + // just ONE of the pattern sets in this.set needs to match + // in order for it to be valid. If negating, then just one + // match means that we have failed. + // Either way, return on the first hit. -function _readFile(loc, encoding) { - return new Promise((resolve, reject) => { - (_fs || _load_fs()).default.readFile(loc, encoding, function (err, content) { - if (err) { - reject(err); - } else { - resolve(content); - } - }); - }); -} + var set = this.set + this.debug(this.pattern, 'set', set) -function readFile(loc) { - return _readFile(loc, 'utf8').then(normalizeOS); -} + // Find the basename of the path by looking for the last non-empty segment + var filename + var i + for (i = f.length - 1; i >= 0; i--) { + filename = f[i] + if (filename) break + } -function readFileRaw(loc) { - return _readFile(loc, 'binary'); -} + for (i = 0; i < set.length; i++) { + var pattern = set[i] + var file = f + if (options.matchBase && pattern.length === 1) { + file = [filename] + } + var hit = this.matchOne(file, pattern, partial) + if (hit) { + if (options.flipNegate) return true + return !this.negate + } + } -function normalizeOS(body) { - return body.replace(/\r\n/g, '\n'); + // didn't get any hits. this is success if it's a negative + // pattern, failure otherwise. + if (options.flipNegate) return false + return this.negate } -const cr = '\r'.charCodeAt(0); -const lf = '\n'.charCodeAt(0); - -/***/ }), -/* 6 */ -/***/ (function(module, exports, __webpack_require__) { +// set partial to true to test if, for example, +// "/a/b" matches the start of "/*/b/*/d" +// Partial means, if you run out of file before you run +// out of pattern, then that's fine, as long as all +// the parts match. +Minimatch.prototype.matchOne = function (file, pattern, partial) { + var options = this.options -"use strict"; + this.debug('matchOne', + { 'this': this, file: file, pattern: pattern }) + this.debug('matchOne', file.length, pattern.length) -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.getPathKey = getPathKey; -const os = __webpack_require__(36); -const path = __webpack_require__(0); -const userHome = __webpack_require__(45).default; + for (var fi = 0, + pi = 0, + fl = file.length, + pl = pattern.length + ; (fi < fl) && (pi < pl) + ; fi++, pi++) { + this.debug('matchOne loop') + var p = pattern[pi] + var f = file[fi] -var _require = __webpack_require__(171); + this.debug(pattern, p, f) -const getCacheDir = _require.getCacheDir, - getConfigDir = _require.getConfigDir, - getDataDir = _require.getDataDir; + // should be impossible. + // some invalid regexp stuff in the set. + if (p === false) return false -const isWebpackBundle = __webpack_require__(227); + if (p === GLOBSTAR) { + this.debug('GLOBSTAR', [pattern, p, f]) -const DEPENDENCY_TYPES = exports.DEPENDENCY_TYPES = ['devDependencies', 'dependencies', 'optionalDependencies', 'peerDependencies']; -const RESOLUTIONS = exports.RESOLUTIONS = 'resolutions'; -const MANIFEST_FIELDS = exports.MANIFEST_FIELDS = [RESOLUTIONS, ...DEPENDENCY_TYPES]; + // "**" + // a/**/b/**/c would match the following: + // a/b/x/y/z/c + // a/x/y/z/b/c + // a/b/x/b/x/c + // a/b/c + // To do this, take the rest of the pattern after + // the **, and see if it would match the file remainder. + // If so, return success. + // If not, the ** "swallows" a segment, and try again. + // This is recursively awful. + // + // a/**/b/**/c matching a/b/x/y/z/c + // - a matches a + // - doublestar + // - matchOne(b/x/y/z/c, b/**/c) + // - b matches b + // - doublestar + // - matchOne(x/y/z/c, c) -> no + // - matchOne(y/z/c, c) -> no + // - matchOne(z/c, c) -> no + // - matchOne(c, c) yes, hit + var fr = fi + var pr = pi + 1 + if (pr === pl) { + this.debug('** at the end') + // a ** at the end will just swallow the rest. + // We have found a match. + // however, it will not swallow /.x, unless + // options.dot is set. + // . and .. are *never* matched by **, for explosively + // exponential reasons. + for (; fi < fl; fi++) { + if (file[fi] === '.' || file[fi] === '..' || + (!options.dot && file[fi].charAt(0) === '.')) return false + } + return true + } -const SUPPORTED_NODE_VERSIONS = exports.SUPPORTED_NODE_VERSIONS = '^4.8.0 || ^5.7.0 || ^6.2.2 || >=8.0.0'; + // ok, let's see if we can swallow whatever we can. + while (fr < fl) { + var swallowee = file[fr] -const YARN_REGISTRY = exports.YARN_REGISTRY = 'https://registry.yarnpkg.com'; + this.debug('\nglobstar while', file, fr, pattern, pr, swallowee) -const YARN_DOCS = exports.YARN_DOCS = 'https://yarnpkg.com/en/docs/cli/'; -const YARN_INSTALLER_SH = exports.YARN_INSTALLER_SH = 'https://yarnpkg.com/install.sh'; -const YARN_INSTALLER_MSI = exports.YARN_INSTALLER_MSI = 'https://yarnpkg.com/latest.msi'; + // XXX remove this slice. Just pass the start index. + if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { + this.debug('globstar found match!', fr, fl, swallowee) + // found a match. + return true + } else { + // can't swallow "." or ".." ever. + // can only swallow ".foo" when explicitly asked. + if (swallowee === '.' || swallowee === '..' || + (!options.dot && swallowee.charAt(0) === '.')) { + this.debug('dot detected!', file, fr, pattern, pr) + break + } -const SELF_UPDATE_VERSION_URL = exports.SELF_UPDATE_VERSION_URL = 'https://yarnpkg.com/latest-version'; + // ** swallows a segment, and continue. + this.debug('globstar swallow a segment, and continue') + fr++ + } + } -// cache version, bump whenever we make backwards incompatible changes -const CACHE_VERSION = exports.CACHE_VERSION = 2; + // no match was found. + // However, in partial mode, we can't say this is necessarily over. + // If there's more *pattern* left, then + if (partial) { + // ran out of file + this.debug('\n>>> no match, partial?', file, fr, pattern, pr) + if (fr === fl) return true + } + return false + } -// lockfile version, bump whenever we make backwards incompatible changes -const LOCKFILE_VERSION = exports.LOCKFILE_VERSION = 1; + // something other than ** + // non-magic patterns just have to match exactly + // patterns with magic have been turned into regexps. + var hit + if (typeof p === 'string') { + if (options.nocase) { + hit = f.toLowerCase() === p.toLowerCase() + } else { + hit = f === p + } + this.debug('string match', p, f, hit) + } else { + hit = f.match(p) + this.debug('pattern match', p, f, hit) + } -// max amount of network requests to perform concurrently -const NETWORK_CONCURRENCY = exports.NETWORK_CONCURRENCY = 8; + if (!hit) return false + } -// HTTP timeout used when downloading packages -const NETWORK_TIMEOUT = exports.NETWORK_TIMEOUT = 30 * 1000; // in milliseconds + // Note: ending in / means that we'll get a final "" + // at the end of the pattern. This can only match a + // corresponding "" at the end of the file. + // If the file ends in /, then it can only match a + // a pattern that ends in /, unless the pattern just + // doesn't have any more for it. But, a/b/ should *not* + // match "a/b/*", even though "" matches against the + // [^/]*? pattern, except in partial mode, where it might + // simply not be reached yet. + // However, a/b/ should still satisfy a/* -// max amount of child processes to execute concurrently -const CHILD_CONCURRENCY = exports.CHILD_CONCURRENCY = 5; + // now either we fell off the end of the pattern, or we're done. + if (fi === fl && pi === pl) { + // ran out of pattern and filename at the same time. + // an exact hit! + return true + } else if (fi === fl) { + // ran out of file, but still had pattern left. + // this is ok if we're doing the match as part of + // a glob fs traversal. + return partial + } else if (pi === pl) { + // ran out of pattern, still have file left. + // this is only acceptable if we're on the very last + // empty segment of a file with a trailing slash. + // a/* should match a/b/ + var emptyFileEnd = (fi === fl - 1) && (file[fi] === '') + return emptyFileEnd + } -const REQUIRED_PACKAGE_KEYS = exports.REQUIRED_PACKAGE_KEYS = ['name', 'version', '_uid']; + // should be unreachable. + throw new Error('wtf?') +} -function getPreferredCacheDirectories() { - const preferredCacheDirectories = [getCacheDir()]; +// replace stuff like \* with * +function globUnescape (s) { + return s.replace(/\\(.)/g, '$1') +} - if (process.getuid) { - // $FlowFixMe: process.getuid exists, dammit - preferredCacheDirectories.push(path.join(os.tmpdir(), `.yarn-cache-${process.getuid()}`)); - } +function regExpEscape (s) { + return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') +} - preferredCacheDirectories.push(path.join(os.tmpdir(), `.yarn-cache`)); - return preferredCacheDirectories; -} +/***/ }), +/* 61 */ +/***/ (function(module, exports, __webpack_require__) { -const PREFERRED_MODULE_CACHE_DIRECTORIES = exports.PREFERRED_MODULE_CACHE_DIRECTORIES = getPreferredCacheDirectories(); -const CONFIG_DIRECTORY = exports.CONFIG_DIRECTORY = getConfigDir(); -const DATA_DIRECTORY = exports.DATA_DIRECTORY = getDataDir(); -const LINK_REGISTRY_DIRECTORY = exports.LINK_REGISTRY_DIRECTORY = path.join(DATA_DIRECTORY, 'link'); -const GLOBAL_MODULE_DIRECTORY = exports.GLOBAL_MODULE_DIRECTORY = path.join(DATA_DIRECTORY, 'global'); +var wrappy = __webpack_require__(123) +module.exports = wrappy(once) +module.exports.strict = wrappy(onceStrict) -const NODE_BIN_PATH = exports.NODE_BIN_PATH = process.execPath; -const YARN_BIN_PATH = exports.YARN_BIN_PATH = getYarnBinPath(); +once.proto = once(function () { + Object.defineProperty(Function.prototype, 'once', { + value: function () { + return once(this) + }, + configurable: true + }) -// Webpack needs to be configured with node.__dirname/__filename = false -function getYarnBinPath() { - if (isWebpackBundle) { - return __filename; - } else { - return path.join(__dirname, '..', 'bin', 'yarn.js'); + Object.defineProperty(Function.prototype, 'onceStrict', { + value: function () { + return onceStrict(this) + }, + configurable: true + }) +}) + +function once (fn) { + var f = function () { + if (f.called) return f.value + f.called = true + return f.value = fn.apply(this, arguments) } + f.called = false + return f } -const NODE_MODULES_FOLDER = exports.NODE_MODULES_FOLDER = 'node_modules'; -const NODE_PACKAGE_JSON = exports.NODE_PACKAGE_JSON = 'package.json'; +function onceStrict (fn) { + var f = function () { + if (f.called) + throw new Error(f.onceError) + f.called = true + return f.value = fn.apply(this, arguments) + } + var name = fn.name || 'Function wrapped with `once`' + f.onceError = name + " shouldn't be called more than once" + f.called = false + return f +} -const POSIX_GLOBAL_PREFIX = exports.POSIX_GLOBAL_PREFIX = `${process.env.DESTDIR || ''}/usr/local`; -const FALLBACK_GLOBAL_PREFIX = exports.FALLBACK_GLOBAL_PREFIX = path.join(userHome, '.yarn'); -const META_FOLDER = exports.META_FOLDER = '.yarn-meta'; -const INTEGRITY_FILENAME = exports.INTEGRITY_FILENAME = '.yarn-integrity'; -const LOCKFILE_FILENAME = exports.LOCKFILE_FILENAME = 'yarn.lock'; -const METADATA_FILENAME = exports.METADATA_FILENAME = '.yarn-metadata.json'; -const TARBALL_FILENAME = exports.TARBALL_FILENAME = '.yarn-tarball.tgz'; -const CLEAN_FILENAME = exports.CLEAN_FILENAME = '.yarnclean'; +/***/ }), +/* 62 */, +/* 63 */ +/***/ (function(module, exports) { -const NPM_LOCK_FILENAME = exports.NPM_LOCK_FILENAME = 'package-lock.json'; -const NPM_SHRINKWRAP_FILENAME = exports.NPM_SHRINKWRAP_FILENAME = 'npm-shrinkwrap.json'; +module.exports = __webpack_require__(277); -const DEFAULT_INDENT = exports.DEFAULT_INDENT = ' '; -const SINGLE_INSTANCE_PORT = exports.SINGLE_INSTANCE_PORT = 31997; -const SINGLE_INSTANCE_FILENAME = exports.SINGLE_INSTANCE_FILENAME = '.yarn-single-instance'; +/***/ }), +/* 64 */, +/* 65 */, +/* 66 */, +/* 67 */ +/***/ (function(module, exports) { -const ENV_PATH_KEY = exports.ENV_PATH_KEY = getPathKey(process.platform, process.env); +// 7.2.1 RequireObjectCoercible(argument) +module.exports = function (it) { + if (it == undefined) throw TypeError("Can't call method on " + it); + return it; +}; -function getPathKey(platform, env) { - let pathKey = 'PATH'; - // windows calls its path "Path" usually, but this is not guaranteed. - if (platform === 'win32') { - pathKey = 'Path'; +/***/ }), +/* 68 */ +/***/ (function(module, exports, __webpack_require__) { - for (const key in env) { - if (key.toLowerCase() === 'path') { - pathKey = key; - } - } - } +var isObject = __webpack_require__(34); +var document = __webpack_require__(11).document; +// typeof document.createElement is 'object' in old IE +var is = isObject(document) && isObject(document.createElement); +module.exports = function (it) { + return is ? document.createElement(it) : {}; +}; - return pathKey; -} -const VERSION_COLOR_SCHEME = exports.VERSION_COLOR_SCHEME = { - major: 'red', - premajor: 'red', - minor: 'yellow', - preminor: 'yellow', - patch: 'green', - prepatch: 'green', - prerelease: 'red', - unchanged: 'white', - unknown: 'red' -}; +/***/ }), +/* 69 */ +/***/ (function(module, exports) { + +module.exports = true; + /***/ }), -/* 7 */ +/* 70 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/** - * Copyright (c) 2013-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ +// 25.4.1.5 NewPromiseCapability(C) +var aFunction = __webpack_require__(46); +function PromiseCapability(C) { + var resolve, reject; + this.promise = new C(function ($$resolve, $$reject) { + if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor'); + resolve = $$resolve; + reject = $$reject; + }); + this.resolve = aFunction(resolve); + this.reject = aFunction(reject); +} -/** - * Use invariant() to assert state which your program assumes to be true. - * - * Provide sprintf-style format (only %s is supported) and arguments - * to provide information about what broke and what you were - * expecting. - * - * The invariant message will be stripped in production, but the invariant - * will remain to ensure logic does not differ in production. - */ +module.exports.f = function (C) { + return new PromiseCapability(C); +}; -var NODE_ENV = "none"; -var invariant = function(condition, format, a, b, c, d, e, f) { - if (NODE_ENV !== 'production') { - if (format === undefined) { - throw new Error('invariant requires an error message argument'); - } - } +/***/ }), +/* 71 */ +/***/ (function(module, exports, __webpack_require__) { - if (!condition) { - var error; - if (format === undefined) { - error = new Error( - 'Minified exception occurred; use the non-minified dev environment ' + - 'for the full error message and additional helpful warnings.' - ); - } else { - var args = [a, b, c, d, e, f]; - var argIndex = 0; - error = new Error( - format.replace(/%s/g, function() { return args[argIndex++]; }) - ); - error.name = 'Invariant Violation'; - } +var def = __webpack_require__(50).f; +var has = __webpack_require__(49); +var TAG = __webpack_require__(13)('toStringTag'); - error.framesToPop = 1; // we don't care about invariant's own frame - throw error; - } +module.exports = function (it, tag, stat) { + if (it && !has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { configurable: true, value: tag }); }; -module.exports = invariant; - /***/ }), -/* 8 */, -/* 9 */ -/***/ (function(module, exports) { +/* 72 */ +/***/ (function(module, exports, __webpack_require__) { + +var shared = __webpack_require__(107)('keys'); +var uid = __webpack_require__(111); +module.exports = function (key) { + return shared[key] || (shared[key] = uid(key)); +}; -module.exports = __webpack_require__(282); /***/ }), -/* 10 */, -/* 11 */ +/* 73 */ /***/ (function(module, exports) { -// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 -var global = module.exports = typeof window != 'undefined' && window.Math == Math - ? window : typeof self != 'undefined' && self.Math == Math ? self - // eslint-disable-next-line no-new-func - : Function('return this')(); -if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef +// 7.1.4 ToInteger +var ceil = Math.ceil; +var floor = Math.floor; +module.exports = function (it) { + return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it); +}; /***/ }), -/* 12 */ +/* 74 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - +// to indexed object, toObject with fallback for non-array-like ES3 strings +var IObject = __webpack_require__(131); +var defined = __webpack_require__(67); +module.exports = function (it) { + return IObject(defined(it)); +}; -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.sortAlpha = sortAlpha; -exports.entries = entries; -exports.removePrefix = removePrefix; -exports.removeSuffix = removeSuffix; -exports.addSuffix = addSuffix; -exports.hyphenate = hyphenate; -exports.camelCase = camelCase; -exports.compareSortedArrays = compareSortedArrays; -exports.sleep = sleep; -const _camelCase = __webpack_require__(176); -function sortAlpha(a, b) { - // sort alphabetically in a deterministic way - const shortLen = Math.min(a.length, b.length); - for (let i = 0; i < shortLen; i++) { - const aChar = a.charCodeAt(i); - const bChar = b.charCodeAt(i); - if (aChar !== bChar) { - return aChar - bChar; - } - } - return a.length - b.length; -} +/***/ }), +/* 75 */ +/***/ (function(module, exports, __webpack_require__) { -function entries(obj) { - const entries = []; - if (obj) { - for (const key in obj) { - entries.push([key, obj[key]]); - } - } - return entries; -} +// Approach: +// +// 1. Get the minimatch set +// 2. For each pattern in the set, PROCESS(pattern, false) +// 3. Store matches per-set, then uniq them +// +// PROCESS(pattern, inGlobStar) +// Get the first [n] items from pattern that are all strings +// Join these together. This is PREFIX. +// If there is no more remaining, then stat(PREFIX) and +// add to matches if it succeeds. END. +// +// If inGlobStar and PREFIX is symlink and points to dir +// set ENTRIES = [] +// else readdir(PREFIX) as ENTRIES +// If fail, END +// +// with ENTRIES +// If pattern[n] is GLOBSTAR +// // handle the case where the globstar match is empty +// // by pruning it out, and testing the resulting pattern +// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) +// // handle other cases. +// for ENTRY in ENTRIES (not dotfiles) +// // attach globstar + tail onto the entry +// // Mark that this entry is a globstar match +// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) +// +// else // not globstar +// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) +// Test ENTRY against pattern[n] +// If fails, continue +// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) +// +// Caveat: +// Cache all stats and readdirs results to minimize syscall. Since all +// we ever care about is existence and directory-ness, we can just keep +// `true` for files, and [children,...] for directories, or `false` for +// things that don't exist. -function removePrefix(pattern, prefix) { - if (pattern.startsWith(prefix)) { - pattern = pattern.slice(prefix.length); - } +module.exports = glob - return pattern; -} +var fs = __webpack_require__(3) +var rp = __webpack_require__(114) +var minimatch = __webpack_require__(60) +var Minimatch = minimatch.Minimatch +var inherits = __webpack_require__(42) +var EE = __webpack_require__(54).EventEmitter +var path = __webpack_require__(0) +var assert = __webpack_require__(22) +var isAbsolute = __webpack_require__(76) +var globSync = __webpack_require__(218) +var common = __webpack_require__(115) +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var inflight = __webpack_require__(223) +var util = __webpack_require__(2) +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored -function removeSuffix(pattern, suffix) { - if (pattern.endsWith(suffix)) { - return pattern.slice(0, -suffix.length); - } +var once = __webpack_require__(61) - return pattern; -} +function glob (pattern, options, cb) { + if (typeof options === 'function') cb = options, options = {} + if (!options) options = {} -function addSuffix(pattern, suffix) { - if (!pattern.endsWith(suffix)) { - return pattern + suffix; + if (options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return globSync(pattern, options) } - return pattern; + return new Glob(pattern, options, cb) } -function hyphenate(str) { - return str.replace(/[A-Z]/g, match => { - return '-' + match.charAt(0).toLowerCase(); - }); -} +glob.sync = globSync +var GlobSync = glob.GlobSync = globSync.GlobSync -function camelCase(str) { - if (/[A-Z]/.test(str)) { - return null; - } else { - return _camelCase(str); - } -} +// old api surface +glob.glob = glob -function compareSortedArrays(array1, array2) { - if (array1.length !== array2.length) { - return false; - } - for (let i = 0, len = array1.length; i < len; i++) { - if (array1[i] !== array2[i]) { - return false; - } +function extend (origin, add) { + if (add === null || typeof add !== 'object') { + return origin } - return true; -} -function sleep(ms) { - return new Promise(resolve => { - setTimeout(resolve, ms); - }); + var keys = Object.keys(add) + var i = keys.length + while (i--) { + origin[keys[i]] = add[keys[i]] + } + return origin } -/***/ }), -/* 13 */ -/***/ (function(module, exports, __webpack_require__) { +glob.hasMagic = function (pattern, options_) { + var options = extend({}, options_) + options.noprocess = true -var store = __webpack_require__(107)('wks'); -var uid = __webpack_require__(111); -var Symbol = __webpack_require__(11).Symbol; -var USE_SYMBOL = typeof Symbol == 'function'; + var g = new Glob(pattern, options) + var set = g.minimatch.set -var $exports = module.exports = function (name) { - return store[name] || (store[name] = - USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name)); -}; + if (!pattern) + return false -$exports.store = store; + if (set.length > 1) + return true + for (var j = 0; j < set[0].length; j++) { + if (typeof set[0][j] !== 'string') + return true + } -/***/ }), -/* 14 */ -/***/ (function(module, exports, __webpack_require__) { + return false +} -"use strict"; +glob.Glob = Glob +inherits(Glob, EE) +function Glob (pattern, options, cb) { + if (typeof options === 'function') { + cb = options + options = null + } + if (options && options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return new GlobSync(pattern, options) + } -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.stringify = exports.parse = undefined; + if (!(this instanceof Glob)) + return new Glob(pattern, options, cb) -var _asyncToGenerator2; + setopts(this, pattern, options) + this._didRealPath = false -function _load_asyncToGenerator() { - return _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(1)); -} - -var _parse; + // process each pattern in the minimatch set + var n = this.minimatch.set.length -function _load_parse() { - return _parse = __webpack_require__(81); -} + // The matches are stored as {: true,...} so that + // duplicates are automagically pruned. + // Later, we do an Object.keys() on these. + // Keep them as a list so we can fill in when nonull is set. + this.matches = new Array(n) -Object.defineProperty(exports, 'parse', { - enumerable: true, - get: function get() { - return _interopRequireDefault(_parse || _load_parse()).default; + if (typeof cb === 'function') { + cb = once(cb) + this.on('error', cb) + this.on('end', function (matches) { + cb(null, matches) + }) } -}); - -var _stringify; -function _load_stringify() { - return _stringify = __webpack_require__(150); -} + var self = this + this._processing = 0 -Object.defineProperty(exports, 'stringify', { - enumerable: true, - get: function get() { - return _interopRequireDefault(_stringify || _load_stringify()).default; - } -}); -exports.implodeEntry = implodeEntry; -exports.explodeEntry = explodeEntry; + this._emitQueue = [] + this._processQueue = [] + this.paused = false -var _misc; + if (this.noprocess) + return this -function _load_misc() { - return _misc = __webpack_require__(12); -} + if (n === 0) + return done() -var _normalizePattern; + var sync = true + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false, done) + } + sync = false -function _load_normalizePattern() { - return _normalizePattern = __webpack_require__(29); + function done () { + --self._processing + if (self._processing <= 0) { + if (sync) { + process.nextTick(function () { + self._finish() + }) + } else { + self._finish() + } + } + } } -var _parse2; +Glob.prototype._finish = function () { + assert(this instanceof Glob) + if (this.aborted) + return -function _load_parse2() { - return _parse2 = _interopRequireDefault(__webpack_require__(81)); + if (this.realpath && !this._didRealpath) + return this._realpath() + + common.finish(this) + this.emit('end', this.found) } -var _constants; +Glob.prototype._realpath = function () { + if (this._didRealpath) + return -function _load_constants() { - return _constants = __webpack_require__(6); -} + this._didRealpath = true -var _fs; + var n = this.matches.length + if (n === 0) + return this._finish() -function _load_fs() { - return _fs = _interopRequireWildcard(__webpack_require__(5)); + var self = this + for (var i = 0; i < this.matches.length; i++) + this._realpathSet(i, next) + + function next () { + if (--n === 0) + self._finish() + } } -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; } } +Glob.prototype._realpathSet = function (index, cb) { + var matchset = this.matches[index] + if (!matchset) + return cb() -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + var found = Object.keys(matchset) + var self = this + var n = found.length -const invariant = __webpack_require__(7); + if (n === 0) + return cb() -const path = __webpack_require__(0); -const ssri = __webpack_require__(55); + var set = this.matches[index] = Object.create(null) + found.forEach(function (p, i) { + // If there's a problem with the stat, then it means that + // one or more of the links in the realpath couldn't be + // resolved. just return the abs value in that case. + p = self._makeAbs(p) + rp.realpath(p, self.realpathCache, function (er, real) { + if (!er) + set[real] = true + else if (er.syscall === 'stat') + set[p] = true + else + self.emit('error', er) // srsly wtf right here -function getName(pattern) { - return (0, (_normalizePattern || _load_normalizePattern()).normalizePattern)(pattern).name; + if (--n === 0) { + self.matches[index] = set + cb() + } + }) + }) } -function blankObjectUndefined(obj) { - return obj && Object.keys(obj).length ? obj : undefined; +Glob.prototype._mark = function (p) { + return common.mark(this, p) } -function keyForRemote(remote) { - return remote.resolved || (remote.reference && remote.hash ? `${remote.reference}#${remote.hash}` : null); +Glob.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) } -function serializeIntegrity(integrity) { - // We need this because `Integrity.toString()` does not use sorting to ensure a stable string output - // See https://git.io/vx2Hy - return integrity.toString().split(' ').sort().join(' '); +Glob.prototype.abort = function () { + this.aborted = true + this.emit('abort') } -function implodeEntry(pattern, obj) { - const inferredName = getName(pattern); - const integrity = obj.integrity ? serializeIntegrity(obj.integrity) : ''; - const imploded = { - name: inferredName === obj.name ? undefined : obj.name, - version: obj.version, - uid: obj.uid === obj.version ? undefined : obj.uid, - resolved: obj.resolved, - registry: obj.registry === 'npm' ? undefined : obj.registry, - dependencies: blankObjectUndefined(obj.dependencies), - optionalDependencies: blankObjectUndefined(obj.optionalDependencies), - permissions: blankObjectUndefined(obj.permissions), - prebuiltVariants: blankObjectUndefined(obj.prebuiltVariants) - }; - if (integrity) { - imploded.integrity = integrity; +Glob.prototype.pause = function () { + if (!this.paused) { + this.paused = true + this.emit('pause') } - return imploded; } -function explodeEntry(pattern, obj) { - obj.optionalDependencies = obj.optionalDependencies || {}; - obj.dependencies = obj.dependencies || {}; - obj.uid = obj.uid || obj.version; - obj.permissions = obj.permissions || {}; - obj.registry = obj.registry || 'npm'; - obj.name = obj.name || getName(pattern); - const integrity = obj.integrity; - if (integrity && integrity.isIntegrity) { - obj.integrity = ssri.parse(integrity); +Glob.prototype.resume = function () { + if (this.paused) { + this.emit('resume') + this.paused = false + if (this._emitQueue.length) { + var eq = this._emitQueue.slice(0) + this._emitQueue.length = 0 + for (var i = 0; i < eq.length; i ++) { + var e = eq[i] + this._emitMatch(e[0], e[1]) + } + } + if (this._processQueue.length) { + var pq = this._processQueue.slice(0) + this._processQueue.length = 0 + for (var i = 0; i < pq.length; i ++) { + var p = pq[i] + this._processing-- + this._process(p[0], p[1], p[2], p[3]) + } + } } - return obj; } -class Lockfile { - constructor({ cache, source, parseResultType } = {}) { - this.source = source || ''; - this.cache = cache; - this.parseResultType = parseResultType; - } - - // source string if the `cache` was parsed - - - // if true, we're parsing an old yarn file and need to update integrity fields - hasEntriesExistWithoutIntegrity() { - if (!this.cache) { - return false; - } +Glob.prototype._process = function (pattern, index, inGlobStar, cb) { + assert(this instanceof Glob) + assert(typeof cb === 'function') - for (const key in this.cache) { - // $FlowFixMe - `this.cache` is clearly defined at this point - if (!/^.*@(file:|http)/.test(key) && this.cache[key] && !this.cache[key].integrity) { - return true; - } - } + if (this.aborted) + return - return false; + this._processing++ + if (this.paused) { + this._processQueue.push([pattern, index, inGlobStar, cb]) + return } - static fromDirectory(dir, reporter) { - return (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* () { - // read the manifest in this directory - const lockfileLoc = path.join(dir, (_constants || _load_constants()).LOCKFILE_FILENAME); - - let lockfile; - let rawLockfile = ''; - let parseResult; + //console.error('PROCESS %d', this._processing, pattern) - if (yield (_fs || _load_fs()).exists(lockfileLoc)) { - rawLockfile = yield (_fs || _load_fs()).readFile(lockfileLoc); - parseResult = (0, (_parse2 || _load_parse2()).default)(rawLockfile, lockfileLoc); + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. - if (reporter) { - if (parseResult.type === 'merge') { - reporter.info(reporter.lang('lockfileMerged')); - } else if (parseResult.type === 'conflict') { - reporter.warn(reporter.lang('lockfileConflict')); - } - } + // see if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index, cb) + return - lockfile = parseResult.object; - } else if (reporter) { - reporter.info(reporter.lang('noLockfileFound')); - } + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break - return new Lockfile({ cache: lockfile, source: rawLockfile, parseResultType: parseResult && parseResult.type }); - })(); + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break } - getLocked(pattern) { - const cache = this.cache; - if (!cache) { - return undefined; - } + var remain = pattern.slice(n) - const shrunk = pattern in cache && cache[pattern]; + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix - if (typeof shrunk === 'string') { - return this.getLocked(shrunk); - } else if (shrunk) { - explodeEntry(pattern, shrunk); - return shrunk; - } + var abs = this._makeAbs(read) - return undefined; - } + //if ignored, skip _processing + if (childrenIgnored(this, read)) + return cb() - removePattern(pattern) { - const cache = this.cache; - if (!cache) { - return; - } - delete cache[pattern]; - } + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) +} - getLockfile(patterns) { - const lockfile = {}; - const seen = new Map(); +Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} - // order by name so that lockfile manifest is assigned to the first dependency with this manifest - // the others that have the same remoteKey will just refer to the first - // ordering allows for consistency in lockfile when it is serialized - const sortedPatternsKeys = Object.keys(patterns).sort((_misc || _load_misc()).sortAlpha); +Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { - for (var _iterator = sortedPatternsKeys, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { - var _ref; + // if the abs isn't a dir, then nothing can match! + if (!entries) + return cb() - if (_isArray) { - if (_i >= _iterator.length) break; - _ref = _iterator[_i++]; + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) } else { - _i = _iterator.next(); - if (_i.done) break; - _ref = _i.value; + m = e.match(pn) } + if (m) + matchedEntries.push(e) + } + } - const pattern = _ref; + //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) - const pkg = patterns[pattern]; - const remote = pkg._remote, - ref = pkg._reference; + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return cb() - invariant(ref, 'Package is missing a reference'); - invariant(remote, 'Package is missing a remote'); + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. - const remoteKey = keyForRemote(remote); - const seenPattern = remoteKey && seen.get(remoteKey); - if (seenPattern) { - // no point in duplicating it - lockfile[pattern] = seenPattern; + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) - // if we're relying on our name being inferred and two of the patterns have - // different inferred names then we need to set it - if (!seenPattern.name && getName(pattern) !== pkg.name) { - seenPattern.name = pkg.name; - } - continue; + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e } - const obj = implodeEntry(pattern, { - name: pkg.name, - version: pkg.version, - uid: pkg._uid, - resolved: remote.resolved, - integrity: remote.integrity, - registry: remote.registry, - dependencies: pkg.dependencies, - peerDependencies: pkg.peerDependencies, - optionalDependencies: pkg.optionalDependencies, - permissions: ref.permissions, - prebuiltVariants: pkg.prebuiltVariants - }); - lockfile[pattern] = obj; - - if (remoteKey) { - seen.set(remoteKey, obj); + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) } + this._emitMatch(index, e) } + // This was the last one, and no stats were needed + return cb() + } - return lockfile; + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + this._process([e].concat(remain), index, inGlobStar, cb) } + cb() } -exports.default = Lockfile; - -/***/ }), -/* 15 */, -/* 16 */, -/* 17 */ -/***/ (function(module, exports) { -module.exports = __webpack_require__(137); - -/***/ }), -/* 18 */, -/* 19 */, -/* 20 */ -/***/ (function(module, exports, __webpack_require__) { +Glob.prototype._emitMatch = function (index, e) { + if (this.aborted) + return -"use strict"; + if (isIgnored(this, e)) + return + if (this.paused) { + this._emitQueue.push([index, e]) + return + } -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = nullify; -function nullify(obj = {}) { - if (Array.isArray(obj)) { - for (var _iterator = obj, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { - var _ref; + var abs = isAbsolute(e) ? e : this._makeAbs(e) - if (_isArray) { - if (_i >= _iterator.length) break; - _ref = _iterator[_i++]; - } else { - _i = _iterator.next(); - if (_i.done) break; - _ref = _i.value; - } + if (this.mark) + e = this._mark(e) - const item = _ref; + if (this.absolute) + e = abs - nullify(item); - } - } else if (obj !== null && typeof obj === 'object' || typeof obj === 'function') { - Object.setPrototypeOf(obj, null); + if (this.matches[index][e]) + return - // for..in can only be applied to 'object', not 'function' - if (typeof obj === 'object') { - for (const key in obj) { - nullify(obj[key]); - } - } + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return } - return obj; -} + this.matches[index][e] = true -/***/ }), -/* 21 */, -/* 22 */ -/***/ (function(module, exports) { + var st = this.statCache[abs] + if (st) + this.emit('stat', e, st) -module.exports = __webpack_require__(139); + this.emit('match', e) +} -/***/ }), -/* 23 */ -/***/ (function(module, exports) { +Glob.prototype._readdirInGlobStar = function (abs, cb) { + if (this.aborted) + return -var core = module.exports = { version: '2.5.7' }; -if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false, cb) + var lstatkey = 'lstat\0' + abs + var self = this + var lstatcb = inflight(lstatkey, lstatcb_) -/***/ }), -/* 24 */, -/* 25 */, -/* 26 */, -/* 27 */ -/***/ (function(module, exports, __webpack_require__) { + if (lstatcb) + fs.lstat(abs, lstatcb) -var isObject = __webpack_require__(34); -module.exports = function (it) { - if (!isObject(it)) throw TypeError(it + ' is not an object!'); - return it; -}; + function lstatcb_ (er, lstat) { + if (er && er.code === 'ENOENT') + return cb() + var isSym = lstat && lstat.isSymbolicLink() + self.symlinks[abs] = isSym -/***/ }), -/* 28 */, -/* 29 */ -/***/ (function(module, exports, __webpack_require__) { + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && lstat && !lstat.isDirectory()) { + self.cache[abs] = 'FILE' + cb() + } else + self._readdir(abs, false, cb) + } +} -"use strict"; +Glob.prototype._readdir = function (abs, inGlobStar, cb) { + if (this.aborted) + return + cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) + if (!cb) + return -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.normalizePattern = normalizePattern; + //console.error('RD %j %j', +inGlobStar, abs) + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs, cb) -/** - * Explode and normalize a pattern into its name and range. - */ + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return cb() -function normalizePattern(pattern) { - let hasVersion = false; - let range = 'latest'; - let name = pattern; + if (Array.isArray(c)) + return cb(null, c) + } - // if we're a scope then remove the @ and add it back later - let isScoped = false; - if (name[0] === '@') { - isScoped = true; - name = name.slice(1); + var self = this + fs.readdir(abs, readdirCb(this, abs, cb)) +} + +function readdirCb (self, abs, cb) { + return function (er, entries) { + if (er) + self._readdirError(abs, er, cb) + else + self._readdirEntries(abs, entries, cb) } +} - // take first part as the name - const parts = name.split('@'); - if (parts.length > 1) { - name = parts.shift(); - range = parts.join('@'); +Glob.prototype._readdirEntries = function (abs, entries, cb) { + if (this.aborted) + return - if (range) { - hasVersion = true; - } else { - range = '*'; + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true } } - // add back @ scope suffix - if (isScoped) { - name = `@${name}`; + this.cache[abs] = entries + return cb(null, entries) +} + +Glob.prototype._readdirError = function (f, er, cb) { + if (this.aborted) + return + + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + var abs = this._makeAbs(f) + this.cache[abs] = 'FILE' + if (abs === this.cwdAbs) { + var error = new Error(er.code + ' invalid cwd ' + this.cwd) + error.path = this.cwd + error.code = er.code + this.emit('error', error) + this.abort() + } + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) { + this.emit('error', er) + // If the error is handled, then we abort + // if not, we threw out of here + this.abort() + } + if (!this.silent) + console.error('glob error', er) + break } - return { name, range, hasVersion }; + return cb() } -/***/ }), -/* 30 */, -/* 31 */ -/***/ (function(module, exports, __webpack_require__) { +Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} -var dP = __webpack_require__(50); -var createDesc = __webpack_require__(106); -module.exports = __webpack_require__(33) ? function (object, key, value) { - return dP.f(object, key, createDesc(1, value)); -} : function (object, key, value) { - object[key] = value; - return object; -}; +Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + //console.error('pgs2', prefix, remain[0], entries) -/***/ }), -/* 32 */ -/***/ (function(module, exports, __webpack_require__) { + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return cb() -/* eslint-disable node/no-deprecated-api */ -var buffer = __webpack_require__(63) -var Buffer = buffer.Buffer + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) -// alternative to using Object.keys for old browsers -function copyProps (src, dst) { - for (var key in src) { - dst[key] = src[key] + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false, cb) + + var isSym = this.symlinks[abs] + var len = entries.length + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return cb() + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true, cb) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true, cb) } -} -if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { - module.exports = buffer -} else { - // Copy properties from require('buffer') - copyProps(buffer, exports) - exports.Buffer = SafeBuffer + + cb() } -function SafeBuffer (arg, encodingOrOffset, length) { - return Buffer(arg, encodingOrOffset, length) +Glob.prototype._processSimple = function (prefix, index, cb) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var self = this + this._stat(prefix, function (er, exists) { + self._processSimple2(prefix, index, er, exists, cb) + }) } +Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { -// Copy static methods from Buffer -copyProps(Buffer, SafeBuffer) + //console.error('ps2', prefix, exists) -SafeBuffer.from = function (arg, encodingOrOffset, length) { - if (typeof arg === 'number') { - throw new TypeError('Argument must not be a number') + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return cb() + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } } - return Buffer(arg, encodingOrOffset, length) + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this._emitMatch(index, prefix) + cb() } -SafeBuffer.alloc = function (size, fill, encoding) { - if (typeof size !== 'number') { - throw new TypeError('Argument must be a number') +// Returns either 'DIR', 'FILE', or false +Glob.prototype._stat = function (f, cb) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return cb() + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return cb(null, c) + + if (needDir && c === 'FILE') + return cb() + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. } - var buf = Buffer(size) - if (fill !== undefined) { - if (typeof encoding === 'string') { - buf.fill(fill, encoding) - } else { - buf.fill(fill) + + var exists + var stat = this.statCache[abs] + if (stat !== undefined) { + if (stat === false) + return cb(null, stat) + else { + var type = stat.isDirectory() ? 'DIR' : 'FILE' + if (needDir && type === 'FILE') + return cb() + else + return cb(null, type, stat) } - } else { - buf.fill(0) } - return buf -} -SafeBuffer.allocUnsafe = function (size) { - if (typeof size !== 'number') { - throw new TypeError('Argument must be a number') + var self = this + var statcb = inflight('stat\0' + abs, lstatcb_) + if (statcb) + fs.lstat(abs, statcb) + + function lstatcb_ (er, lstat) { + if (lstat && lstat.isSymbolicLink()) { + // If it's a symlink, then treat it as the target, unless + // the target does not exist, then treat it as a file. + return fs.stat(abs, function (er, stat) { + if (er) + self._stat2(f, abs, null, lstat, cb) + else + self._stat2(f, abs, er, stat, cb) + }) + } else { + self._stat2(f, abs, er, lstat, cb) + } } - return Buffer(size) } -SafeBuffer.allocUnsafeSlow = function (size) { - if (typeof size !== 'number') { - throw new TypeError('Argument must be a number') +Glob.prototype._stat2 = function (f, abs, er, stat, cb) { + if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { + this.statCache[abs] = false + return cb() } - return buffer.SlowBuffer(size) + + var needDir = f.slice(-1) === '/' + this.statCache[abs] = stat + + if (abs.slice(-1) === '/' && stat && !stat.isDirectory()) + return cb(null, false, stat) + + var c = true + if (stat) + c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c === 'FILE') + return cb() + + return cb(null, c, stat) } /***/ }), -/* 33 */ +/* 76 */ /***/ (function(module, exports, __webpack_require__) { -// Thank's IE8 for his funny defineProperty -module.exports = !__webpack_require__(85)(function () { - return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7; -}); - +"use strict"; -/***/ }), -/* 34 */ -/***/ (function(module, exports) { -module.exports = function (it) { - return typeof it === 'object' ? it !== null : typeof it === 'function'; -}; +function posix(path) { + return path.charAt(0) === '/'; +} +function win32(path) { + // https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56 + var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; + var result = splitDeviceRe.exec(path); + var device = result[1] || ''; + var isUnc = Boolean(device && device.charAt(1) !== ':'); -/***/ }), -/* 35 */ -/***/ (function(module, exports) { + // UNC paths are always absolute + return Boolean(result[2] || isUnc); +} -module.exports = {}; +module.exports = process.platform === 'win32' ? win32 : posix; +module.exports.posix = posix; +module.exports.win32 = win32; /***/ }), -/* 36 */ +/* 77 */, +/* 78 */, +/* 79 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(120); +module.exports = __webpack_require__(122); /***/ }), -/* 37 */, -/* 38 */, -/* 39 */, -/* 40 */ +/* 80 */, +/* 81 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -31453,11068 +32396,10574 @@ module.exports = __webpack_require__(120); Object.defineProperty(exports, "__esModule", { value: true }); -exports.wait = wait; -exports.promisify = promisify; -exports.queue = queue; -function wait(delay) { - return new Promise(resolve => { - setTimeout(resolve, delay); - }); -} -function promisify(fn, firstData) { - return function (...args) { - return new Promise(function (resolve, reject) { - args.push(function (err, ...result) { - let res = result; +exports.default = function (str, fileLoc = 'lockfile') { + str = (0, (_stripBom || _load_stripBom()).default)(str); + return hasMergeConflicts(str) ? parseWithConflict(str, fileLoc) : { type: 'success', object: parse(str, fileLoc) }; +}; - if (result.length <= 1) { - res = result[0]; - } +var _util; - if (firstData) { - res = err; - err = null; - } +function _load_util() { + return _util = _interopRequireDefault(__webpack_require__(2)); +} - if (err) { - reject(err); - } else { - resolve(res); - } - }); +var _invariant; - fn.apply(null, args); - }); - }; +function _load_invariant() { + return _invariant = _interopRequireDefault(__webpack_require__(7)); } -function queue(arr, promiseProducer, concurrency = Infinity) { - concurrency = Math.min(concurrency, arr.length); +var _stripBom; - // clone - arr = arr.slice(); +function _load_stripBom() { + return _stripBom = _interopRequireDefault(__webpack_require__(122)); +} - const results = []; - let total = arr.length; - if (!total) { - return Promise.resolve(results); - } +var _constants; - return new Promise((resolve, reject) => { - for (let i = 0; i < concurrency; i++) { - next(); - } +function _load_constants() { + return _constants = __webpack_require__(6); +} - function next() { - const item = arr.shift(); - const promise = promiseProducer(item); +var _errors; - promise.then(function (result) { - results.push(result); +function _load_errors() { + return _errors = __webpack_require__(4); +} - total--; - if (total === 0) { - resolve(results); - } else { - if (arr.length) { - next(); - } - } - }, reject); - } - }); +var _map; + +function _load_map() { + return _map = _interopRequireDefault(__webpack_require__(20)); } -/***/ }), -/* 41 */ -/***/ (function(module, exports, __webpack_require__) { +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -var global = __webpack_require__(11); -var core = __webpack_require__(23); -var ctx = __webpack_require__(48); -var hide = __webpack_require__(31); -var has = __webpack_require__(49); -var PROTOTYPE = 'prototype'; +/* eslint quotes: 0 */ -var $export = function (type, name, source) { - var IS_FORCED = type & $export.F; - var IS_GLOBAL = type & $export.G; - var IS_STATIC = type & $export.S; - var IS_PROTO = type & $export.P; - var IS_BIND = type & $export.B; - var IS_WRAP = type & $export.W; - var exports = IS_GLOBAL ? core : core[name] || (core[name] = {}); - var expProto = exports[PROTOTYPE]; - var target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE]; - var key, own, out; - if (IS_GLOBAL) source = name; - for (key in source) { - // contains in native - own = !IS_FORCED && target && target[key] !== undefined; - if (own && has(exports, key)) continue; - // export native or passed - out = own ? target[key] : source[key]; - // prevent global pollution for namespaces - exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key] - // bind timers to global for call from export context - : IS_BIND && own ? ctx(out, global) - // wrap global constructors for prevent change them in library - : IS_WRAP && target[key] == out ? (function (C) { - var F = function (a, b, c) { - if (this instanceof C) { - switch (arguments.length) { - case 0: return new C(); - case 1: return new C(a); - case 2: return new C(a, b); - } return new C(a, b, c); - } return C.apply(this, arguments); - }; - F[PROTOTYPE] = C[PROTOTYPE]; - return F; - // make static versions for prototype methods - })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out; - // export proto methods to core.%CONSTRUCTOR%.methods.%NAME% - if (IS_PROTO) { - (exports.virtual || (exports.virtual = {}))[key] = out; - // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME% - if (type & $export.R && expProto && !expProto[key]) hide(expProto, key, out); - } - } -}; -// type bitmap -$export.F = 1; // forced -$export.G = 2; // global -$export.S = 4; // static -$export.P = 8; // proto -$export.B = 16; // bind -$export.W = 32; // wrap -$export.U = 64; // safe -$export.R = 128; // real proto method for `library` -module.exports = $export; +const VERSION_REGEX = /^yarn lockfile v(\d+)$/; +const TOKEN_TYPES = { + boolean: 'BOOLEAN', + string: 'STRING', + identifier: 'IDENTIFIER', + eof: 'EOF', + colon: 'COLON', + newline: 'NEWLINE', + comment: 'COMMENT', + indent: 'INDENT', + invalid: 'INVALID', + number: 'NUMBER', + comma: 'COMMA' +}; -/***/ }), -/* 42 */ -/***/ (function(module, exports, __webpack_require__) { +const VALID_PROP_VALUE_TOKENS = [TOKEN_TYPES.boolean, TOKEN_TYPES.string, TOKEN_TYPES.number]; -try { - var util = __webpack_require__(2); - if (typeof util.inherits !== 'function') throw ''; - module.exports = util.inherits; -} catch (e) { - module.exports = __webpack_require__(224); +function isValidPropValueToken(token) { + return VALID_PROP_VALUE_TOKENS.indexOf(token.type) >= 0; } +function* tokenise(input) { + let lastNewline = false; + let line = 1; + let col = 0; -/***/ }), -/* 43 */, -/* 44 */, -/* 45 */ -/***/ (function(module, exports, __webpack_require__) { + function buildToken(type, value) { + return { line, col, type, value }; + } -"use strict"; + while (input.length) { + let chop = 0; + if (input[0] === '\n' || input[0] === '\r') { + chop++; + // If this is a \r\n line, ignore both chars but only add one new line + if (input[1] === '\n') { + chop++; + } + line++; + col = 0; + yield buildToken(TOKEN_TYPES.newline); + } else if (input[0] === '#') { + chop++; -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.home = undefined; + let val = ''; + while (input[chop] !== '\n') { + val += input[chop]; + chop++; + } + yield buildToken(TOKEN_TYPES.comment, val); + } else if (input[0] === ' ') { + if (lastNewline) { + let indent = ''; + for (let i = 0; input[i] === ' '; i++) { + indent += input[i]; + } -var _rootUser; + if (indent.length % 2) { + throw new TypeError('Invalid number of spaces'); + } else { + chop = indent.length; + yield buildToken(TOKEN_TYPES.indent, indent.length / 2); + } + } else { + chop++; + } + } else if (input[0] === '"') { + let val = ''; -function _load_rootUser() { - return _rootUser = _interopRequireDefault(__webpack_require__(169)); -} + for (let i = 0;; i++) { + const currentChar = input[i]; + val += currentChar; -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + if (i > 0 && currentChar === '"') { + const isEscaped = input[i - 1] === '\\' && input[i - 2] !== '\\'; + if (!isEscaped) { + break; + } + } + } -const path = __webpack_require__(0); + chop = val.length; -const home = exports.home = __webpack_require__(36).homedir(); + try { + yield buildToken(TOKEN_TYPES.string, JSON.parse(val)); + } catch (err) { + if (err instanceof SyntaxError) { + yield buildToken(TOKEN_TYPES.invalid); + } else { + throw err; + } + } + } else if (/^[0-9]/.test(input)) { + let val = ''; + for (let i = 0; /^[0-9]$/.test(input[i]); i++) { + val += input[i]; + } + chop = val.length; -const userHomeDir = (_rootUser || _load_rootUser()).default ? path.resolve('/usr/local/share') : home; + yield buildToken(TOKEN_TYPES.number, +val); + } else if (/^true/.test(input)) { + yield buildToken(TOKEN_TYPES.boolean, true); + chop = 4; + } else if (/^false/.test(input)) { + yield buildToken(TOKEN_TYPES.boolean, false); + chop = 5; + } else if (input[0] === ':') { + yield buildToken(TOKEN_TYPES.colon); + chop++; + } else if (input[0] === ',') { + yield buildToken(TOKEN_TYPES.comma); + chop++; + } else if (/^[a-zA-Z\/-]/g.test(input)) { + let name = ''; + for (let i = 0; i < input.length; i++) { + const char = input[i]; + if (char === ':' || char === ' ' || char === '\n' || char === '\r' || char === ',') { + break; + } else { + name += char; + } + } + chop = name.length; -exports.default = userHomeDir; + yield buildToken(TOKEN_TYPES.string, name); + } else { + yield buildToken(TOKEN_TYPES.invalid); + } -/***/ }), -/* 46 */ -/***/ (function(module, exports) { + if (!chop) { + // will trigger infinite recursion + yield buildToken(TOKEN_TYPES.invalid); + } -module.exports = function (it) { - if (typeof it != 'function') throw TypeError(it + ' is not a function!'); - return it; -}; + col += chop; + lastNewline = input[0] === '\n' || input[0] === '\r' && input[1] === '\n'; + input = input.slice(chop); + } + yield buildToken(TOKEN_TYPES.eof); +} -/***/ }), -/* 47 */ -/***/ (function(module, exports) { +class Parser { + constructor(input, fileLoc = 'lockfile') { + this.comments = []; + this.tokens = tokenise(input); + this.fileLoc = fileLoc; + } -var toString = {}.toString; + onComment(token) { + const value = token.value; + (0, (_invariant || _load_invariant()).default)(typeof value === 'string', 'expected token value to be a string'); -module.exports = function (it) { - return toString.call(it).slice(8, -1); -}; + const comment = value.trim(); + const versionMatch = comment.match(VERSION_REGEX); + if (versionMatch) { + const version = +versionMatch[1]; + if (version > (_constants || _load_constants()).LOCKFILE_VERSION) { + throw new (_errors || _load_errors()).MessageError(`Can't install from a lockfile of version ${version} as you're on an old yarn version that only supports ` + `versions up to ${(_constants || _load_constants()).LOCKFILE_VERSION}. Run \`$ yarn self-update\` to upgrade to the latest version.`); + } + } -/***/ }), -/* 48 */ -/***/ (function(module, exports, __webpack_require__) { + this.comments.push(comment); + } -// optional / simple context binding -var aFunction = __webpack_require__(46); -module.exports = function (fn, that, length) { - aFunction(fn); - if (that === undefined) return fn; - switch (length) { - case 1: return function (a) { - return fn.call(that, a); - }; - case 2: return function (a, b) { - return fn.call(that, a, b); - }; - case 3: return function (a, b, c) { - return fn.call(that, a, b, c); - }; + next() { + const item = this.tokens.next(); + (0, (_invariant || _load_invariant()).default)(item, 'expected a token'); + + const done = item.done, + value = item.value; + + if (done || !value) { + throw new Error('No more tokens'); + } else if (value.type === TOKEN_TYPES.comment) { + this.onComment(value); + return this.next(); + } else { + return this.token = value; + } } - return function (/* ...args */) { - return fn.apply(that, arguments); - }; -}; + unexpected(msg = 'Unexpected token') { + throw new SyntaxError(`${msg} ${this.token.line}:${this.token.col} in ${this.fileLoc}`); + } -/***/ }), -/* 49 */ -/***/ (function(module, exports) { + expect(tokType) { + if (this.token.type === tokType) { + this.next(); + } else { + this.unexpected(); + } + } -var hasOwnProperty = {}.hasOwnProperty; -module.exports = function (it, key) { - return hasOwnProperty.call(it, key); -}; + eat(tokType) { + if (this.token.type === tokType) { + this.next(); + return true; + } else { + return false; + } + } + parse(indent = 0) { + const obj = (0, (_map || _load_map()).default)(); -/***/ }), -/* 50 */ -/***/ (function(module, exports, __webpack_require__) { + while (true) { + const propToken = this.token; -var anObject = __webpack_require__(27); -var IE8_DOM_DEFINE = __webpack_require__(184); -var toPrimitive = __webpack_require__(201); -var dP = Object.defineProperty; + if (propToken.type === TOKEN_TYPES.newline) { + const nextToken = this.next(); + if (!indent) { + // if we have 0 indentation then the next token doesn't matter + continue; + } -exports.f = __webpack_require__(33) ? Object.defineProperty : function defineProperty(O, P, Attributes) { - anObject(O); - P = toPrimitive(P, true); - anObject(Attributes); - if (IE8_DOM_DEFINE) try { - return dP(O, P, Attributes); - } catch (e) { /* empty */ } - if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!'); - if ('value' in Attributes) O[P] = Attributes.value; - return O; -}; + if (nextToken.type !== TOKEN_TYPES.indent) { + // if we have no indentation after a newline then we've gone down a level + break; + } + if (nextToken.value === indent) { + // all is good, the indent is on our level + this.next(); + } else { + // the indentation is less than our level + break; + } + } else if (propToken.type === TOKEN_TYPES.indent) { + if (propToken.value === indent) { + this.next(); + } else { + break; + } + } else if (propToken.type === TOKEN_TYPES.eof) { + break; + } else if (propToken.type === TOKEN_TYPES.string) { + // property key + const key = propToken.value; + (0, (_invariant || _load_invariant()).default)(key, 'Expected a key'); -/***/ }), -/* 51 */, -/* 52 */, -/* 53 */, -/* 54 */ -/***/ (function(module, exports) { + const keys = [key]; + this.next(); -module.exports = __webpack_require__(155); + // support multiple keys + while (this.token.type === TOKEN_TYPES.comma) { + this.next(); // skip comma -/***/ }), -/* 55 */ -/***/ (function(module, exports, __webpack_require__) { + const keyToken = this.token; + if (keyToken.type !== TOKEN_TYPES.string) { + this.unexpected('Expected string'); + } -"use strict"; + const key = keyToken.value; + (0, (_invariant || _load_invariant()).default)(key, 'Expected a key'); + keys.push(key); + this.next(); + } + const valToken = this.token; -const Buffer = __webpack_require__(32).Buffer + if (valToken.type === TOKEN_TYPES.colon) { + // object + this.next(); -const crypto = __webpack_require__(9) -const Transform = __webpack_require__(17).Transform + // parse object + const val = this.parse(indent + 1); -const SPEC_ALGORITHMS = ['sha256', 'sha384', 'sha512'] + for (var _iterator = keys, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { + var _ref; -const BASE64_REGEX = /^[a-z0-9+/]+(?:=?=?)$/i -const SRI_REGEX = /^([^-]+)-([^?]+)([?\S*]*)$/ -const STRICT_SRI_REGEX = /^([^-]+)-([A-Za-z0-9+/=]{44,88})(\?[\x21-\x7E]*)*$/ -const VCHAR_REGEX = /^[\x21-\x7E]+$/ + if (_isArray) { + if (_i >= _iterator.length) break; + _ref = _iterator[_i++]; + } else { + _i = _iterator.next(); + if (_i.done) break; + _ref = _i.value; + } -class Hash { - get isHash () { return true } - constructor (hash, opts) { - const strict = !!(opts && opts.strict) - this.source = hash.trim() - // 3.1. Integrity metadata (called "Hash" by ssri) - // https://w3c.github.io/webappsec-subresource-integrity/#integrity-metadata-description - const match = this.source.match( - strict - ? STRICT_SRI_REGEX - : SRI_REGEX - ) - if (!match) { return } - if (strict && !SPEC_ALGORITHMS.some(a => a === match[1])) { return } - this.algorithm = match[1] - this.digest = match[2] + const key = _ref; - const rawOpts = match[3] - this.options = rawOpts ? rawOpts.slice(1).split('?') : [] - } - hexDigest () { - return this.digest && Buffer.from(this.digest, 'base64').toString('hex') - } - toJSON () { - return this.toString() - } - toString (opts) { - if (opts && opts.strict) { - // Strict mode enforces the standard as close to the foot of the - // letter as it can. - if (!( - // The spec has very restricted productions for algorithms. - // https://www.w3.org/TR/CSP2/#source-list-syntax - SPEC_ALGORITHMS.some(x => x === this.algorithm) && - // Usually, if someone insists on using a "different" base64, we - // leave it as-is, since there's multiple standards, and the - // specified is not a URL-safe variant. - // https://www.w3.org/TR/CSP2/#base64_value - this.digest.match(BASE64_REGEX) && - // Option syntax is strictly visual chars. - // https://w3c.github.io/webappsec-subresource-integrity/#grammardef-option-expression - // https://tools.ietf.org/html/rfc5234#appendix-B.1 - (this.options || []).every(opt => opt.match(VCHAR_REGEX)) - )) { - return '' + obj[key] = val; + } + + if (indent && this.token.type !== TOKEN_TYPES.indent) { + break; + } + } else if (isValidPropValueToken(valToken)) { + // plain value + for (var _iterator2 = keys, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { + var _ref2; + + if (_isArray2) { + if (_i2 >= _iterator2.length) break; + _ref2 = _iterator2[_i2++]; + } else { + _i2 = _iterator2.next(); + if (_i2.done) break; + _ref2 = _i2.value; + } + + const key = _ref2; + + obj[key] = valToken.value; + } + + this.next(); + } else { + this.unexpected('Invalid value type'); + } + } else { + this.unexpected(`Unknown token: ${(_util || _load_util()).default.inspect(propToken)}`); } } - const options = this.options && this.options.length - ? `?${this.options.join('?')}` - : '' - return `${this.algorithm}-${this.digest}${options}` + + return obj; } } -class Integrity { - get isIntegrity () { return true } - toJSON () { - return this.toString() - } - toString (opts) { - opts = opts || {} - let sep = opts.sep || ' ' - if (opts.strict) { - // Entries must be separated by whitespace, according to spec. - sep = sep.replace(/\S+/g, ' ') - } - return Object.keys(this).map(k => { - return this[k].map(hash => { - return Hash.prototype.toString.call(hash, opts) - }).filter(x => x.length).join(sep) - }).filter(x => x.length).join(sep) - } - concat (integrity, opts) { - const other = typeof integrity === 'string' - ? integrity - : stringify(integrity, opts) - return parse(`${this.toString(opts)} ${other}`, opts) - } - hexDigest () { - return parse(this, {single: true}).hexDigest() - } - match (integrity, opts) { - const other = parse(integrity, opts) - const algo = other.pickAlgorithm(opts) - return ( - this[algo] && - other[algo] && - this[algo].find(hash => - other[algo].find(otherhash => - hash.digest === otherhash.digest - ) - ) - ) || false - } - pickAlgorithm (opts) { - const pickAlgorithm = (opts && opts.pickAlgorithm) || getPrioritizedHash - const keys = Object.keys(this) - if (!keys.length) { - throw new Error(`No algorithms available for ${ - JSON.stringify(this.toString()) - }`) - } - return keys.reduce((acc, algo) => { - return pickAlgorithm(acc, algo) || acc - }) - } -} - -module.exports.parse = parse -function parse (sri, opts) { - opts = opts || {} - if (typeof sri === 'string') { - return _parse(sri, opts) - } else if (sri.algorithm && sri.digest) { - const fullSri = new Integrity() - fullSri[sri.algorithm] = [sri] - return _parse(stringify(fullSri, opts), opts) - } else { - return _parse(stringify(sri, opts), opts) - } -} - -function _parse (integrity, opts) { - // 3.4.3. Parse metadata - // https://w3c.github.io/webappsec-subresource-integrity/#parse-metadata - if (opts.single) { - return new Hash(integrity, opts) - } - return integrity.trim().split(/\s+/).reduce((acc, string) => { - const hash = new Hash(string, opts) - if (hash.algorithm && hash.digest) { - const algo = hash.algorithm - if (!acc[algo]) { acc[algo] = [] } - acc[algo].push(hash) - } - return acc - }, new Integrity()) -} - -module.exports.stringify = stringify -function stringify (obj, opts) { - if (obj.algorithm && obj.digest) { - return Hash.prototype.toString.call(obj, opts) - } else if (typeof obj === 'string') { - return stringify(parse(obj, opts), opts) - } else { - return Integrity.prototype.toString.call(obj, opts) - } -} - -module.exports.fromHex = fromHex -function fromHex (hexDigest, algorithm, opts) { - const optString = (opts && opts.options && opts.options.length) - ? `?${opts.options.join('?')}` - : '' - return parse( - `${algorithm}-${ - Buffer.from(hexDigest, 'hex').toString('base64') - }${optString}`, opts - ) -} +const MERGE_CONFLICT_ANCESTOR = '|||||||'; +const MERGE_CONFLICT_END = '>>>>>>>'; +const MERGE_CONFLICT_SEP = '======='; +const MERGE_CONFLICT_START = '<<<<<<<'; -module.exports.fromData = fromData -function fromData (data, opts) { - opts = opts || {} - const algorithms = opts.algorithms || ['sha512'] - const optString = opts.options && opts.options.length - ? `?${opts.options.join('?')}` - : '' - return algorithms.reduce((acc, algo) => { - const digest = crypto.createHash(algo).update(data).digest('base64') - const hash = new Hash( - `${algo}-${digest}${optString}`, - opts - ) - if (hash.algorithm && hash.digest) { - const algo = hash.algorithm - if (!acc[algo]) { acc[algo] = [] } - acc[algo].push(hash) - } - return acc - }, new Integrity()) -} +/** + * Extract the two versions of the lockfile from a merge conflict. + */ +function extractConflictVariants(str) { + const variants = [[], []]; + const lines = str.split(/\r?\n/g); + let skip = false; -module.exports.fromStream = fromStream -function fromStream (stream, opts) { - opts = opts || {} - const P = opts.Promise || Promise - const istream = integrityStream(opts) - return new P((resolve, reject) => { - stream.pipe(istream) - stream.on('error', reject) - istream.on('error', reject) - let sri - istream.on('integrity', s => { sri = s }) - istream.on('end', () => resolve(sri)) - istream.on('data', () => {}) - }) -} + while (lines.length) { + const line = lines.shift(); + if (line.startsWith(MERGE_CONFLICT_START)) { + // get the first variant + while (lines.length) { + const conflictLine = lines.shift(); + if (conflictLine === MERGE_CONFLICT_SEP) { + skip = false; + break; + } else if (skip || conflictLine.startsWith(MERGE_CONFLICT_ANCESTOR)) { + skip = true; + continue; + } else { + variants[0].push(conflictLine); + } + } -module.exports.checkData = checkData -function checkData (data, sri, opts) { - opts = opts || {} - sri = parse(sri, opts) - if (!Object.keys(sri).length) { - if (opts.error) { - throw Object.assign( - new Error('No valid integrity hashes to check against'), { - code: 'EINTEGRITY' + // get the second variant + while (lines.length) { + const conflictLine = lines.shift(); + if (conflictLine.startsWith(MERGE_CONFLICT_END)) { + break; + } else { + variants[1].push(conflictLine); } - ) + } } else { - return false + variants[0].push(line); + variants[1].push(line); } } - const algorithm = sri.pickAlgorithm(opts) - const digest = crypto.createHash(algorithm).update(data).digest('base64') - const newSri = parse({algorithm, digest}) - const match = newSri.match(sri, opts) - if (match || !opts.error) { - return match - } else if (typeof opts.size === 'number' && (data.length !== opts.size)) { - const err = new Error(`data size mismatch when checking ${sri}.\n Wanted: ${opts.size}\n Found: ${data.length}`) - err.code = 'EBADSIZE' - err.found = data.length - err.expected = opts.size - err.sri = sri - throw err - } else { - const err = new Error(`Integrity checksum failed when using ${algorithm}: Wanted ${sri}, but got ${newSri}. (${data.length} bytes)`) - err.code = 'EINTEGRITY' - err.found = newSri - err.expected = sri - err.algorithm = algorithm - err.sri = sri - throw err - } -} -module.exports.checkStream = checkStream -function checkStream (stream, sri, opts) { - opts = opts || {} - const P = opts.Promise || Promise - const checker = integrityStream(Object.assign({}, opts, { - integrity: sri - })) - return new P((resolve, reject) => { - stream.pipe(checker) - stream.on('error', reject) - checker.on('error', reject) - let sri - checker.on('verified', s => { sri = s }) - checker.on('end', () => resolve(sri)) - checker.on('data', () => {}) - }) + return [variants[0].join('\n'), variants[1].join('\n')]; } -module.exports.integrityStream = integrityStream -function integrityStream (opts) { - opts = opts || {} - // For verification - const sri = opts.integrity && parse(opts.integrity, opts) - const goodSri = sri && Object.keys(sri).length - const algorithm = goodSri && sri.pickAlgorithm(opts) - const digests = goodSri && sri[algorithm] - // Calculating stream - const algorithms = Array.from( - new Set( - (opts.algorithms || ['sha512']) - .concat(algorithm ? [algorithm] : []) - ) - ) - const hashes = algorithms.map(crypto.createHash) - let streamSize = 0 - const stream = new Transform({ - transform (chunk, enc, cb) { - streamSize += chunk.length - hashes.forEach(h => h.update(chunk, enc)) - cb(null, chunk, enc) - } - }).on('end', () => { - const optString = (opts.options && opts.options.length) - ? `?${opts.options.join('?')}` - : '' - const newSri = parse(hashes.map((h, i) => { - return `${algorithms[i]}-${h.digest('base64')}${optString}` - }).join(' '), opts) - // Integrity verification mode - const match = goodSri && newSri.match(sri, opts) - if (typeof opts.size === 'number' && streamSize !== opts.size) { - const err = new Error(`stream size mismatch when checking ${sri}.\n Wanted: ${opts.size}\n Found: ${streamSize}`) - err.code = 'EBADSIZE' - err.found = streamSize - err.expected = opts.size - err.sri = sri - stream.emit('error', err) - } else if (opts.integrity && !match) { - const err = new Error(`${sri} integrity checksum failed when using ${algorithm}: wanted ${digests} but got ${newSri}. (${streamSize} bytes)`) - err.code = 'EINTEGRITY' - err.found = newSri - err.expected = digests - err.algorithm = algorithm - err.sri = sri - stream.emit('error', err) - } else { - stream.emit('size', streamSize) - stream.emit('integrity', newSri) - match && stream.emit('verified', match) - } - }) - return stream +/** + * Check if a lockfile has merge conflicts. + */ +function hasMergeConflicts(str) { + return str.includes(MERGE_CONFLICT_START) && str.includes(MERGE_CONFLICT_SEP) && str.includes(MERGE_CONFLICT_END); } -module.exports.create = createIntegrity -function createIntegrity (opts) { - opts = opts || {} - const algorithms = opts.algorithms || ['sha512'] - const optString = opts.options && opts.options.length - ? `?${opts.options.join('?')}` - : '' - - const hashes = algorithms.map(crypto.createHash) - - return { - update: function (chunk, enc) { - hashes.forEach(h => h.update(chunk, enc)) - return this - }, - digest: function (enc) { - const integrity = algorithms.reduce((acc, algo) => { - const digest = hashes.shift().digest('base64') - const hash = new Hash( - `${algo}-${digest}${optString}`, - opts - ) - if (hash.algorithm && hash.digest) { - const algo = hash.algorithm - if (!acc[algo]) { acc[algo] = [] } - acc[algo].push(hash) - } - return acc - }, new Integrity()) +/** + * Parse the lockfile. + */ +function parse(str, fileLoc) { + const parser = new Parser(str, fileLoc); + parser.next(); + return parser.parse(); +} - return integrity +/** + * Parse and merge the two variants in a conflicted lockfile. + */ +function parseWithConflict(str, fileLoc) { + const variants = extractConflictVariants(str); + try { + return { type: 'merge', object: Object.assign({}, parse(variants[0], fileLoc), parse(variants[1], fileLoc)) }; + } catch (err) { + if (err instanceof SyntaxError) { + return { type: 'conflict', object: {} }; + } else { + throw err; } } } -const NODE_HASHES = new Set(crypto.getHashes()) - -// This is a Best Effort™ at a reasonable priority for hash algos -const DEFAULT_PRIORITY = [ - 'md5', 'whirlpool', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512', - // TODO - it's unclear _which_ of these Node will actually use as its name - // for the algorithm, so we guesswork it based on the OpenSSL names. - 'sha3', - 'sha3-256', 'sha3-384', 'sha3-512', - 'sha3_256', 'sha3_384', 'sha3_512' -].filter(algo => NODE_HASHES.has(algo)) - -function getPrioritizedHash (algo1, algo2) { - return DEFAULT_PRIORITY.indexOf(algo1.toLowerCase()) >= DEFAULT_PRIORITY.indexOf(algo2.toLowerCase()) - ? algo1 - : algo2 -} - - /***/ }), -/* 56 */, -/* 57 */, -/* 58 */, -/* 59 */, -/* 60 */ +/* 82 */, +/* 83 */, +/* 84 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = minimatch -minimatch.Minimatch = Minimatch - -var path = { sep: '/' } -try { - path = __webpack_require__(0) -} catch (er) {} - -var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} -var expand = __webpack_require__(175) +"use strict"; -var plTypes = { - '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, - '?': { open: '(?:', close: ')?' }, - '+': { open: '(?:', close: ')+' }, - '*': { open: '(?:', close: ')*' }, - '@': { open: '(?:', close: ')' } -} -// any single thing other than / -// don't need to escape / when using new RegExp() -var qmark = '[^/]' +Object.defineProperty(exports, "__esModule", { + value: true +}); -// * => any number of characters -var star = qmark + '*?' +var _map; -// ** when dots are allowed. Anything goes, except .. and . -// not (^ or / followed by one or two dots followed by $ or /), -// followed by anything, any number of times. -var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' +function _load_map() { + return _map = _interopRequireDefault(__webpack_require__(20)); +} -// not a ^ or / followed by a dot, -// followed by anything, any number of times. -var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } -// characters that need to be escaped in RegExp. -var reSpecials = charSet('().*{}+?[]^$\\!') +const debug = __webpack_require__(212)('yarn'); -// "abc" -> { a:true, b:true, c:true } -function charSet (s) { - return s.split('').reduce(function (set, c) { - set[c] = true - return set - }, {}) -} +class BlockingQueue { + constructor(alias, maxConcurrency = Infinity) { + this.concurrencyQueue = []; + this.maxConcurrency = maxConcurrency; + this.runningCount = 0; + this.warnedStuck = false; + this.alias = alias; + this.first = true; -// normalizes slashes. -var slashSplit = /\/+/ + this.running = (0, (_map || _load_map()).default)(); + this.queue = (0, (_map || _load_map()).default)(); -minimatch.filter = filter -function filter (pattern, options) { - options = options || {} - return function (p, i, list) { - return minimatch(p, pattern, options) + this.stuckTick = this.stuckTick.bind(this); } -} - -function ext (a, b) { - a = a || {} - b = b || {} - var t = {} - Object.keys(b).forEach(function (k) { - t[k] = b[k] - }) - Object.keys(a).forEach(function (k) { - t[k] = a[k] - }) - return t -} -minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return minimatch + stillActive() { + if (this.stuckTimer) { + clearTimeout(this.stuckTimer); + } - var orig = minimatch + this.stuckTimer = setTimeout(this.stuckTick, 5000); - var m = function minimatch (p, pattern, options) { - return orig.minimatch(p, pattern, ext(def, options)) + // We need to check the existence of unref because of https://github.com/facebook/jest/issues/4559 + // $FlowFixMe: Node's setInterval returns a Timeout, not a Number + this.stuckTimer.unref && this.stuckTimer.unref(); } - m.Minimatch = function Minimatch (pattern, options) { - return new orig.Minimatch(pattern, ext(def, options)) + stuckTick() { + if (this.runningCount === 1) { + this.warnedStuck = true; + debug(`The ${JSON.stringify(this.alias)} blocking queue may be stuck. 5 seconds ` + `without any activity with 1 worker: ${Object.keys(this.running)[0]}`); + } } - return m -} + push(key, factory) { + if (this.first) { + this.first = false; + } else { + this.stillActive(); + } -Minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return Minimatch - return minimatch.defaults(def).Minimatch -} + return new Promise((resolve, reject) => { + // we're already running so push ourselves to the queue + const queue = this.queue[key] = this.queue[key] || []; + queue.push({ factory, resolve, reject }); -function minimatch (p, pattern, options) { - if (typeof pattern !== 'string') { - throw new TypeError('glob pattern string required') + if (!this.running[key]) { + this.shift(key); + } + }); } - if (!options) options = {} + shift(key) { + if (this.running[key]) { + delete this.running[key]; + this.runningCount--; - // shortcut: comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - return false - } + if (this.stuckTimer) { + clearTimeout(this.stuckTimer); + this.stuckTimer = null; + } - // "" only matches "" - if (pattern.trim() === '') return p === '' + if (this.warnedStuck) { + this.warnedStuck = false; + debug(`${JSON.stringify(this.alias)} blocking queue finally resolved. Nothing to worry about.`); + } + } - return new Minimatch(pattern, options).match(p) -} + const queue = this.queue[key]; + if (!queue) { + return; + } -function Minimatch (pattern, options) { - if (!(this instanceof Minimatch)) { - return new Minimatch(pattern, options) - } + var _queue$shift = queue.shift(); - if (typeof pattern !== 'string') { - throw new TypeError('glob pattern string required') - } + const resolve = _queue$shift.resolve, + reject = _queue$shift.reject, + factory = _queue$shift.factory; - if (!options) options = {} - pattern = pattern.trim() + if (!queue.length) { + delete this.queue[key]; + } - // windows support: need to use /, not \ - if (path.sep !== '/') { - pattern = pattern.split(path.sep).join('/') - } + const next = () => { + this.shift(key); + this.shiftConcurrencyQueue(); + }; - this.options = options - this.set = [] - this.pattern = pattern - this.regexp = null - this.negate = false - this.comment = false - this.empty = false - - // make the set of regexps etc. - this.make() -} - -Minimatch.prototype.debug = function () {} + const run = () => { + this.running[key] = true; + this.runningCount++; -Minimatch.prototype.make = make -function make () { - // don't do it more than once. - if (this._made) return + factory().then(function (val) { + resolve(val); + next(); + return null; + }).catch(function (err) { + reject(err); + next(); + }); + }; - var pattern = this.pattern - var options = this.options + this.maybePushConcurrencyQueue(run); + } - // empty patterns and comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - this.comment = true - return + maybePushConcurrencyQueue(run) { + if (this.runningCount < this.maxConcurrency) { + run(); + } else { + this.concurrencyQueue.push(run); + } } - if (!pattern) { - this.empty = true - return + + shiftConcurrencyQueue() { + if (this.runningCount < this.maxConcurrency) { + const fn = this.concurrencyQueue.shift(); + if (fn) { + fn(); + } + } } +} +exports.default = BlockingQueue; - // step 1: figure out negation, etc. - this.parseNegate() +/***/ }), +/* 85 */ +/***/ (function(module, exports) { - // step 2: expand braces - var set = this.globSet = this.braceExpand() +module.exports = function (exec) { + try { + return !!exec(); + } catch (e) { + return true; + } +}; - if (options.debug) this.debug = console.error - this.debug(this.pattern, set) +/***/ }), +/* 86 */, +/* 87 */, +/* 88 */, +/* 89 */, +/* 90 */, +/* 91 */, +/* 92 */, +/* 93 */, +/* 94 */, +/* 95 */, +/* 96 */, +/* 97 */, +/* 98 */, +/* 99 */, +/* 100 */ +/***/ (function(module, exports, __webpack_require__) { - // step 3: now we have a set, so turn each one into a series of path-portion - // matching patterns. - // These will be regexps, except in the case of "**", which is - // set to the GLOBSTAR object for globstar behavior, - // and will not contain any / characters - set = this.globParts = set.map(function (s) { - return s.split(slashSplit) - }) +// getting tag from 19.1.3.6 Object.prototype.toString() +var cof = __webpack_require__(47); +var TAG = __webpack_require__(13)('toStringTag'); +// ES3 wrong here +var ARG = cof(function () { return arguments; }()) == 'Arguments'; - this.debug(this.pattern, set) +// fallback for IE11 Script Access Denied error +var tryGet = function (it, key) { + try { + return it[key]; + } catch (e) { /* empty */ } +}; - // glob --> regexps - set = set.map(function (s, si, set) { - return s.map(this.parse, this) - }, this) +module.exports = function (it) { + var O, T, B; + return it === undefined ? 'Undefined' : it === null ? 'Null' + // @@toStringTag case + : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T + // builtinTag case + : ARG ? cof(O) + // ES3 arguments fallback + : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B; +}; - this.debug(this.pattern, set) - // filter out everything that didn't compile properly. - set = set.filter(function (s) { - return s.indexOf(false) === -1 - }) +/***/ }), +/* 101 */ +/***/ (function(module, exports) { - this.debug(this.pattern, set) +// IE 8- don't enum bug keys +module.exports = ( + 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf' +).split(','); - this.set = set -} -Minimatch.prototype.parseNegate = parseNegate -function parseNegate () { - var pattern = this.pattern - var negate = false - var options = this.options - var negateOffset = 0 +/***/ }), +/* 102 */ +/***/ (function(module, exports, __webpack_require__) { - if (options.nonegate) return +var document = __webpack_require__(11).document; +module.exports = document && document.documentElement; - for (var i = 0, l = pattern.length - ; i < l && pattern.charAt(i) === '!' - ; i++) { - negate = !negate - negateOffset++ - } - if (negateOffset) this.pattern = pattern.substr(negateOffset) - this.negate = negate -} +/***/ }), +/* 103 */ +/***/ (function(module, exports, __webpack_require__) { -// Brace expansion: -// a{b,c}d -> abd acd -// a{b,}c -> abc ac -// a{0..3}d -> a0d a1d a2d a3d -// a{b,c{d,e}f}g -> abg acdfg acefg -// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg -// -// Invalid sets are not expanded. -// a{2..}b -> a{2..}b -// a{b}c -> a{b}c -minimatch.braceExpand = function (pattern, options) { - return braceExpand(pattern, options) -} +"use strict"; -Minimatch.prototype.braceExpand = braceExpand +var LIBRARY = __webpack_require__(69); +var $export = __webpack_require__(41); +var redefine = __webpack_require__(197); +var hide = __webpack_require__(31); +var Iterators = __webpack_require__(35); +var $iterCreate = __webpack_require__(188); +var setToStringTag = __webpack_require__(71); +var getPrototypeOf = __webpack_require__(194); +var ITERATOR = __webpack_require__(13)('iterator'); +var BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next` +var FF_ITERATOR = '@@iterator'; +var KEYS = 'keys'; +var VALUES = 'values'; -function braceExpand (pattern, options) { - if (!options) { - if (this instanceof Minimatch) { - options = this.options - } else { - options = {} +var returnThis = function () { return this; }; + +module.exports = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) { + $iterCreate(Constructor, NAME, next); + var getMethod = function (kind) { + if (!BUGGY && kind in proto) return proto[kind]; + switch (kind) { + case KEYS: return function keys() { return new Constructor(this, kind); }; + case VALUES: return function values() { return new Constructor(this, kind); }; + } return function entries() { return new Constructor(this, kind); }; + }; + var TAG = NAME + ' Iterator'; + var DEF_VALUES = DEFAULT == VALUES; + var VALUES_BUG = false; + var proto = Base.prototype; + var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT]; + var $default = $native || getMethod(DEFAULT); + var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined; + var $anyNative = NAME == 'Array' ? proto.entries || $native : $native; + var methods, key, IteratorPrototype; + // Fix native + if ($anyNative) { + IteratorPrototype = getPrototypeOf($anyNative.call(new Base())); + if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) { + // Set @@toStringTag to native iterators + setToStringTag(IteratorPrototype, TAG, true); + // fix for some old engines + if (!LIBRARY && typeof IteratorPrototype[ITERATOR] != 'function') hide(IteratorPrototype, ITERATOR, returnThis); } } - - pattern = typeof pattern === 'undefined' - ? this.pattern : pattern - - if (typeof pattern === 'undefined') { - throw new TypeError('undefined pattern') + // fix Array#{values, @@iterator}.name in V8 / FF + if (DEF_VALUES && $native && $native.name !== VALUES) { + VALUES_BUG = true; + $default = function values() { return $native.call(this); }; } - - if (options.nobrace || - !pattern.match(/\{.*\}/)) { - // shortcut. no need to expand. - return [pattern] + // Define iterator + if ((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) { + hide(proto, ITERATOR, $default); } - - return expand(pattern) -} - -// parse a component of the expanded set. -// At this point, no pattern may contain "/" in it -// so we're going to return a 2d array, where each entry is the full -// pattern, split on '/', and then turned into a regular expression. -// A regexp is made at the end which joins each array with an -// escaped /, and another full one which joins each regexp with |. -// -// Following the lead of Bash 4.1, note that "**" only has special meaning -// when it is the *only* thing in a path portion. Otherwise, any series -// of * is equivalent to a single *. Globstar behavior is enabled by -// default, and can be disabled by setting options.noglobstar. -Minimatch.prototype.parse = parse -var SUBPARSE = {} -function parse (pattern, isSub) { - if (pattern.length > 1024 * 64) { - throw new TypeError('pattern is too long') + // Plug for library + Iterators[NAME] = $default; + Iterators[TAG] = returnThis; + if (DEFAULT) { + methods = { + values: DEF_VALUES ? $default : getMethod(VALUES), + keys: IS_SET ? $default : getMethod(KEYS), + entries: $entries + }; + if (FORCED) for (key in methods) { + if (!(key in proto)) redefine(proto, key, methods[key]); + } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods); } + return methods; +}; - var options = this.options - - // shortcuts - if (!options.noglobstar && pattern === '**') return GLOBSTAR - if (pattern === '') return '' - var re = '' - var hasMagic = !!options.nocase - var escaping = false - // ? => one single character - var patternListStack = [] - var negativeLists = [] - var stateChar - var inClass = false - var reClassStart = -1 - var classStart = -1 - // . and .. never match anything that doesn't start with ., - // even when options.dot is set. - var patternStart = pattern.charAt(0) === '.' ? '' // anything - // not (start or / followed by . or .. followed by / or end) - : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' - : '(?!\\.)' - var self = this +/***/ }), +/* 104 */ +/***/ (function(module, exports) { - function clearStateChar () { - if (stateChar) { - // we had some state-tracking character - // that wasn't consumed by this pass. - switch (stateChar) { - case '*': - re += star - hasMagic = true - break - case '?': - re += qmark - hasMagic = true - break - default: - re += '\\' + stateChar - break - } - self.debug('clearStateChar %j %j', stateChar, re) - stateChar = false - } +module.exports = function (exec) { + try { + return { e: false, v: exec() }; + } catch (e) { + return { e: true, v: e }; } +}; - for (var i = 0, len = pattern.length, c - ; (i < len) && (c = pattern.charAt(i)) - ; i++) { - this.debug('%s\t%s %s %j', pattern, i, re, c) - - // skip over any that are escaped. - if (escaping && reSpecials[c]) { - re += '\\' + c - escaping = false - continue - } - - switch (c) { - case '/': - // completely not allowed, even escaped. - // Should already be path-split by now. - return false - case '\\': - clearStateChar() - escaping = true - continue +/***/ }), +/* 105 */ +/***/ (function(module, exports, __webpack_require__) { - // the various stateChar values - // for the "extglob" stuff. - case '?': - case '*': - case '+': - case '@': - case '!': - this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) +var anObject = __webpack_require__(27); +var isObject = __webpack_require__(34); +var newPromiseCapability = __webpack_require__(70); - // all of those are literals inside a class, except that - // the glob [!a] means [^a] in regexp - if (inClass) { - this.debug(' in class') - if (c === '!' && i === classStart + 1) c = '^' - re += c - continue - } +module.exports = function (C, x) { + anObject(C); + if (isObject(x) && x.constructor === C) return x; + var promiseCapability = newPromiseCapability.f(C); + var resolve = promiseCapability.resolve; + resolve(x); + return promiseCapability.promise; +}; - // if we already have a stateChar, then it means - // that there was something like ** or +? in there. - // Handle the stateChar, then proceed with this one. - self.debug('call clearStateChar %j', stateChar) - clearStateChar() - stateChar = c - // if extglob is disabled, then +(asdf|foo) isn't a thing. - // just clear the statechar *now*, rather than even diving into - // the patternList stuff. - if (options.noext) clearStateChar() - continue - case '(': - if (inClass) { - re += '(' - continue - } +/***/ }), +/* 106 */ +/***/ (function(module, exports) { - if (!stateChar) { - re += '\\(' - continue - } +module.exports = function (bitmap, value) { + return { + enumerable: !(bitmap & 1), + configurable: !(bitmap & 2), + writable: !(bitmap & 4), + value: value + }; +}; - patternListStack.push({ - type: stateChar, - start: i - 1, - reStart: re.length, - open: plTypes[stateChar].open, - close: plTypes[stateChar].close - }) - // negation is (?:(?!js)[^/]*) - re += stateChar === '!' ? '(?:(?!(?:' : '(?:' - this.debug('plType %j %j', stateChar, re) - stateChar = false - continue - case ')': - if (inClass || !patternListStack.length) { - re += '\\)' - continue - } +/***/ }), +/* 107 */ +/***/ (function(module, exports, __webpack_require__) { - clearStateChar() - hasMagic = true - var pl = patternListStack.pop() - // negation is (?:(?!js)[^/]*) - // The others are (?:) - re += pl.close - if (pl.type === '!') { - negativeLists.push(pl) - } - pl.reEnd = re.length - continue +var core = __webpack_require__(23); +var global = __webpack_require__(11); +var SHARED = '__core-js_shared__'; +var store = global[SHARED] || (global[SHARED] = {}); - case '|': - if (inClass || !patternListStack.length || escaping) { - re += '\\|' - escaping = false - continue - } +(module.exports = function (key, value) { + return store[key] || (store[key] = value !== undefined ? value : {}); +})('versions', []).push({ + version: core.version, + mode: __webpack_require__(69) ? 'pure' : 'global', + copyright: '© 2018 Denis Pushkarev (zloirock.ru)' +}); - clearStateChar() - re += '|' - continue - // these are mostly the same in regexp and glob - case '[': - // swallow any state-tracking char before the [ - clearStateChar() +/***/ }), +/* 108 */ +/***/ (function(module, exports, __webpack_require__) { - if (inClass) { - re += '\\' + c - continue - } +// 7.3.20 SpeciesConstructor(O, defaultConstructor) +var anObject = __webpack_require__(27); +var aFunction = __webpack_require__(46); +var SPECIES = __webpack_require__(13)('species'); +module.exports = function (O, D) { + var C = anObject(O).constructor; + var S; + return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S); +}; - inClass = true - classStart = i - reClassStart = re.length - re += c - continue - case ']': - // a right bracket shall lose its special - // meaning and represent itself in - // a bracket expression if it occurs - // first in the list. -- POSIX.2 2.8.3.2 - if (i === classStart + 1 || !inClass) { - re += '\\' + c - escaping = false - continue - } +/***/ }), +/* 109 */ +/***/ (function(module, exports, __webpack_require__) { - // handle the case where we left a class open. - // "[z-a]" is valid, equivalent to "\[z-a\]" - if (inClass) { - // split where the last [ was, make sure we don't have - // an invalid re. if so, re-walk the contents of the - // would-be class to re-translate any characters that - // were passed through as-is - // TODO: It would probably be faster to determine this - // without a try/catch and a new RegExp, but it's tricky - // to do safely. For now, this is safe and works. - var cs = pattern.substring(classStart + 1, i) - try { - RegExp('[' + cs + ']') - } catch (er) { - // not a valid class! - var sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' - hasMagic = hasMagic || sp[1] - inClass = false - continue - } - } +var ctx = __webpack_require__(48); +var invoke = __webpack_require__(185); +var html = __webpack_require__(102); +var cel = __webpack_require__(68); +var global = __webpack_require__(11); +var process = global.process; +var setTask = global.setImmediate; +var clearTask = global.clearImmediate; +var MessageChannel = global.MessageChannel; +var Dispatch = global.Dispatch; +var counter = 0; +var queue = {}; +var ONREADYSTATECHANGE = 'onreadystatechange'; +var defer, channel, port; +var run = function () { + var id = +this; + // eslint-disable-next-line no-prototype-builtins + if (queue.hasOwnProperty(id)) { + var fn = queue[id]; + delete queue[id]; + fn(); + } +}; +var listener = function (event) { + run.call(event.data); +}; +// Node.js 0.9+ & IE10+ has setImmediate, otherwise: +if (!setTask || !clearTask) { + setTask = function setImmediate(fn) { + var args = []; + var i = 1; + while (arguments.length > i) args.push(arguments[i++]); + queue[++counter] = function () { + // eslint-disable-next-line no-new-func + invoke(typeof fn == 'function' ? fn : Function(fn), args); + }; + defer(counter); + return counter; + }; + clearTask = function clearImmediate(id) { + delete queue[id]; + }; + // Node.js 0.8- + if (__webpack_require__(47)(process) == 'process') { + defer = function (id) { + process.nextTick(ctx(run, id, 1)); + }; + // Sphere (JS game engine) Dispatch API + } else if (Dispatch && Dispatch.now) { + defer = function (id) { + Dispatch.now(ctx(run, id, 1)); + }; + // Browsers with MessageChannel, includes WebWorkers + } else if (MessageChannel) { + channel = new MessageChannel(); + port = channel.port2; + channel.port1.onmessage = listener; + defer = ctx(port.postMessage, port, 1); + // Browsers with postMessage, skip WebWorkers + // IE8 has postMessage, but it's sync & typeof its postMessage is 'object' + } else if (global.addEventListener && typeof postMessage == 'function' && !global.importScripts) { + defer = function (id) { + global.postMessage(id + '', '*'); + }; + global.addEventListener('message', listener, false); + // IE8- + } else if (ONREADYSTATECHANGE in cel('script')) { + defer = function (id) { + html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function () { + html.removeChild(this); + run.call(id); + }; + }; + // Rest old browsers + } else { + defer = function (id) { + setTimeout(ctx(run, id, 1), 0); + }; + } +} +module.exports = { + set: setTask, + clear: clearTask +}; - // finish up the class. - hasMagic = true - inClass = false - re += c - continue - default: - // swallow any state char that wasn't consumed - clearStateChar() +/***/ }), +/* 110 */ +/***/ (function(module, exports, __webpack_require__) { - if (escaping) { - // no need - escaping = false - } else if (reSpecials[c] - && !(c === '^' && inClass)) { - re += '\\' - } +// 7.1.15 ToLength +var toInteger = __webpack_require__(73); +var min = Math.min; +module.exports = function (it) { + return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991 +}; - re += c - } // switch - } // for +/***/ }), +/* 111 */ +/***/ (function(module, exports) { - // handle the case where we left a class open. - // "[abc" is valid, equivalent to "\[abc" - if (inClass) { - // split where the last [ was, and escape it - // this is a huge pita. We now have to re-walk - // the contents of the would-be class to re-translate - // any characters that were passed through as-is - cs = pattern.substr(classStart + 1) - sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + '\\[' + sp[0] - hasMagic = hasMagic || sp[1] - } +var id = 0; +var px = Math.random(); +module.exports = function (key) { + return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36)); +}; - // handle the case where we had a +( thing at the *end* - // of the pattern. - // each pattern list stack adds 3 chars, and we need to go through - // and escape any | chars that were passed through as-is for the regexp. - // Go through and escape them, taking care not to double-escape any - // | chars that were already escaped. - for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { - var tail = re.slice(pl.reStart + pl.open.length) - this.debug('setting tail', re, pl) - // maybe some even number of \, then maybe 1 \, followed by a | - tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { - if (!$2) { - // the | isn't already escaped, so escape it. - $2 = '\\' - } - // need to escape all those slashes *again*, without escaping the - // one that we need for escaping the | character. As it works out, - // escaping an even number of slashes can be done by simply repeating - // it exactly after itself. That's why this trick works. - // - // I am sorry that you have to see this. - return $1 + $1 + $2 + '|' - }) +/***/ }), +/* 112 */ +/***/ (function(module, exports, __webpack_require__) { - this.debug('tail=%j\n %s', tail, tail, pl, re) - var t = pl.type === '*' ? star - : pl.type === '?' ? qmark - : '\\' + pl.type - hasMagic = true - re = re.slice(0, pl.reStart) + t + '\\(' + tail - } +/** + * This is the common logic for both the Node.js and web browser + * implementations of `debug()`. + * + * Expose `debug()` as the module. + */ - // handle trailing things that only matter at the very end. - clearStateChar() - if (escaping) { - // trailing \\ - re += '\\\\' - } +exports = module.exports = createDebug.debug = createDebug['default'] = createDebug; +exports.coerce = coerce; +exports.disable = disable; +exports.enable = enable; +exports.enabled = enabled; +exports.humanize = __webpack_require__(229); - // only need to apply the nodot start if the re starts with - // something that could conceivably capture a dot - var addPatternStart = false - switch (re.charAt(0)) { - case '.': - case '[': - case '(': addPatternStart = true - } +/** + * Active `debug` instances. + */ +exports.instances = []; - // Hack to work around lack of negative lookbehind in JS - // A pattern like: *.!(x).!(y|z) needs to ensure that a name - // like 'a.xyz.yz' doesn't match. So, the first negative - // lookahead, has to look ALL the way ahead, to the end of - // the pattern. - for (var n = negativeLists.length - 1; n > -1; n--) { - var nl = negativeLists[n] +/** + * The currently active debug mode names, and names to skip. + */ - var nlBefore = re.slice(0, nl.reStart) - var nlFirst = re.slice(nl.reStart, nl.reEnd - 8) - var nlLast = re.slice(nl.reEnd - 8, nl.reEnd) - var nlAfter = re.slice(nl.reEnd) +exports.names = []; +exports.skips = []; - nlLast += nlAfter +/** + * Map of special "%n" handling functions, for the debug "format" argument. + * + * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". + */ - // Handle nested stuff like *(*.js|!(*.json)), where open parens - // mean that we should *not* include the ) in the bit that is considered - // "after" the negated section. - var openParensBefore = nlBefore.split('(').length - 1 - var cleanAfter = nlAfter - for (i = 0; i < openParensBefore; i++) { - cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') - } - nlAfter = cleanAfter +exports.formatters = {}; - var dollar = '' - if (nlAfter === '' && isSub !== SUBPARSE) { - dollar = '$' - } - var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast - re = newRe - } +/** + * Select a color. + * @param {String} namespace + * @return {Number} + * @api private + */ - // if the re is not "" at this point, then we need to make sure - // it doesn't match against an empty path part. - // Otherwise a/* will match a/, which it should not. - if (re !== '' && hasMagic) { - re = '(?=.)' + re - } +function selectColor(namespace) { + var hash = 0, i; - if (addPatternStart) { - re = patternStart + re + for (i in namespace) { + hash = ((hash << 5) - hash) + namespace.charCodeAt(i); + hash |= 0; // Convert to 32bit integer } - // parsing just a piece of a larger pattern. - if (isSub === SUBPARSE) { - return [re, hasMagic] - } + return exports.colors[Math.abs(hash) % exports.colors.length]; +} - // skip the regexp for non-magical patterns - // unescape anything in it, though, so that it'll be - // an exact match against a file etc. - if (!hasMagic) { - return globUnescape(pattern) - } +/** + * Create a debugger with the given `namespace`. + * + * @param {String} namespace + * @return {Function} + * @api public + */ - var flags = options.nocase ? 'i' : '' - try { - var regExp = new RegExp('^' + re + '$', flags) - } catch (er) { - // If it was an invalid regular expression, then it can't match - // anything. This trick looks for a character after the end of - // the string, which is of course impossible, except in multi-line - // mode, but it's not a /m regex. - return new RegExp('$.') - } +function createDebug(namespace) { - regExp._glob = pattern - regExp._src = re + var prevTime; - return regExp -} + function debug() { + // disabled? + if (!debug.enabled) return; -minimatch.makeRe = function (pattern, options) { - return new Minimatch(pattern, options || {}).makeRe() -} + var self = debug; -Minimatch.prototype.makeRe = makeRe -function makeRe () { - if (this.regexp || this.regexp === false) return this.regexp + // set `diff` timestamp + var curr = +new Date(); + var ms = curr - (prevTime || curr); + self.diff = ms; + self.prev = prevTime; + self.curr = curr; + prevTime = curr; - // at this point, this.set is a 2d array of partial - // pattern strings, or "**". - // - // It's better to use .match(). This function shouldn't - // be used, really, but it's pretty convenient sometimes, - // when you just want to work with a regex. - var set = this.set + // turn the `arguments` into a proper Array + var args = new Array(arguments.length); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i]; + } - if (!set.length) { - this.regexp = false - return this.regexp - } - var options = this.options + args[0] = exports.coerce(args[0]); - var twoStar = options.noglobstar ? star - : options.dot ? twoStarDot - : twoStarNoDot - var flags = options.nocase ? 'i' : '' + if ('string' !== typeof args[0]) { + // anything else let's inspect with %O + args.unshift('%O'); + } - var re = set.map(function (pattern) { - return pattern.map(function (p) { - return (p === GLOBSTAR) ? twoStar - : (typeof p === 'string') ? regExpEscape(p) - : p._src - }).join('\\\/') - }).join('|') + // apply any `formatters` transformations + var index = 0; + args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) { + // if we encounter an escaped % then don't increase the array index + if (match === '%%') return match; + index++; + var formatter = exports.formatters[format]; + if ('function' === typeof formatter) { + var val = args[index]; + match = formatter.call(self, val); - // must match entire pattern - // ending in a * or ** will make it less strict. - re = '^(?:' + re + ')$' + // now we need to remove `args[index]` since it's inlined in the `format` + args.splice(index, 1); + index--; + } + return match; + }); - // can match anything, as long as it's not this. - if (this.negate) re = '^(?!' + re + ').*$' + // apply env-specific formatting (colors, etc.) + exports.formatArgs.call(self, args); - try { - this.regexp = new RegExp(re, flags) - } catch (ex) { - this.regexp = false + var logFn = debug.log || exports.log || console.log.bind(console); + logFn.apply(self, args); } - return this.regexp -} -minimatch.match = function (list, pattern, options) { - options = options || {} - var mm = new Minimatch(pattern, options) - list = list.filter(function (f) { - return mm.match(f) - }) - if (mm.options.nonull && !list.length) { - list.push(pattern) - } - return list -} + debug.namespace = namespace; + debug.enabled = exports.enabled(namespace); + debug.useColors = exports.useColors(); + debug.color = selectColor(namespace); + debug.destroy = destroy; -Minimatch.prototype.match = match -function match (f, partial) { - this.debug('match', f, this.pattern) - // short-circuit in the case of busted things. - // comments, etc. - if (this.comment) return false - if (this.empty) return f === '' + // env-specific initialization logic for debug instances + if ('function' === typeof exports.init) { + exports.init(debug); + } - if (f === '/' && partial) return true + exports.instances.push(debug); - var options = this.options + return debug; +} - // windows: need to use /, not \ - if (path.sep !== '/') { - f = f.split(path.sep).join('/') +function destroy () { + var index = exports.instances.indexOf(this); + if (index !== -1) { + exports.instances.splice(index, 1); + return true; + } else { + return false; } +} - // treat the test path as a set of pathparts. - f = f.split(slashSplit) - this.debug(this.pattern, 'split', f) +/** + * Enables a debug mode by namespaces. This can include modes + * separated by a colon and wildcards. + * + * @param {String} namespaces + * @api public + */ - // just ONE of the pattern sets in this.set needs to match - // in order for it to be valid. If negating, then just one - // match means that we have failed. - // Either way, return on the first hit. +function enable(namespaces) { + exports.save(namespaces); - var set = this.set - this.debug(this.pattern, 'set', set) + exports.names = []; + exports.skips = []; - // Find the basename of the path by looking for the last non-empty segment - var filename - var i - for (i = f.length - 1; i >= 0; i--) { - filename = f[i] - if (filename) break - } + var i; + var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); + var len = split.length; - for (i = 0; i < set.length; i++) { - var pattern = set[i] - var file = f - if (options.matchBase && pattern.length === 1) { - file = [filename] - } - var hit = this.matchOne(file, pattern, partial) - if (hit) { - if (options.flipNegate) return true - return !this.negate + for (i = 0; i < len; i++) { + if (!split[i]) continue; // ignore empty strings + namespaces = split[i].replace(/\*/g, '.*?'); + if (namespaces[0] === '-') { + exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); + } else { + exports.names.push(new RegExp('^' + namespaces + '$')); } } - // didn't get any hits. this is success if it's a negative - // pattern, failure otherwise. - if (options.flipNegate) return false - return this.negate + for (i = 0; i < exports.instances.length; i++) { + var instance = exports.instances[i]; + instance.enabled = exports.enabled(instance.namespace); + } } -// set partial to true to test if, for example, -// "/a/b" matches the start of "/*/b/*/d" -// Partial means, if you run out of file before you run -// out of pattern, then that's fine, as long as all -// the parts match. -Minimatch.prototype.matchOne = function (file, pattern, partial) { - var options = this.options - - this.debug('matchOne', - { 'this': this, file: file, pattern: pattern }) - - this.debug('matchOne', file.length, pattern.length) +/** + * Disable debug output. + * + * @api public + */ - for (var fi = 0, - pi = 0, - fl = file.length, - pl = pattern.length - ; (fi < fl) && (pi < pl) - ; fi++, pi++) { - this.debug('matchOne loop') - var p = pattern[pi] - var f = file[fi] +function disable() { + exports.enable(''); +} - this.debug(pattern, p, f) +/** + * Returns true if the given mode name is enabled, false otherwise. + * + * @param {String} name + * @return {Boolean} + * @api public + */ - // should be impossible. - // some invalid regexp stuff in the set. - if (p === false) return false +function enabled(name) { + if (name[name.length - 1] === '*') { + return true; + } + var i, len; + for (i = 0, len = exports.skips.length; i < len; i++) { + if (exports.skips[i].test(name)) { + return false; + } + } + for (i = 0, len = exports.names.length; i < len; i++) { + if (exports.names[i].test(name)) { + return true; + } + } + return false; +} - if (p === GLOBSTAR) { - this.debug('GLOBSTAR', [pattern, p, f]) +/** + * Coerce `val`. + * + * @param {Mixed} val + * @return {Mixed} + * @api private + */ - // "**" - // a/**/b/**/c would match the following: - // a/b/x/y/z/c - // a/x/y/z/b/c - // a/b/x/b/x/c - // a/b/c - // To do this, take the rest of the pattern after - // the **, and see if it would match the file remainder. - // If so, return success. - // If not, the ** "swallows" a segment, and try again. - // This is recursively awful. - // - // a/**/b/**/c matching a/b/x/y/z/c - // - a matches a - // - doublestar - // - matchOne(b/x/y/z/c, b/**/c) - // - b matches b - // - doublestar - // - matchOne(x/y/z/c, c) -> no - // - matchOne(y/z/c, c) -> no - // - matchOne(z/c, c) -> no - // - matchOne(c, c) yes, hit - var fr = fi - var pr = pi + 1 - if (pr === pl) { - this.debug('** at the end') - // a ** at the end will just swallow the rest. - // We have found a match. - // however, it will not swallow /.x, unless - // options.dot is set. - // . and .. are *never* matched by **, for explosively - // exponential reasons. - for (; fi < fl; fi++) { - if (file[fi] === '.' || file[fi] === '..' || - (!options.dot && file[fi].charAt(0) === '.')) return false - } - return true - } +function coerce(val) { + if (val instanceof Error) return val.stack || val.message; + return val; +} - // ok, let's see if we can swallow whatever we can. - while (fr < fl) { - var swallowee = file[fr] - this.debug('\nglobstar while', file, fr, pattern, pr, swallowee) +/***/ }), +/* 113 */, +/* 114 */ +/***/ (function(module, exports, __webpack_require__) { - // XXX remove this slice. Just pass the start index. - if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { - this.debug('globstar found match!', fr, fl, swallowee) - // found a match. - return true - } else { - // can't swallow "." or ".." ever. - // can only swallow ".foo" when explicitly asked. - if (swallowee === '.' || swallowee === '..' || - (!options.dot && swallowee.charAt(0) === '.')) { - this.debug('dot detected!', file, fr, pattern, pr) - break - } +module.exports = realpath +realpath.realpath = realpath +realpath.sync = realpathSync +realpath.realpathSync = realpathSync +realpath.monkeypatch = monkeypatch +realpath.unmonkeypatch = unmonkeypatch - // ** swallows a segment, and continue. - this.debug('globstar swallow a segment, and continue') - fr++ - } - } +var fs = __webpack_require__(3) +var origRealpath = fs.realpath +var origRealpathSync = fs.realpathSync - // no match was found. - // However, in partial mode, we can't say this is necessarily over. - // If there's more *pattern* left, then - if (partial) { - // ran out of file - this.debug('\n>>> no match, partial?', file, fr, pattern, pr) - if (fr === fl) return true - } - return false - } +var version = process.version +var ok = /^v[0-5]\./.test(version) +var old = __webpack_require__(217) - // something other than ** - // non-magic patterns just have to match exactly - // patterns with magic have been turned into regexps. - var hit - if (typeof p === 'string') { - if (options.nocase) { - hit = f.toLowerCase() === p.toLowerCase() - } else { - hit = f === p - } - this.debug('string match', p, f, hit) - } else { - hit = f.match(p) - this.debug('pattern match', p, f, hit) - } +function newError (er) { + return er && er.syscall === 'realpath' && ( + er.code === 'ELOOP' || + er.code === 'ENOMEM' || + er.code === 'ENAMETOOLONG' + ) +} - if (!hit) return false +function realpath (p, cache, cb) { + if (ok) { + return origRealpath(p, cache, cb) } - // Note: ending in / means that we'll get a final "" - // at the end of the pattern. This can only match a - // corresponding "" at the end of the file. - // If the file ends in /, then it can only match a - // a pattern that ends in /, unless the pattern just - // doesn't have any more for it. But, a/b/ should *not* - // match "a/b/*", even though "" matches against the - // [^/]*? pattern, except in partial mode, where it might - // simply not be reached yet. - // However, a/b/ should still satisfy a/* + if (typeof cache === 'function') { + cb = cache + cache = null + } + origRealpath(p, cache, function (er, result) { + if (newError(er)) { + old.realpath(p, cache, cb) + } else { + cb(er, result) + } + }) +} - // now either we fell off the end of the pattern, or we're done. - if (fi === fl && pi === pl) { - // ran out of pattern and filename at the same time. - // an exact hit! - return true - } else if (fi === fl) { - // ran out of file, but still had pattern left. - // this is ok if we're doing the match as part of - // a glob fs traversal. - return partial - } else if (pi === pl) { - // ran out of pattern, still have file left. - // this is only acceptable if we're on the very last - // empty segment of a file with a trailing slash. - // a/* should match a/b/ - var emptyFileEnd = (fi === fl - 1) && (file[fi] === '') - return emptyFileEnd +function realpathSync (p, cache) { + if (ok) { + return origRealpathSync(p, cache) } - // should be unreachable. - throw new Error('wtf?') + try { + return origRealpathSync(p, cache) + } catch (er) { + if (newError(er)) { + return old.realpathSync(p, cache) + } else { + throw er + } + } } -// replace stuff like \* with * -function globUnescape (s) { - return s.replace(/\\(.)/g, '$1') +function monkeypatch () { + fs.realpath = realpath + fs.realpathSync = realpathSync } -function regExpEscape (s) { - return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') +function unmonkeypatch () { + fs.realpath = origRealpath + fs.realpathSync = origRealpathSync } /***/ }), -/* 61 */ +/* 115 */ /***/ (function(module, exports, __webpack_require__) { -var wrappy = __webpack_require__(123) -module.exports = wrappy(once) -module.exports.strict = wrappy(onceStrict) +exports.alphasort = alphasort +exports.alphasorti = alphasorti +exports.setopts = setopts +exports.ownProp = ownProp +exports.makeAbs = makeAbs +exports.finish = finish +exports.mark = mark +exports.isIgnored = isIgnored +exports.childrenIgnored = childrenIgnored -once.proto = once(function () { - Object.defineProperty(Function.prototype, 'once', { - value: function () { - return once(this) - }, - configurable: true - }) +function ownProp (obj, field) { + return Object.prototype.hasOwnProperty.call(obj, field) +} - Object.defineProperty(Function.prototype, 'onceStrict', { - value: function () { - return onceStrict(this) - }, - configurable: true - }) -}) +var path = __webpack_require__(0) +var minimatch = __webpack_require__(60) +var isAbsolute = __webpack_require__(76) +var Minimatch = minimatch.Minimatch -function once (fn) { - var f = function () { - if (f.called) return f.value - f.called = true - return f.value = fn.apply(this, arguments) - } - f.called = false - return f +function alphasorti (a, b) { + return a.toLowerCase().localeCompare(b.toLowerCase()) } -function onceStrict (fn) { - var f = function () { - if (f.called) - throw new Error(f.onceError) - f.called = true - return f.value = fn.apply(this, arguments) - } - var name = fn.name || 'Function wrapped with `once`' - f.onceError = name + " shouldn't be called more than once" - f.called = false - return f +function alphasort (a, b) { + return a.localeCompare(b) } +function setupIgnores (self, options) { + self.ignore = options.ignore || [] -/***/ }), -/* 62 */, -/* 63 */ -/***/ (function(module, exports) { - -module.exports = __webpack_require__(285); + if (!Array.isArray(self.ignore)) + self.ignore = [self.ignore] -/***/ }), -/* 64 */, -/* 65 */, -/* 66 */, -/* 67 */ -/***/ (function(module, exports) { + if (self.ignore.length) { + self.ignore = self.ignore.map(ignoreMap) + } +} -// 7.2.1 RequireObjectCoercible(argument) -module.exports = function (it) { - if (it == undefined) throw TypeError("Can't call method on " + it); - return it; -}; +// ignore patterns are always in dot:true mode. +function ignoreMap (pattern) { + var gmatcher = null + if (pattern.slice(-3) === '/**') { + var gpattern = pattern.replace(/(\/\*\*)+$/, '') + gmatcher = new Minimatch(gpattern, { dot: true }) + } + return { + matcher: new Minimatch(pattern, { dot: true }), + gmatcher: gmatcher + } +} -/***/ }), -/* 68 */ -/***/ (function(module, exports, __webpack_require__) { +function setopts (self, pattern, options) { + if (!options) + options = {} -var isObject = __webpack_require__(34); -var document = __webpack_require__(11).document; -// typeof document.createElement is 'object' in old IE -var is = isObject(document) && isObject(document.createElement); -module.exports = function (it) { - return is ? document.createElement(it) : {}; -}; + // base-matching: just use globstar for that. + if (options.matchBase && -1 === pattern.indexOf("/")) { + if (options.noglobstar) { + throw new Error("base matching requires globstar") + } + pattern = "**/" + pattern + } + self.silent = !!options.silent + self.pattern = pattern + self.strict = options.strict !== false + self.realpath = !!options.realpath + self.realpathCache = options.realpathCache || Object.create(null) + self.follow = !!options.follow + self.dot = !!options.dot + self.mark = !!options.mark + self.nodir = !!options.nodir + if (self.nodir) + self.mark = true + self.sync = !!options.sync + self.nounique = !!options.nounique + self.nonull = !!options.nonull + self.nosort = !!options.nosort + self.nocase = !!options.nocase + self.stat = !!options.stat + self.noprocess = !!options.noprocess + self.absolute = !!options.absolute -/***/ }), -/* 69 */ -/***/ (function(module, exports) { + self.maxLength = options.maxLength || Infinity + self.cache = options.cache || Object.create(null) + self.statCache = options.statCache || Object.create(null) + self.symlinks = options.symlinks || Object.create(null) -module.exports = true; + setupIgnores(self, options) + self.changedCwd = false + var cwd = process.cwd() + if (!ownProp(options, "cwd")) + self.cwd = cwd + else { + self.cwd = path.resolve(options.cwd) + self.changedCwd = self.cwd !== cwd + } -/***/ }), -/* 70 */ -/***/ (function(module, exports, __webpack_require__) { + self.root = options.root || path.resolve(self.cwd, "/") + self.root = path.resolve(self.root) + if (process.platform === "win32") + self.root = self.root.replace(/\\/g, "/") -"use strict"; + // TODO: is an absolute `cwd` supposed to be resolved against `root`? + // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test') + self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd) + if (process.platform === "win32") + self.cwdAbs = self.cwdAbs.replace(/\\/g, "/") + self.nomount = !!options.nomount -// 25.4.1.5 NewPromiseCapability(C) -var aFunction = __webpack_require__(46); + // disable comments and negation in Minimatch. + // Note that they are not supported in Glob itself anyway. + options.nonegate = true + options.nocomment = true -function PromiseCapability(C) { - var resolve, reject; - this.promise = new C(function ($$resolve, $$reject) { - if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor'); - resolve = $$resolve; - reject = $$reject; - }); - this.resolve = aFunction(resolve); - this.reject = aFunction(reject); + self.minimatch = new Minimatch(pattern, options) + self.options = self.minimatch.options } -module.exports.f = function (C) { - return new PromiseCapability(C); -}; +function finish (self) { + var nou = self.nounique + var all = nou ? [] : Object.create(null) + for (var i = 0, l = self.matches.length; i < l; i ++) { + var matches = self.matches[i] + if (!matches || Object.keys(matches).length === 0) { + if (self.nonull) { + // do like the shell, and spit out the literal glob + var literal = self.minimatch.globSet[i] + if (nou) + all.push(literal) + else + all[literal] = true + } + } else { + // had matches + var m = Object.keys(matches) + if (nou) + all.push.apply(all, m) + else + m.forEach(function (m) { + all[m] = true + }) + } + } -/***/ }), -/* 71 */ -/***/ (function(module, exports, __webpack_require__) { + if (!nou) + all = Object.keys(all) -var def = __webpack_require__(50).f; -var has = __webpack_require__(49); -var TAG = __webpack_require__(13)('toStringTag'); + if (!self.nosort) + all = all.sort(self.nocase ? alphasorti : alphasort) -module.exports = function (it, tag, stat) { - if (it && !has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { configurable: true, value: tag }); -}; + // at *some* point we statted all of these + if (self.mark) { + for (var i = 0; i < all.length; i++) { + all[i] = self._mark(all[i]) + } + if (self.nodir) { + all = all.filter(function (e) { + var notDir = !(/\/$/.test(e)) + var c = self.cache[e] || self.cache[makeAbs(self, e)] + if (notDir && c) + notDir = c !== 'DIR' && !Array.isArray(c) + return notDir + }) + } + } + if (self.ignore.length) + all = all.filter(function(m) { + return !isIgnored(self, m) + }) -/***/ }), -/* 72 */ -/***/ (function(module, exports, __webpack_require__) { + self.found = all +} -var shared = __webpack_require__(107)('keys'); -var uid = __webpack_require__(111); -module.exports = function (key) { - return shared[key] || (shared[key] = uid(key)); -}; +function mark (self, p) { + var abs = makeAbs(self, p) + var c = self.cache[abs] + var m = p + if (c) { + var isDir = c === 'DIR' || Array.isArray(c) + var slash = p.slice(-1) === '/' + if (isDir && !slash) + m += '/' + else if (!isDir && slash) + m = m.slice(0, -1) -/***/ }), -/* 73 */ -/***/ (function(module, exports) { + if (m !== p) { + var mabs = makeAbs(self, m) + self.statCache[mabs] = self.statCache[abs] + self.cache[mabs] = self.cache[abs] + } + } -// 7.1.4 ToInteger -var ceil = Math.ceil; -var floor = Math.floor; -module.exports = function (it) { - return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it); -}; + return m +} +// lotta situps... +function makeAbs (self, f) { + var abs = f + if (f.charAt(0) === '/') { + abs = path.join(self.root, f) + } else if (isAbsolute(f) || f === '') { + abs = f + } else if (self.changedCwd) { + abs = path.resolve(self.cwd, f) + } else { + abs = path.resolve(f) + } -/***/ }), -/* 74 */ -/***/ (function(module, exports, __webpack_require__) { + if (process.platform === 'win32') + abs = abs.replace(/\\/g, '/') -// to indexed object, toObject with fallback for non-array-like ES3 strings -var IObject = __webpack_require__(131); -var defined = __webpack_require__(67); -module.exports = function (it) { - return IObject(defined(it)); -}; + return abs +} -/***/ }), -/* 75 */ -/***/ (function(module, exports, __webpack_require__) { +// Return true, if pattern ends with globstar '**', for the accompanying parent directory. +// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents +function isIgnored (self, path) { + if (!self.ignore.length) + return false -// Approach: -// -// 1. Get the minimatch set -// 2. For each pattern in the set, PROCESS(pattern, false) -// 3. Store matches per-set, then uniq them -// -// PROCESS(pattern, inGlobStar) -// Get the first [n] items from pattern that are all strings -// Join these together. This is PREFIX. -// If there is no more remaining, then stat(PREFIX) and -// add to matches if it succeeds. END. -// -// If inGlobStar and PREFIX is symlink and points to dir -// set ENTRIES = [] -// else readdir(PREFIX) as ENTRIES -// If fail, END -// -// with ENTRIES -// If pattern[n] is GLOBSTAR -// // handle the case where the globstar match is empty -// // by pruning it out, and testing the resulting pattern -// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) -// // handle other cases. -// for ENTRY in ENTRIES (not dotfiles) -// // attach globstar + tail onto the entry -// // Mark that this entry is a globstar match -// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) -// -// else // not globstar -// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) -// Test ENTRY against pattern[n] -// If fails, continue -// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) -// -// Caveat: -// Cache all stats and readdirs results to minimize syscall. Since all -// we ever care about is existence and directory-ness, we can just keep -// `true` for files, and [children,...] for directories, or `false` for -// things that don't exist. + return self.ignore.some(function(item) { + return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) + }) +} -module.exports = glob +function childrenIgnored (self, path) { + if (!self.ignore.length) + return false -var fs = __webpack_require__(3) -var rp = __webpack_require__(114) -var minimatch = __webpack_require__(60) -var Minimatch = minimatch.Minimatch -var inherits = __webpack_require__(42) -var EE = __webpack_require__(54).EventEmitter -var path = __webpack_require__(0) -var assert = __webpack_require__(22) -var isAbsolute = __webpack_require__(76) -var globSync = __webpack_require__(218) -var common = __webpack_require__(115) -var alphasort = common.alphasort -var alphasorti = common.alphasorti -var setopts = common.setopts -var ownProp = common.ownProp -var inflight = __webpack_require__(223) -var util = __webpack_require__(2) -var childrenIgnored = common.childrenIgnored -var isIgnored = common.isIgnored + return self.ignore.some(function(item) { + return !!(item.gmatcher && item.gmatcher.match(path)) + }) +} -var once = __webpack_require__(61) -function glob (pattern, options, cb) { - if (typeof options === 'function') cb = options, options = {} - if (!options) options = {} +/***/ }), +/* 116 */ +/***/ (function(module, exports, __webpack_require__) { - if (options.sync) { - if (cb) - throw new TypeError('callback provided to sync glob') - return globSync(pattern, options) - } +var path = __webpack_require__(0); +var fs = __webpack_require__(3); +var _0777 = parseInt('0777', 8); - return new Glob(pattern, options, cb) +module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP; + +function mkdirP (p, opts, f, made) { + if (typeof opts === 'function') { + f = opts; + opts = {}; + } + else if (!opts || typeof opts !== 'object') { + opts = { mode: opts }; + } + + var mode = opts.mode; + var xfs = opts.fs || fs; + + if (mode === undefined) { + mode = _0777 & (~process.umask()); + } + if (!made) made = null; + + var cb = f || function () {}; + p = path.resolve(p); + + xfs.mkdir(p, mode, function (er) { + if (!er) { + made = made || p; + return cb(null, made); + } + switch (er.code) { + case 'ENOENT': + mkdirP(path.dirname(p), opts, function (er, made) { + if (er) cb(er, made); + else mkdirP(p, opts, cb, made); + }); + break; + + // In the case of any other error, just see if there's a dir + // there already. If so, then hooray! If not, then something + // is borked. + default: + xfs.stat(p, function (er2, stat) { + // if the stat fails, then that's super weird. + // let the original error be the failure reason. + if (er2 || !stat.isDirectory()) cb(er, made) + else cb(null, made); + }); + break; + } + }); } -glob.sync = globSync -var GlobSync = glob.GlobSync = globSync.GlobSync +mkdirP.sync = function sync (p, opts, made) { + if (!opts || typeof opts !== 'object') { + opts = { mode: opts }; + } + + var mode = opts.mode; + var xfs = opts.fs || fs; + + if (mode === undefined) { + mode = _0777 & (~process.umask()); + } + if (!made) made = null; -// old api surface -glob.glob = glob + p = path.resolve(p); -function extend (origin, add) { - if (add === null || typeof add !== 'object') { - return origin - } + try { + xfs.mkdirSync(p, mode); + made = made || p; + } + catch (err0) { + switch (err0.code) { + case 'ENOENT' : + made = sync(path.dirname(p), opts, made); + sync(p, opts, made); + break; - var keys = Object.keys(add) - var i = keys.length - while (i--) { - origin[keys[i]] = add[keys[i]] - } - return origin -} + // In the case of any other error, just see if there's a dir + // there already. If so, then hooray! If not, then something + // is borked. + default: + var stat; + try { + stat = xfs.statSync(p); + } + catch (err1) { + throw err0; + } + if (!stat.isDirectory()) throw err0; + break; + } + } -glob.hasMagic = function (pattern, options_) { - var options = extend({}, options_) - options.noprocess = true + return made; +}; - var g = new Glob(pattern, options) - var set = g.minimatch.set - if (!pattern) - return false +/***/ }), +/* 117 */, +/* 118 */, +/* 119 */, +/* 120 */, +/* 121 */, +/* 122 */ +/***/ (function(module, exports, __webpack_require__) { - if (set.length > 1) - return true +"use strict"; - for (var j = 0; j < set[0].length; j++) { - if (typeof set[0][j] !== 'string') - return true - } +module.exports = x => { + if (typeof x !== 'string') { + throw new TypeError('Expected a string, got ' + typeof x); + } - return false -} + // Catches EFBBBF (UTF-8 BOM) because the buffer-to-string + // conversion translates it to FEFF (UTF-16 BOM) + if (x.charCodeAt(0) === 0xFEFF) { + return x.slice(1); + } -glob.Glob = Glob -inherits(Glob, EE) -function Glob (pattern, options, cb) { - if (typeof options === 'function') { - cb = options - options = null - } + return x; +}; - if (options && options.sync) { - if (cb) - throw new TypeError('callback provided to sync glob') - return new GlobSync(pattern, options) - } - if (!(this instanceof Glob)) - return new Glob(pattern, options, cb) +/***/ }), +/* 123 */ +/***/ (function(module, exports) { - setopts(this, pattern, options) - this._didRealPath = false +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) - // process each pattern in the minimatch set - var n = this.minimatch.set.length + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') - // The matches are stored as {: true,...} so that - // duplicates are automagically pruned. - // Later, we do an Object.keys() on these. - // Keep them as a list so we can fill in when nonull is set. - this.matches = new Array(n) + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) - if (typeof cb === 'function') { - cb = once(cb) - this.on('error', cb) - this.on('end', function (matches) { - cb(null, matches) - }) + return wrapper + + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] + } + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret } +} - var self = this - this._processing = 0 - this._emitQueue = [] - this._processQueue = [] - this.paused = false +/***/ }), +/* 124 */, +/* 125 */, +/* 126 */, +/* 127 */, +/* 128 */, +/* 129 */, +/* 130 */, +/* 131 */ +/***/ (function(module, exports, __webpack_require__) { - if (this.noprocess) - return this +// fallback for non-array-like ES3 and non-enumerable old V8 strings +var cof = __webpack_require__(47); +// eslint-disable-next-line no-prototype-builtins +module.exports = Object('z').propertyIsEnumerable(0) ? Object : function (it) { + return cof(it) == 'String' ? it.split('') : Object(it); +}; - if (n === 0) - return done() - var sync = true - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false, done) - } - sync = false +/***/ }), +/* 132 */ +/***/ (function(module, exports, __webpack_require__) { - function done () { - --self._processing - if (self._processing <= 0) { - if (sync) { - process.nextTick(function () { - self._finish() - }) - } else { - self._finish() - } - } - } -} +// 19.1.2.14 / 15.2.3.14 Object.keys(O) +var $keys = __webpack_require__(195); +var enumBugKeys = __webpack_require__(101); -Glob.prototype._finish = function () { - assert(this instanceof Glob) - if (this.aborted) - return +module.exports = Object.keys || function keys(O) { + return $keys(O, enumBugKeys); +}; - if (this.realpath && !this._didRealpath) - return this._realpath() - common.finish(this) - this.emit('end', this.found) -} +/***/ }), +/* 133 */ +/***/ (function(module, exports, __webpack_require__) { -Glob.prototype._realpath = function () { - if (this._didRealpath) - return +// 7.1.13 ToObject(argument) +var defined = __webpack_require__(67); +module.exports = function (it) { + return Object(defined(it)); +}; - this._didRealpath = true - var n = this.matches.length - if (n === 0) - return this._finish() +/***/ }), +/* 134 */, +/* 135 */, +/* 136 */, +/* 137 */, +/* 138 */, +/* 139 */, +/* 140 */, +/* 141 */, +/* 142 */, +/* 143 */, +/* 144 */, +/* 145 */ +/***/ (function(module, exports) { - var self = this - for (var i = 0; i < this.matches.length; i++) - this._realpathSet(i, next) +module.exports = {"name":"yarn","installationMethod":"unknown","version":"1.10.0-0","license":"BSD-2-Clause","preferGlobal":true,"description":"📦🐈 Fast, reliable, and secure dependency management.","dependencies":{"@zkochan/cmd-shim":"^2.2.4","babel-runtime":"^6.26.0","bytes":"^3.0.0","camelcase":"^4.0.0","chalk":"^2.1.0","commander":"^2.9.0","death":"^1.0.0","debug":"^3.0.0","deep-equal":"^1.0.1","detect-indent":"^5.0.0","dnscache":"^1.0.1","glob":"^7.1.1","gunzip-maybe":"^1.4.0","hash-for-dep":"^1.2.3","imports-loader":"^0.8.0","ini":"^1.3.4","inquirer":"^3.0.1","invariant":"^2.2.0","is-builtin-module":"^2.0.0","is-ci":"^1.0.10","is-webpack-bundle":"^1.0.0","leven":"^2.0.0","loud-rejection":"^1.2.0","micromatch":"^2.3.11","mkdirp":"^0.5.1","node-emoji":"^1.6.1","normalize-url":"^2.0.0","npm-logical-tree":"^1.2.1","object-path":"^0.11.2","proper-lockfile":"^2.0.0","puka":"^1.0.0","read":"^1.0.7","request":"^2.87.0","request-capture-har":"^1.2.2","rimraf":"^2.5.0","semver":"^5.1.0","ssri":"^5.3.0","strip-ansi":"^4.0.0","strip-bom":"^3.0.0","tar-fs":"^1.16.0","tar-stream":"^1.6.1","uuid":"^3.0.1","v8-compile-cache":"^2.0.0","validate-npm-package-license":"^3.0.3","yn":"^2.0.0"},"devDependencies":{"babel-core":"^6.26.0","babel-eslint":"^7.2.3","babel-loader":"^6.2.5","babel-plugin-array-includes":"^2.0.3","babel-plugin-transform-builtin-extend":"^1.1.2","babel-plugin-transform-inline-imports-commonjs":"^1.0.0","babel-plugin-transform-runtime":"^6.4.3","babel-preset-env":"^1.6.0","babel-preset-flow":"^6.23.0","babel-preset-stage-0":"^6.0.0","babylon":"^6.5.0","commitizen":"^2.9.6","cz-conventional-changelog":"^2.0.0","eslint":"^4.3.0","eslint-config-fb-strict":"^22.0.0","eslint-plugin-babel":"^5.0.0","eslint-plugin-flowtype":"^2.35.0","eslint-plugin-jasmine":"^2.6.2","eslint-plugin-jest":"^21.0.0","eslint-plugin-jsx-a11y":"^6.0.2","eslint-plugin-prefer-object-spread":"^1.2.1","eslint-plugin-prettier":"^2.1.2","eslint-plugin-react":"^7.1.0","eslint-plugin-relay":"^0.0.24","eslint-plugin-yarn-internal":"file:scripts/eslint-rules","execa":"^0.10.0","flow-bin":"^0.66.0","git-release-notes":"^3.0.0","gulp":"^3.9.0","gulp-babel":"^7.0.0","gulp-if":"^2.0.1","gulp-newer":"^1.0.0","gulp-plumber":"^1.0.1","gulp-sourcemaps":"^2.2.0","gulp-util":"^3.0.7","gulp-watch":"^5.0.0","jest":"^22.4.4","jsinspect":"^0.12.6","minimatch":"^3.0.4","mock-stdin":"^0.3.0","prettier":"^1.5.2","temp":"^0.8.3","webpack":"^2.1.0-beta.25","yargs":"^6.3.0"},"resolutions":{"sshpk":"^1.14.2"},"engines":{"node":">=4.0.0"},"repository":"yarnpkg/yarn","bin":{"yarn":"./bin/yarn.js","yarnpkg":"./bin/yarn.js"},"scripts":{"build":"gulp build","build-bundle":"node ./scripts/build-webpack.js","build-chocolatey":"powershell ./scripts/build-chocolatey.ps1","build-deb":"./scripts/build-deb.sh","build-dist":"bash ./scripts/build-dist.sh","build-win-installer":"scripts\\build-windows-installer.bat","changelog":"git-release-notes $(git describe --tags --abbrev=0 $(git describe --tags --abbrev=0)^)..$(git describe --tags --abbrev=0) scripts/changelog.md","dupe-check":"yarn jsinspect ./src","lint":"eslint . && flow check","pkg-tests":"yarn --cwd packages/pkg-tests jest yarn.test.js","prettier":"eslint src __tests__ --fix","release-branch":"./scripts/release-branch.sh","test":"yarn lint && yarn test-only","test-only":"node --max_old_space_size=4096 node_modules/jest/bin/jest.js --verbose","test-only-debug":"node --inspect-brk --max_old_space_size=4096 node_modules/jest/bin/jest.js --runInBand --verbose","test-coverage":"node --max_old_space_size=4096 node_modules/jest/bin/jest.js --coverage --verbose","watch":"gulp watch","commit":"git-cz"},"jest":{"collectCoverageFrom":["src/**/*.js"],"testEnvironment":"node","modulePathIgnorePatterns":["__tests__/fixtures/","packages/pkg-tests/pkg-tests-fixtures","dist/"],"testPathIgnorePatterns":["__tests__/(fixtures|__mocks__)/","updates/","_(temp|mock|install|init|helpers).js$","packages/pkg-tests"]},"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}}} - function next () { - if (--n === 0) - self._finish() - } -} +/***/ }), +/* 146 */, +/* 147 */, +/* 148 */, +/* 149 */, +/* 150 */ +/***/ (function(module, exports, __webpack_require__) { -Glob.prototype._realpathSet = function (index, cb) { - var matchset = this.matches[index] - if (!matchset) - return cb() +"use strict"; - var found = Object.keys(matchset) - var self = this - var n = found.length - if (n === 0) - return cb() +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = stringify; - var set = this.matches[index] = Object.create(null) - found.forEach(function (p, i) { - // If there's a problem with the stat, then it means that - // one or more of the links in the realpath couldn't be - // resolved. just return the abs value in that case. - p = self._makeAbs(p) - rp.realpath(p, self.realpathCache, function (er, real) { - if (!er) - set[real] = true - else if (er.syscall === 'stat') - set[p] = true - else - self.emit('error', er) // srsly wtf right here +var _misc; - if (--n === 0) { - self.matches[index] = set - cb() - } - }) - }) +function _load_misc() { + return _misc = __webpack_require__(12); } -Glob.prototype._mark = function (p) { - return common.mark(this, p) -} +var _constants; -Glob.prototype._makeAbs = function (f) { - return common.makeAbs(this, f) +function _load_constants() { + return _constants = __webpack_require__(6); } -Glob.prototype.abort = function () { - this.aborted = true - this.emit('abort') +var _package; + +function _load_package() { + return _package = __webpack_require__(145); } -Glob.prototype.pause = function () { - if (!this.paused) { - this.paused = true - this.emit('pause') - } +const NODE_VERSION = process.version; + +function shouldWrapKey(str) { + return str.indexOf('true') === 0 || str.indexOf('false') === 0 || /[:\s\n\\",\[\]]/g.test(str) || /^[0-9]/g.test(str) || !/^[a-zA-Z]/g.test(str); } -Glob.prototype.resume = function () { - if (this.paused) { - this.emit('resume') - this.paused = false - if (this._emitQueue.length) { - var eq = this._emitQueue.slice(0) - this._emitQueue.length = 0 - for (var i = 0; i < eq.length; i ++) { - var e = eq[i] - this._emitMatch(e[0], e[1]) - } - } - if (this._processQueue.length) { - var pq = this._processQueue.slice(0) - this._processQueue.length = 0 - for (var i = 0; i < pq.length; i ++) { - var p = pq[i] - this._processing-- - this._process(p[0], p[1], p[2], p[3]) - } - } +function maybeWrap(str) { + if (typeof str === 'boolean' || typeof str === 'number' || shouldWrapKey(str)) { + return JSON.stringify(str); + } else { + return str; } } -Glob.prototype._process = function (pattern, index, inGlobStar, cb) { - assert(this instanceof Glob) - assert(typeof cb === 'function') +const priorities = { + name: 1, + version: 2, + uid: 3, + resolved: 4, + integrity: 5, + registry: 6, + dependencies: 7 +}; - if (this.aborted) - return +function priorityThenAlphaSort(a, b) { + if (priorities[a] || priorities[b]) { + return (priorities[a] || 100) > (priorities[b] || 100) ? 1 : -1; + } else { + return (0, (_misc || _load_misc()).sortAlpha)(a, b); + } +} - this._processing++ - if (this.paused) { - this._processQueue.push([pattern, index, inGlobStar, cb]) - return +function _stringify(obj, options) { + if (typeof obj !== 'object') { + throw new TypeError(); } - //console.error('PROCESS %d', this._processing, pattern) + const indent = options.indent; + const lines = []; - // Get the first [n] parts of pattern that are all strings. - var n = 0 - while (typeof pattern[n] === 'string') { - n ++ - } - // now n is the index of the first one that is *not* a string. + // Sorting order needs to be consistent between runs, we run native sort by name because there are no + // problems with it being unstable because there are no to keys the same + // However priorities can be duplicated and native sort can shuffle things from run to run + const keys = Object.keys(obj).sort(priorityThenAlphaSort); - // see if there's anything else - var prefix - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index, cb) - return + let addedKeys = []; - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null - break + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + const val = obj[key]; + if (val == null || addedKeys.indexOf(key) >= 0) { + continue; + } - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/') - break - } + const valKeys = [key]; - var remain = pattern.slice(n) + // get all keys that have the same value equality, we only want this for objects + if (typeof val === 'object') { + for (let j = i + 1; j < keys.length; j++) { + const key = keys[j]; + if (val === obj[key]) { + valKeys.push(key); + } + } + } - // get the list of entries. - var read - if (prefix === null) - read = '.' - else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { - if (!prefix || !isAbsolute(prefix)) - prefix = '/' + prefix - read = prefix - } else - read = prefix + const keyLine = valKeys.sort((_misc || _load_misc()).sortAlpha).map(maybeWrap).join(', '); - var abs = this._makeAbs(read) + if (typeof val === 'string' || typeof val === 'boolean' || typeof val === 'number') { + lines.push(`${keyLine} ${maybeWrap(val)}`); + } else if (typeof val === 'object') { + lines.push(`${keyLine}:\n${_stringify(val, { indent: indent + ' ' })}` + (options.topLevel ? '\n' : '')); + } else { + throw new TypeError(); + } - //if ignored, skip _processing - if (childrenIgnored(this, read)) - return cb() + addedKeys = addedKeys.concat(valKeys); + } - var isGlobStar = remain[0] === minimatch.GLOBSTAR - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) + return indent + lines.join(`\n${indent}`); } -Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this - this._readdir(abs, inGlobStar, function (er, entries) { - return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) - }) -} +function stringify(obj, noHeader, enableVersions) { + const val = _stringify(obj, { + indent: '', + topLevel: true + }); + if (noHeader) { + return val; + } -Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + const lines = []; + lines.push('# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.'); + lines.push(`# yarn lockfile v${(_constants || _load_constants()).LOCKFILE_VERSION}`); + if (enableVersions) { + lines.push(`# yarn v${(_package || _load_package()).version}`); + lines.push(`# node ${NODE_VERSION}`); + } + lines.push('\n'); + lines.push(val); - // if the abs isn't a dir, then nothing can match! - if (!entries) - return cb() + return lines.join('\n'); +} - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0] - var negate = !!this.minimatch.negate - var rawGlob = pn._glob - var dotOk = this.dot || rawGlob.charAt(0) === '.' +/***/ }), +/* 151 */, +/* 152 */, +/* 153 */, +/* 154 */, +/* 155 */, +/* 156 */, +/* 157 */, +/* 158 */, +/* 159 */, +/* 160 */, +/* 161 */, +/* 162 */, +/* 163 */, +/* 164 */ +/***/ (function(module, exports, __webpack_require__) { - var matchedEntries = [] - for (var i = 0; i < entries.length; i++) { - var e = entries[i] - if (e.charAt(0) !== '.' || dotOk) { - var m - if (negate && !prefix) { - m = !e.match(pn) - } else { - m = e.match(pn) - } - if (m) - matchedEntries.push(e) - } - } +"use strict"; - //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) - var len = matchedEntries.length - // If there are no matched entries, then nothing matches. - if (len === 0) - return cb() +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.fileDatesEqual = exports.copyFile = exports.unlink = undefined; - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. +var _asyncToGenerator2; - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null) +function _load_asyncToGenerator() { + return _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(1)); +} - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e - else - e = prefix + e - } +// We want to preserve file timestamps when copying a file, since yarn uses them to decide if a file has +// changed compared to the cache. +// There are some OS specific cases here: +// * On linux, fs.copyFile does not preserve timestamps, but does on OSX and Win. +// * On windows, you must open a file with write permissions to call `fs.futimes`. +// * On OSX you can open with read permissions and still call `fs.futimes`. +let fixTimes = (() => { + var _ref3 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (fd, dest, data) { + const doOpen = fd === undefined; + let openfd = fd ? fd : -1; - if (e.charAt(0) === '/' && !this.nomount) { - e = path.join(this.root, e) - } - this._emitMatch(index, e) + if (disableTimestampCorrection === undefined) { + // if timestamps match already, no correction is needed. + // the need to correct timestamps varies based on OS and node versions. + const destStat = yield lstat(dest); + disableTimestampCorrection = fileDatesEqual(destStat.mtime, data.mtime); } - // This was the last one, and no stats were needed - return cb() - } - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift() - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - var newPattern - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e - else - e = prefix + e + if (disableTimestampCorrection) { + return; } - this._process([e].concat(remain), index, inGlobStar, cb) - } - cb() -} - -Glob.prototype._emitMatch = function (index, e) { - if (this.aborted) - return - if (isIgnored(this, e)) - return - - if (this.paused) { - this._emitQueue.push([index, e]) - return - } + if (doOpen) { + try { + openfd = yield open(dest, 'a', data.mode); + } catch (er) { + // file is likely read-only + try { + openfd = yield open(dest, 'r', data.mode); + } catch (err) { + // We can't even open this file for reading. + return; + } + } + } - var abs = isAbsolute(e) ? e : this._makeAbs(e) + try { + if (openfd) { + yield futimes(openfd, data.atime, data.mtime); + } + } catch (er) { + // If `futimes` throws an exception, we probably have a case of a read-only file on Windows. + // In this case we can just return. The incorrect timestamp will just cause that file to be recopied + // on subsequent installs, which will effect yarn performance but not break anything. + } finally { + if (doOpen && openfd) { + yield close(openfd); + } + } + }); - if (this.mark) - e = this._mark(e) + return function fixTimes(_x7, _x8, _x9) { + return _ref3.apply(this, arguments); + }; +})(); - if (this.absolute) - e = abs +// Compare file timestamps. +// Some versions of Node on windows zero the milliseconds when utime is used. - if (this.matches[index][e]) - return - if (this.nodir) { - var c = this.cache[abs] - if (c === 'DIR' || Array.isArray(c)) - return - } +var _fs; - this.matches[index][e] = true +function _load_fs() { + return _fs = _interopRequireDefault(__webpack_require__(3)); +} - var st = this.statCache[abs] - if (st) - this.emit('stat', e, st) +var _promise; - this.emit('match', e) +function _load_promise() { + return _promise = __webpack_require__(40); } -Glob.prototype._readdirInGlobStar = function (abs, cb) { - if (this.aborted) - return +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false, cb) +// This module serves as a wrapper for file operations that are inconsistant across node and OS versions. - var lstatkey = 'lstat\0' + abs - var self = this - var lstatcb = inflight(lstatkey, lstatcb_) +let disableTimestampCorrection = undefined; // OS dependent. will be detected on first file copy. - if (lstatcb) - fs.lstat(abs, lstatcb) +const readFileBuffer = (0, (_promise || _load_promise()).promisify)((_fs || _load_fs()).default.readFile); +const close = (0, (_promise || _load_promise()).promisify)((_fs || _load_fs()).default.close); +const lstat = (0, (_promise || _load_promise()).promisify)((_fs || _load_fs()).default.lstat); +const open = (0, (_promise || _load_promise()).promisify)((_fs || _load_fs()).default.open); +const futimes = (0, (_promise || _load_promise()).promisify)((_fs || _load_fs()).default.futimes); - function lstatcb_ (er, lstat) { - if (er && er.code === 'ENOENT') - return cb() +const write = (0, (_promise || _load_promise()).promisify)((_fs || _load_fs()).default.write); - var isSym = lstat && lstat.isSymbolicLink() - self.symlinks[abs] = isSym +const unlink = exports.unlink = (0, (_promise || _load_promise()).promisify)(__webpack_require__(233)); - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && lstat && !lstat.isDirectory()) { - self.cache[abs] = 'FILE' - cb() - } else - self._readdir(abs, false, cb) - } -} +/** + * Unlinks the destination to force a recreation. This is needed on case-insensitive file systems + * to force the correct naming when the filename has changed only in character-casing. (Jest -> jest). + */ +const copyFile = exports.copyFile = (() => { + var _ref = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data, cleanup) { + try { + yield unlink(data.dest); + yield copyFilePoly(data.src, data.dest, 0, data); + } finally { + if (cleanup) { + cleanup(); + } + } + }); -Glob.prototype._readdir = function (abs, inGlobStar, cb) { - if (this.aborted) - return + return function copyFile(_x, _x2) { + return _ref.apply(this, arguments); + }; +})(); - cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) - if (!cb) - return +// Node 8.5.0 introduced `fs.copyFile` which is much faster, so use that when available. +// Otherwise we fall back to reading and writing files as buffers. +const copyFilePoly = (src, dest, flags, data) => { + if ((_fs || _load_fs()).default.copyFile) { + return new Promise((resolve, reject) => (_fs || _load_fs()).default.copyFile(src, dest, flags, err => { + if (err) { + reject(err); + } else { + fixTimes(undefined, dest, data).then(() => resolve()).catch(ex => reject(ex)); + } + })); + } else { + return copyWithBuffer(src, dest, flags, data); + } +}; - //console.error('RD %j %j', +inGlobStar, abs) - if (inGlobStar && !ownProp(this.symlinks, abs)) - return this._readdirInGlobStar(abs, cb) +const copyWithBuffer = (() => { + var _ref2 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (src, dest, flags, data) { + // Use open -> write -> futimes -> close sequence to avoid opening the file twice: + // one with writeFile and one with utimes + const fd = yield open(dest, 'w', data.mode); + try { + const buffer = yield readFileBuffer(src); + yield write(fd, buffer, 0, buffer.length); + yield fixTimes(fd, dest, data); + } finally { + yield close(fd); + } + }); - if (ownProp(this.cache, abs)) { - var c = this.cache[abs] - if (!c || c === 'FILE') - return cb() + return function copyWithBuffer(_x3, _x4, _x5, _x6) { + return _ref2.apply(this, arguments); + }; +})();const fileDatesEqual = exports.fileDatesEqual = (a, b) => { + const aTime = a.getTime(); + const bTime = b.getTime(); - if (Array.isArray(c)) - return cb(null, c) + if (process.platform !== 'win32') { + return aTime === bTime; } - var self = this - fs.readdir(abs, readdirCb(this, abs, cb)) -} - -function readdirCb (self, abs, cb) { - return function (er, entries) { - if (er) - self._readdirError(abs, er, cb) - else - self._readdirEntries(abs, entries, cb) + // See https://github.com/nodejs/node/pull/12607 + // Submillisecond times from stat and utimes are truncated on Windows, + // causing a file with mtime 8.0079998 and 8.0081144 to become 8.007 and 8.008 + // and making it impossible to update these files to their correct timestamps. + if (Math.abs(aTime - bTime) <= 1) { + return true; } -} -Glob.prototype._readdirEntries = function (abs, entries, cb) { - if (this.aborted) - return + const aTimeSec = Math.floor(aTime / 1000); + const bTimeSec = Math.floor(bTime / 1000); - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i] - if (abs === '/') - e = abs + e - else - e = abs + '/' + e - this.cache[e] = true - } + // See https://github.com/nodejs/node/issues/2069 + // Some versions of Node on windows zero the milliseconds when utime is used + // So if any of the time has a milliseconds part of zero we suspect that the + // bug is present and compare only seconds. + if (aTime - aTimeSec * 1000 === 0 || bTime - bTimeSec * 1000 === 0) { + return aTimeSec === bTimeSec; } - this.cache[abs] = entries - return cb(null, entries) -} + return aTime === bTime; +}; -Glob.prototype._readdirError = function (f, er, cb) { - if (this.aborted) - return +/***/ }), +/* 165 */, +/* 166 */, +/* 167 */, +/* 168 */, +/* 169 */ +/***/ (function(module, exports, __webpack_require__) { - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - var abs = this._makeAbs(f) - this.cache[abs] = 'FILE' - if (abs === this.cwdAbs) { - var error = new Error(er.code + ' invalid cwd ' + this.cwd) - error.path = this.cwd - error.code = er.code - this.emit('error', error) - this.abort() - } - break +"use strict"; - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false - break - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false - if (this.strict) { - this.emit('error', er) - // If the error is handled, then we abort - // if not, we threw out of here - this.abort() - } - if (!this.silent) - console.error('glob error', er) - break +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.isFakeRoot = isFakeRoot; +exports.isRootUser = isRootUser; +function getUid() { + if (process.platform !== 'win32' && process.getuid) { + return process.getuid(); } - - return cb() + return null; } -Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this - this._readdir(abs, inGlobStar, function (er, entries) { - self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) - }) +exports.default = isRootUser(getUid()) && !isFakeRoot(); +function isFakeRoot() { + return Boolean(process.env.FAKEROOTKEY); } +function isRootUser(uid) { + return uid === 0; +} -Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { - //console.error('pgs2', prefix, remain[0], entries) +/***/ }), +/* 170 */, +/* 171 */ +/***/ (function(module, exports, __webpack_require__) { - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return cb() +"use strict"; - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1) - var gspref = prefix ? [ prefix ] : [] - var noGlobStar = gspref.concat(remainWithoutGlobStar) - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false, cb) - - var isSym = this.symlinks[abs] - var len = entries.length - - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return cb() +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getDataDir = getDataDir; +exports.getCacheDir = getCacheDir; +exports.getConfigDir = getConfigDir; +const path = __webpack_require__(0); +const userHome = __webpack_require__(45).default; - for (var i = 0; i < len; i++) { - var e = entries[i] - if (e.charAt(0) === '.' && !this.dot) - continue +const FALLBACK_CONFIG_DIR = path.join(userHome, '.config', 'yarn'); +const FALLBACK_CACHE_DIR = path.join(userHome, '.cache', 'yarn'); - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar) - this._process(instead, index, true, cb) +function getDataDir() { + if (process.platform === 'win32') { + const WIN32_APPDATA_DIR = getLocalAppDataDir(); + return WIN32_APPDATA_DIR == null ? FALLBACK_CONFIG_DIR : path.join(WIN32_APPDATA_DIR, 'Data'); + } else if (process.env.XDG_DATA_HOME) { + return path.join(process.env.XDG_DATA_HOME, 'yarn'); + } else { + // This could arguably be ~/Library/Application Support/Yarn on Macs, + // but that feels unintuitive for a cli tool - var below = gspref.concat(entries[i], remain) - this._process(below, index, true, cb) + // Instead, use our prior fallback. Some day this could be + // path.join(userHome, '.local', 'share', 'yarn') + // or return path.join(WIN32_APPDATA_DIR, 'Data') on win32 + return FALLBACK_CONFIG_DIR; } +} - cb() +function getCacheDir() { + if (process.platform === 'win32') { + // process.env.TEMP also exists, but most apps put caches here + return path.join(getLocalAppDataDir() || path.join(userHome, 'AppData', 'Local', 'Yarn'), 'Cache'); + } else if (process.env.XDG_CACHE_HOME) { + return path.join(process.env.XDG_CACHE_HOME, 'yarn'); + } else if (process.platform === 'darwin') { + return path.join(userHome, 'Library', 'Caches', 'Yarn'); + } else { + return FALLBACK_CACHE_DIR; + } } -Glob.prototype._processSimple = function (prefix, index, cb) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var self = this - this._stat(prefix, function (er, exists) { - self._processSimple2(prefix, index, er, exists, cb) - }) +function getConfigDir() { + if (process.platform === 'win32') { + // Use our prior fallback. Some day this could be + // return path.join(WIN32_APPDATA_DIR, 'Config') + const WIN32_APPDATA_DIR = getLocalAppDataDir(); + return WIN32_APPDATA_DIR == null ? FALLBACK_CONFIG_DIR : path.join(WIN32_APPDATA_DIR, 'Config'); + } else if (process.env.XDG_CONFIG_HOME) { + return path.join(process.env.XDG_CONFIG_HOME, 'yarn'); + } else { + return FALLBACK_CONFIG_DIR; + } } -Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { - //console.error('ps2', prefix, exists) +function getLocalAppDataDir() { + return process.env.LOCALAPPDATA ? path.join(process.env.LOCALAPPDATA, 'Yarn') : null; +} - if (!this.matches[index]) - this.matches[index] = Object.create(null) +/***/ }), +/* 172 */, +/* 173 */ +/***/ (function(module, exports, __webpack_require__) { - // If it doesn't exist, then just mark the lack of results - if (!exists) - return cb() +module.exports = { "default": __webpack_require__(179), __esModule: true }; - if (prefix && isAbsolute(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix) - if (prefix.charAt(0) === '/') { - prefix = path.join(this.root, prefix) - } else { - prefix = path.resolve(this.root, prefix) - if (trail) - prefix += '/' - } - } +/***/ }), +/* 174 */ +/***/ (function(module, exports, __webpack_require__) { - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/') +"use strict"; - // Mark this as a match - this._emitMatch(index, prefix) - cb() -} +module.exports = balanced; +function balanced(a, b, str) { + if (a instanceof RegExp) a = maybeMatch(a, str); + if (b instanceof RegExp) b = maybeMatch(b, str); -// Returns either 'DIR', 'FILE', or false -Glob.prototype._stat = function (f, cb) { - var abs = this._makeAbs(f) - var needDir = f.slice(-1) === '/' + var r = range(a, b, str); - if (f.length > this.maxLength) - return cb() + return r && { + start: r[0], + end: r[1], + pre: str.slice(0, r[0]), + body: str.slice(r[0] + a.length, r[1]), + post: str.slice(r[1] + b.length) + }; +} - if (!this.stat && ownProp(this.cache, abs)) { - var c = this.cache[abs] +function maybeMatch(reg, str) { + var m = str.match(reg); + return m ? m[0] : null; +} - if (Array.isArray(c)) - c = 'DIR' +balanced.range = range; +function range(a, b, str) { + var begs, beg, left, right, result; + var ai = str.indexOf(a); + var bi = str.indexOf(b, ai + 1); + var i = ai; - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return cb(null, c) + if (ai >= 0 && bi > 0) { + begs = []; + left = str.length; - if (needDir && c === 'FILE') - return cb() + while (i >= 0 && !result) { + if (i == ai) { + begs.push(i); + ai = str.indexOf(a, i + 1); + } else if (begs.length == 1) { + result = [ begs.pop(), bi ]; + } else { + beg = begs.pop(); + if (beg < left) { + left = beg; + right = bi; + } - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. - } + bi = str.indexOf(b, i + 1); + } - var exists - var stat = this.statCache[abs] - if (stat !== undefined) { - if (stat === false) - return cb(null, stat) - else { - var type = stat.isDirectory() ? 'DIR' : 'FILE' - if (needDir && type === 'FILE') - return cb() - else - return cb(null, type, stat) + i = ai < bi && ai >= 0 ? ai : bi; } - } - - var self = this - var statcb = inflight('stat\0' + abs, lstatcb_) - if (statcb) - fs.lstat(abs, statcb) - function lstatcb_ (er, lstat) { - if (lstat && lstat.isSymbolicLink()) { - // If it's a symlink, then treat it as the target, unless - // the target does not exist, then treat it as a file. - return fs.stat(abs, function (er, stat) { - if (er) - self._stat2(f, abs, null, lstat, cb) - else - self._stat2(f, abs, er, stat, cb) - }) - } else { - self._stat2(f, abs, er, lstat, cb) + if (begs.length) { + result = [ left, right ]; } } -} - -Glob.prototype._stat2 = function (f, abs, er, stat, cb) { - if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { - this.statCache[abs] = false - return cb() - } - - var needDir = f.slice(-1) === '/' - this.statCache[abs] = stat - - if (abs.slice(-1) === '/' && stat && !stat.isDirectory()) - return cb(null, false, stat) - - var c = true - if (stat) - c = stat.isDirectory() ? 'DIR' : 'FILE' - this.cache[abs] = this.cache[abs] || c - - if (needDir && c === 'FILE') - return cb() - return cb(null, c, stat) + return result; } /***/ }), -/* 76 */ +/* 175 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +var concatMap = __webpack_require__(178); +var balanced = __webpack_require__(174); +module.exports = expandTop; -function posix(path) { - return path.charAt(0) === '/'; +var escSlash = '\0SLASH'+Math.random()+'\0'; +var escOpen = '\0OPEN'+Math.random()+'\0'; +var escClose = '\0CLOSE'+Math.random()+'\0'; +var escComma = '\0COMMA'+Math.random()+'\0'; +var escPeriod = '\0PERIOD'+Math.random()+'\0'; + +function numeric(str) { + return parseInt(str, 10) == str + ? parseInt(str, 10) + : str.charCodeAt(0); } -function win32(path) { - // https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56 - var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; - var result = splitDeviceRe.exec(path); - var device = result[1] || ''; - var isUnc = Boolean(device && device.charAt(1) !== ':'); +function escapeBraces(str) { + return str.split('\\\\').join(escSlash) + .split('\\{').join(escOpen) + .split('\\}').join(escClose) + .split('\\,').join(escComma) + .split('\\.').join(escPeriod); +} - // UNC paths are always absolute - return Boolean(result[2] || isUnc); +function unescapeBraces(str) { + return str.split(escSlash).join('\\') + .split(escOpen).join('{') + .split(escClose).join('}') + .split(escComma).join(',') + .split(escPeriod).join('.'); } -module.exports = process.platform === 'win32' ? win32 : posix; -module.exports.posix = posix; -module.exports.win32 = win32; +// Basically just str.split(","), but handling cases +// where we have nested braced sections, which should be +// treated as individual members, like {a,{b,c},d} +function parseCommaParts(str) { + if (!str) + return ['']; -/***/ }), -/* 77 */, -/* 78 */, -/* 79 */ -/***/ (function(module, exports) { + var parts = []; + var m = balanced('{', '}', str); -module.exports = __webpack_require__(121); + if (!m) + return str.split(','); -/***/ }), -/* 80 */, -/* 81 */ -/***/ (function(module, exports, __webpack_require__) { + var pre = m.pre; + var body = m.body; + var post = m.post; + var p = pre.split(','); -"use strict"; + p[p.length-1] += '{' + body + '}'; + var postParts = parseCommaParts(post); + if (post.length) { + p[p.length-1] += postParts.shift(); + p.push.apply(p, postParts); + } + parts.push.apply(parts, p); -Object.defineProperty(exports, "__esModule", { - value: true -}); + return parts; +} -exports.default = function (str, fileLoc = 'lockfile') { - str = (0, (_stripBom || _load_stripBom()).default)(str); - return hasMergeConflicts(str) ? parseWithConflict(str, fileLoc) : { type: 'success', object: parse(str, fileLoc) }; -}; +function expandTop(str) { + if (!str) + return []; -var _util; + // I don't know why Bash 4.3 does this, but it does. + // Anything starting with {} will have the first two bytes preserved + // but *only* at the top level, so {},a}b will not expand to anything, + // but a{},b}c will be expanded to [a}c,abc]. + // One could argue that this is a bug in Bash, but since the goal of + // this module is to match Bash's rules, we escape a leading {} + if (str.substr(0, 2) === '{}') { + str = '\\{\\}' + str.substr(2); + } -function _load_util() { - return _util = _interopRequireDefault(__webpack_require__(2)); + return expand(escapeBraces(str), true).map(unescapeBraces); } -var _invariant; - -function _load_invariant() { - return _invariant = _interopRequireDefault(__webpack_require__(7)); +function identity(e) { + return e; } -var _stripBom; +function embrace(str) { + return '{' + str + '}'; +} +function isPadded(el) { + return /^-?0\d/.test(el); +} -function _load_stripBom() { - return _stripBom = _interopRequireDefault(__webpack_require__(122)); +function lte(i, y) { + return i <= y; +} +function gte(i, y) { + return i >= y; } -var _constants; +function expand(str, isTop) { + var expansions = []; -function _load_constants() { - return _constants = __webpack_require__(6); -} + var m = balanced('{', '}', str); + if (!m || /\$$/.test(m.pre)) return [str]; -var _errors; + var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); + var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); + var isSequence = isNumericSequence || isAlphaSequence; + var isOptions = m.body.indexOf(',') >= 0; + if (!isSequence && !isOptions) { + // {a},b} + if (m.post.match(/,.*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; + return expand(str); + } + return [str]; + } -function _load_errors() { - return _errors = __webpack_require__(4); -} + var n; + if (isSequence) { + n = m.body.split(/\.\./); + } else { + n = parseCommaParts(m.body); + if (n.length === 1) { + // x{{a,b}}y ==> x{a}y x{b}y + n = expand(n[0], false).map(embrace); + if (n.length === 1) { + var post = m.post.length + ? expand(m.post, false) + : ['']; + return post.map(function(p) { + return m.pre + n[0] + p; + }); + } + } + } -var _map; + // at this point, n is the parts, and we know it's not a comma set + // with a single entry. -function _load_map() { - return _map = _interopRequireDefault(__webpack_require__(20)); -} + // no need to expand pre, since it is guaranteed to be free of brace-sets + var pre = m.pre; + var post = m.post.length + ? expand(m.post, false) + : ['']; -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + var N; -/* eslint quotes: 0 */ + if (isSequence) { + var x = numeric(n[0]); + var y = numeric(n[1]); + var width = Math.max(n[0].length, n[1].length) + var incr = n.length == 3 + ? Math.abs(numeric(n[2])) + : 1; + var test = lte; + var reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; + } + var pad = n.some(isPadded); -const VERSION_REGEX = /^yarn lockfile v(\d+)$/; + N = []; -const TOKEN_TYPES = { - boolean: 'BOOLEAN', - string: 'STRING', - identifier: 'IDENTIFIER', - eof: 'EOF', - colon: 'COLON', - newline: 'NEWLINE', - comment: 'COMMENT', - indent: 'INDENT', - invalid: 'INVALID', - number: 'NUMBER', - comma: 'COMMA' -}; + for (var i = x; test(i, y); i += incr) { + var c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') + c = ''; + } else { + c = String(i); + if (pad) { + var need = width - c.length; + if (need > 0) { + var z = new Array(need + 1).join('0'); + if (i < 0) + c = '-' + z + c.slice(1); + else + c = z + c; + } + } + } + N.push(c); + } + } else { + N = concatMap(n, function(el) { return expand(el, false) }); + } -const VALID_PROP_VALUE_TOKENS = [TOKEN_TYPES.boolean, TOKEN_TYPES.string, TOKEN_TYPES.number]; + for (var j = 0; j < N.length; j++) { + for (var k = 0; k < post.length; k++) { + var expansion = pre + N[j] + post[k]; + if (!isTop || isSequence || expansion) + expansions.push(expansion); + } + } -function isValidPropValueToken(token) { - return VALID_PROP_VALUE_TOKENS.indexOf(token.type) >= 0; + return expansions; } -function* tokenise(input) { - let lastNewline = false; - let line = 1; - let col = 0; - function buildToken(type, value) { - return { line, col, type, value }; - } - while (input.length) { - let chop = 0; +/***/ }), +/* 176 */ +/***/ (function(module, exports, __webpack_require__) { - if (input[0] === '\n' || input[0] === '\r') { - chop++; - // If this is a \r\n line, ignore both chars but only add one new line - if (input[1] === '\n') { - chop++; - } - line++; - col = 0; - yield buildToken(TOKEN_TYPES.newline); - } else if (input[0] === '#') { - chop++; +"use strict"; - let val = ''; - while (input[chop] !== '\n') { - val += input[chop]; - chop++; - } - yield buildToken(TOKEN_TYPES.comment, val); - } else if (input[0] === ' ') { - if (lastNewline) { - let indent = ''; - for (let i = 0; input[i] === ' '; i++) { - indent += input[i]; - } - if (indent.length % 2) { - throw new TypeError('Invalid number of spaces'); - } else { - chop = indent.length; - yield buildToken(TOKEN_TYPES.indent, indent.length / 2); - } - } else { - chop++; - } - } else if (input[0] === '"') { - let val = ''; +function preserveCamelCase(str) { + let isLastCharLower = false; + let isLastCharUpper = false; + let isLastLastCharUpper = false; - for (let i = 0;; i++) { - const currentChar = input[i]; - val += currentChar; - - if (i > 0 && currentChar === '"') { - const isEscaped = input[i - 1] === '\\' && input[i - 2] !== '\\'; - if (!isEscaped) { - break; - } - } - } - - chop = val.length; - - try { - yield buildToken(TOKEN_TYPES.string, JSON.parse(val)); - } catch (err) { - if (err instanceof SyntaxError) { - yield buildToken(TOKEN_TYPES.invalid); - } else { - throw err; - } - } - } else if (/^[0-9]/.test(input)) { - let val = ''; - for (let i = 0; /^[0-9]$/.test(input[i]); i++) { - val += input[i]; - } - chop = val.length; - - yield buildToken(TOKEN_TYPES.number, +val); - } else if (/^true/.test(input)) { - yield buildToken(TOKEN_TYPES.boolean, true); - chop = 4; - } else if (/^false/.test(input)) { - yield buildToken(TOKEN_TYPES.boolean, false); - chop = 5; - } else if (input[0] === ':') { - yield buildToken(TOKEN_TYPES.colon); - chop++; - } else if (input[0] === ',') { - yield buildToken(TOKEN_TYPES.comma); - chop++; - } else if (/^[a-zA-Z\/-]/g.test(input)) { - let name = ''; - for (let i = 0; i < input.length; i++) { - const char = input[i]; - if (char === ':' || char === ' ' || char === '\n' || char === '\r' || char === ',') { - break; - } else { - name += char; - } - } - chop = name.length; - - yield buildToken(TOKEN_TYPES.string, name); - } else { - yield buildToken(TOKEN_TYPES.invalid); - } - - if (!chop) { - // will trigger infinite recursion - yield buildToken(TOKEN_TYPES.invalid); - } + for (let i = 0; i < str.length; i++) { + const c = str[i]; - col += chop; - lastNewline = input[0] === '\n' || input[0] === '\r' && input[1] === '\n'; - input = input.slice(chop); - } + if (isLastCharLower && /[a-zA-Z]/.test(c) && c.toUpperCase() === c) { + str = str.substr(0, i) + '-' + str.substr(i); + isLastCharLower = false; + isLastLastCharUpper = isLastCharUpper; + isLastCharUpper = true; + i++; + } else if (isLastCharUpper && isLastLastCharUpper && /[a-zA-Z]/.test(c) && c.toLowerCase() === c) { + str = str.substr(0, i - 1) + '-' + str.substr(i - 1); + isLastLastCharUpper = isLastCharUpper; + isLastCharUpper = false; + isLastCharLower = true; + } else { + isLastCharLower = c.toLowerCase() === c; + isLastLastCharUpper = isLastCharUpper; + isLastCharUpper = c.toUpperCase() === c; + } + } - yield buildToken(TOKEN_TYPES.eof); + return str; } -class Parser { - constructor(input, fileLoc = 'lockfile') { - this.comments = []; - this.tokens = tokenise(input); - this.fileLoc = fileLoc; - } - - onComment(token) { - const value = token.value; - (0, (_invariant || _load_invariant()).default)(typeof value === 'string', 'expected token value to be a string'); +module.exports = function (str) { + if (arguments.length > 1) { + str = Array.from(arguments) + .map(x => x.trim()) + .filter(x => x.length) + .join('-'); + } else { + str = str.trim(); + } - const comment = value.trim(); + if (str.length === 0) { + return ''; + } - const versionMatch = comment.match(VERSION_REGEX); - if (versionMatch) { - const version = +versionMatch[1]; - if (version > (_constants || _load_constants()).LOCKFILE_VERSION) { - throw new (_errors || _load_errors()).MessageError(`Can't install from a lockfile of version ${version} as you're on an old yarn version that only supports ` + `versions up to ${(_constants || _load_constants()).LOCKFILE_VERSION}. Run \`$ yarn self-update\` to upgrade to the latest version.`); - } - } + if (str.length === 1) { + return str.toLowerCase(); + } - this.comments.push(comment); - } + if (/^[a-z0-9]+$/.test(str)) { + return str; + } - next() { - const item = this.tokens.next(); - (0, (_invariant || _load_invariant()).default)(item, 'expected a token'); + const hasUpperCase = str !== str.toLowerCase(); - const done = item.done, - value = item.value; + if (hasUpperCase) { + str = preserveCamelCase(str); + } - if (done || !value) { - throw new Error('No more tokens'); - } else if (value.type === TOKEN_TYPES.comment) { - this.onComment(value); - return this.next(); - } else { - return this.token = value; - } - } + return str + .replace(/^[_.\- ]+/, '') + .toLowerCase() + .replace(/[_.\- ]+(\w|$)/g, (m, p1) => p1.toUpperCase()); +}; - unexpected(msg = 'Unexpected token') { - throw new SyntaxError(`${msg} ${this.token.line}:${this.token.col} in ${this.fileLoc}`); - } - expect(tokType) { - if (this.token.type === tokType) { - this.next(); - } else { - this.unexpected(); - } - } +/***/ }), +/* 177 */, +/* 178 */ +/***/ (function(module, exports) { - eat(tokType) { - if (this.token.type === tokType) { - this.next(); - return true; - } else { - return false; +module.exports = function (xs, fn) { + var res = []; + for (var i = 0; i < xs.length; i++) { + var x = fn(xs[i], i); + if (isArray(x)) res.push.apply(res, x); + else res.push(x); } - } - - parse(indent = 0) { - const obj = (0, (_map || _load_map()).default)(); + return res; +}; - while (true) { - const propToken = this.token; +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; - if (propToken.type === TOKEN_TYPES.newline) { - const nextToken = this.next(); - if (!indent) { - // if we have 0 indentation then the next token doesn't matter - continue; - } - if (nextToken.type !== TOKEN_TYPES.indent) { - // if we have no indentation after a newline then we've gone down a level - break; - } +/***/ }), +/* 179 */ +/***/ (function(module, exports, __webpack_require__) { - if (nextToken.value === indent) { - // all is good, the indent is on our level - this.next(); - } else { - // the indentation is less than our level - break; - } - } else if (propToken.type === TOKEN_TYPES.indent) { - if (propToken.value === indent) { - this.next(); - } else { - break; - } - } else if (propToken.type === TOKEN_TYPES.eof) { - break; - } else if (propToken.type === TOKEN_TYPES.string) { - // property key - const key = propToken.value; - (0, (_invariant || _load_invariant()).default)(key, 'Expected a key'); +__webpack_require__(205); +__webpack_require__(207); +__webpack_require__(210); +__webpack_require__(206); +__webpack_require__(208); +__webpack_require__(209); +module.exports = __webpack_require__(23).Promise; - const keys = [key]; - this.next(); - // support multiple keys - while (this.token.type === TOKEN_TYPES.comma) { - this.next(); // skip comma +/***/ }), +/* 180 */ +/***/ (function(module, exports) { - const keyToken = this.token; - if (keyToken.type !== TOKEN_TYPES.string) { - this.unexpected('Expected string'); - } +module.exports = function () { /* empty */ }; - const key = keyToken.value; - (0, (_invariant || _load_invariant()).default)(key, 'Expected a key'); - keys.push(key); - this.next(); - } - const valToken = this.token; +/***/ }), +/* 181 */ +/***/ (function(module, exports) { - if (valToken.type === TOKEN_TYPES.colon) { - // object - this.next(); +module.exports = function (it, Constructor, name, forbiddenField) { + if (!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)) { + throw TypeError(name + ': incorrect invocation!'); + } return it; +}; - // parse object - const val = this.parse(indent + 1); - for (var _iterator = keys, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { - var _ref; +/***/ }), +/* 182 */ +/***/ (function(module, exports, __webpack_require__) { - if (_isArray) { - if (_i >= _iterator.length) break; - _ref = _iterator[_i++]; - } else { - _i = _iterator.next(); - if (_i.done) break; - _ref = _i.value; - } +// false -> Array#indexOf +// true -> Array#includes +var toIObject = __webpack_require__(74); +var toLength = __webpack_require__(110); +var toAbsoluteIndex = __webpack_require__(200); +module.exports = function (IS_INCLUDES) { + return function ($this, el, fromIndex) { + var O = toIObject($this); + var length = toLength(O.length); + var index = toAbsoluteIndex(fromIndex, length); + var value; + // Array#includes uses SameValueZero equality algorithm + // eslint-disable-next-line no-self-compare + if (IS_INCLUDES && el != el) while (length > index) { + value = O[index++]; + // eslint-disable-next-line no-self-compare + if (value != value) return true; + // Array#indexOf ignores holes, Array#includes - not + } else for (;length > index; index++) if (IS_INCLUDES || index in O) { + if (O[index] === el) return IS_INCLUDES || index || 0; + } return !IS_INCLUDES && -1; + }; +}; - const key = _ref; - obj[key] = val; - } +/***/ }), +/* 183 */ +/***/ (function(module, exports, __webpack_require__) { - if (indent && this.token.type !== TOKEN_TYPES.indent) { - break; - } - } else if (isValidPropValueToken(valToken)) { - // plain value - for (var _iterator2 = keys, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { - var _ref2; +var ctx = __webpack_require__(48); +var call = __webpack_require__(187); +var isArrayIter = __webpack_require__(186); +var anObject = __webpack_require__(27); +var toLength = __webpack_require__(110); +var getIterFn = __webpack_require__(203); +var BREAK = {}; +var RETURN = {}; +var exports = module.exports = function (iterable, entries, fn, that, ITERATOR) { + var iterFn = ITERATOR ? function () { return iterable; } : getIterFn(iterable); + var f = ctx(fn, that, entries ? 2 : 1); + var index = 0; + var length, step, iterator, result; + if (typeof iterFn != 'function') throw TypeError(iterable + ' is not iterable!'); + // fast case for arrays with default iterator + if (isArrayIter(iterFn)) for (length = toLength(iterable.length); length > index; index++) { + result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]); + if (result === BREAK || result === RETURN) return result; + } else for (iterator = iterFn.call(iterable); !(step = iterator.next()).done;) { + result = call(iterator, f, step.value, entries); + if (result === BREAK || result === RETURN) return result; + } +}; +exports.BREAK = BREAK; +exports.RETURN = RETURN; - if (_isArray2) { - if (_i2 >= _iterator2.length) break; - _ref2 = _iterator2[_i2++]; - } else { - _i2 = _iterator2.next(); - if (_i2.done) break; - _ref2 = _i2.value; - } - const key = _ref2; +/***/ }), +/* 184 */ +/***/ (function(module, exports, __webpack_require__) { - obj[key] = valToken.value; - } +module.exports = !__webpack_require__(33) && !__webpack_require__(85)(function () { + return Object.defineProperty(__webpack_require__(68)('div'), 'a', { get: function () { return 7; } }).a != 7; +}); - this.next(); - } else { - this.unexpected('Invalid value type'); - } - } else { - this.unexpected(`Unknown token: ${(_util || _load_util()).default.inspect(propToken)}`); - } - } - return obj; - } -} +/***/ }), +/* 185 */ +/***/ (function(module, exports) { -const MERGE_CONFLICT_ANCESTOR = '|||||||'; -const MERGE_CONFLICT_END = '>>>>>>>'; -const MERGE_CONFLICT_SEP = '======='; -const MERGE_CONFLICT_START = '<<<<<<<'; +// fast apply, http://jsperf.lnkit.com/fast-apply/5 +module.exports = function (fn, args, that) { + var un = that === undefined; + switch (args.length) { + case 0: return un ? fn() + : fn.call(that); + case 1: return un ? fn(args[0]) + : fn.call(that, args[0]); + case 2: return un ? fn(args[0], args[1]) + : fn.call(that, args[0], args[1]); + case 3: return un ? fn(args[0], args[1], args[2]) + : fn.call(that, args[0], args[1], args[2]); + case 4: return un ? fn(args[0], args[1], args[2], args[3]) + : fn.call(that, args[0], args[1], args[2], args[3]); + } return fn.apply(that, args); +}; -/** - * Extract the two versions of the lockfile from a merge conflict. - */ -function extractConflictVariants(str) { - const variants = [[], []]; - const lines = str.split(/\r?\n/g); - let skip = false; - while (lines.length) { - const line = lines.shift(); - if (line.startsWith(MERGE_CONFLICT_START)) { - // get the first variant - while (lines.length) { - const conflictLine = lines.shift(); - if (conflictLine === MERGE_CONFLICT_SEP) { - skip = false; - break; - } else if (skip || conflictLine.startsWith(MERGE_CONFLICT_ANCESTOR)) { - skip = true; - continue; - } else { - variants[0].push(conflictLine); - } - } +/***/ }), +/* 186 */ +/***/ (function(module, exports, __webpack_require__) { - // get the second variant - while (lines.length) { - const conflictLine = lines.shift(); - if (conflictLine.startsWith(MERGE_CONFLICT_END)) { - break; - } else { - variants[1].push(conflictLine); - } - } - } else { - variants[0].push(line); - variants[1].push(line); - } - } +// check on default Array iterator +var Iterators = __webpack_require__(35); +var ITERATOR = __webpack_require__(13)('iterator'); +var ArrayProto = Array.prototype; - return [variants[0].join('\n'), variants[1].join('\n')]; -} +module.exports = function (it) { + return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it); +}; -/** - * Check if a lockfile has merge conflicts. - */ -function hasMergeConflicts(str) { - return str.includes(MERGE_CONFLICT_START) && str.includes(MERGE_CONFLICT_SEP) && str.includes(MERGE_CONFLICT_END); -} -/** - * Parse the lockfile. - */ -function parse(str, fileLoc) { - const parser = new Parser(str, fileLoc); - parser.next(); - return parser.parse(); -} +/***/ }), +/* 187 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Parse and merge the two variants in a conflicted lockfile. - */ -function parseWithConflict(str, fileLoc) { - const variants = extractConflictVariants(str); +// call something on iterator step with safe closing on error +var anObject = __webpack_require__(27); +module.exports = function (iterator, fn, value, entries) { try { - return { type: 'merge', object: Object.assign({}, parse(variants[0], fileLoc), parse(variants[1], fileLoc)) }; - } catch (err) { - if (err instanceof SyntaxError) { - return { type: 'conflict', object: {} }; - } else { - throw err; - } + return entries ? fn(anObject(value)[0], value[1]) : fn(value); + // 7.4.6 IteratorClose(iterator, completion) + } catch (e) { + var ret = iterator['return']; + if (ret !== undefined) anObject(ret.call(iterator)); + throw e; } -} +}; + /***/ }), -/* 82 */, -/* 83 */, -/* 84 */ +/* 188 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +var create = __webpack_require__(192); +var descriptor = __webpack_require__(106); +var setToStringTag = __webpack_require__(71); +var IteratorPrototype = {}; -Object.defineProperty(exports, "__esModule", { - value: true -}); +// 25.1.2.1.1 %IteratorPrototype%[@@iterator]() +__webpack_require__(31)(IteratorPrototype, __webpack_require__(13)('iterator'), function () { return this; }); -var _map; +module.exports = function (Constructor, NAME, next) { + Constructor.prototype = create(IteratorPrototype, { next: descriptor(1, next) }); + setToStringTag(Constructor, NAME + ' Iterator'); +}; -function _load_map() { - return _map = _interopRequireDefault(__webpack_require__(20)); -} -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +/***/ }), +/* 189 */ +/***/ (function(module, exports, __webpack_require__) { -const debug = __webpack_require__(212)('yarn'); +var ITERATOR = __webpack_require__(13)('iterator'); +var SAFE_CLOSING = false; -class BlockingQueue { - constructor(alias, maxConcurrency = Infinity) { - this.concurrencyQueue = []; - this.maxConcurrency = maxConcurrency; - this.runningCount = 0; - this.warnedStuck = false; - this.alias = alias; - this.first = true; +try { + var riter = [7][ITERATOR](); + riter['return'] = function () { SAFE_CLOSING = true; }; + // eslint-disable-next-line no-throw-literal + Array.from(riter, function () { throw 2; }); +} catch (e) { /* empty */ } - this.running = (0, (_map || _load_map()).default)(); - this.queue = (0, (_map || _load_map()).default)(); +module.exports = function (exec, skipClosing) { + if (!skipClosing && !SAFE_CLOSING) return false; + var safe = false; + try { + var arr = [7]; + var iter = arr[ITERATOR](); + iter.next = function () { return { done: safe = true }; }; + arr[ITERATOR] = function () { return iter; }; + exec(arr); + } catch (e) { /* empty */ } + return safe; +}; - this.stuckTick = this.stuckTick.bind(this); - } - stillActive() { - if (this.stuckTimer) { - clearTimeout(this.stuckTimer); - } +/***/ }), +/* 190 */ +/***/ (function(module, exports) { - this.stuckTimer = setTimeout(this.stuckTick, 5000); +module.exports = function (done, value) { + return { value: value, done: !!done }; +}; - // We need to check the existence of unref because of https://github.com/facebook/jest/issues/4559 - // $FlowFixMe: Node's setInterval returns a Timeout, not a Number - this.stuckTimer.unref && this.stuckTimer.unref(); - } - stuckTick() { - if (this.runningCount === 1) { - this.warnedStuck = true; - debug(`The ${JSON.stringify(this.alias)} blocking queue may be stuck. 5 seconds ` + `without any activity with 1 worker: ${Object.keys(this.running)[0]}`); - } - } +/***/ }), +/* 191 */ +/***/ (function(module, exports, __webpack_require__) { - push(key, factory) { - if (this.first) { - this.first = false; - } else { - this.stillActive(); - } +var global = __webpack_require__(11); +var macrotask = __webpack_require__(109).set; +var Observer = global.MutationObserver || global.WebKitMutationObserver; +var process = global.process; +var Promise = global.Promise; +var isNode = __webpack_require__(47)(process) == 'process'; - return new Promise((resolve, reject) => { - // we're already running so push ourselves to the queue - const queue = this.queue[key] = this.queue[key] || []; - queue.push({ factory, resolve, reject }); +module.exports = function () { + var head, last, notify; - if (!this.running[key]) { - this.shift(key); + var flush = function () { + var parent, fn; + if (isNode && (parent = process.domain)) parent.exit(); + while (head) { + fn = head.fn; + head = head.next; + try { + fn(); + } catch (e) { + if (head) notify(); + else last = undefined; + throw e; } - }); - } - - shift(key) { - if (this.running[key]) { - delete this.running[key]; - this.runningCount--; + } last = undefined; + if (parent) parent.enter(); + }; - if (this.stuckTimer) { - clearTimeout(this.stuckTimer); - this.stuckTimer = null; - } + // Node.js + if (isNode) { + notify = function () { + process.nextTick(flush); + }; + // browsers with MutationObserver, except iOS Safari - https://github.com/zloirock/core-js/issues/339 + } else if (Observer && !(global.navigator && global.navigator.standalone)) { + var toggle = true; + var node = document.createTextNode(''); + new Observer(flush).observe(node, { characterData: true }); // eslint-disable-line no-new + notify = function () { + node.data = toggle = !toggle; + }; + // environments with maybe non-completely correct, but existent Promise + } else if (Promise && Promise.resolve) { + // Promise.resolve without an argument throws an error in LG WebOS 2 + var promise = Promise.resolve(undefined); + notify = function () { + promise.then(flush); + }; + // for other environments - macrotask based on: + // - setImmediate + // - MessageChannel + // - window.postMessag + // - onreadystatechange + // - setTimeout + } else { + notify = function () { + // strange IE + webpack dev server bug - use .call(global) + macrotask.call(global, flush); + }; + } - if (this.warnedStuck) { - this.warnedStuck = false; - debug(`${JSON.stringify(this.alias)} blocking queue finally resolved. Nothing to worry about.`); - } - } + return function (fn) { + var task = { fn: fn, next: undefined }; + if (last) last.next = task; + if (!head) { + head = task; + notify(); + } last = task; + }; +}; - const queue = this.queue[key]; - if (!queue) { - return; - } - var _queue$shift = queue.shift(); +/***/ }), +/* 192 */ +/***/ (function(module, exports, __webpack_require__) { - const resolve = _queue$shift.resolve, - reject = _queue$shift.reject, - factory = _queue$shift.factory; +// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties]) +var anObject = __webpack_require__(27); +var dPs = __webpack_require__(193); +var enumBugKeys = __webpack_require__(101); +var IE_PROTO = __webpack_require__(72)('IE_PROTO'); +var Empty = function () { /* empty */ }; +var PROTOTYPE = 'prototype'; - if (!queue.length) { - delete this.queue[key]; - } +// Create object with fake `null` prototype: use iframe Object with cleared prototype +var createDict = function () { + // Thrash, waste and sodomy: IE GC bug + var iframe = __webpack_require__(68)('iframe'); + var i = enumBugKeys.length; + var lt = '<'; + var gt = '>'; + var iframeDocument; + iframe.style.display = 'none'; + __webpack_require__(102).appendChild(iframe); + iframe.src = 'javascript:'; // eslint-disable-line no-script-url + // createDict = iframe.contentWindow.Object; + // html.removeChild(iframe); + iframeDocument = iframe.contentWindow.document; + iframeDocument.open(); + iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt); + iframeDocument.close(); + createDict = iframeDocument.F; + while (i--) delete createDict[PROTOTYPE][enumBugKeys[i]]; + return createDict(); +}; - const next = () => { - this.shift(key); - this.shiftConcurrencyQueue(); - }; +module.exports = Object.create || function create(O, Properties) { + var result; + if (O !== null) { + Empty[PROTOTYPE] = anObject(O); + result = new Empty(); + Empty[PROTOTYPE] = null; + // add "__proto__" for Object.getPrototypeOf polyfill + result[IE_PROTO] = O; + } else result = createDict(); + return Properties === undefined ? result : dPs(result, Properties); +}; - const run = () => { - this.running[key] = true; - this.runningCount++; - factory().then(function (val) { - resolve(val); - next(); - return null; - }).catch(function (err) { - reject(err); - next(); - }); - }; +/***/ }), +/* 193 */ +/***/ (function(module, exports, __webpack_require__) { - this.maybePushConcurrencyQueue(run); - } +var dP = __webpack_require__(50); +var anObject = __webpack_require__(27); +var getKeys = __webpack_require__(132); - maybePushConcurrencyQueue(run) { - if (this.runningCount < this.maxConcurrency) { - run(); - } else { - this.concurrencyQueue.push(run); - } - } +module.exports = __webpack_require__(33) ? Object.defineProperties : function defineProperties(O, Properties) { + anObject(O); + var keys = getKeys(Properties); + var length = keys.length; + var i = 0; + var P; + while (length > i) dP.f(O, P = keys[i++], Properties[P]); + return O; +}; - shiftConcurrencyQueue() { - if (this.runningCount < this.maxConcurrency) { - const fn = this.concurrencyQueue.shift(); - if (fn) { - fn(); - } - } - } -} -exports.default = BlockingQueue; /***/ }), -/* 85 */ -/***/ (function(module, exports) { +/* 194 */ +/***/ (function(module, exports, __webpack_require__) { -module.exports = function (exec) { - try { - return !!exec(); - } catch (e) { - return true; - } +// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O) +var has = __webpack_require__(49); +var toObject = __webpack_require__(133); +var IE_PROTO = __webpack_require__(72)('IE_PROTO'); +var ObjectProto = Object.prototype; + +module.exports = Object.getPrototypeOf || function (O) { + O = toObject(O); + if (has(O, IE_PROTO)) return O[IE_PROTO]; + if (typeof O.constructor == 'function' && O instanceof O.constructor) { + return O.constructor.prototype; + } return O instanceof Object ? ObjectProto : null; }; /***/ }), -/* 86 */, -/* 87 */, -/* 88 */, -/* 89 */, -/* 90 */, -/* 91 */, -/* 92 */, -/* 93 */, -/* 94 */, -/* 95 */, -/* 96 */, -/* 97 */, -/* 98 */, -/* 99 */, -/* 100 */ +/* 195 */ /***/ (function(module, exports, __webpack_require__) { -// getting tag from 19.1.3.6 Object.prototype.toString() -var cof = __webpack_require__(47); -var TAG = __webpack_require__(13)('toStringTag'); -// ES3 wrong here -var ARG = cof(function () { return arguments; }()) == 'Arguments'; - -// fallback for IE11 Script Access Denied error -var tryGet = function (it, key) { - try { - return it[key]; - } catch (e) { /* empty */ } -}; +var has = __webpack_require__(49); +var toIObject = __webpack_require__(74); +var arrayIndexOf = __webpack_require__(182)(false); +var IE_PROTO = __webpack_require__(72)('IE_PROTO'); -module.exports = function (it) { - var O, T, B; - return it === undefined ? 'Undefined' : it === null ? 'Null' - // @@toStringTag case - : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T - // builtinTag case - : ARG ? cof(O) - // ES3 arguments fallback - : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B; +module.exports = function (object, names) { + var O = toIObject(object); + var i = 0; + var result = []; + var key; + for (key in O) if (key != IE_PROTO) has(O, key) && result.push(key); + // Don't enum bug & hidden keys + while (names.length > i) if (has(O, key = names[i++])) { + ~arrayIndexOf(result, key) || result.push(key); + } + return result; }; /***/ }), -/* 101 */ -/***/ (function(module, exports) { +/* 196 */ +/***/ (function(module, exports, __webpack_require__) { -// IE 8- don't enum bug keys -module.exports = ( - 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf' -).split(','); +var hide = __webpack_require__(31); +module.exports = function (target, src, safe) { + for (var key in src) { + if (safe && target[key]) target[key] = src[key]; + else hide(target, key, src[key]); + } return target; +}; /***/ }), -/* 102 */ +/* 197 */ /***/ (function(module, exports, __webpack_require__) { -var document = __webpack_require__(11).document; -module.exports = document && document.documentElement; +module.exports = __webpack_require__(31); /***/ }), -/* 103 */ +/* 198 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var LIBRARY = __webpack_require__(69); -var $export = __webpack_require__(41); -var redefine = __webpack_require__(197); -var hide = __webpack_require__(31); -var Iterators = __webpack_require__(35); -var $iterCreate = __webpack_require__(188); -var setToStringTag = __webpack_require__(71); -var getPrototypeOf = __webpack_require__(194); -var ITERATOR = __webpack_require__(13)('iterator'); -var BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next` -var FF_ITERATOR = '@@iterator'; -var KEYS = 'keys'; -var VALUES = 'values'; - -var returnThis = function () { return this; }; +var global = __webpack_require__(11); +var core = __webpack_require__(23); +var dP = __webpack_require__(50); +var DESCRIPTORS = __webpack_require__(33); +var SPECIES = __webpack_require__(13)('species'); -module.exports = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) { - $iterCreate(Constructor, NAME, next); - var getMethod = function (kind) { - if (!BUGGY && kind in proto) return proto[kind]; - switch (kind) { - case KEYS: return function keys() { return new Constructor(this, kind); }; - case VALUES: return function values() { return new Constructor(this, kind); }; - } return function entries() { return new Constructor(this, kind); }; - }; - var TAG = NAME + ' Iterator'; - var DEF_VALUES = DEFAULT == VALUES; - var VALUES_BUG = false; - var proto = Base.prototype; - var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT]; - var $default = $native || getMethod(DEFAULT); - var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined; - var $anyNative = NAME == 'Array' ? proto.entries || $native : $native; - var methods, key, IteratorPrototype; - // Fix native - if ($anyNative) { - IteratorPrototype = getPrototypeOf($anyNative.call(new Base())); - if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) { - // Set @@toStringTag to native iterators - setToStringTag(IteratorPrototype, TAG, true); - // fix for some old engines - if (!LIBRARY && typeof IteratorPrototype[ITERATOR] != 'function') hide(IteratorPrototype, ITERATOR, returnThis); - } - } - // fix Array#{values, @@iterator}.name in V8 / FF - if (DEF_VALUES && $native && $native.name !== VALUES) { - VALUES_BUG = true; - $default = function values() { return $native.call(this); }; - } - // Define iterator - if ((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) { - hide(proto, ITERATOR, $default); - } - // Plug for library - Iterators[NAME] = $default; - Iterators[TAG] = returnThis; - if (DEFAULT) { - methods = { - values: DEF_VALUES ? $default : getMethod(VALUES), - keys: IS_SET ? $default : getMethod(KEYS), - entries: $entries - }; - if (FORCED) for (key in methods) { - if (!(key in proto)) redefine(proto, key, methods[key]); - } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods); - } - return methods; +module.exports = function (KEY) { + var C = typeof core[KEY] == 'function' ? core[KEY] : global[KEY]; + if (DESCRIPTORS && C && !C[SPECIES]) dP.f(C, SPECIES, { + configurable: true, + get: function () { return this; } + }); }; /***/ }), -/* 104 */ -/***/ (function(module, exports) { +/* 199 */ +/***/ (function(module, exports, __webpack_require__) { -module.exports = function (exec) { - try { - return { e: false, v: exec() }; - } catch (e) { - return { e: true, v: e }; - } +var toInteger = __webpack_require__(73); +var defined = __webpack_require__(67); +// true -> String#at +// false -> String#codePointAt +module.exports = function (TO_STRING) { + return function (that, pos) { + var s = String(defined(that)); + var i = toInteger(pos); + var l = s.length; + var a, b; + if (i < 0 || i >= l) return TO_STRING ? '' : undefined; + a = s.charCodeAt(i); + return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff + ? TO_STRING ? s.charAt(i) : a + : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000; + }; }; /***/ }), -/* 105 */ +/* 200 */ /***/ (function(module, exports, __webpack_require__) { -var anObject = __webpack_require__(27); -var isObject = __webpack_require__(34); -var newPromiseCapability = __webpack_require__(70); - -module.exports = function (C, x) { - anObject(C); - if (isObject(x) && x.constructor === C) return x; - var promiseCapability = newPromiseCapability.f(C); - var resolve = promiseCapability.resolve; - resolve(x); - return promiseCapability.promise; +var toInteger = __webpack_require__(73); +var max = Math.max; +var min = Math.min; +module.exports = function (index, length) { + index = toInteger(index); + return index < 0 ? max(index + length, 0) : min(index, length); }; /***/ }), -/* 106 */ -/***/ (function(module, exports) { +/* 201 */ +/***/ (function(module, exports, __webpack_require__) { -module.exports = function (bitmap, value) { - return { - enumerable: !(bitmap & 1), - configurable: !(bitmap & 2), - writable: !(bitmap & 4), - value: value - }; +// 7.1.1 ToPrimitive(input [, PreferredType]) +var isObject = __webpack_require__(34); +// instead of the ES6 spec version, we didn't implement @@toPrimitive case +// and the second argument - flag - preferred type is a string +module.exports = function (it, S) { + if (!isObject(it)) return it; + var fn, val; + if (S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val; + if (typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it))) return val; + if (!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val; + throw TypeError("Can't convert object to primitive value"); }; /***/ }), -/* 107 */ +/* 202 */ /***/ (function(module, exports, __webpack_require__) { -var core = __webpack_require__(23); var global = __webpack_require__(11); -var SHARED = '__core-js_shared__'; -var store = global[SHARED] || (global[SHARED] = {}); +var navigator = global.navigator; -(module.exports = function (key, value) { - return store[key] || (store[key] = value !== undefined ? value : {}); -})('versions', []).push({ - version: core.version, - mode: __webpack_require__(69) ? 'pure' : 'global', - copyright: '© 2018 Denis Pushkarev (zloirock.ru)' -}); +module.exports = navigator && navigator.userAgent || ''; /***/ }), -/* 108 */ +/* 203 */ /***/ (function(module, exports, __webpack_require__) { -// 7.3.20 SpeciesConstructor(O, defaultConstructor) -var anObject = __webpack_require__(27); -var aFunction = __webpack_require__(46); -var SPECIES = __webpack_require__(13)('species'); -module.exports = function (O, D) { - var C = anObject(O).constructor; - var S; - return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S); +var classof = __webpack_require__(100); +var ITERATOR = __webpack_require__(13)('iterator'); +var Iterators = __webpack_require__(35); +module.exports = __webpack_require__(23).getIteratorMethod = function (it) { + if (it != undefined) return it[ITERATOR] + || it['@@iterator'] + || Iterators[classof(it)]; }; /***/ }), -/* 109 */ +/* 204 */ /***/ (function(module, exports, __webpack_require__) { -var ctx = __webpack_require__(48); -var invoke = __webpack_require__(185); -var html = __webpack_require__(102); -var cel = __webpack_require__(68); -var global = __webpack_require__(11); -var process = global.process; -var setTask = global.setImmediate; -var clearTask = global.clearImmediate; -var MessageChannel = global.MessageChannel; -var Dispatch = global.Dispatch; -var counter = 0; -var queue = {}; -var ONREADYSTATECHANGE = 'onreadystatechange'; -var defer, channel, port; -var run = function () { - var id = +this; - // eslint-disable-next-line no-prototype-builtins - if (queue.hasOwnProperty(id)) { - var fn = queue[id]; - delete queue[id]; - fn(); - } -}; -var listener = function (event) { - run.call(event.data); -}; -// Node.js 0.9+ & IE10+ has setImmediate, otherwise: -if (!setTask || !clearTask) { - setTask = function setImmediate(fn) { - var args = []; - var i = 1; - while (arguments.length > i) args.push(arguments[i++]); - queue[++counter] = function () { - // eslint-disable-next-line no-new-func - invoke(typeof fn == 'function' ? fn : Function(fn), args); - }; - defer(counter); - return counter; - }; - clearTask = function clearImmediate(id) { - delete queue[id]; - }; - // Node.js 0.8- - if (__webpack_require__(47)(process) == 'process') { - defer = function (id) { - process.nextTick(ctx(run, id, 1)); - }; - // Sphere (JS game engine) Dispatch API - } else if (Dispatch && Dispatch.now) { - defer = function (id) { - Dispatch.now(ctx(run, id, 1)); - }; - // Browsers with MessageChannel, includes WebWorkers - } else if (MessageChannel) { - channel = new MessageChannel(); - port = channel.port2; - channel.port1.onmessage = listener; - defer = ctx(port.postMessage, port, 1); - // Browsers with postMessage, skip WebWorkers - // IE8 has postMessage, but it's sync & typeof its postMessage is 'object' - } else if (global.addEventListener && typeof postMessage == 'function' && !global.importScripts) { - defer = function (id) { - global.postMessage(id + '', '*'); - }; - global.addEventListener('message', listener, false); - // IE8- - } else if (ONREADYSTATECHANGE in cel('script')) { - defer = function (id) { - html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function () { - html.removeChild(this); - run.call(id); - }; - }; - // Rest old browsers - } else { - defer = function (id) { - setTimeout(ctx(run, id, 1), 0); - }; - } -} -module.exports = { - set: setTask, - clear: clearTask -}; +"use strict"; +var addToUnscopables = __webpack_require__(180); +var step = __webpack_require__(190); +var Iterators = __webpack_require__(35); +var toIObject = __webpack_require__(74); -/***/ }), -/* 110 */ -/***/ (function(module, exports, __webpack_require__) { +// 22.1.3.4 Array.prototype.entries() +// 22.1.3.13 Array.prototype.keys() +// 22.1.3.29 Array.prototype.values() +// 22.1.3.30 Array.prototype[@@iterator]() +module.exports = __webpack_require__(103)(Array, 'Array', function (iterated, kind) { + this._t = toIObject(iterated); // target + this._i = 0; // next index + this._k = kind; // kind +// 22.1.5.2.1 %ArrayIteratorPrototype%.next() +}, function () { + var O = this._t; + var kind = this._k; + var index = this._i++; + if (!O || index >= O.length) { + this._t = undefined; + return step(1); + } + if (kind == 'keys') return step(0, index); + if (kind == 'values') return step(0, O[index]); + return step(0, [index, O[index]]); +}, 'values'); -// 7.1.15 ToLength -var toInteger = __webpack_require__(73); -var min = Math.min; -module.exports = function (it) { - return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991 -}; +// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7) +Iterators.Arguments = Iterators.Array; + +addToUnscopables('keys'); +addToUnscopables('values'); +addToUnscopables('entries'); /***/ }), -/* 111 */ +/* 205 */ /***/ (function(module, exports) { -var id = 0; -var px = Math.random(); -module.exports = function (key) { - return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36)); -}; /***/ }), -/* 112 */ +/* 206 */ /***/ (function(module, exports, __webpack_require__) { +"use strict"; -/** - * This is the common logic for both the Node.js and web browser - * implementations of `debug()`. - * - * Expose `debug()` as the module. - */ - -exports = module.exports = createDebug.debug = createDebug['default'] = createDebug; -exports.coerce = coerce; -exports.disable = disable; -exports.enable = enable; -exports.enabled = enabled; -exports.humanize = __webpack_require__(229); - -/** - * Active `debug` instances. - */ -exports.instances = []; - -/** - * The currently active debug mode names, and names to skip. - */ - -exports.names = []; -exports.skips = []; +var LIBRARY = __webpack_require__(69); +var global = __webpack_require__(11); +var ctx = __webpack_require__(48); +var classof = __webpack_require__(100); +var $export = __webpack_require__(41); +var isObject = __webpack_require__(34); +var aFunction = __webpack_require__(46); +var anInstance = __webpack_require__(181); +var forOf = __webpack_require__(183); +var speciesConstructor = __webpack_require__(108); +var task = __webpack_require__(109).set; +var microtask = __webpack_require__(191)(); +var newPromiseCapabilityModule = __webpack_require__(70); +var perform = __webpack_require__(104); +var userAgent = __webpack_require__(202); +var promiseResolve = __webpack_require__(105); +var PROMISE = 'Promise'; +var TypeError = global.TypeError; +var process = global.process; +var versions = process && process.versions; +var v8 = versions && versions.v8 || ''; +var $Promise = global[PROMISE]; +var isNode = classof(process) == 'process'; +var empty = function () { /* empty */ }; +var Internal, newGenericPromiseCapability, OwnPromiseCapability, Wrapper; +var newPromiseCapability = newGenericPromiseCapability = newPromiseCapabilityModule.f; -/** - * Map of special "%n" handling functions, for the debug "format" argument. - * - * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". - */ +var USE_NATIVE = !!function () { + try { + // correct subclassing with @@species support + var promise = $Promise.resolve(1); + var FakePromise = (promise.constructor = {})[__webpack_require__(13)('species')] = function (exec) { + exec(empty, empty); + }; + // unhandled rejections tracking support, NodeJS Promise without it fails @@species test + return (isNode || typeof PromiseRejectionEvent == 'function') + && promise.then(empty) instanceof FakePromise + // v8 6.6 (Node 10 and Chrome 66) have a bug with resolving custom thenables + // https://bugs.chromium.org/p/chromium/issues/detail?id=830565 + // we can't detect it synchronously, so just check versions + && v8.indexOf('6.6') !== 0 + && userAgent.indexOf('Chrome/66') === -1; + } catch (e) { /* empty */ } +}(); -exports.formatters = {}; +// helpers +var isThenable = function (it) { + var then; + return isObject(it) && typeof (then = it.then) == 'function' ? then : false; +}; +var notify = function (promise, isReject) { + if (promise._n) return; + promise._n = true; + var chain = promise._c; + microtask(function () { + var value = promise._v; + var ok = promise._s == 1; + var i = 0; + var run = function (reaction) { + var handler = ok ? reaction.ok : reaction.fail; + var resolve = reaction.resolve; + var reject = reaction.reject; + var domain = reaction.domain; + var result, then, exited; + try { + if (handler) { + if (!ok) { + if (promise._h == 2) onHandleUnhandled(promise); + promise._h = 1; + } + if (handler === true) result = value; + else { + if (domain) domain.enter(); + result = handler(value); // may throw + if (domain) { + domain.exit(); + exited = true; + } + } + if (result === reaction.promise) { + reject(TypeError('Promise-chain cycle')); + } else if (then = isThenable(result)) { + then.call(result, resolve, reject); + } else resolve(result); + } else reject(value); + } catch (e) { + if (domain && !exited) domain.exit(); + reject(e); + } + }; + while (chain.length > i) run(chain[i++]); // variable length - can't use forEach + promise._c = []; + promise._n = false; + if (isReject && !promise._h) onUnhandled(promise); + }); +}; +var onUnhandled = function (promise) { + task.call(global, function () { + var value = promise._v; + var unhandled = isUnhandled(promise); + var result, handler, console; + if (unhandled) { + result = perform(function () { + if (isNode) { + process.emit('unhandledRejection', value, promise); + } else if (handler = global.onunhandledrejection) { + handler({ promise: promise, reason: value }); + } else if ((console = global.console) && console.error) { + console.error('Unhandled promise rejection', value); + } + }); + // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should + promise._h = isNode || isUnhandled(promise) ? 2 : 1; + } promise._a = undefined; + if (unhandled && result.e) throw result.v; + }); +}; +var isUnhandled = function (promise) { + return promise._h !== 1 && (promise._a || promise._c).length === 0; +}; +var onHandleUnhandled = function (promise) { + task.call(global, function () { + var handler; + if (isNode) { + process.emit('rejectionHandled', promise); + } else if (handler = global.onrejectionhandled) { + handler({ promise: promise, reason: promise._v }); + } + }); +}; +var $reject = function (value) { + var promise = this; + if (promise._d) return; + promise._d = true; + promise = promise._w || promise; // unwrap + promise._v = value; + promise._s = 2; + if (!promise._a) promise._a = promise._c.slice(); + notify(promise, true); +}; +var $resolve = function (value) { + var promise = this; + var then; + if (promise._d) return; + promise._d = true; + promise = promise._w || promise; // unwrap + try { + if (promise === value) throw TypeError("Promise can't be resolved itself"); + if (then = isThenable(value)) { + microtask(function () { + var wrapper = { _w: promise, _d: false }; // wrap + try { + then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1)); + } catch (e) { + $reject.call(wrapper, e); + } + }); + } else { + promise._v = value; + promise._s = 1; + notify(promise, false); + } + } catch (e) { + $reject.call({ _w: promise, _d: false }, e); // wrap + } +}; -/** - * Select a color. - * @param {String} namespace - * @return {Number} - * @api private - */ +// constructor polyfill +if (!USE_NATIVE) { + // 25.4.3.1 Promise(executor) + $Promise = function Promise(executor) { + anInstance(this, $Promise, PROMISE, '_h'); + aFunction(executor); + Internal.call(this); + try { + executor(ctx($resolve, this, 1), ctx($reject, this, 1)); + } catch (err) { + $reject.call(this, err); + } + }; + // eslint-disable-next-line no-unused-vars + Internal = function Promise(executor) { + this._c = []; // <- awaiting reactions + this._a = undefined; // <- checked in isUnhandled reactions + this._s = 0; // <- state + this._d = false; // <- done + this._v = undefined; // <- value + this._h = 0; // <- rejection state, 0 - default, 1 - handled, 2 - unhandled + this._n = false; // <- notify + }; + Internal.prototype = __webpack_require__(196)($Promise.prototype, { + // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected) + then: function then(onFulfilled, onRejected) { + var reaction = newPromiseCapability(speciesConstructor(this, $Promise)); + reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true; + reaction.fail = typeof onRejected == 'function' && onRejected; + reaction.domain = isNode ? process.domain : undefined; + this._c.push(reaction); + if (this._a) this._a.push(reaction); + if (this._s) notify(this, false); + return reaction.promise; + }, + // 25.4.5.1 Promise.prototype.catch(onRejected) + 'catch': function (onRejected) { + return this.then(undefined, onRejected); + } + }); + OwnPromiseCapability = function () { + var promise = new Internal(); + this.promise = promise; + this.resolve = ctx($resolve, promise, 1); + this.reject = ctx($reject, promise, 1); + }; + newPromiseCapabilityModule.f = newPromiseCapability = function (C) { + return C === $Promise || C === Wrapper + ? new OwnPromiseCapability(C) + : newGenericPromiseCapability(C); + }; +} -function selectColor(namespace) { - var hash = 0, i; +$export($export.G + $export.W + $export.F * !USE_NATIVE, { Promise: $Promise }); +__webpack_require__(71)($Promise, PROMISE); +__webpack_require__(198)(PROMISE); +Wrapper = __webpack_require__(23)[PROMISE]; - for (i in namespace) { - hash = ((hash << 5) - hash) + namespace.charCodeAt(i); - hash |= 0; // Convert to 32bit integer +// statics +$export($export.S + $export.F * !USE_NATIVE, PROMISE, { + // 25.4.4.5 Promise.reject(r) + reject: function reject(r) { + var capability = newPromiseCapability(this); + var $$reject = capability.reject; + $$reject(r); + return capability.promise; + } +}); +$export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, { + // 25.4.4.6 Promise.resolve(x) + resolve: function resolve(x) { + return promiseResolve(LIBRARY && this === Wrapper ? $Promise : this, x); + } +}); +$export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(189)(function (iter) { + $Promise.all(iter)['catch'](empty); +})), PROMISE, { + // 25.4.4.1 Promise.all(iterable) + all: function all(iterable) { + var C = this; + var capability = newPromiseCapability(C); + var resolve = capability.resolve; + var reject = capability.reject; + var result = perform(function () { + var values = []; + var index = 0; + var remaining = 1; + forOf(iterable, false, function (promise) { + var $index = index++; + var alreadyCalled = false; + values.push(undefined); + remaining++; + C.resolve(promise).then(function (value) { + if (alreadyCalled) return; + alreadyCalled = true; + values[$index] = value; + --remaining || resolve(values); + }, reject); + }); + --remaining || resolve(values); + }); + if (result.e) reject(result.v); + return capability.promise; + }, + // 25.4.4.4 Promise.race(iterable) + race: function race(iterable) { + var C = this; + var capability = newPromiseCapability(C); + var reject = capability.reject; + var result = perform(function () { + forOf(iterable, false, function (promise) { + C.resolve(promise).then(capability.resolve, reject); + }); + }); + if (result.e) reject(result.v); + return capability.promise; } +}); - return exports.colors[Math.abs(hash) % exports.colors.length]; -} -/** - * Create a debugger with the given `namespace`. - * - * @param {String} namespace - * @return {Function} - * @api public - */ +/***/ }), +/* 207 */ +/***/ (function(module, exports, __webpack_require__) { -function createDebug(namespace) { +"use strict"; - var prevTime; +var $at = __webpack_require__(199)(true); - function debug() { - // disabled? - if (!debug.enabled) return; +// 21.1.3.27 String.prototype[@@iterator]() +__webpack_require__(103)(String, 'String', function (iterated) { + this._t = String(iterated); // target + this._i = 0; // next index +// 21.1.5.2.1 %StringIteratorPrototype%.next() +}, function () { + var O = this._t; + var index = this._i; + var point; + if (index >= O.length) return { value: undefined, done: true }; + point = $at(O, index); + this._i += point.length; + return { value: point, done: false }; +}); - var self = debug; - // set `diff` timestamp - var curr = +new Date(); - var ms = curr - (prevTime || curr); - self.diff = ms; - self.prev = prevTime; - self.curr = curr; - prevTime = curr; +/***/ }), +/* 208 */ +/***/ (function(module, exports, __webpack_require__) { - // turn the `arguments` into a proper Array - var args = new Array(arguments.length); - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i]; - } +"use strict"; +// https://github.com/tc39/proposal-promise-finally - args[0] = exports.coerce(args[0]); +var $export = __webpack_require__(41); +var core = __webpack_require__(23); +var global = __webpack_require__(11); +var speciesConstructor = __webpack_require__(108); +var promiseResolve = __webpack_require__(105); - if ('string' !== typeof args[0]) { - // anything else let's inspect with %O - args.unshift('%O'); - } +$export($export.P + $export.R, 'Promise', { 'finally': function (onFinally) { + var C = speciesConstructor(this, core.Promise || global.Promise); + var isFunction = typeof onFinally == 'function'; + return this.then( + isFunction ? function (x) { + return promiseResolve(C, onFinally()).then(function () { return x; }); + } : onFinally, + isFunction ? function (e) { + return promiseResolve(C, onFinally()).then(function () { throw e; }); + } : onFinally + ); +} }); - // apply any `formatters` transformations - var index = 0; - args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) { - // if we encounter an escaped % then don't increase the array index - if (match === '%%') return match; - index++; - var formatter = exports.formatters[format]; - if ('function' === typeof formatter) { - var val = args[index]; - match = formatter.call(self, val); - // now we need to remove `args[index]` since it's inlined in the `format` - args.splice(index, 1); - index--; - } - return match; - }); +/***/ }), +/* 209 */ +/***/ (function(module, exports, __webpack_require__) { - // apply env-specific formatting (colors, etc.) - exports.formatArgs.call(self, args); +"use strict"; - var logFn = debug.log || exports.log || console.log.bind(console); - logFn.apply(self, args); - } +// https://github.com/tc39/proposal-promise-try +var $export = __webpack_require__(41); +var newPromiseCapability = __webpack_require__(70); +var perform = __webpack_require__(104); - debug.namespace = namespace; - debug.enabled = exports.enabled(namespace); - debug.useColors = exports.useColors(); - debug.color = selectColor(namespace); - debug.destroy = destroy; +$export($export.S, 'Promise', { 'try': function (callbackfn) { + var promiseCapability = newPromiseCapability.f(this); + var result = perform(callbackfn); + (result.e ? promiseCapability.reject : promiseCapability.resolve)(result.v); + return promiseCapability.promise; +} }); - // env-specific initialization logic for debug instances - if ('function' === typeof exports.init) { - exports.init(debug); - } - exports.instances.push(debug); +/***/ }), +/* 210 */ +/***/ (function(module, exports, __webpack_require__) { - return debug; +__webpack_require__(204); +var global = __webpack_require__(11); +var hide = __webpack_require__(31); +var Iterators = __webpack_require__(35); +var TO_STRING_TAG = __webpack_require__(13)('toStringTag'); + +var DOMIterables = ('CSSRuleList,CSSStyleDeclaration,CSSValueList,ClientRectList,DOMRectList,DOMStringList,' + + 'DOMTokenList,DataTransferItemList,FileList,HTMLAllCollection,HTMLCollection,HTMLFormElement,HTMLSelectElement,' + + 'MediaList,MimeTypeArray,NamedNodeMap,NodeList,PaintRequestList,Plugin,PluginArray,SVGLengthList,SVGNumberList,' + + 'SVGPathSegList,SVGPointList,SVGStringList,SVGTransformList,SourceBufferList,StyleSheetList,TextTrackCueList,' + + 'TextTrackList,TouchList').split(','); + +for (var i = 0; i < DOMIterables.length; i++) { + var NAME = DOMIterables[i]; + var Collection = global[NAME]; + var proto = Collection && Collection.prototype; + if (proto && !proto[TO_STRING_TAG]) hide(proto, TO_STRING_TAG, NAME); + Iterators[NAME] = Iterators.Array; } -function destroy () { - var index = exports.instances.indexOf(this); - if (index !== -1) { - exports.instances.splice(index, 1); + +/***/ }), +/* 211 */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * This is the web browser implementation of `debug()`. + * + * Expose `debug()` as the module. + */ + +exports = module.exports = __webpack_require__(112); +exports.log = log; +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; +exports.storage = 'undefined' != typeof chrome + && 'undefined' != typeof chrome.storage + ? chrome.storage.local + : localstorage(); + +/** + * Colors. + */ + +exports.colors = [ + '#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', + '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', + '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', + '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', + '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', + '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', + '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', + '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', + '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', + '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', + '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33' +]; + +/** + * Currently only WebKit-based Web Inspectors, Firefox >= v31, + * and the Firebug extension (any Firefox version) are known + * to support "%c" CSS customizations. + * + * TODO: add a `localStorage` variable to explicitly enable/disable colors + */ + +function useColors() { + // NB: In an Electron preload script, document will be defined but not fully + // initialized. Since we know we're in Chrome, we'll just detect this case + // explicitly + if (typeof window !== 'undefined' && window.process && window.process.type === 'renderer') { return true; - } else { + } + + // Internet Explorer and Edge do not support colors. + if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { return false; } + + // is webkit? http://stackoverflow.com/a/16459606/376773 + // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 + return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) || + // is firebug? http://stackoverflow.com/a/398120/376773 + (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) || + // is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) || + // double check webkit in userAgent just in case we are in a worker + (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)); } /** - * Enables a debug mode by namespaces. This can include modes - * separated by a colon and wildcards. + * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. + */ + +exports.formatters.j = function(v) { + try { + return JSON.stringify(v); + } catch (err) { + return '[UnexpectedJSONParseError]: ' + err.message; + } +}; + + +/** + * Colorize log arguments if enabled. * - * @param {String} namespaces * @api public */ -function enable(namespaces) { - exports.save(namespaces); +function formatArgs(args) { + var useColors = this.useColors; - exports.names = []; - exports.skips = []; + args[0] = (useColors ? '%c' : '') + + this.namespace + + (useColors ? ' %c' : ' ') + + args[0] + + (useColors ? '%c ' : ' ') + + '+' + exports.humanize(this.diff); - var i; - var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); - var len = split.length; + if (!useColors) return; - for (i = 0; i < len; i++) { - if (!split[i]) continue; // ignore empty strings - namespaces = split[i].replace(/\*/g, '.*?'); - if (namespaces[0] === '-') { - exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); - } else { - exports.names.push(new RegExp('^' + namespaces + '$')); + var c = 'color: ' + this.color; + args.splice(1, 0, c, 'color: inherit') + + // the final "%c" is somewhat tricky, because there could be other + // arguments passed either before or after the %c, so we need to + // figure out the correct index to insert the CSS into + var index = 0; + var lastC = 0; + args[0].replace(/%[a-zA-Z%]/g, function(match) { + if ('%%' === match) return; + index++; + if ('%c' === match) { + // we only are interested in the *last* %c + // (the user may have provided their own) + lastC = index; } - } + }); - for (i = 0; i < exports.instances.length; i++) { - var instance = exports.instances[i]; - instance.enabled = exports.enabled(instance.namespace); - } + args.splice(lastC, 0, c); } /** - * Disable debug output. + * Invokes `console.log()` when available. + * No-op when `console.log` is not a "function". * * @api public */ -function disable() { - exports.enable(''); +function log() { + // this hackery is required for IE8/9, where + // the `console.log` function doesn't have 'apply' + return 'object' === typeof console + && console.log + && Function.prototype.apply.call(console.log, console, arguments); } /** - * Returns true if the given mode name is enabled, false otherwise. + * Save `namespaces`. * - * @param {String} name - * @return {Boolean} - * @api public + * @param {String} namespaces + * @api private */ -function enabled(name) { - if (name[name.length - 1] === '*') { - return true; - } - var i, len; - for (i = 0, len = exports.skips.length; i < len; i++) { - if (exports.skips[i].test(name)) { - return false; - } - } - for (i = 0, len = exports.names.length; i < len; i++) { - if (exports.names[i].test(name)) { - return true; +function save(namespaces) { + try { + if (null == namespaces) { + exports.storage.removeItem('debug'); + } else { + exports.storage.debug = namespaces; } + } catch(e) {} +} + +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ + +function load() { + var r; + try { + r = exports.storage.debug; + } catch(e) {} + + // If debug isn't set in LS, and we're in Electron, try to load $DEBUG + if (!r && typeof process !== 'undefined' && 'env' in process) { + r = process.env.DEBUG; } - return false; + + return r; } /** - * Coerce `val`. + * Enable namespaces listed in `localStorage.debug` initially. + */ + +exports.enable(load()); + +/** + * Localstorage attempts to return the localstorage. * - * @param {Mixed} val - * @return {Mixed} + * This is necessary because safari throws + * when a user disables cookies/localstorage + * and you attempt to access it. + * + * @return {LocalStorage} * @api private */ -function coerce(val) { - if (val instanceof Error) return val.stack || val.message; - return val; +function localstorage() { + try { + return window.localStorage; + } catch (e) {} } /***/ }), -/* 113 */, -/* 114 */ +/* 212 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = realpath -realpath.realpath = realpath -realpath.sync = realpathSync -realpath.realpathSync = realpathSync -realpath.monkeypatch = monkeypatch -realpath.unmonkeypatch = unmonkeypatch +/** + * Detect Electron renderer process, which is node, but we should + * treat as a browser. + */ -var fs = __webpack_require__(3) -var origRealpath = fs.realpath -var origRealpathSync = fs.realpathSync +if (typeof process === 'undefined' || process.type === 'renderer') { + module.exports = __webpack_require__(211); +} else { + module.exports = __webpack_require__(213); +} -var version = process.version -var ok = /^v[0-5]\./.test(version) -var old = __webpack_require__(217) -function newError (er) { - return er && er.syscall === 'realpath' && ( - er.code === 'ELOOP' || - er.code === 'ENOMEM' || - er.code === 'ENAMETOOLONG' - ) -} +/***/ }), +/* 213 */ +/***/ (function(module, exports, __webpack_require__) { -function realpath (p, cache, cb) { - if (ok) { - return origRealpath(p, cache, cb) - } +/** + * Module dependencies. + */ - if (typeof cache === 'function') { - cb = cache - cache = null - } - origRealpath(p, cache, function (er, result) { - if (newError(er)) { - old.realpath(p, cache, cb) - } else { - cb(er, result) - } - }) -} +var tty = __webpack_require__(79); +var util = __webpack_require__(2); -function realpathSync (p, cache) { - if (ok) { - return origRealpathSync(p, cache) - } +/** + * This is the Node.js implementation of `debug()`. + * + * Expose `debug()` as the module. + */ - try { - return origRealpathSync(p, cache) - } catch (er) { - if (newError(er)) { - return old.realpathSync(p, cache) - } else { - throw er - } +exports = module.exports = __webpack_require__(112); +exports.init = init; +exports.log = log; +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; + +/** + * Colors. + */ + +exports.colors = [ 6, 2, 3, 4, 5, 1 ]; + +try { + var supportsColor = __webpack_require__(239); + if (supportsColor && supportsColor.level >= 2) { + exports.colors = [ + 20, 21, 26, 27, 32, 33, 38, 39, 40, 41, 42, 43, 44, 45, 56, 57, 62, 63, 68, + 69, 74, 75, 76, 77, 78, 79, 80, 81, 92, 93, 98, 99, 112, 113, 128, 129, 134, + 135, 148, 149, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 172, 173, 178, 179, 184, 185, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 214, 215, 220, 221 + ]; } +} catch (err) { + // swallow - we only care if `supports-color` is available; it doesn't have to be. } -function monkeypatch () { - fs.realpath = realpath - fs.realpathSync = realpathSync -} +/** + * Build up the default `inspectOpts` object from the environment variables. + * + * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js + */ -function unmonkeypatch () { - fs.realpath = origRealpath - fs.realpathSync = origRealpathSync -} +exports.inspectOpts = Object.keys(process.env).filter(function (key) { + return /^debug_/i.test(key); +}).reduce(function (obj, key) { + // camel-case + var prop = key + .substring(6) + .toLowerCase() + .replace(/_([a-z])/g, function (_, k) { return k.toUpperCase() }); + // coerce string value into JS value + var val = process.env[key]; + if (/^(yes|on|true|enabled)$/i.test(val)) val = true; + else if (/^(no|off|false|disabled)$/i.test(val)) val = false; + else if (val === 'null') val = null; + else val = Number(val); -/***/ }), -/* 115 */ -/***/ (function(module, exports, __webpack_require__) { + obj[prop] = val; + return obj; +}, {}); -exports.alphasort = alphasort -exports.alphasorti = alphasorti -exports.setopts = setopts -exports.ownProp = ownProp -exports.makeAbs = makeAbs -exports.finish = finish -exports.mark = mark -exports.isIgnored = isIgnored -exports.childrenIgnored = childrenIgnored +/** + * Is stdout a TTY? Colored output is enabled when `true`. + */ -function ownProp (obj, field) { - return Object.prototype.hasOwnProperty.call(obj, field) +function useColors() { + return 'colors' in exports.inspectOpts + ? Boolean(exports.inspectOpts.colors) + : tty.isatty(process.stderr.fd); } -var path = __webpack_require__(0) -var minimatch = __webpack_require__(60) -var isAbsolute = __webpack_require__(76) -var Minimatch = minimatch.Minimatch +/** + * Map %o to `util.inspect()`, all on a single line. + */ -function alphasorti (a, b) { - return a.toLowerCase().localeCompare(b.toLowerCase()) -} +exports.formatters.o = function(v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts) + .split('\n').map(function(str) { + return str.trim() + }).join(' '); +}; -function alphasort (a, b) { - return a.localeCompare(b) -} +/** + * Map %o to `util.inspect()`, allowing multiple lines if needed. + */ -function setupIgnores (self, options) { - self.ignore = options.ignore || [] +exports.formatters.O = function(v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts); +}; - if (!Array.isArray(self.ignore)) - self.ignore = [self.ignore] +/** + * Adds ANSI color escape codes if enabled. + * + * @api public + */ - if (self.ignore.length) { - self.ignore = self.ignore.map(ignoreMap) - } -} +function formatArgs(args) { + var name = this.namespace; + var useColors = this.useColors; -// ignore patterns are always in dot:true mode. -function ignoreMap (pattern) { - var gmatcher = null - if (pattern.slice(-3) === '/**') { - var gpattern = pattern.replace(/(\/\*\*)+$/, '') - gmatcher = new Minimatch(gpattern, { dot: true }) + if (useColors) { + var c = this.color; + var colorCode = '\u001b[3' + (c < 8 ? c : '8;5;' + c); + var prefix = ' ' + colorCode + ';1m' + name + ' ' + '\u001b[0m'; + + args[0] = prefix + args[0].split('\n').join('\n' + prefix); + args.push(colorCode + 'm+' + exports.humanize(this.diff) + '\u001b[0m'); + } else { + args[0] = getDate() + name + ' ' + args[0]; } +} - return { - matcher: new Minimatch(pattern, { dot: true }), - gmatcher: gmatcher +function getDate() { + if (exports.inspectOpts.hideDate) { + return ''; + } else { + return new Date().toISOString() + ' '; } } -function setopts (self, pattern, options) { - if (!options) - options = {} - - // base-matching: just use globstar for that. - if (options.matchBase && -1 === pattern.indexOf("/")) { - if (options.noglobstar) { - throw new Error("base matching requires globstar") - } - pattern = "**/" + pattern - } - - self.silent = !!options.silent - self.pattern = pattern - self.strict = options.strict !== false - self.realpath = !!options.realpath - self.realpathCache = options.realpathCache || Object.create(null) - self.follow = !!options.follow - self.dot = !!options.dot - self.mark = !!options.mark - self.nodir = !!options.nodir - if (self.nodir) - self.mark = true - self.sync = !!options.sync - self.nounique = !!options.nounique - self.nonull = !!options.nonull - self.nosort = !!options.nosort - self.nocase = !!options.nocase - self.stat = !!options.stat - self.noprocess = !!options.noprocess - self.absolute = !!options.absolute +/** + * Invokes `util.format()` with the specified arguments and writes to stderr. + */ - self.maxLength = options.maxLength || Infinity - self.cache = options.cache || Object.create(null) - self.statCache = options.statCache || Object.create(null) - self.symlinks = options.symlinks || Object.create(null) +function log() { + return process.stderr.write(util.format.apply(util, arguments) + '\n'); +} - setupIgnores(self, options) +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ - self.changedCwd = false - var cwd = process.cwd() - if (!ownProp(options, "cwd")) - self.cwd = cwd - else { - self.cwd = path.resolve(options.cwd) - self.changedCwd = self.cwd !== cwd +function save(namespaces) { + if (null == namespaces) { + // If you set a process.env field to null or undefined, it gets cast to the + // string 'null' or 'undefined'. Just delete instead. + delete process.env.DEBUG; + } else { + process.env.DEBUG = namespaces; } +} - self.root = options.root || path.resolve(self.cwd, "/") - self.root = path.resolve(self.root) - if (process.platform === "win32") - self.root = self.root.replace(/\\/g, "/") +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ - // TODO: is an absolute `cwd` supposed to be resolved against `root`? - // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test') - self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd) - if (process.platform === "win32") - self.cwdAbs = self.cwdAbs.replace(/\\/g, "/") - self.nomount = !!options.nomount +function load() { + return process.env.DEBUG; +} - // disable comments and negation in Minimatch. - // Note that they are not supported in Glob itself anyway. - options.nonegate = true - options.nocomment = true +/** + * Init logic for `debug` instances. + * + * Create a new `inspectOpts` object in case `useColors` is set + * differently for a particular `debug` instance. + */ - self.minimatch = new Minimatch(pattern, options) - self.options = self.minimatch.options +function init (debug) { + debug.inspectOpts = {}; + + var keys = Object.keys(exports.inspectOpts); + for (var i = 0; i < keys.length; i++) { + debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]]; + } } -function finish (self) { - var nou = self.nounique - var all = nou ? [] : Object.create(null) +/** + * Enable namespaces listed in `process.env.DEBUG` initially. + */ - for (var i = 0, l = self.matches.length; i < l; i ++) { - var matches = self.matches[i] - if (!matches || Object.keys(matches).length === 0) { - if (self.nonull) { - // do like the shell, and spit out the literal glob - var literal = self.minimatch.globSet[i] - if (nou) - all.push(literal) - else - all[literal] = true - } - } else { - // had matches - var m = Object.keys(matches) - if (nou) - all.push.apply(all, m) - else - m.forEach(function (m) { - all[m] = true - }) - } - } +exports.enable(load()); - if (!nou) - all = Object.keys(all) - if (!self.nosort) - all = all.sort(self.nocase ? alphasorti : alphasort) +/***/ }), +/* 214 */, +/* 215 */, +/* 216 */, +/* 217 */ +/***/ (function(module, exports, __webpack_require__) { - // at *some* point we statted all of these - if (self.mark) { - for (var i = 0; i < all.length; i++) { - all[i] = self._mark(all[i]) - } - if (self.nodir) { - all = all.filter(function (e) { - var notDir = !(/\/$/.test(e)) - var c = self.cache[e] || self.cache[makeAbs(self, e)] - if (notDir && c) - notDir = c !== 'DIR' && !Array.isArray(c) - return notDir - }) - } - } +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. - if (self.ignore.length) - all = all.filter(function(m) { - return !isIgnored(self, m) - }) +var pathModule = __webpack_require__(0); +var isWindows = process.platform === 'win32'; +var fs = __webpack_require__(3); - self.found = all -} +// JavaScript implementation of realpath, ported from node pre-v6 -function mark (self, p) { - var abs = makeAbs(self, p) - var c = self.cache[abs] - var m = p - if (c) { - var isDir = c === 'DIR' || Array.isArray(c) - var slash = p.slice(-1) === '/' +var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); - if (isDir && !slash) - m += '/' - else if (!isDir && slash) - m = m.slice(0, -1) +function rethrow() { + // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and + // is fairly slow to generate. + var callback; + if (DEBUG) { + var backtrace = new Error; + callback = debugCallback; + } else + callback = missingCallback; - if (m !== p) { - var mabs = makeAbs(self, m) - self.statCache[mabs] = self.statCache[abs] - self.cache[mabs] = self.cache[abs] + return callback; + + function debugCallback(err) { + if (err) { + backtrace.message = err.message; + err = backtrace; + missingCallback(err); } } - return m -} - -// lotta situps... -function makeAbs (self, f) { - var abs = f - if (f.charAt(0) === '/') { - abs = path.join(self.root, f) - } else if (isAbsolute(f) || f === '') { - abs = f - } else if (self.changedCwd) { - abs = path.resolve(self.cwd, f) - } else { - abs = path.resolve(f) + function missingCallback(err) { + if (err) { + if (process.throwDeprecation) + throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs + else if (!process.noDeprecation) { + var msg = 'fs: missing callback ' + (err.stack || err.message); + if (process.traceDeprecation) + console.trace(msg); + else + console.error(msg); + } + } } - - if (process.platform === 'win32') - abs = abs.replace(/\\/g, '/') - - return abs } +function maybeCallback(cb) { + return typeof cb === 'function' ? cb : rethrow(); +} -// Return true, if pattern ends with globstar '**', for the accompanying parent directory. -// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents -function isIgnored (self, path) { - if (!self.ignore.length) - return false +var normalize = pathModule.normalize; - return self.ignore.some(function(item) { - return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) - }) +// Regexp that finds the next partion of a (partial) path +// result is [base_with_slash, base], e.g. ['somedir/', 'somedir'] +if (isWindows) { + var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; +} else { + var nextPartRe = /(.*?)(?:[\/]+|$)/g; } -function childrenIgnored (self, path) { - if (!self.ignore.length) - return false - - return self.ignore.some(function(item) { - return !!(item.gmatcher && item.gmatcher.match(path)) - }) +// Regex to find the device root, including trailing slash. E.g. 'c:\\'. +if (isWindows) { + var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; +} else { + var splitRootRe = /^[\/]*/; } +exports.realpathSync = function realpathSync(p, cache) { + // make p is absolute + p = pathModule.resolve(p); -/***/ }), -/* 116 */ -/***/ (function(module, exports, __webpack_require__) { + if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { + return cache[p]; + } -var path = __webpack_require__(0); -var fs = __webpack_require__(3); -var _0777 = parseInt('0777', 8); + var original = p, + seenLinks = {}, + knownHard = {}; -module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP; + // current character position in p + var pos; + // the partial path so far, including a trailing slash if any + var current; + // the partial path without a trailing slash (except when pointing at a root) + var base; + // the partial path scanned in the previous round, with slash + var previous; -function mkdirP (p, opts, f, made) { - if (typeof opts === 'function') { - f = opts; - opts = {}; - } - else if (!opts || typeof opts !== 'object') { - opts = { mode: opts }; - } - - var mode = opts.mode; - var xfs = opts.fs || fs; - - if (mode === undefined) { - mode = _0777 & (~process.umask()); - } - if (!made) made = null; - - var cb = f || function () {}; - p = path.resolve(p); - - xfs.mkdir(p, mode, function (er) { - if (!er) { - made = made || p; - return cb(null, made); - } - switch (er.code) { - case 'ENOENT': - mkdirP(path.dirname(p), opts, function (er, made) { - if (er) cb(er, made); - else mkdirP(p, opts, cb, made); - }); - break; + start(); - // In the case of any other error, just see if there's a dir - // there already. If so, then hooray! If not, then something - // is borked. - default: - xfs.stat(p, function (er2, stat) { - // if the stat fails, then that's super weird. - // let the original error be the failure reason. - if (er2 || !stat.isDirectory()) cb(er, made) - else cb(null, made); - }); - break; - } - }); -} + function start() { + // Skip over roots + var m = splitRootRe.exec(p); + pos = m[0].length; + current = m[0]; + base = m[0]; + previous = ''; -mkdirP.sync = function sync (p, opts, made) { - if (!opts || typeof opts !== 'object') { - opts = { mode: opts }; - } - - var mode = opts.mode; - var xfs = opts.fs || fs; - - if (mode === undefined) { - mode = _0777 & (~process.umask()); + // On windows, check that the root exists. On unix there is no need. + if (isWindows && !knownHard[base]) { + fs.lstatSync(base); + knownHard[base] = true; } - if (!made) made = null; + } - p = path.resolve(p); + // walk down the path, swapping out linked pathparts for their real + // values + // NB: p.length changes. + while (pos < p.length) { + // find the next part + nextPartRe.lastIndex = pos; + var result = nextPartRe.exec(p); + previous = current; + current += result[0]; + base = previous + result[1]; + pos = nextPartRe.lastIndex; - try { - xfs.mkdirSync(p, mode); - made = made || p; + // continue if not a symlink + if (knownHard[base] || (cache && cache[base] === base)) { + continue; } - catch (err0) { - switch (err0.code) { - case 'ENOENT' : - made = sync(path.dirname(p), opts, made); - sync(p, opts, made); - break; - // In the case of any other error, just see if there's a dir - // there already. If so, then hooray! If not, then something - // is borked. - default: - var stat; - try { - stat = xfs.statSync(p); - } - catch (err1) { - throw err0; - } - if (!stat.isDirectory()) throw err0; - break; + var resolvedLink; + if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { + // some known symbolic link. no need to stat again. + resolvedLink = cache[base]; + } else { + var stat = fs.lstatSync(base); + if (!stat.isSymbolicLink()) { + knownHard[base] = true; + if (cache) cache[base] = base; + continue; + } + + // read the link if it wasn't read before + // dev/ino always return 0 on windows, so skip the check. + var linkTarget = null; + if (!isWindows) { + var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); + if (seenLinks.hasOwnProperty(id)) { + linkTarget = seenLinks[id]; } + } + if (linkTarget === null) { + fs.statSync(base); + linkTarget = fs.readlinkSync(base); + } + resolvedLink = pathModule.resolve(previous, linkTarget); + // track this, if given a cache. + if (cache) cache[base] = resolvedLink; + if (!isWindows) seenLinks[id] = linkTarget; } - return made; -}; - + // resolve the link, then start over + p = pathModule.resolve(resolvedLink, p.slice(pos)); + start(); + } -/***/ }), -/* 117 */, -/* 118 */, -/* 119 */, -/* 120 */, -/* 121 */, -/* 122 */ -/***/ (function(module, exports, __webpack_require__) { + if (cache) cache[original] = p; -"use strict"; + return p; +}; -module.exports = x => { - if (typeof x !== 'string') { - throw new TypeError('Expected a string, got ' + typeof x); - } - // Catches EFBBBF (UTF-8 BOM) because the buffer-to-string - // conversion translates it to FEFF (UTF-16 BOM) - if (x.charCodeAt(0) === 0xFEFF) { - return x.slice(1); - } +exports.realpath = function realpath(p, cache, cb) { + if (typeof cb !== 'function') { + cb = maybeCallback(cache); + cache = null; + } - return x; -}; + // make p is absolute + p = pathModule.resolve(p); + if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { + return process.nextTick(cb.bind(null, null, cache[p])); + } -/***/ }), -/* 123 */ -/***/ (function(module, exports) { + var original = p, + seenLinks = {}, + knownHard = {}; -// Returns a wrapper function that returns a wrapped callback -// The wrapper function should do some stuff, and return a -// presumably different callback function. -// This makes sure that own properties are retained, so that -// decorations and such are not lost along the way. -module.exports = wrappy -function wrappy (fn, cb) { - if (fn && cb) return wrappy(fn)(cb) + // current character position in p + var pos; + // the partial path so far, including a trailing slash if any + var current; + // the partial path without a trailing slash (except when pointing at a root) + var base; + // the partial path scanned in the previous round, with slash + var previous; - if (typeof fn !== 'function') - throw new TypeError('need wrapper function') + start(); - Object.keys(fn).forEach(function (k) { - wrapper[k] = fn[k] - }) + function start() { + // Skip over roots + var m = splitRootRe.exec(p); + pos = m[0].length; + current = m[0]; + base = m[0]; + previous = ''; - return wrapper - - function wrapper() { - var args = new Array(arguments.length) - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i] - } - var ret = fn.apply(this, args) - var cb = args[args.length-1] - if (typeof ret === 'function' && ret !== cb) { - Object.keys(cb).forEach(function (k) { - ret[k] = cb[k] - }) + // On windows, check that the root exists. On unix there is no need. + if (isWindows && !knownHard[base]) { + fs.lstat(base, function(err) { + if (err) return cb(err); + knownHard[base] = true; + LOOP(); + }); + } else { + process.nextTick(LOOP); } - return ret } -} + // walk down the path, swapping out linked pathparts for their real + // values + function LOOP() { + // stop if scanned past end of path + if (pos >= p.length) { + if (cache) cache[original] = p; + return cb(null, p); + } -/***/ }), -/* 124 */, -/* 125 */, -/* 126 */, -/* 127 */, -/* 128 */, -/* 129 */, -/* 130 */, -/* 131 */ -/***/ (function(module, exports, __webpack_require__) { + // find the next part + nextPartRe.lastIndex = pos; + var result = nextPartRe.exec(p); + previous = current; + current += result[0]; + base = previous + result[1]; + pos = nextPartRe.lastIndex; -// fallback for non-array-like ES3 and non-enumerable old V8 strings -var cof = __webpack_require__(47); -// eslint-disable-next-line no-prototype-builtins -module.exports = Object('z').propertyIsEnumerable(0) ? Object : function (it) { - return cof(it) == 'String' ? it.split('') : Object(it); -}; + // continue if not a symlink + if (knownHard[base] || (cache && cache[base] === base)) { + return process.nextTick(LOOP); + } + if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { + // known symbolic link. no need to stat again. + return gotResolvedLink(cache[base]); + } -/***/ }), -/* 132 */ -/***/ (function(module, exports, __webpack_require__) { + return fs.lstat(base, gotStat); + } -// 19.1.2.14 / 15.2.3.14 Object.keys(O) -var $keys = __webpack_require__(195); -var enumBugKeys = __webpack_require__(101); + function gotStat(err, stat) { + if (err) return cb(err); -module.exports = Object.keys || function keys(O) { - return $keys(O, enumBugKeys); -}; + // if not a symlink, skip to the next path part + if (!stat.isSymbolicLink()) { + knownHard[base] = true; + if (cache) cache[base] = base; + return process.nextTick(LOOP); + } + // stat & read the link if not read before + // call gotTarget as soon as the link target is known + // dev/ino always return 0 on windows, so skip the check. + if (!isWindows) { + var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); + if (seenLinks.hasOwnProperty(id)) { + return gotTarget(null, seenLinks[id], base); + } + } + fs.stat(base, function(err) { + if (err) return cb(err); -/***/ }), -/* 133 */ -/***/ (function(module, exports, __webpack_require__) { + fs.readlink(base, function(err, target) { + if (!isWindows) seenLinks[id] = target; + gotTarget(err, target); + }); + }); + } -// 7.1.13 ToObject(argument) -var defined = __webpack_require__(67); -module.exports = function (it) { - return Object(defined(it)); -}; + function gotTarget(err, target, base) { + if (err) return cb(err); + var resolvedLink = pathModule.resolve(previous, target); + if (cache) cache[base] = resolvedLink; + gotResolvedLink(resolvedLink); + } -/***/ }), -/* 134 */, -/* 135 */, -/* 136 */, -/* 137 */, -/* 138 */, -/* 139 */, -/* 140 */, -/* 141 */, -/* 142 */, -/* 143 */, -/* 144 */, -/* 145 */ -/***/ (function(module, exports) { + function gotResolvedLink(resolvedLink) { + // resolve the link, then start over + p = pathModule.resolve(resolvedLink, p.slice(pos)); + start(); + } +}; -module.exports = {"name":"yarn","installationMethod":"unknown","version":"1.10.0-0","license":"BSD-2-Clause","preferGlobal":true,"description":"📦🐈 Fast, reliable, and secure dependency management.","dependencies":{"@zkochan/cmd-shim":"^2.2.4","babel-runtime":"^6.26.0","bytes":"^3.0.0","camelcase":"^4.0.0","chalk":"^2.1.0","commander":"^2.9.0","death":"^1.0.0","debug":"^3.0.0","deep-equal":"^1.0.1","detect-indent":"^5.0.0","dnscache":"^1.0.1","glob":"^7.1.1","gunzip-maybe":"^1.4.0","hash-for-dep":"^1.2.3","imports-loader":"^0.8.0","ini":"^1.3.4","inquirer":"^3.0.1","invariant":"^2.2.0","is-builtin-module":"^2.0.0","is-ci":"^1.0.10","is-webpack-bundle":"^1.0.0","leven":"^2.0.0","loud-rejection":"^1.2.0","micromatch":"^2.3.11","mkdirp":"^0.5.1","node-emoji":"^1.6.1","normalize-url":"^2.0.0","npm-logical-tree":"^1.2.1","object-path":"^0.11.2","proper-lockfile":"^2.0.0","puka":"^1.0.0","read":"^1.0.7","request":"^2.87.0","request-capture-har":"^1.2.2","rimraf":"^2.5.0","semver":"^5.1.0","ssri":"^5.3.0","strip-ansi":"^4.0.0","strip-bom":"^3.0.0","tar-fs":"^1.16.0","tar-stream":"^1.6.1","uuid":"^3.0.1","v8-compile-cache":"^2.0.0","validate-npm-package-license":"^3.0.3","yn":"^2.0.0"},"devDependencies":{"babel-core":"^6.26.0","babel-eslint":"^7.2.3","babel-loader":"^6.2.5","babel-plugin-array-includes":"^2.0.3","babel-plugin-transform-builtin-extend":"^1.1.2","babel-plugin-transform-inline-imports-commonjs":"^1.0.0","babel-plugin-transform-runtime":"^6.4.3","babel-preset-env":"^1.6.0","babel-preset-flow":"^6.23.0","babel-preset-stage-0":"^6.0.0","babylon":"^6.5.0","commitizen":"^2.9.6","cz-conventional-changelog":"^2.0.0","eslint":"^4.3.0","eslint-config-fb-strict":"^22.0.0","eslint-plugin-babel":"^5.0.0","eslint-plugin-flowtype":"^2.35.0","eslint-plugin-jasmine":"^2.6.2","eslint-plugin-jest":"^21.0.0","eslint-plugin-jsx-a11y":"^6.0.2","eslint-plugin-prefer-object-spread":"^1.2.1","eslint-plugin-prettier":"^2.1.2","eslint-plugin-react":"^7.1.0","eslint-plugin-relay":"^0.0.24","eslint-plugin-yarn-internal":"file:scripts/eslint-rules","execa":"^0.10.0","flow-bin":"^0.66.0","git-release-notes":"^3.0.0","gulp":"^3.9.0","gulp-babel":"^7.0.0","gulp-if":"^2.0.1","gulp-newer":"^1.0.0","gulp-plumber":"^1.0.1","gulp-sourcemaps":"^2.2.0","gulp-util":"^3.0.7","gulp-watch":"^5.0.0","jest":"^22.4.4","jsinspect":"^0.12.6","minimatch":"^3.0.4","mock-stdin":"^0.3.0","prettier":"^1.5.2","temp":"^0.8.3","webpack":"^2.1.0-beta.25","yargs":"^6.3.0"},"resolutions":{"sshpk":"^1.14.2"},"engines":{"node":">=4.0.0"},"repository":"yarnpkg/yarn","bin":{"yarn":"./bin/yarn.js","yarnpkg":"./bin/yarn.js"},"scripts":{"build":"gulp build","build-bundle":"node ./scripts/build-webpack.js","build-chocolatey":"powershell ./scripts/build-chocolatey.ps1","build-deb":"./scripts/build-deb.sh","build-dist":"bash ./scripts/build-dist.sh","build-win-installer":"scripts\\build-windows-installer.bat","changelog":"git-release-notes $(git describe --tags --abbrev=0 $(git describe --tags --abbrev=0)^)..$(git describe --tags --abbrev=0) scripts/changelog.md","dupe-check":"yarn jsinspect ./src","lint":"eslint . && flow check","pkg-tests":"yarn --cwd packages/pkg-tests jest yarn.test.js","prettier":"eslint src __tests__ --fix","release-branch":"./scripts/release-branch.sh","test":"yarn lint && yarn test-only","test-only":"node --max_old_space_size=4096 node_modules/jest/bin/jest.js --verbose","test-only-debug":"node --inspect-brk --max_old_space_size=4096 node_modules/jest/bin/jest.js --runInBand --verbose","test-coverage":"node --max_old_space_size=4096 node_modules/jest/bin/jest.js --coverage --verbose","watch":"gulp watch","commit":"git-cz"},"jest":{"collectCoverageFrom":["src/**/*.js"],"testEnvironment":"node","modulePathIgnorePatterns":["__tests__/fixtures/","packages/pkg-tests/pkg-tests-fixtures","dist/"],"testPathIgnorePatterns":["__tests__/(fixtures|__mocks__)/","updates/","_(temp|mock|install|init|helpers).js$","packages/pkg-tests"]},"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}}} /***/ }), -/* 146 */, -/* 147 */, -/* 148 */, -/* 149 */, -/* 150 */ +/* 218 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - +module.exports = globSync +globSync.GlobSync = GlobSync -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = stringify; +var fs = __webpack_require__(3) +var rp = __webpack_require__(114) +var minimatch = __webpack_require__(60) +var Minimatch = minimatch.Minimatch +var Glob = __webpack_require__(75).Glob +var util = __webpack_require__(2) +var path = __webpack_require__(0) +var assert = __webpack_require__(22) +var isAbsolute = __webpack_require__(76) +var common = __webpack_require__(115) +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored -var _misc; +function globSync (pattern, options) { + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') -function _load_misc() { - return _misc = __webpack_require__(12); + return new GlobSync(pattern, options).found } -var _constants; - -function _load_constants() { - return _constants = __webpack_require__(6); -} +function GlobSync (pattern, options) { + if (!pattern) + throw new Error('must provide pattern') -var _package; + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') -function _load_package() { - return _package = __webpack_require__(145); -} + if (!(this instanceof GlobSync)) + return new GlobSync(pattern, options) -const NODE_VERSION = process.version; + setopts(this, pattern, options) -function shouldWrapKey(str) { - return str.indexOf('true') === 0 || str.indexOf('false') === 0 || /[:\s\n\\",\[\]]/g.test(str) || /^[0-9]/g.test(str) || !/^[a-zA-Z]/g.test(str); -} + if (this.noprocess) + return this -function maybeWrap(str) { - if (typeof str === 'boolean' || typeof str === 'number' || shouldWrapKey(str)) { - return JSON.stringify(str); - } else { - return str; + var n = this.minimatch.set.length + this.matches = new Array(n) + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false) } + this._finish() } -const priorities = { - name: 1, - version: 2, - uid: 3, - resolved: 4, - integrity: 5, - registry: 6, - dependencies: 7 -}; - -function priorityThenAlphaSort(a, b) { - if (priorities[a] || priorities[b]) { - return (priorities[a] || 100) > (priorities[b] || 100) ? 1 : -1; - } else { - return (0, (_misc || _load_misc()).sortAlpha)(a, b); +GlobSync.prototype._finish = function () { + assert(this instanceof GlobSync) + if (this.realpath) { + var self = this + this.matches.forEach(function (matchset, index) { + var set = self.matches[index] = Object.create(null) + for (var p in matchset) { + try { + p = self._makeAbs(p) + var real = rp.realpathSync(p, self.realpathCache) + set[real] = true + } catch (er) { + if (er.syscall === 'stat') + set[self._makeAbs(p)] = true + else + throw er + } + } + }) } + common.finish(this) } -function _stringify(obj, options) { - if (typeof obj !== 'object') { - throw new TypeError(); - } - - const indent = options.indent; - const lines = []; - - // Sorting order needs to be consistent between runs, we run native sort by name because there are no - // problems with it being unstable because there are no to keys the same - // However priorities can be duplicated and native sort can shuffle things from run to run - const keys = Object.keys(obj).sort(priorityThenAlphaSort); - - let addedKeys = []; - - for (let i = 0; i < keys.length; i++) { - const key = keys[i]; - const val = obj[key]; - if (val == null || addedKeys.indexOf(key) >= 0) { - continue; - } - const valKeys = [key]; +GlobSync.prototype._process = function (pattern, index, inGlobStar) { + assert(this instanceof GlobSync) - // get all keys that have the same value equality, we only want this for objects - if (typeof val === 'object') { - for (let j = i + 1; j < keys.length; j++) { - const key = keys[j]; - if (val === obj[key]) { - valKeys.push(key); - } - } - } + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. - const keyLine = valKeys.sort((_misc || _load_misc()).sortAlpha).map(maybeWrap).join(', '); + // See if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index) + return - if (typeof val === 'string' || typeof val === 'boolean' || typeof val === 'number') { - lines.push(`${keyLine} ${maybeWrap(val)}`); - } else if (typeof val === 'object') { - lines.push(`${keyLine}:\n${_stringify(val, { indent: indent + ' ' })}` + (options.topLevel ? '\n' : '')); - } else { - throw new TypeError(); - } + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break - addedKeys = addedKeys.concat(valKeys); + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break } - return indent + lines.join(`\n${indent}`); -} + var remain = pattern.slice(n) -function stringify(obj, noHeader, enableVersions) { - const val = _stringify(obj, { - indent: '', - topLevel: true - }); - if (noHeader) { - return val; - } + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix - const lines = []; - lines.push('# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.'); - lines.push(`# yarn lockfile v${(_constants || _load_constants()).LOCKFILE_VERSION}`); - if (enableVersions) { - lines.push(`# yarn v${(_package || _load_package()).version}`); - lines.push(`# node ${NODE_VERSION}`); - } - lines.push('\n'); - lines.push(val); + var abs = this._makeAbs(read) - return lines.join('\n'); -} + //if ignored, skip processing + if (childrenIgnored(this, read)) + return -/***/ }), -/* 151 */, -/* 152 */, -/* 153 */, -/* 154 */, -/* 155 */, -/* 156 */, -/* 157 */, -/* 158 */, -/* 159 */, -/* 160 */, -/* 161 */, -/* 162 */, -/* 163 */, -/* 164 */ -/***/ (function(module, exports, __webpack_require__) { + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar) +} -"use strict"; +GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { + var entries = this._readdir(abs, inGlobStar) -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.fileDatesEqual = exports.copyFile = exports.unlink = undefined; + // if the abs isn't a dir, then nothing can match! + if (!entries) + return -var _asyncToGenerator2; + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' -function _load_asyncToGenerator() { - return _asyncToGenerator2 = _interopRequireDefault(__webpack_require__(1)); -} + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } -// We want to preserve file timestamps when copying a file, since yarn uses them to decide if a file has -// changed compared to the cache. -// There are some OS specific cases here: -// * On linux, fs.copyFile does not preserve timestamps, but does on OSX and Win. -// * On windows, you must open a file with write permissions to call `fs.futimes`. -// * On OSX you can open with read permissions and still call `fs.futimes`. -let fixTimes = (() => { - var _ref3 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (fd, dest, data) { - const doOpen = fd === undefined; - let openfd = fd ? fd : -1; + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return - if (disableTimestampCorrection === undefined) { - // if timestamps match already, no correction is needed. - // the need to correct timestamps varies based on OS and node versions. - const destStat = yield lstat(dest); - disableTimestampCorrection = fileDatesEqual(destStat.mtime, data.mtime); - } + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. - if (disableTimestampCorrection) { - return; - } + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) - if (doOpen) { - try { - openfd = yield open(dest, 'a', data.mode); - } catch (er) { - // file is likely read-only - try { - openfd = yield open(dest, 'r', data.mode); - } catch (err) { - // We can't even open this file for reading. - return; - } + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix.slice(-1) !== '/') + e = prefix + '/' + e + else + e = prefix + e } - } - try { - if (openfd) { - yield futimes(openfd, data.atime, data.mtime); - } - } catch (er) { - // If `futimes` throws an exception, we probably have a case of a read-only file on Windows. - // In this case we can just return. The incorrect timestamp will just cause that file to be recopied - // on subsequent installs, which will effect yarn performance but not break anything. - } finally { - if (doOpen && openfd) { - yield close(openfd); + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) } + this._emitMatch(index, e) } - }); + // This was the last one, and no stats were needed + return + } - return function fixTimes(_x7, _x8, _x9) { - return _ref3.apply(this, arguments); - }; -})(); + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) + newPattern = [prefix, e] + else + newPattern = [e] + this._process(newPattern.concat(remain), index, inGlobStar) + } +} -// Compare file timestamps. -// Some versions of Node on windows zero the milliseconds when utime is used. +GlobSync.prototype._emitMatch = function (index, e) { + if (isIgnored(this, e)) + return -var _fs; + var abs = this._makeAbs(e) -function _load_fs() { - return _fs = _interopRequireDefault(__webpack_require__(3)); -} + if (this.mark) + e = this._mark(e) -var _promise; + if (this.absolute) { + e = abs + } -function _load_promise() { - return _promise = __webpack_require__(40); -} + if (this.matches[index][e]) + return -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return + } -// This module serves as a wrapper for file operations that are inconsistant across node and OS versions. + this.matches[index][e] = true -let disableTimestampCorrection = undefined; // OS dependent. will be detected on first file copy. - -const readFileBuffer = (0, (_promise || _load_promise()).promisify)((_fs || _load_fs()).default.readFile); -const close = (0, (_promise || _load_promise()).promisify)((_fs || _load_fs()).default.close); -const lstat = (0, (_promise || _load_promise()).promisify)((_fs || _load_fs()).default.lstat); -const open = (0, (_promise || _load_promise()).promisify)((_fs || _load_fs()).default.open); -const futimes = (0, (_promise || _load_promise()).promisify)((_fs || _load_fs()).default.futimes); + if (this.stat) + this._stat(e) +} -const write = (0, (_promise || _load_promise()).promisify)((_fs || _load_fs()).default.write); -const unlink = exports.unlink = (0, (_promise || _load_promise()).promisify)(__webpack_require__(233)); +GlobSync.prototype._readdirInGlobStar = function (abs) { + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false) -/** - * Unlinks the destination to force a recreation. This is needed on case-insensitive file systems - * to force the correct naming when the filename has changed only in character-casing. (Jest -> jest). - */ -const copyFile = exports.copyFile = (() => { - var _ref = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (data, cleanup) { - try { - yield unlink(data.dest); - yield copyFilePoly(data.src, data.dest, 0, data); - } finally { - if (cleanup) { - cleanup(); - } + var entries + var lstat + var stat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + if (er.code === 'ENOENT') { + // lstat failed, doesn't exist + return null } - }); + } - return function copyFile(_x, _x2) { - return _ref.apply(this, arguments); - }; -})(); + var isSym = lstat && lstat.isSymbolicLink() + this.symlinks[abs] = isSym -// Node 8.5.0 introduced `fs.copyFile` which is much faster, so use that when available. -// Otherwise we fall back to reading and writing files as buffers. -const copyFilePoly = (src, dest, flags, data) => { - if ((_fs || _load_fs()).default.copyFile) { - return new Promise((resolve, reject) => (_fs || _load_fs()).default.copyFile(src, dest, flags, err => { - if (err) { - reject(err); - } else { - fixTimes(undefined, dest, data).then(() => resolve()).catch(ex => reject(ex)); - } - })); - } else { - return copyWithBuffer(src, dest, flags, data); - } -}; + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && lstat && !lstat.isDirectory()) + this.cache[abs] = 'FILE' + else + entries = this._readdir(abs, false) -const copyWithBuffer = (() => { - var _ref2 = (0, (_asyncToGenerator2 || _load_asyncToGenerator()).default)(function* (src, dest, flags, data) { - // Use open -> write -> futimes -> close sequence to avoid opening the file twice: - // one with writeFile and one with utimes - const fd = yield open(dest, 'w', data.mode); - try { - const buffer = yield readFileBuffer(src); - yield write(fd, buffer, 0, buffer.length); - yield fixTimes(fd, dest, data); - } finally { - yield close(fd); - } - }); + return entries +} - return function copyWithBuffer(_x3, _x4, _x5, _x6) { - return _ref2.apply(this, arguments); - }; -})();const fileDatesEqual = exports.fileDatesEqual = (a, b) => { - const aTime = a.getTime(); - const bTime = b.getTime(); +GlobSync.prototype._readdir = function (abs, inGlobStar) { + var entries - if (process.platform !== 'win32') { - return aTime === bTime; - } + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs) - // See https://github.com/nodejs/node/pull/12607 - // Submillisecond times from stat and utimes are truncated on Windows, - // causing a file with mtime 8.0079998 and 8.0081144 to become 8.007 and 8.008 - // and making it impossible to update these files to their correct timestamps. - if (Math.abs(aTime - bTime) <= 1) { - return true; + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return null + + if (Array.isArray(c)) + return c } - const aTimeSec = Math.floor(aTime / 1000); - const bTimeSec = Math.floor(bTime / 1000); + try { + return this._readdirEntries(abs, fs.readdirSync(abs)) + } catch (er) { + this._readdirError(abs, er) + return null + } +} - // See https://github.com/nodejs/node/issues/2069 - // Some versions of Node on windows zero the milliseconds when utime is used - // So if any of the time has a milliseconds part of zero we suspect that the - // bug is present and compare only seconds. - if (aTime - aTimeSec * 1000 === 0 || bTime - bTimeSec * 1000 === 0) { - return aTimeSec === bTimeSec; +GlobSync.prototype._readdirEntries = function (abs, entries) { + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } } - return aTime === bTime; -}; + this.cache[abs] = entries -/***/ }), -/* 165 */, -/* 166 */, -/* 167 */, -/* 168 */, -/* 169 */ -/***/ (function(module, exports, __webpack_require__) { + // mark and cache dir-ness + return entries +} -"use strict"; +GlobSync.prototype._readdirError = function (f, er) { + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + var abs = this._makeAbs(f) + this.cache[abs] = 'FILE' + if (abs === this.cwdAbs) { + var error = new Error(er.code + ' invalid cwd ' + this.cwd) + error.path = this.cwd + error.code = er.code + throw error + } + break + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.isFakeRoot = isFakeRoot; -exports.isRootUser = isRootUser; -function getUid() { - if (process.platform !== 'win32' && process.getuid) { - return process.getuid(); + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) + throw er + if (!this.silent) + console.error('glob error', er) + break } - return null; } -exports.default = isRootUser(getUid()) && !isFakeRoot(); -function isFakeRoot() { - return Boolean(process.env.FAKEROOTKEY); -} +GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { -function isRootUser(uid) { - return uid === 0; -} + var entries = this._readdir(abs, inGlobStar) -/***/ }), -/* 170 */, -/* 171 */ -/***/ (function(module, exports, __webpack_require__) { + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return -"use strict"; + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false) -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.getDataDir = getDataDir; -exports.getCacheDir = getCacheDir; -exports.getConfigDir = getConfigDir; -const path = __webpack_require__(0); -const userHome = __webpack_require__(45).default; + var len = entries.length + var isSym = this.symlinks[abs] -const FALLBACK_CONFIG_DIR = path.join(userHome, '.config', 'yarn'); -const FALLBACK_CACHE_DIR = path.join(userHome, '.cache', 'yarn'); + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return -function getDataDir() { - if (process.platform === 'win32') { - const WIN32_APPDATA_DIR = getLocalAppDataDir(); - return WIN32_APPDATA_DIR == null ? FALLBACK_CONFIG_DIR : path.join(WIN32_APPDATA_DIR, 'Data'); - } else if (process.env.XDG_DATA_HOME) { - return path.join(process.env.XDG_DATA_HOME, 'yarn'); - } else { - // This could arguably be ~/Library/Application Support/Yarn on Macs, - // but that feels unintuitive for a cli tool + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue - // Instead, use our prior fallback. Some day this could be - // path.join(userHome, '.local', 'share', 'yarn') - // or return path.join(WIN32_APPDATA_DIR, 'Data') on win32 - return FALLBACK_CONFIG_DIR; - } -} + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true) -function getCacheDir() { - if (process.platform === 'win32') { - // process.env.TEMP also exists, but most apps put caches here - return path.join(getLocalAppDataDir() || path.join(userHome, 'AppData', 'Local', 'Yarn'), 'Cache'); - } else if (process.env.XDG_CACHE_HOME) { - return path.join(process.env.XDG_CACHE_HOME, 'yarn'); - } else if (process.platform === 'darwin') { - return path.join(userHome, 'Library', 'Caches', 'Yarn'); - } else { - return FALLBACK_CACHE_DIR; + var below = gspref.concat(entries[i], remain) + this._process(below, index, true) } } -function getConfigDir() { - if (process.platform === 'win32') { - // Use our prior fallback. Some day this could be - // return path.join(WIN32_APPDATA_DIR, 'Config') - const WIN32_APPDATA_DIR = getLocalAppDataDir(); - return WIN32_APPDATA_DIR == null ? FALLBACK_CONFIG_DIR : path.join(WIN32_APPDATA_DIR, 'Config'); - } else if (process.env.XDG_CONFIG_HOME) { - return path.join(process.env.XDG_CONFIG_HOME, 'yarn'); - } else { - return FALLBACK_CONFIG_DIR; - } -} +GlobSync.prototype._processSimple = function (prefix, index) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var exists = this._stat(prefix) -function getLocalAppDataDir() { - return process.env.LOCALAPPDATA ? path.join(process.env.LOCALAPPDATA, 'Yarn') : null; -} + if (!this.matches[index]) + this.matches[index] = Object.create(null) -/***/ }), -/* 172 */, -/* 173 */ -/***/ (function(module, exports, __webpack_require__) { + // If it doesn't exist, then just mark the lack of results + if (!exists) + return -module.exports = { "default": __webpack_require__(179), __esModule: true }; + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } -/***/ }), -/* 174 */ -/***/ (function(module, exports, __webpack_require__) { + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') -"use strict"; + // Mark this as a match + this._emitMatch(index, prefix) +} -module.exports = balanced; -function balanced(a, b, str) { - if (a instanceof RegExp) a = maybeMatch(a, str); - if (b instanceof RegExp) b = maybeMatch(b, str); +// Returns either 'DIR', 'FILE', or false +GlobSync.prototype._stat = function (f) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' - var r = range(a, b, str); + if (f.length > this.maxLength) + return false - return r && { - start: r[0], - end: r[1], - pre: str.slice(0, r[0]), - body: str.slice(r[0] + a.length, r[1]), - post: str.slice(r[1] + b.length) - }; -} + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] -function maybeMatch(reg, str) { - var m = str.match(reg); - return m ? m[0] : null; -} + if (Array.isArray(c)) + c = 'DIR' -balanced.range = range; -function range(a, b, str) { - var begs, beg, left, right, result; - var ai = str.indexOf(a); - var bi = str.indexOf(b, ai + 1); - var i = ai; + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return c - if (ai >= 0 && bi > 0) { - begs = []; - left = str.length; + if (needDir && c === 'FILE') + return false - while (i >= 0 && !result) { - if (i == ai) { - begs.push(i); - ai = str.indexOf(a, i + 1); - } else if (begs.length == 1) { - result = [ begs.pop(), bi ]; - } else { - beg = begs.pop(); - if (beg < left) { - left = beg; - right = bi; - } + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } - bi = str.indexOf(b, i + 1); + var exists + var stat = this.statCache[abs] + if (!stat) { + var lstat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { + this.statCache[abs] = false + return false } - - i = ai < bi && ai >= 0 ? ai : bi; } - if (begs.length) { - result = [ left, right ]; + if (lstat && lstat.isSymbolicLink()) { + try { + stat = fs.statSync(abs) + } catch (er) { + stat = lstat + } + } else { + stat = lstat } } - return result; -} - - -/***/ }), -/* 175 */ -/***/ (function(module, exports, __webpack_require__) { + this.statCache[abs] = stat -var concatMap = __webpack_require__(178); -var balanced = __webpack_require__(174); + var c = true + if (stat) + c = stat.isDirectory() ? 'DIR' : 'FILE' -module.exports = expandTop; + this.cache[abs] = this.cache[abs] || c -var escSlash = '\0SLASH'+Math.random()+'\0'; -var escOpen = '\0OPEN'+Math.random()+'\0'; -var escClose = '\0CLOSE'+Math.random()+'\0'; -var escComma = '\0COMMA'+Math.random()+'\0'; -var escPeriod = '\0PERIOD'+Math.random()+'\0'; + if (needDir && c === 'FILE') + return false -function numeric(str) { - return parseInt(str, 10) == str - ? parseInt(str, 10) - : str.charCodeAt(0); + return c } -function escapeBraces(str) { - return str.split('\\\\').join(escSlash) - .split('\\{').join(escOpen) - .split('\\}').join(escClose) - .split('\\,').join(escComma) - .split('\\.').join(escPeriod); +GlobSync.prototype._mark = function (p) { + return common.mark(this, p) } -function unescapeBraces(str) { - return str.split(escSlash).join('\\') - .split(escOpen).join('{') - .split(escClose).join('}') - .split(escComma).join(',') - .split(escPeriod).join('.'); +GlobSync.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) } -// Basically just str.split(","), but handling cases -// where we have nested braced sections, which should be -// treated as individual members, like {a,{b,c},d} -function parseCommaParts(str) { - if (!str) - return ['']; - - var parts = []; - var m = balanced('{', '}', str); +/***/ }), +/* 219 */, +/* 220 */, +/* 221 */ +/***/ (function(module, exports, __webpack_require__) { - if (!m) - return str.split(','); +"use strict"; - var pre = m.pre; - var body = m.body; - var post = m.post; - var p = pre.split(','); +module.exports = function (flag, argv) { + argv = argv || process.argv; - p[p.length-1] += '{' + body + '}'; - var postParts = parseCommaParts(post); - if (post.length) { - p[p.length-1] += postParts.shift(); - p.push.apply(p, postParts); - } + var terminatorPos = argv.indexOf('--'); + var prefix = /^--/.test(flag) ? '' : '--'; + var pos = argv.indexOf(prefix + flag); - parts.push.apply(parts, p); + return pos !== -1 && (terminatorPos !== -1 ? pos < terminatorPos : true); +}; - return parts; -} -function expandTop(str) { - if (!str) - return []; +/***/ }), +/* 222 */, +/* 223 */ +/***/ (function(module, exports, __webpack_require__) { - // I don't know why Bash 4.3 does this, but it does. - // Anything starting with {} will have the first two bytes preserved - // but *only* at the top level, so {},a}b will not expand to anything, - // but a{},b}c will be expanded to [a}c,abc]. - // One could argue that this is a bug in Bash, but since the goal of - // this module is to match Bash's rules, we escape a leading {} - if (str.substr(0, 2) === '{}') { - str = '\\{\\}' + str.substr(2); - } +var wrappy = __webpack_require__(123) +var reqs = Object.create(null) +var once = __webpack_require__(61) - return expand(escapeBraces(str), true).map(unescapeBraces); -} +module.exports = wrappy(inflight) -function identity(e) { - return e; +function inflight (key, cb) { + if (reqs[key]) { + reqs[key].push(cb) + return null + } else { + reqs[key] = [cb] + return makeres(key) + } } -function embrace(str) { - return '{' + str + '}'; -} -function isPadded(el) { - return /^-?0\d/.test(el); -} +function makeres (key) { + return once(function RES () { + var cbs = reqs[key] + var len = cbs.length + var args = slice(arguments) -function lte(i, y) { - return i <= y; -} -function gte(i, y) { - return i >= y; -} - -function expand(str, isTop) { - var expansions = []; - - var m = balanced('{', '}', str); - if (!m || /\$$/.test(m.pre)) return [str]; - - var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); - var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); - var isSequence = isNumericSequence || isAlphaSequence; - var isOptions = m.body.indexOf(',') >= 0; - if (!isSequence && !isOptions) { - // {a},b} - if (m.post.match(/,.*\}/)) { - str = m.pre + '{' + m.body + escClose + m.post; - return expand(str); - } - return [str]; - } - - var n; - if (isSequence) { - n = m.body.split(/\.\./); - } else { - n = parseCommaParts(m.body); - if (n.length === 1) { - // x{{a,b}}y ==> x{a}y x{b}y - n = expand(n[0], false).map(embrace); - if (n.length === 1) { - var post = m.post.length - ? expand(m.post, false) - : ['']; - return post.map(function(p) { - return m.pre + n[0] + p; - }); + // XXX It's somewhat ambiguous whether a new callback added in this + // pass should be queued for later execution if something in the + // list of callbacks throws, or if it should just be discarded. + // However, it's such an edge case that it hardly matters, and either + // choice is likely as surprising as the other. + // As it happens, we do go ahead and schedule it for later execution. + try { + for (var i = 0; i < len; i++) { + cbs[i].apply(null, args) + } + } finally { + if (cbs.length > len) { + // added more in the interim. + // de-zalgo, just in case, but don't call again. + cbs.splice(0, len) + process.nextTick(function () { + RES.apply(null, args) + }) + } else { + delete reqs[key] } } - } - - // at this point, n is the parts, and we know it's not a comma set - // with a single entry. + }) +} - // no need to expand pre, since it is guaranteed to be free of brace-sets - var pre = m.pre; - var post = m.post.length - ? expand(m.post, false) - : ['']; +function slice (args) { + var length = args.length + var array = [] - var N; + for (var i = 0; i < length; i++) array[i] = args[i] + return array +} - if (isSequence) { - var x = numeric(n[0]); - var y = numeric(n[1]); - var width = Math.max(n[0].length, n[1].length) - var incr = n.length == 3 - ? Math.abs(numeric(n[2])) - : 1; - var test = lte; - var reverse = y < x; - if (reverse) { - incr *= -1; - test = gte; - } - var pad = n.some(isPadded); - N = []; +/***/ }), +/* 224 */ +/***/ (function(module, exports) { - for (var i = x; test(i, y); i += incr) { - var c; - if (isAlphaSequence) { - c = String.fromCharCode(i); - if (c === '\\') - c = ''; - } else { - c = String(i); - if (pad) { - var need = width - c.length; - if (need > 0) { - var z = new Array(need + 1).join('0'); - if (i < 0) - c = '-' + z + c.slice(1); - else - c = z + c; - } - } +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true } - N.push(c); - } - } else { - N = concatMap(n, function(el) { return expand(el, false) }); - } - - for (var j = 0; j < N.length; j++) { - for (var k = 0; k < post.length; k++) { - var expansion = pre + N[j] + post[k]; - if (!isTop || isSequence || expansion) - expansions.push(expansion); - } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor } - - return expansions; } - /***/ }), -/* 176 */ +/* 225 */, +/* 226 */, +/* 227 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +// @flow +/*:: +declare var __webpack_require__: mixed; +*/ -function preserveCamelCase(str) { - let isLastCharLower = false; - let isLastCharUpper = false; - let isLastLastCharUpper = false; +module.exports = typeof __webpack_require__ !== "undefined"; - for (let i = 0; i < str.length; i++) { - const c = str[i]; - if (isLastCharLower && /[a-zA-Z]/.test(c) && c.toUpperCase() === c) { - str = str.substr(0, i) + '-' + str.substr(i); - isLastCharLower = false; - isLastLastCharUpper = isLastCharUpper; - isLastCharUpper = true; - i++; - } else if (isLastCharUpper && isLastLastCharUpper && /[a-zA-Z]/.test(c) && c.toLowerCase() === c) { - str = str.substr(0, i - 1) + '-' + str.substr(i - 1); - isLastLastCharUpper = isLastCharUpper; - isLastCharUpper = false; - isLastCharLower = true; - } else { - isLastCharLower = c.toLowerCase() === c; - isLastLastCharUpper = isLastCharUpper; - isLastCharUpper = c.toUpperCase() === c; - } - } +/***/ }), +/* 228 */, +/* 229 */ +/***/ (function(module, exports) { - return str; -} +/** + * Helpers. + */ -module.exports = function (str) { - if (arguments.length > 1) { - str = Array.from(arguments) - .map(x => x.trim()) - .filter(x => x.length) - .join('-'); - } else { - str = str.trim(); - } +var s = 1000; +var m = s * 60; +var h = m * 60; +var d = h * 24; +var y = d * 365.25; - if (str.length === 0) { - return ''; - } +/** + * Parse or format the given `val`. + * + * Options: + * + * - `long` verbose formatting [false] + * + * @param {String|Number} val + * @param {Object} [options] + * @throws {Error} throw an error if val is not a non-empty string or a number + * @return {String|Number} + * @api public + */ - if (str.length === 1) { - return str.toLowerCase(); - } +module.exports = function(val, options) { + options = options || {}; + var type = typeof val; + if (type === 'string' && val.length > 0) { + return parse(val); + } else if (type === 'number' && isNaN(val) === false) { + return options.long ? fmtLong(val) : fmtShort(val); + } + throw new Error( + 'val is not a non-empty string or a valid number. val=' + + JSON.stringify(val) + ); +}; - if (/^[a-z0-9]+$/.test(str)) { - return str; - } +/** + * Parse the given `str` and return milliseconds. + * + * @param {String} str + * @return {Number} + * @api private + */ - const hasUpperCase = str !== str.toLowerCase(); +function parse(str) { + str = String(str); + if (str.length > 100) { + return; + } + var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec( + str + ); + if (!match) { + return; + } + var n = parseFloat(match[1]); + var type = (match[2] || 'ms').toLowerCase(); + switch (type) { + case 'years': + case 'year': + case 'yrs': + case 'yr': + case 'y': + return n * y; + case 'days': + case 'day': + case 'd': + return n * d; + case 'hours': + case 'hour': + case 'hrs': + case 'hr': + case 'h': + return n * h; + case 'minutes': + case 'minute': + case 'mins': + case 'min': + case 'm': + return n * m; + case 'seconds': + case 'second': + case 'secs': + case 'sec': + case 's': + return n * s; + case 'milliseconds': + case 'millisecond': + case 'msecs': + case 'msec': + case 'ms': + return n; + default: + return undefined; + } +} - if (hasUpperCase) { - str = preserveCamelCase(str); - } +/** + * Short format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ - return str - .replace(/^[_.\- ]+/, '') - .toLowerCase() - .replace(/[_.\- ]+(\w|$)/g, (m, p1) => p1.toUpperCase()); -}; +function fmtShort(ms) { + if (ms >= d) { + return Math.round(ms / d) + 'd'; + } + if (ms >= h) { + return Math.round(ms / h) + 'h'; + } + if (ms >= m) { + return Math.round(ms / m) + 'm'; + } + if (ms >= s) { + return Math.round(ms / s) + 's'; + } + return ms + 'ms'; +} +/** + * Long format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ -/***/ }), -/* 177 */, -/* 178 */ -/***/ (function(module, exports) { +function fmtLong(ms) { + return plural(ms, d, 'day') || + plural(ms, h, 'hour') || + plural(ms, m, 'minute') || + plural(ms, s, 'second') || + ms + ' ms'; +} -module.exports = function (xs, fn) { - var res = []; - for (var i = 0; i < xs.length; i++) { - var x = fn(xs[i], i); - if (isArray(x)) res.push.apply(res, x); - else res.push(x); - } - return res; -}; +/** + * Pluralization helper. + */ -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; +function plural(ms, n, name) { + if (ms < n) { + return; + } + if (ms < n * 1.5) { + return Math.floor(ms / n) + ' ' + name; + } + return Math.ceil(ms / n) + ' ' + name + 's'; +} /***/ }), -/* 179 */ +/* 230 */, +/* 231 */, +/* 232 */, +/* 233 */ /***/ (function(module, exports, __webpack_require__) { -__webpack_require__(205); -__webpack_require__(207); -__webpack_require__(210); -__webpack_require__(206); -__webpack_require__(208); -__webpack_require__(209); -module.exports = __webpack_require__(23).Promise; - +module.exports = rimraf +rimraf.sync = rimrafSync -/***/ }), -/* 180 */ -/***/ (function(module, exports) { +var assert = __webpack_require__(22) +var path = __webpack_require__(0) +var fs = __webpack_require__(3) +var glob = __webpack_require__(75) +var _0666 = parseInt('666', 8) -module.exports = function () { /* empty */ }; +var defaultGlobOpts = { + nosort: true, + silent: true +} +// for EMFILE handling +var timeout = 0 -/***/ }), -/* 181 */ -/***/ (function(module, exports) { +var isWindows = (process.platform === "win32") -module.exports = function (it, Constructor, name, forbiddenField) { - if (!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)) { - throw TypeError(name + ': incorrect invocation!'); - } return it; -}; +function defaults (options) { + var methods = [ + 'unlink', + 'chmod', + 'stat', + 'lstat', + 'rmdir', + 'readdir' + ] + methods.forEach(function(m) { + options[m] = options[m] || fs[m] + m = m + 'Sync' + options[m] = options[m] || fs[m] + }) + options.maxBusyTries = options.maxBusyTries || 3 + options.emfileWait = options.emfileWait || 1000 + if (options.glob === false) { + options.disableGlob = true + } + options.disableGlob = options.disableGlob || false + options.glob = options.glob || defaultGlobOpts +} -/***/ }), -/* 182 */ -/***/ (function(module, exports, __webpack_require__) { +function rimraf (p, options, cb) { + if (typeof options === 'function') { + cb = options + options = {} + } -// false -> Array#indexOf -// true -> Array#includes -var toIObject = __webpack_require__(74); -var toLength = __webpack_require__(110); -var toAbsoluteIndex = __webpack_require__(200); -module.exports = function (IS_INCLUDES) { - return function ($this, el, fromIndex) { - var O = toIObject($this); - var length = toLength(O.length); - var index = toAbsoluteIndex(fromIndex, length); - var value; - // Array#includes uses SameValueZero equality algorithm - // eslint-disable-next-line no-self-compare - if (IS_INCLUDES && el != el) while (length > index) { - value = O[index++]; - // eslint-disable-next-line no-self-compare - if (value != value) return true; - // Array#indexOf ignores holes, Array#includes - not - } else for (;length > index; index++) if (IS_INCLUDES || index in O) { - if (O[index] === el) return IS_INCLUDES || index || 0; - } return !IS_INCLUDES && -1; - }; -}; + assert(p, 'rimraf: missing path') + assert.equal(typeof p, 'string', 'rimraf: path should be a string') + assert.equal(typeof cb, 'function', 'rimraf: callback function required') + assert(options, 'rimraf: invalid options argument provided') + assert.equal(typeof options, 'object', 'rimraf: options should be object') + defaults(options) -/***/ }), -/* 183 */ -/***/ (function(module, exports, __webpack_require__) { + var busyTries = 0 + var errState = null + var n = 0 -var ctx = __webpack_require__(48); -var call = __webpack_require__(187); -var isArrayIter = __webpack_require__(186); -var anObject = __webpack_require__(27); -var toLength = __webpack_require__(110); -var getIterFn = __webpack_require__(203); -var BREAK = {}; -var RETURN = {}; -var exports = module.exports = function (iterable, entries, fn, that, ITERATOR) { - var iterFn = ITERATOR ? function () { return iterable; } : getIterFn(iterable); - var f = ctx(fn, that, entries ? 2 : 1); - var index = 0; - var length, step, iterator, result; - if (typeof iterFn != 'function') throw TypeError(iterable + ' is not iterable!'); - // fast case for arrays with default iterator - if (isArrayIter(iterFn)) for (length = toLength(iterable.length); length > index; index++) { - result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]); - if (result === BREAK || result === RETURN) return result; - } else for (iterator = iterFn.call(iterable); !(step = iterator.next()).done;) { - result = call(iterator, f, step.value, entries); - if (result === BREAK || result === RETURN) return result; - } -}; -exports.BREAK = BREAK; -exports.RETURN = RETURN; + if (options.disableGlob || !glob.hasMagic(p)) + return afterGlob(null, [p]) + options.lstat(p, function (er, stat) { + if (!er) + return afterGlob(null, [p]) -/***/ }), -/* 184 */ -/***/ (function(module, exports, __webpack_require__) { - -module.exports = !__webpack_require__(33) && !__webpack_require__(85)(function () { - return Object.defineProperty(__webpack_require__(68)('div'), 'a', { get: function () { return 7; } }).a != 7; -}); - - -/***/ }), -/* 185 */ -/***/ (function(module, exports) { - -// fast apply, http://jsperf.lnkit.com/fast-apply/5 -module.exports = function (fn, args, that) { - var un = that === undefined; - switch (args.length) { - case 0: return un ? fn() - : fn.call(that); - case 1: return un ? fn(args[0]) - : fn.call(that, args[0]); - case 2: return un ? fn(args[0], args[1]) - : fn.call(that, args[0], args[1]); - case 3: return un ? fn(args[0], args[1], args[2]) - : fn.call(that, args[0], args[1], args[2]); - case 4: return un ? fn(args[0], args[1], args[2], args[3]) - : fn.call(that, args[0], args[1], args[2], args[3]); - } return fn.apply(that, args); -}; + glob(p, options.glob, afterGlob) + }) + function next (er) { + errState = errState || er + if (--n === 0) + cb(errState) + } -/***/ }), -/* 186 */ -/***/ (function(module, exports, __webpack_require__) { + function afterGlob (er, results) { + if (er) + return cb(er) -// check on default Array iterator -var Iterators = __webpack_require__(35); -var ITERATOR = __webpack_require__(13)('iterator'); -var ArrayProto = Array.prototype; + n = results.length + if (n === 0) + return cb() -module.exports = function (it) { - return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it); -}; + results.forEach(function (p) { + rimraf_(p, options, function CB (er) { + if (er) { + if ((er.code === "EBUSY" || er.code === "ENOTEMPTY" || er.code === "EPERM") && + busyTries < options.maxBusyTries) { + busyTries ++ + var time = busyTries * 100 + // try again, with the same exact callback as this one. + return setTimeout(function () { + rimraf_(p, options, CB) + }, time) + } + // this one won't happen if graceful-fs is used. + if (er.code === "EMFILE" && timeout < options.emfileWait) { + return setTimeout(function () { + rimraf_(p, options, CB) + }, timeout ++) + } -/***/ }), -/* 187 */ -/***/ (function(module, exports, __webpack_require__) { + // already gone + if (er.code === "ENOENT") er = null + } -// call something on iterator step with safe closing on error -var anObject = __webpack_require__(27); -module.exports = function (iterator, fn, value, entries) { - try { - return entries ? fn(anObject(value)[0], value[1]) : fn(value); - // 7.4.6 IteratorClose(iterator, completion) - } catch (e) { - var ret = iterator['return']; - if (ret !== undefined) anObject(ret.call(iterator)); - throw e; + timeout = 0 + next(er) + }) + }) } -}; - +} -/***/ }), -/* 188 */ -/***/ (function(module, exports, __webpack_require__) { +// Two possible strategies. +// 1. Assume it's a file. unlink it, then do the dir stuff on EPERM or EISDIR +// 2. Assume it's a directory. readdir, then do the file stuff on ENOTDIR +// +// Both result in an extra syscall when you guess wrong. However, there +// are likely far more normal files in the world than directories. This +// is based on the assumption that a the average number of files per +// directory is >= 1. +// +// If anyone ever complains about this, then I guess the strategy could +// be made configurable somehow. But until then, YAGNI. +function rimraf_ (p, options, cb) { + assert(p) + assert(options) + assert(typeof cb === 'function') -"use strict"; + // sunos lets the root user unlink directories, which is... weird. + // so we have to lstat here and make sure it's not a dir. + options.lstat(p, function (er, st) { + if (er && er.code === "ENOENT") + return cb(null) -var create = __webpack_require__(192); -var descriptor = __webpack_require__(106); -var setToStringTag = __webpack_require__(71); -var IteratorPrototype = {}; + // Windows can EPERM on stat. Life is suffering. + if (er && er.code === "EPERM" && isWindows) + fixWinEPERM(p, options, er, cb) -// 25.1.2.1.1 %IteratorPrototype%[@@iterator]() -__webpack_require__(31)(IteratorPrototype, __webpack_require__(13)('iterator'), function () { return this; }); + if (st && st.isDirectory()) + return rmdir(p, options, er, cb) -module.exports = function (Constructor, NAME, next) { - Constructor.prototype = create(IteratorPrototype, { next: descriptor(1, next) }); - setToStringTag(Constructor, NAME + ' Iterator'); -}; + options.unlink(p, function (er) { + if (er) { + if (er.code === "ENOENT") + return cb(null) + if (er.code === "EPERM") + return (isWindows) + ? fixWinEPERM(p, options, er, cb) + : rmdir(p, options, er, cb) + if (er.code === "EISDIR") + return rmdir(p, options, er, cb) + } + return cb(er) + }) + }) +} +function fixWinEPERM (p, options, er, cb) { + assert(p) + assert(options) + assert(typeof cb === 'function') + if (er) + assert(er instanceof Error) -/***/ }), -/* 189 */ -/***/ (function(module, exports, __webpack_require__) { + options.chmod(p, _0666, function (er2) { + if (er2) + cb(er2.code === "ENOENT" ? null : er) + else + options.stat(p, function(er3, stats) { + if (er3) + cb(er3.code === "ENOENT" ? null : er) + else if (stats.isDirectory()) + rmdir(p, options, er, cb) + else + options.unlink(p, cb) + }) + }) +} -var ITERATOR = __webpack_require__(13)('iterator'); -var SAFE_CLOSING = false; +function fixWinEPERMSync (p, options, er) { + assert(p) + assert(options) + if (er) + assert(er instanceof Error) -try { - var riter = [7][ITERATOR](); - riter['return'] = function () { SAFE_CLOSING = true; }; - // eslint-disable-next-line no-throw-literal - Array.from(riter, function () { throw 2; }); -} catch (e) { /* empty */ } + try { + options.chmodSync(p, _0666) + } catch (er2) { + if (er2.code === "ENOENT") + return + else + throw er + } -module.exports = function (exec, skipClosing) { - if (!skipClosing && !SAFE_CLOSING) return false; - var safe = false; try { - var arr = [7]; - var iter = arr[ITERATOR](); - iter.next = function () { return { done: safe = true }; }; - arr[ITERATOR] = function () { return iter; }; - exec(arr); - } catch (e) { /* empty */ } - return safe; -}; + var stats = options.statSync(p) + } catch (er3) { + if (er3.code === "ENOENT") + return + else + throw er + } + if (stats.isDirectory()) + rmdirSync(p, options, er) + else + options.unlinkSync(p) +} -/***/ }), -/* 190 */ -/***/ (function(module, exports) { +function rmdir (p, options, originalEr, cb) { + assert(p) + assert(options) + if (originalEr) + assert(originalEr instanceof Error) + assert(typeof cb === 'function') -module.exports = function (done, value) { - return { value: value, done: !!done }; -}; + // try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS) + // if we guessed wrong, and it's not a directory, then + // raise the original error. + options.rmdir(p, function (er) { + if (er && (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM")) + rmkids(p, options, cb) + else if (er && er.code === "ENOTDIR") + cb(originalEr) + else + cb(er) + }) +} +function rmkids(p, options, cb) { + assert(p) + assert(options) + assert(typeof cb === 'function') -/***/ }), -/* 191 */ -/***/ (function(module, exports, __webpack_require__) { + options.readdir(p, function (er, files) { + if (er) + return cb(er) + var n = files.length + if (n === 0) + return options.rmdir(p, cb) + var errState + files.forEach(function (f) { + rimraf(path.join(p, f), options, function (er) { + if (errState) + return + if (er) + return cb(errState = er) + if (--n === 0) + options.rmdir(p, cb) + }) + }) + }) +} -var global = __webpack_require__(11); -var macrotask = __webpack_require__(109).set; -var Observer = global.MutationObserver || global.WebKitMutationObserver; -var process = global.process; -var Promise = global.Promise; -var isNode = __webpack_require__(47)(process) == 'process'; +// this looks simpler, and is strictly *faster*, but will +// tie up the JavaScript thread and fail on excessively +// deep directory trees. +function rimrafSync (p, options) { + options = options || {} + defaults(options) -module.exports = function () { - var head, last, notify; + assert(p, 'rimraf: missing path') + assert.equal(typeof p, 'string', 'rimraf: path should be a string') + assert(options, 'rimraf: missing options') + assert.equal(typeof options, 'object', 'rimraf: options should be object') - var flush = function () { - var parent, fn; - if (isNode && (parent = process.domain)) parent.exit(); - while (head) { - fn = head.fn; - head = head.next; - try { - fn(); - } catch (e) { - if (head) notify(); - else last = undefined; - throw e; - } - } last = undefined; - if (parent) parent.enter(); - }; + var results - // Node.js - if (isNode) { - notify = function () { - process.nextTick(flush); - }; - // browsers with MutationObserver, except iOS Safari - https://github.com/zloirock/core-js/issues/339 - } else if (Observer && !(global.navigator && global.navigator.standalone)) { - var toggle = true; - var node = document.createTextNode(''); - new Observer(flush).observe(node, { characterData: true }); // eslint-disable-line no-new - notify = function () { - node.data = toggle = !toggle; - }; - // environments with maybe non-completely correct, but existent Promise - } else if (Promise && Promise.resolve) { - // Promise.resolve without an argument throws an error in LG WebOS 2 - var promise = Promise.resolve(undefined); - notify = function () { - promise.then(flush); - }; - // for other environments - macrotask based on: - // - setImmediate - // - MessageChannel - // - window.postMessag - // - onreadystatechange - // - setTimeout + if (options.disableGlob || !glob.hasMagic(p)) { + results = [p] } else { - notify = function () { - // strange IE + webpack dev server bug - use .call(global) - macrotask.call(global, flush); - }; + try { + options.lstatSync(p) + results = [p] + } catch (er) { + results = glob.sync(p, options.glob) + } } - return function (fn) { - var task = { fn: fn, next: undefined }; - if (last) last.next = task; - if (!head) { - head = task; - notify(); - } last = task; - }; -}; + if (!results.length) + return + for (var i = 0; i < results.length; i++) { + var p = results[i] -/***/ }), -/* 192 */ -/***/ (function(module, exports, __webpack_require__) { + try { + var st = options.lstatSync(p) + } catch (er) { + if (er.code === "ENOENT") + return -// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties]) -var anObject = __webpack_require__(27); -var dPs = __webpack_require__(193); -var enumBugKeys = __webpack_require__(101); -var IE_PROTO = __webpack_require__(72)('IE_PROTO'); -var Empty = function () { /* empty */ }; -var PROTOTYPE = 'prototype'; + // Windows can EPERM on stat. Life is suffering. + if (er.code === "EPERM" && isWindows) + fixWinEPERMSync(p, options, er) + } -// Create object with fake `null` prototype: use iframe Object with cleared prototype -var createDict = function () { - // Thrash, waste and sodomy: IE GC bug - var iframe = __webpack_require__(68)('iframe'); - var i = enumBugKeys.length; - var lt = '<'; - var gt = '>'; - var iframeDocument; - iframe.style.display = 'none'; - __webpack_require__(102).appendChild(iframe); - iframe.src = 'javascript:'; // eslint-disable-line no-script-url - // createDict = iframe.contentWindow.Object; - // html.removeChild(iframe); - iframeDocument = iframe.contentWindow.document; - iframeDocument.open(); - iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt); - iframeDocument.close(); - createDict = iframeDocument.F; - while (i--) delete createDict[PROTOTYPE][enumBugKeys[i]]; - return createDict(); -}; + try { + // sunos lets the root user unlink directories, which is... weird. + if (st && st.isDirectory()) + rmdirSync(p, options, null) + else + options.unlinkSync(p) + } catch (er) { + if (er.code === "ENOENT") + return + if (er.code === "EPERM") + return isWindows ? fixWinEPERMSync(p, options, er) : rmdirSync(p, options, er) + if (er.code !== "EISDIR") + throw er -module.exports = Object.create || function create(O, Properties) { - var result; - if (O !== null) { - Empty[PROTOTYPE] = anObject(O); - result = new Empty(); - Empty[PROTOTYPE] = null; - // add "__proto__" for Object.getPrototypeOf polyfill - result[IE_PROTO] = O; - } else result = createDict(); - return Properties === undefined ? result : dPs(result, Properties); -}; + rmdirSync(p, options, er) + } + } +} +function rmdirSync (p, options, originalEr) { + assert(p) + assert(options) + if (originalEr) + assert(originalEr instanceof Error) -/***/ }), -/* 193 */ -/***/ (function(module, exports, __webpack_require__) { + try { + options.rmdirSync(p) + } catch (er) { + if (er.code === "ENOENT") + return + if (er.code === "ENOTDIR") + throw originalEr + if (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM") + rmkidsSync(p, options) + } +} -var dP = __webpack_require__(50); -var anObject = __webpack_require__(27); -var getKeys = __webpack_require__(132); +function rmkidsSync (p, options) { + assert(p) + assert(options) + options.readdirSync(p).forEach(function (f) { + rimrafSync(path.join(p, f), options) + }) -module.exports = __webpack_require__(33) ? Object.defineProperties : function defineProperties(O, Properties) { - anObject(O); - var keys = getKeys(Properties); - var length = keys.length; - var i = 0; - var P; - while (length > i) dP.f(O, P = keys[i++], Properties[P]); - return O; -}; + // We only end up here once we got ENOTEMPTY at least once, and + // at this point, we are guaranteed to have removed all the kids. + // So, we know that it won't be ENOENT or ENOTDIR or anything else. + // try really hard to delete stuff on windows, because it has a + // PROFOUNDLY annoying habit of not closing handles promptly when + // files are deleted, resulting in spurious ENOTEMPTY errors. + var retries = isWindows ? 100 : 1 + var i = 0 + do { + var threw = true + try { + var ret = options.rmdirSync(p, options) + threw = false + return ret + } finally { + if (++i < retries && threw) + continue + } + } while (true) +} /***/ }), -/* 194 */ +/* 234 */, +/* 235 */, +/* 236 */, +/* 237 */, +/* 238 */, +/* 239 */ /***/ (function(module, exports, __webpack_require__) { -// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O) -var has = __webpack_require__(49); -var toObject = __webpack_require__(133); -var IE_PROTO = __webpack_require__(72)('IE_PROTO'); -var ObjectProto = Object.prototype; - -module.exports = Object.getPrototypeOf || function (O) { - O = toObject(O); - if (has(O, IE_PROTO)) return O[IE_PROTO]; - if (typeof O.constructor == 'function' && O instanceof O.constructor) { - return O.constructor.prototype; - } return O instanceof Object ? ObjectProto : null; -}; +"use strict"; +var hasFlag = __webpack_require__(221); -/***/ }), -/* 195 */ -/***/ (function(module, exports, __webpack_require__) { +var support = function (level) { + if (level === 0) { + return false; + } -var has = __webpack_require__(49); -var toIObject = __webpack_require__(74); -var arrayIndexOf = __webpack_require__(182)(false); -var IE_PROTO = __webpack_require__(72)('IE_PROTO'); - -module.exports = function (object, names) { - var O = toIObject(object); - var i = 0; - var result = []; - var key; - for (key in O) if (key != IE_PROTO) has(O, key) && result.push(key); - // Don't enum bug & hidden keys - while (names.length > i) if (has(O, key = names[i++])) { - ~arrayIndexOf(result, key) || result.push(key); - } - return result; -}; + return { + level: level, + hasBasic: true, + has256: level >= 2, + has16m: level >= 3 + }; +}; +var supportLevel = (function () { + if (hasFlag('no-color') || + hasFlag('no-colors') || + hasFlag('color=false')) { + return 0; + } -/***/ }), -/* 196 */ -/***/ (function(module, exports, __webpack_require__) { + if (hasFlag('color=16m') || + hasFlag('color=full') || + hasFlag('color=truecolor')) { + return 3; + } -var hide = __webpack_require__(31); -module.exports = function (target, src, safe) { - for (var key in src) { - if (safe && target[key]) target[key] = src[key]; - else hide(target, key, src[key]); - } return target; -}; + if (hasFlag('color=256')) { + return 2; + } + if (hasFlag('color') || + hasFlag('colors') || + hasFlag('color=true') || + hasFlag('color=always')) { + return 1; + } -/***/ }), -/* 197 */ -/***/ (function(module, exports, __webpack_require__) { + if (process.stdout && !process.stdout.isTTY) { + return 0; + } -module.exports = __webpack_require__(31); + if (process.platform === 'win32') { + return 1; + } + if ('CI' in process.env) { + if ('TRAVIS' in process.env || process.env.CI === 'Travis') { + return 1; + } -/***/ }), -/* 198 */ -/***/ (function(module, exports, __webpack_require__) { + return 0; + } -"use strict"; + if ('TEAMCITY_VERSION' in process.env) { + return process.env.TEAMCITY_VERSION.match(/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/) === null ? 0 : 1; + } -var global = __webpack_require__(11); -var core = __webpack_require__(23); -var dP = __webpack_require__(50); -var DESCRIPTORS = __webpack_require__(33); -var SPECIES = __webpack_require__(13)('species'); + if (/^(screen|xterm)-256(?:color)?/.test(process.env.TERM)) { + return 2; + } -module.exports = function (KEY) { - var C = typeof core[KEY] == 'function' ? core[KEY] : global[KEY]; - if (DESCRIPTORS && C && !C[SPECIES]) dP.f(C, SPECIES, { - configurable: true, - get: function () { return this; } - }); -}; + if (/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i.test(process.env.TERM)) { + return 1; + } + if ('COLORTERM' in process.env) { + return 1; + } -/***/ }), -/* 199 */ -/***/ (function(module, exports, __webpack_require__) { + if (process.env.TERM === 'dumb') { + return 0; + } -var toInteger = __webpack_require__(73); -var defined = __webpack_require__(67); -// true -> String#at -// false -> String#codePointAt -module.exports = function (TO_STRING) { - return function (that, pos) { - var s = String(defined(that)); - var i = toInteger(pos); - var l = s.length; - var a, b; - if (i < 0 || i >= l) return TO_STRING ? '' : undefined; - a = s.charCodeAt(i); - return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff - ? TO_STRING ? s.charAt(i) : a - : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000; - }; -}; + return 0; +})(); +if (supportLevel === 0 && 'FORCE_COLOR' in process.env) { + supportLevel = 1; +} -/***/ }), -/* 200 */ -/***/ (function(module, exports, __webpack_require__) { +module.exports = process && support(supportLevel); -var toInteger = __webpack_require__(73); -var max = Math.max; -var min = Math.min; -module.exports = function (index, length) { - index = toInteger(index); - return index < 0 ? max(index + length, 0) : min(index, length); -}; +/***/ }) +/******/ ]); /***/ }), -/* 201 */ -/***/ (function(module, exports, __webpack_require__) { - -// 7.1.1 ToPrimitive(input [, PreferredType]) -var isObject = __webpack_require__(34); -// instead of the ES6 spec version, we didn't implement @@toPrimitive case -// and the second argument - flag - preferred type is a string -module.exports = function (it, S) { - if (!isObject(it)) return it; - var fn, val; - if (S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val; - if (typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it))) return val; - if (!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val; - throw TypeError("Can't convert object to primitive value"); -}; +/* 277 */ +/***/ (function(module, exports) { +module.exports = require("buffer"); /***/ }), -/* 202 */ -/***/ (function(module, exports, __webpack_require__) { +/* 278 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { -var global = __webpack_require__(11); -var navigator = global.navigator; +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BootstrapCacheFile", function() { return BootstrapCacheFile; }); +/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(134); +/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__); +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; } -module.exports = navigator && navigator.userAgent || ''; +/* + * 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. + */ -/***/ }), -/* 203 */ -/***/ (function(module, exports, __webpack_require__) { +class BootstrapCacheFile { + constructor(kbn, project, checksums) { + _defineProperty(this, "path", void 0); -var classof = __webpack_require__(100); -var ITERATOR = __webpack_require__(13)('iterator'); -var Iterators = __webpack_require__(35); -module.exports = __webpack_require__(23).getIteratorMethod = function (it) { - if (it != undefined) return it[ITERATOR] - || it['@@iterator'] - || Iterators[classof(it)]; -}; + _defineProperty(this, "expectedValue", void 0); + this.path = path__WEBPACK_IMPORTED_MODULE_1___default.a.resolve(project.targetLocation, '.bootstrap-cache'); -/***/ }), -/* 204 */ -/***/ (function(module, exports, __webpack_require__) { + if (!checksums) { + return; + } -"use strict"; + const projectAndDepCacheKeys = Array.from(kbn.getProjectAndDeps(project.name).values()) // sort deps by name so that the key is stable + .sort((a, b) => a.name.localeCompare(b.name)) // get the cacheKey for each project, return undefined if the cache key couldn't be determined + .map(p => { + const cacheKey = checksums.get(p.name); -var addToUnscopables = __webpack_require__(180); -var step = __webpack_require__(190); -var Iterators = __webpack_require__(35); -var toIObject = __webpack_require__(74); + if (cacheKey) { + return `${p.name}:${cacheKey}`; + } + }); // if any of the relevant cache keys are undefined then the projectCacheKey must be too -// 22.1.3.4 Array.prototype.entries() -// 22.1.3.13 Array.prototype.keys() -// 22.1.3.29 Array.prototype.values() -// 22.1.3.30 Array.prototype[@@iterator]() -module.exports = __webpack_require__(103)(Array, 'Array', function (iterated, kind) { - this._t = toIObject(iterated); // target - this._i = 0; // next index - this._k = kind; // kind -// 22.1.5.2.1 %ArrayIteratorPrototype%.next() -}, function () { - var O = this._t; - var kind = this._k; - var index = this._i++; - if (!O || index >= O.length) { - this._t = undefined; - return step(1); + this.expectedValue = projectAndDepCacheKeys.some(k => !k) ? undefined : [`# this is only human readable for debugging, please don't try to parse this`, ...projectAndDepCacheKeys].join('\n'); } - if (kind == 'keys') return step(0, index); - if (kind == 'values') return step(0, O[index]); - return step(0, [index, O[index]]); -}, 'values'); -// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7) -Iterators.Arguments = Iterators.Array; + isValid() { + if (!this.expectedValue) { + return false; + } -addToUnscopables('keys'); -addToUnscopables('values'); -addToUnscopables('entries'); + try { + return fs__WEBPACK_IMPORTED_MODULE_0___default.a.readFileSync(this.path, 'utf8') === this.expectedValue; + } catch (error) { + if (error.code === 'ENOENT') { + return false; + } + throw error; + } + } -/***/ }), -/* 205 */ -/***/ (function(module, exports) { + delete() { + try { + fs__WEBPACK_IMPORTED_MODULE_0___default.a.unlinkSync(this.path); + } catch (error) { + if (error.code !== 'ENOENT') { + throw error; + } + } + } + + write() { + if (!this.expectedValue) { + return; + } + fs__WEBPACK_IMPORTED_MODULE_0___default.a.mkdirSync(path__WEBPACK_IMPORTED_MODULE_1___default.a.dirname(this.path), { + recursive: true + }); + fs__WEBPACK_IMPORTED_MODULE_0___default.a.writeFileSync(this.path, this.expectedValue); + } +} /***/ }), -/* 206 */ -/***/ (function(module, exports, __webpack_require__) { +/* 279 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "validateYarnLock", function() { return validateYarnLock; }); +/* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(276); +/* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var dedent__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2); +/* harmony import */ var dedent__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(dedent__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var _fs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(131); +/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(144); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +// @ts-expect-error published types are useless -var LIBRARY = __webpack_require__(69); -var global = __webpack_require__(11); -var ctx = __webpack_require__(48); -var classof = __webpack_require__(100); -var $export = __webpack_require__(41); -var isObject = __webpack_require__(34); -var aFunction = __webpack_require__(46); -var anInstance = __webpack_require__(181); -var forOf = __webpack_require__(183); -var speciesConstructor = __webpack_require__(108); -var task = __webpack_require__(109).set; -var microtask = __webpack_require__(191)(); -var newPromiseCapabilityModule = __webpack_require__(70); -var perform = __webpack_require__(104); -var userAgent = __webpack_require__(202); -var promiseResolve = __webpack_require__(105); -var PROMISE = 'Promise'; -var TypeError = global.TypeError; -var process = global.process; -var versions = process && process.versions; -var v8 = versions && versions.v8 || ''; -var $Promise = global[PROMISE]; -var isNode = classof(process) == 'process'; -var empty = function () { /* empty */ }; -var Internal, newGenericPromiseCapability, OwnPromiseCapability, Wrapper; -var newPromiseCapability = newGenericPromiseCapability = newPromiseCapabilityModule.f; -var USE_NATIVE = !!function () { - try { - // correct subclassing with @@species support - var promise = $Promise.resolve(1); - var FakePromise = (promise.constructor = {})[__webpack_require__(13)('species')] = function (exec) { - exec(empty, empty); - }; - // unhandled rejections tracking support, NodeJS Promise without it fails @@species test - return (isNode || typeof PromiseRejectionEvent == 'function') - && promise.then(empty) instanceof FakePromise - // v8 6.6 (Node 10 and Chrome 66) have a bug with resolving custom thenables - // https://bugs.chromium.org/p/chromium/issues/detail?id=830565 - // we can't detect it synchronously, so just check versions - && v8.indexOf('6.6') !== 0 - && userAgent.indexOf('Chrome/66') === -1; - } catch (e) { /* empty */ } -}(); -// helpers -var isThenable = function (it) { - var then; - return isObject(it) && typeof (then = it.then) == 'function' ? then : false; -}; -var notify = function (promise, isReject) { - if (promise._n) return; - promise._n = true; - var chain = promise._c; - microtask(function () { - var value = promise._v; - var ok = promise._s == 1; - var i = 0; - var run = function (reaction) { - var handler = ok ? reaction.ok : reaction.fail; - var resolve = reaction.resolve; - var reject = reaction.reject; - var domain = reaction.domain; - var result, then, exited; - try { - if (handler) { - if (!ok) { - if (promise._h == 2) onHandleUnhandled(promise); - promise._h = 1; - } - if (handler === true) result = value; - else { - if (domain) domain.enter(); - result = handler(value); // may throw - if (domain) { - domain.exit(); - exited = true; - } - } - if (result === reaction.promise) { - reject(TypeError('Promise-chain cycle')); - } else if (then = isThenable(result)) { - then.call(result, resolve, reject); - } else resolve(result); - } else reject(value); - } catch (e) { - if (domain && !exited) domain.exit(); - reject(e); - } - }; - while (chain.length > i) run(chain[i++]); // variable length - can't use forEach - promise._c = []; - promise._n = false; - if (isReject && !promise._h) onUnhandled(promise); - }); -}; -var onUnhandled = function (promise) { - task.call(global, function () { - var value = promise._v; - var unhandled = isUnhandled(promise); - var result, handler, console; - if (unhandled) { - result = perform(function () { - if (isNode) { - process.emit('unhandledRejection', value, promise); - } else if (handler = global.onunhandledrejection) { - handler({ promise: promise, reason: value }); - } else if ((console = global.console) && console.error) { - console.error('Unhandled promise rejection', value); - } - }); - // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should - promise._h = isNode || isUnhandled(promise) ? 2 : 1; - } promise._a = undefined; - if (unhandled && result.e) throw result.v; - }); -}; -var isUnhandled = function (promise) { - return promise._h !== 1 && (promise._a || promise._c).length === 0; -}; -var onHandleUnhandled = function (promise) { - task.call(global, function () { - var handler; - if (isNode) { - process.emit('rejectionHandled', promise); - } else if (handler = global.onrejectionhandled) { - handler({ promise: promise, reason: promise._v }); - } - }); -}; -var $reject = function (value) { - var promise = this; - if (promise._d) return; - promise._d = true; - promise = promise._w || promise; // unwrap - promise._v = value; - promise._s = 2; - if (!promise._a) promise._a = promise._c.slice(); - notify(promise, true); -}; -var $resolve = function (value) { - var promise = this; - var then; - if (promise._d) return; - promise._d = true; - promise = promise._w || promise; // unwrap - try { - if (promise === value) throw TypeError("Promise can't be resolved itself"); - if (then = isThenable(value)) { - microtask(function () { - var wrapper = { _w: promise, _d: false }; // wrap - try { - then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1)); - } catch (e) { - $reject.call(wrapper, e); - } - }); - } else { - promise._v = value; - promise._s = 1; - notify(promise, false); + +async function validateYarnLock(kbn, yarnLock) { + // look through all of the packages in the yarn.lock file to see if + // we have accidentally installed multiple lodash v4 versions + const lodash4Versions = new Set(); + const lodash4Reqs = new Set(); + + for (const [req, dep] of Object.entries(yarnLock)) { + if (req.startsWith('lodash@') && dep.version.startsWith('4.')) { + lodash4Reqs.add(req); + lodash4Versions.add(dep.version); } - } catch (e) { - $reject.call({ _w: promise, _d: false }, e); // wrap - } -}; + } // if we find more than one lodash v4 version installed then delete + // lodash v4 requests from the yarn.lock file and prompt the user to + // retry bootstrap so that a single v4 version will be installed -// constructor polyfill -if (!USE_NATIVE) { - // 25.4.3.1 Promise(executor) - $Promise = function Promise(executor) { - anInstance(this, $Promise, PROMISE, '_h'); - aFunction(executor); - Internal.call(this); - try { - executor(ctx($resolve, this, 1), ctx($reject, this, 1)); - } catch (err) { - $reject.call(this, err); + + if (lodash4Versions.size > 1) { + for (const req of lodash4Reqs) { + delete yarnLock[req]; } - }; - // eslint-disable-next-line no-unused-vars - Internal = function Promise(executor) { - this._c = []; // <- awaiting reactions - this._a = undefined; // <- checked in isUnhandled reactions - this._s = 0; // <- state - this._d = false; // <- done - this._v = undefined; // <- value - this._h = 0; // <- rejection state, 0 - default, 1 - handled, 2 - unhandled - this._n = false; // <- notify - }; - Internal.prototype = __webpack_require__(196)($Promise.prototype, { - // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected) - then: function then(onFulfilled, onRejected) { - var reaction = newPromiseCapability(speciesConstructor(this, $Promise)); - reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true; - reaction.fail = typeof onRejected == 'function' && onRejected; - reaction.domain = isNode ? process.domain : undefined; - this._c.push(reaction); - if (this._a) this._a.push(reaction); - if (this._s) notify(this, false); - return reaction.promise; - }, - // 25.4.5.1 Promise.prototype.catch(onRejected) - 'catch': function (onRejected) { - return this.then(undefined, onRejected); - } - }); - OwnPromiseCapability = function () { - var promise = new Internal(); - this.promise = promise; - this.resolve = ctx($resolve, promise, 1); - this.reject = ctx($reject, promise, 1); - }; - newPromiseCapabilityModule.f = newPromiseCapability = function (C) { - return C === $Promise || C === Wrapper - ? new OwnPromiseCapability(C) - : newGenericPromiseCapability(C); - }; -} -$export($export.G + $export.W + $export.F * !USE_NATIVE, { Promise: $Promise }); -__webpack_require__(71)($Promise, PROMISE); -__webpack_require__(198)(PROMISE); -Wrapper = __webpack_require__(23)[PROMISE]; + await Object(_fs__WEBPACK_IMPORTED_MODULE_2__["writeFile"])(kbn.getAbsolute('yarn.lock'), Object(_yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__["stringify"])(yarnLock), 'utf8'); + _log__WEBPACK_IMPORTED_MODULE_3__["log"].error(dedent__WEBPACK_IMPORTED_MODULE_1___default.a` -// statics -$export($export.S + $export.F * !USE_NATIVE, PROMISE, { - // 25.4.4.5 Promise.reject(r) - reject: function reject(r) { - var capability = newPromiseCapability(this); - var $$reject = capability.reject; - $$reject(r); - return capability.promise; - } -}); -$export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, { - // 25.4.4.6 Promise.resolve(x) - resolve: function resolve(x) { - return promiseResolve(LIBRARY && this === Wrapper ? $Promise : this, x); - } -}); -$export($export.S + $export.F * !(USE_NATIVE && __webpack_require__(189)(function (iter) { - $Promise.all(iter)['catch'](empty); -})), PROMISE, { - // 25.4.4.1 Promise.all(iterable) - all: function all(iterable) { - var C = this; - var capability = newPromiseCapability(C); - var resolve = capability.resolve; - var reject = capability.reject; - var result = perform(function () { - var values = []; - var index = 0; - var remaining = 1; - forOf(iterable, false, function (promise) { - var $index = index++; - var alreadyCalled = false; - values.push(undefined); - remaining++; - C.resolve(promise).then(function (value) { - if (alreadyCalled) return; - alreadyCalled = true; - values[$index] = value; - --remaining || resolve(values); - }, reject); - }); - --remaining || resolve(values); - }); - if (result.e) reject(result.v); - return capability.promise; - }, - // 25.4.4.4 Promise.race(iterable) - race: function race(iterable) { - var C = this; - var capability = newPromiseCapability(C); - var reject = capability.reject; - var result = perform(function () { - forOf(iterable, false, function (promise) { - C.resolve(promise).then(capability.resolve, reject); - }); - }); - if (result.e) reject(result.v); - return capability.promise; - } -}); + Multiple version of lodash v4 were detected, so they have been removed + from the yarn.lock file. Please rerun yarn kbn bootstrap to coalese the + lodash versions installed. + If you still see this error when you re-bootstrap then you might need + to force a new dependency to use the latest version of lodash via the + "resolutions" field in package.json. -/***/ }), -/* 207 */ -/***/ (function(module, exports, __webpack_require__) { + If you have questions about this please reach out to the operations team. -"use strict"; + `); + process.exit(1); + } // look through all the dependencies of production packages and production + // dependencies of those packages to determine if we're shipping any versions + // of lodash v3 in the distributable -var $at = __webpack_require__(199)(true); -// 21.1.3.27 String.prototype[@@iterator]() -__webpack_require__(103)(String, 'String', function (iterated) { - this._t = String(iterated); // target - this._i = 0; // next index -// 21.1.5.2.1 %StringIteratorPrototype%.next() -}, function () { - var O = this._t; - var index = this._i; - var point; - if (index >= O.length) return { value: undefined, done: true }; - point = $at(O, index); - this._i += point.length; - return { value: point, done: false }; -}); + const prodDependencies = kbn.resolveAllProductionDependencies(yarnLock, _log__WEBPACK_IMPORTED_MODULE_3__["log"]); + const lodash3Versions = new Set(); + for (const dep of prodDependencies.values()) { + if (dep.name === 'lodash' && dep.version.startsWith('3.')) { + lodash3Versions.add(dep.version); + } + } // if any lodash v3 packages were found we abort and tell the user to fix things -/***/ }), -/* 208 */ -/***/ (function(module, exports, __webpack_require__) { -"use strict"; -// https://github.com/tc39/proposal-promise-finally + if (lodash3Versions.size) { + _log__WEBPACK_IMPORTED_MODULE_3__["log"].error(dedent__WEBPACK_IMPORTED_MODULE_1___default.a` -var $export = __webpack_require__(41); -var core = __webpack_require__(23); -var global = __webpack_require__(11); -var speciesConstructor = __webpack_require__(108); -var promiseResolve = __webpack_require__(105); + Due to changes in the yarn.lock file and/or package.json files a version of + lodash 3 is now included in the production dependencies. To reduce the size of + our distributable and especially our front-end bundles we have decided to + prevent adding any new instances of lodash 3. -$export($export.P + $export.R, 'Promise', { 'finally': function (onFinally) { - var C = speciesConstructor(this, core.Promise || global.Promise); - var isFunction = typeof onFinally == 'function'; - return this.then( - isFunction ? function (x) { - return promiseResolve(C, onFinally()).then(function () { return x; }); - } : onFinally, - isFunction ? function (e) { - return promiseResolve(C, onFinally()).then(function () { throw e; }); - } : onFinally - ); -} }); + Please inspect the changes to yarn.lock or package.json files to identify where + the lodash 3 version is coming from and remove it. + If you have questions about this please reack out to the operations team. -/***/ }), -/* 209 */ -/***/ (function(module, exports, __webpack_require__) { + `); + process.exit(1); + } // TODO: remove this once we move into a single package.json + // look through all the package.json files to find packages which have mismatched version ranges -"use strict"; -// https://github.com/tc39/proposal-promise-try -var $export = __webpack_require__(41); -var newPromiseCapability = __webpack_require__(70); -var perform = __webpack_require__(104); + const depRanges = new Map(); -$export($export.S, 'Promise', { 'try': function (callbackfn) { - var promiseCapability = newPromiseCapability.f(this); - var result = perform(callbackfn); - (result.e ? promiseCapability.reject : promiseCapability.resolve)(result.v); - return promiseCapability.promise; -} }); + for (const project of kbn.getAllProjects().values()) { + for (const [dep, range] of Object.entries(project.allDependencies)) { + const existingDep = depRanges.get(dep); + if (!existingDep) { + depRanges.set(dep, [{ + range, + projects: [project] + }]); + continue; + } -/***/ }), -/* 210 */ -/***/ (function(module, exports, __webpack_require__) { + const existingRange = existingDep.find(existing => existing.range === range); -__webpack_require__(204); -var global = __webpack_require__(11); -var hide = __webpack_require__(31); -var Iterators = __webpack_require__(35); -var TO_STRING_TAG = __webpack_require__(13)('toStringTag'); + if (!existingRange) { + existingDep.push({ + range, + projects: [project] + }); + continue; + } -var DOMIterables = ('CSSRuleList,CSSStyleDeclaration,CSSValueList,ClientRectList,DOMRectList,DOMStringList,' + - 'DOMTokenList,DataTransferItemList,FileList,HTMLAllCollection,HTMLCollection,HTMLFormElement,HTMLSelectElement,' + - 'MediaList,MimeTypeArray,NamedNodeMap,NodeList,PaintRequestList,Plugin,PluginArray,SVGLengthList,SVGNumberList,' + - 'SVGPathSegList,SVGPointList,SVGStringList,SVGTransformList,SourceBufferList,StyleSheetList,TextTrackCueList,' + - 'TextTrackList,TouchList').split(','); + existingRange.projects.push(project); + } + } -for (var i = 0; i < DOMIterables.length; i++) { - var NAME = DOMIterables[i]; - var Collection = global[NAME]; - var proto = Collection && Collection.prototype; - if (proto && !proto[TO_STRING_TAG]) hide(proto, TO_STRING_TAG, NAME); - Iterators[NAME] = Iterators.Array; -} + const duplicateRanges = Array.from(depRanges.entries()).filter(([, ranges]) => ranges.length > 1).reduce((acc, [dep, ranges]) => [...acc, dep, ...ranges.map(({ + range, + projects + }) => ` ${range} => ${projects.map(p => p.name).join(', ')}`)], []).join('\n '); + if (duplicateRanges) { + _log__WEBPACK_IMPORTED_MODULE_3__["log"].error(dedent__WEBPACK_IMPORTED_MODULE_1___default.a` -/***/ }), -/* 211 */ -/***/ (function(module, exports, __webpack_require__) { + [single_version_dependencies] Multiple version ranges for the same dependency + were found declared across different package.json files. Please consolidate + those to match across all package.json files. Different versions for the + same dependency is not supported. -/** - * This is the web browser implementation of `debug()`. - * - * Expose `debug()` as the module. - */ + If you have questions about this please reach out to the operations team. -exports = module.exports = __webpack_require__(112); -exports.log = log; -exports.formatArgs = formatArgs; -exports.save = save; -exports.load = load; -exports.useColors = useColors; -exports.storage = 'undefined' != typeof chrome - && 'undefined' != typeof chrome.storage - ? chrome.storage.local - : localstorage(); + The conflicting dependencies are: -/** - * Colors. - */ + ${duplicateRanges} + `); + process.exit(1); + } -exports.colors = [ - '#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', - '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', - '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', - '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', - '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', - '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', - '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', - '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', - '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', - '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', - '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33' -]; + _log__WEBPACK_IMPORTED_MODULE_3__["log"].success('yarn.lock analysis completed without any issues'); +} -/** - * Currently only WebKit-based Web Inspectors, Firefox >= v31, - * and the Firebug extension (any Firefox version) are known - * to support "%c" CSS customizations. +/***/ }), +/* 280 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CleanCommand", function() { return CleanCommand; }); +/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(281); +/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(del__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(367); +/* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(ora__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(131); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(144); +/* + * 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 * - * TODO: add a `localStorage` variable to explicitly enable/disable colors + * 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 useColors() { - // NB: In an Electron preload script, document will be defined but not fully - // initialized. Since we know we're in Chrome, we'll just detect this case - // explicitly - if (typeof window !== 'undefined' && window.process && window.process.type === 'renderer') { - return true; - } - - // Internet Explorer and Edge do not support colors. - if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { - return false; - } - - // is webkit? http://stackoverflow.com/a/16459606/376773 - // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 - return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) || - // is firebug? http://stackoverflow.com/a/398120/376773 - (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) || - // is firefox >= v31? - // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages - (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) || - // double check webkit in userAgent just in case we are in a worker - (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)); -} -/** - * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. - */ -exports.formatters.j = function(v) { - try { - return JSON.stringify(v); - } catch (err) { - return '[UnexpectedJSONParseError]: ' + err.message; - } -}; -/** - * Colorize log arguments if enabled. - * - * @api public - */ +const CleanCommand = { + description: 'Remove the node_modules and target directories from all projects.', + name: 'clean', -function formatArgs(args) { - var useColors = this.useColors; + async run(projects) { + const toDelete = []; - args[0] = (useColors ? '%c' : '') - + this.namespace - + (useColors ? ' %c' : ' ') - + args[0] - + (useColors ? '%c ' : ' ') - + '+' + exports.humanize(this.diff); + for (const project of projects.values()) { + if (await Object(_utils_fs__WEBPACK_IMPORTED_MODULE_3__["isDirectory"])(project.nodeModulesLocation)) { + toDelete.push({ + cwd: project.path, + pattern: Object(path__WEBPACK_IMPORTED_MODULE_2__["relative"])(project.path, project.nodeModulesLocation) + }); + } - if (!useColors) return; + if (await Object(_utils_fs__WEBPACK_IMPORTED_MODULE_3__["isDirectory"])(project.targetLocation)) { + toDelete.push({ + cwd: project.path, + pattern: Object(path__WEBPACK_IMPORTED_MODULE_2__["relative"])(project.path, project.targetLocation) + }); + } - var c = 'color: ' + this.color; - args.splice(1, 0, c, 'color: inherit') + const { + extraPatterns + } = project.getCleanConfig(); - // the final "%c" is somewhat tricky, because there could be other - // arguments passed either before or after the %c, so we need to - // figure out the correct index to insert the CSS into - var index = 0; - var lastC = 0; - args[0].replace(/%[a-zA-Z%]/g, function(match) { - if ('%%' === match) return; - index++; - if ('%c' === match) { - // we only are interested in the *last* %c - // (the user may have provided their own) - lastC = index; + if (extraPatterns) { + toDelete.push({ + cwd: project.path, + pattern: extraPatterns + }); + } } - }); - - args.splice(lastC, 0, c); -} -/** - * Invokes `console.log()` when available. - * No-op when `console.log` is not a "function". - * - * @api public - */ + if (toDelete.length === 0) { + _utils_log__WEBPACK_IMPORTED_MODULE_4__["log"].success('Nothing to delete'); + } else { + /** + * 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(); -function log() { - // this hackery is required for IE8/9, where - // the `console.log` function doesn't have 'apply' - return 'object' === typeof console - && console.log - && Function.prototype.apply.call(console.log, console, arguments); -} + try { + for (const { + pattern, + cwd + } of toDelete) { + process.chdir(cwd); + const promise = del__WEBPACK_IMPORTED_MODULE_0___default()(pattern); -/** - * Save `namespaces`. - * - * @param {String} namespaces - * @api private - */ + if (_utils_log__WEBPACK_IMPORTED_MODULE_4__["log"].wouldLogLevel('info')) { + ora__WEBPACK_IMPORTED_MODULE_1___default.a.promise(promise, Object(path__WEBPACK_IMPORTED_MODULE_2__["relative"])(originalCwd, Object(path__WEBPACK_IMPORTED_MODULE_2__["join"])(cwd, String(pattern)))); + } -function save(namespaces) { - try { - if (null == namespaces) { - exports.storage.removeItem('debug'); - } else { - exports.storage.debug = namespaces; + await promise; + } + } finally { + process.chdir(originalCwd); + } } - } catch(e) {} -} + } -/** - * Load `namespaces`. - * - * @return {String} returns the previously persisted debug modes - * @api private - */ +}; -function load() { - var r; - try { - r = exports.storage.debug; - } catch(e) {} +/***/ }), +/* 281 */ +/***/ (function(module, exports, __webpack_require__) { - // If debug isn't set in LS, and we're in Electron, try to load $DEBUG - if (!r && typeof process !== 'undefined' && 'env' in process) { - r = process.env.DEBUG; - } +"use strict"; - return r; -} +const {promisify} = __webpack_require__(112); +const path = __webpack_require__(4); +const globby = __webpack_require__(282); +const isGlob = __webpack_require__(294); +const slash = __webpack_require__(358); +const gracefulFs = __webpack_require__(133); +const isPathCwd = __webpack_require__(360); +const isPathInside = __webpack_require__(361); +const rimraf = __webpack_require__(362); +const pMap = __webpack_require__(363); -/** - * Enable namespaces listed in `localStorage.debug` initially. - */ +const rimrafP = promisify(rimraf); -exports.enable(load()); +const rimrafOptions = { + glob: false, + unlink: gracefulFs.unlink, + unlinkSync: gracefulFs.unlinkSync, + chmod: gracefulFs.chmod, + chmodSync: gracefulFs.chmodSync, + stat: gracefulFs.stat, + statSync: gracefulFs.statSync, + lstat: gracefulFs.lstat, + lstatSync: gracefulFs.lstatSync, + rmdir: gracefulFs.rmdir, + rmdirSync: gracefulFs.rmdirSync, + readdir: gracefulFs.readdir, + readdirSync: gracefulFs.readdirSync +}; -/** - * Localstorage attempts to return the localstorage. - * - * This is necessary because safari throws - * when a user disables cookies/localstorage - * and you attempt to access it. - * - * @return {LocalStorage} - * @api private - */ +function safeCheck(file, cwd) { + if (isPathCwd(file)) { + throw new Error('Cannot delete the current working directory. Can be overridden with the `force` option.'); + } -function localstorage() { - try { - return window.localStorage; - } catch (e) {} + if (!isPathInside(file, cwd)) { + throw new Error('Cannot delete files/directories outside the current working directory. Can be overridden with the `force` option.'); + } } +function normalizePatterns(patterns) { + patterns = Array.isArray(patterns) ? patterns : [patterns]; -/***/ }), -/* 212 */ -/***/ (function(module, exports, __webpack_require__) { + patterns = patterns.map(pattern => { + if (process.platform === 'win32' && isGlob(pattern) === false) { + return slash(pattern); + } -/** - * Detect Electron renderer process, which is node, but we should - * treat as a browser. - */ + return pattern; + }); -if (typeof process === 'undefined' || process.type === 'renderer') { - module.exports = __webpack_require__(211); -} else { - module.exports = __webpack_require__(213); + return patterns; } +module.exports = async (patterns, {force, dryRun, cwd = process.cwd(), ...options} = {}) => { + options = { + expandDirectories: false, + onlyFiles: false, + followSymbolicLinks: false, + cwd, + ...options + }; -/***/ }), -/* 213 */ -/***/ (function(module, exports, __webpack_require__) { + patterns = normalizePatterns(patterns); -/** - * Module dependencies. - */ + const files = (await globby(patterns, options)) + .sort((a, b) => b.localeCompare(a)); -var tty = __webpack_require__(79); -var util = __webpack_require__(2); + const mapper = async file => { + file = path.resolve(cwd, file); -/** - * This is the Node.js implementation of `debug()`. - * - * Expose `debug()` as the module. - */ + if (!force) { + safeCheck(file, cwd); + } -exports = module.exports = __webpack_require__(112); -exports.init = init; -exports.log = log; -exports.formatArgs = formatArgs; -exports.save = save; -exports.load = load; -exports.useColors = useColors; + if (!dryRun) { + await rimrafP(file, rimrafOptions); + } -/** - * Colors. - */ + return file; + }; -exports.colors = [ 6, 2, 3, 4, 5, 1 ]; + const removedFiles = await pMap(files, mapper, options); -try { - var supportsColor = __webpack_require__(239); - if (supportsColor && supportsColor.level >= 2) { - exports.colors = [ - 20, 21, 26, 27, 32, 33, 38, 39, 40, 41, 42, 43, 44, 45, 56, 57, 62, 63, 68, - 69, 74, 75, 76, 77, 78, 79, 80, 81, 92, 93, 98, 99, 112, 113, 128, 129, 134, - 135, 148, 149, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 173, 178, 179, 184, 185, 196, 197, 198, 199, 200, 201, 202, 203, 204, - 205, 206, 207, 208, 209, 214, 215, 220, 221 - ]; - } -} catch (err) { - // swallow - we only care if `supports-color` is available; it doesn't have to be. -} + removedFiles.sort((a, b) => a.localeCompare(b)); -/** - * Build up the default `inspectOpts` object from the environment variables. - * - * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js - */ + return removedFiles; +}; -exports.inspectOpts = Object.keys(process.env).filter(function (key) { - return /^debug_/i.test(key); -}).reduce(function (obj, key) { - // camel-case - var prop = key - .substring(6) - .toLowerCase() - .replace(/_([a-z])/g, function (_, k) { return k.toUpperCase() }); +module.exports.sync = (patterns, {force, dryRun, cwd = process.cwd(), ...options} = {}) => { + options = { + expandDirectories: false, + onlyFiles: false, + followSymbolicLinks: false, + cwd, + ...options + }; - // coerce string value into JS value - var val = process.env[key]; - if (/^(yes|on|true|enabled)$/i.test(val)) val = true; - else if (/^(no|off|false|disabled)$/i.test(val)) val = false; - else if (val === 'null') val = null; - else val = Number(val); + patterns = normalizePatterns(patterns); - obj[prop] = val; - return obj; -}, {}); + const files = globby.sync(patterns, options) + .sort((a, b) => b.localeCompare(a)); -/** - * Is stdout a TTY? Colored output is enabled when `true`. - */ + const removedFiles = files.map(file => { + file = path.resolve(cwd, file); -function useColors() { - return 'colors' in exports.inspectOpts - ? Boolean(exports.inspectOpts.colors) - : tty.isatty(process.stderr.fd); -} + if (!force) { + safeCheck(file, cwd); + } -/** - * Map %o to `util.inspect()`, all on a single line. - */ + if (!dryRun) { + rimraf.sync(file, rimrafOptions); + } -exports.formatters.o = function(v) { - this.inspectOpts.colors = this.useColors; - return util.inspect(v, this.inspectOpts) - .split('\n').map(function(str) { - return str.trim() - }).join(' '); -}; + return file; + }); -/** - * Map %o to `util.inspect()`, allowing multiple lines if needed. - */ + removedFiles.sort((a, b) => a.localeCompare(b)); -exports.formatters.O = function(v) { - this.inspectOpts.colors = this.useColors; - return util.inspect(v, this.inspectOpts); + return removedFiles; }; -/** - * Adds ANSI color escape codes if enabled. - * - * @api public - */ -function formatArgs(args) { - var name = this.namespace; - var useColors = this.useColors; +/***/ }), +/* 282 */ +/***/ (function(module, exports, __webpack_require__) { - if (useColors) { - var c = this.color; - var colorCode = '\u001b[3' + (c < 8 ? c : '8;5;' + c); - var prefix = ' ' + colorCode + ';1m' + name + ' ' + '\u001b[0m'; +"use strict"; - args[0] = prefix + args[0].split('\n').join('\n' + prefix); - args.push(colorCode + 'm+' + exports.humanize(this.diff) + '\u001b[0m'); - } else { - args[0] = getDate() + name + ' ' + args[0]; - } -} +const fs = __webpack_require__(134); +const arrayUnion = __webpack_require__(283); +const merge2 = __webpack_require__(284); +const glob = __webpack_require__(147); +const fastGlob = __webpack_require__(285); +const dirGlob = __webpack_require__(354); +const gitignore = __webpack_require__(356); +const {FilterStream, UniqueStream} = __webpack_require__(359); -function getDate() { - if (exports.inspectOpts.hideDate) { - return ''; - } else { - return new Date().toISOString() + ' '; - } -} +const DEFAULT_FILTER = () => false; -/** - * Invokes `util.format()` with the specified arguments and writes to stderr. - */ +const isNegative = pattern => pattern[0] === '!'; -function log() { - return process.stderr.write(util.format.apply(util, arguments) + '\n'); -} +const assertPatternsInput = patterns => { + if (!patterns.every(pattern => typeof pattern === 'string')) { + throw new TypeError('Patterns must be a string or an array of strings'); + } +}; -/** - * Save `namespaces`. - * - * @param {String} namespaces - * @api private - */ +const checkCwdOption = (options = {}) => { + if (!options.cwd) { + return; + } -function save(namespaces) { - if (null == namespaces) { - // If you set a process.env field to null or undefined, it gets cast to the - // string 'null' or 'undefined'. Just delete instead. - delete process.env.DEBUG; - } else { - process.env.DEBUG = namespaces; - } -} + let stat; + try { + stat = fs.statSync(options.cwd); + } catch (_) { + return; + } -/** - * Load `namespaces`. - * - * @return {String} returns the previously persisted debug modes - * @api private - */ + if (!stat.isDirectory()) { + throw new Error('The `cwd` option must be a path to a directory'); + } +}; -function load() { - return process.env.DEBUG; -} +const getPathString = p => p.stats instanceof fs.Stats ? p.path : p; -/** - * Init logic for `debug` instances. - * - * Create a new `inspectOpts` object in case `useColors` is set - * differently for a particular `debug` instance. - */ +const generateGlobTasks = (patterns, taskOptions) => { + patterns = arrayUnion([].concat(patterns)); + assertPatternsInput(patterns); + checkCwdOption(taskOptions); -function init (debug) { - debug.inspectOpts = {}; + const globTasks = []; - var keys = Object.keys(exports.inspectOpts); - for (var i = 0; i < keys.length; i++) { - debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]]; - } -} + taskOptions = { + ignore: [], + expandDirectories: true, + ...taskOptions + }; -/** - * Enable namespaces listed in `process.env.DEBUG` initially. - */ + for (const [index, pattern] of patterns.entries()) { + if (isNegative(pattern)) { + continue; + } -exports.enable(load()); + const ignore = patterns + .slice(index) + .filter(isNegative) + .map(pattern => pattern.slice(1)); + const options = { + ...taskOptions, + ignore: taskOptions.ignore.concat(ignore) + }; -/***/ }), -/* 214 */, -/* 215 */, -/* 216 */, -/* 217 */ -/***/ (function(module, exports, __webpack_require__) { + globTasks.push({pattern, options}); + } -// Copyright Joyent, Inc. and other Node contributors. -// -// 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. + return globTasks; +}; -var pathModule = __webpack_require__(0); -var isWindows = process.platform === 'win32'; -var fs = __webpack_require__(3); +const globDirs = (task, fn) => { + let options = {}; + if (task.options.cwd) { + options.cwd = task.options.cwd; + } -// JavaScript implementation of realpath, ported from node pre-v6 + if (Array.isArray(task.options.expandDirectories)) { + options = { + ...options, + files: task.options.expandDirectories + }; + } else if (typeof task.options.expandDirectories === 'object') { + options = { + ...options, + ...task.options.expandDirectories + }; + } -var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); + return fn(task.pattern, options); +}; -function rethrow() { - // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and - // is fairly slow to generate. - var callback; - if (DEBUG) { - var backtrace = new Error; - callback = debugCallback; - } else - callback = missingCallback; +const getPattern = (task, fn) => task.options.expandDirectories ? globDirs(task, fn) : [task.pattern]; - return callback; +const getFilterSync = options => { + return options && options.gitignore ? + gitignore.sync({cwd: options.cwd, ignore: options.ignore}) : + DEFAULT_FILTER; +}; - function debugCallback(err) { - if (err) { - backtrace.message = err.message; - err = backtrace; - missingCallback(err); - } - } +const globToTask = task => glob => { + const {options} = task; + if (options.ignore && Array.isArray(options.ignore) && options.expandDirectories) { + options.ignore = dirGlob.sync(options.ignore); + } - function missingCallback(err) { - if (err) { - if (process.throwDeprecation) - throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs - else if (!process.noDeprecation) { - var msg = 'fs: missing callback ' + (err.stack || err.message); - if (process.traceDeprecation) - console.trace(msg); - else - console.error(msg); - } - } - } -} + return { + pattern: glob, + options + }; +}; -function maybeCallback(cb) { - return typeof cb === 'function' ? cb : rethrow(); -} +module.exports = async (patterns, options) => { + const globTasks = generateGlobTasks(patterns, options); -var normalize = pathModule.normalize; + const getFilter = async () => { + return options && options.gitignore ? + gitignore({cwd: options.cwd, ignore: options.ignore}) : + DEFAULT_FILTER; + }; -// Regexp that finds the next partion of a (partial) path -// result is [base_with_slash, base], e.g. ['somedir/', 'somedir'] -if (isWindows) { - var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; -} else { - var nextPartRe = /(.*?)(?:[\/]+|$)/g; -} + const getTasks = async () => { + const tasks = await Promise.all(globTasks.map(async task => { + const globs = await getPattern(task, dirGlob); + return Promise.all(globs.map(globToTask(task))); + })); -// Regex to find the device root, including trailing slash. E.g. 'c:\\'. -if (isWindows) { - var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; -} else { - var splitRootRe = /^[\/]*/; -} + return arrayUnion(...tasks); + }; -exports.realpathSync = function realpathSync(p, cache) { - // make p is absolute - p = pathModule.resolve(p); + const [filter, tasks] = await Promise.all([getFilter(), getTasks()]); + const paths = await Promise.all(tasks.map(task => fastGlob(task.pattern, task.options))); - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return cache[p]; - } + return arrayUnion(...paths).filter(path_ => !filter(getPathString(path_))); +}; - var original = p, - seenLinks = {}, - knownHard = {}; +module.exports.sync = (patterns, options) => { + const globTasks = generateGlobTasks(patterns, options); - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; + const tasks = globTasks.reduce((tasks, task) => { + const newTask = getPattern(task, dirGlob.sync).map(globToTask(task)); + return tasks.concat(newTask); + }, []); - start(); + const filter = getFilterSync(options); - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; + return tasks.reduce( + (matches, task) => arrayUnion(matches, fastGlob.sync(task.pattern, task.options)), + [] + ).filter(path_ => !filter(path_)); +}; - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstatSync(base); - knownHard[base] = true; - } - } +module.exports.stream = (patterns, options) => { + const globTasks = generateGlobTasks(patterns, options); - // walk down the path, swapping out linked pathparts for their real - // values - // NB: p.length changes. - while (pos < p.length) { - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; + const tasks = globTasks.reduce((tasks, task) => { + const newTask = getPattern(task, dirGlob.sync).map(globToTask(task)); + return tasks.concat(newTask); + }, []); - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - continue; - } + const filter = getFilterSync(options); + const filterStream = new FilterStream(p => !filter(p)); + const uniqueStream = new UniqueStream(); - var resolvedLink; - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // some known symbolic link. no need to stat again. - resolvedLink = cache[base]; - } else { - var stat = fs.lstatSync(base); - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - continue; - } + return merge2(tasks.map(task => fastGlob.stream(task.pattern, task.options))) + .pipe(filterStream) + .pipe(uniqueStream); +}; - // read the link if it wasn't read before - // dev/ino always return 0 on windows, so skip the check. - var linkTarget = null; - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - linkTarget = seenLinks[id]; - } - } - if (linkTarget === null) { - fs.statSync(base); - linkTarget = fs.readlinkSync(base); - } - resolvedLink = pathModule.resolve(previous, linkTarget); - // track this, if given a cache. - if (cache) cache[base] = resolvedLink; - if (!isWindows) seenLinks[id] = linkTarget; - } +module.exports.generateGlobTasks = generateGlobTasks; - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } +module.exports.hasMagic = (patterns, options) => [] + .concat(patterns) + .some(pattern => glob.hasMagic(pattern, options)); - if (cache) cache[original] = p; +module.exports.gitignore = gitignore; - return p; -}; +/***/ }), +/* 283 */ +/***/ (function(module, exports, __webpack_require__) { -exports.realpath = function realpath(p, cache, cb) { - if (typeof cb !== 'function') { - cb = maybeCallback(cache); - cache = null; - } +"use strict"; - // make p is absolute - p = pathModule.resolve(p); - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return process.nextTick(cb.bind(null, null, cache[p])); - } +module.exports = (...arguments_) => { + return [...new Set([].concat(...arguments_))]; +}; - var original = p, - seenLinks = {}, - knownHard = {}; - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; +/***/ }), +/* 284 */ +/***/ (function(module, exports, __webpack_require__) { - start(); +"use strict"; - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; +/* + * merge2 + * https://github.com/teambition/merge2 + * + * Copyright (c) 2014-2020 Teambition + * Licensed under the MIT license. + */ +const Stream = __webpack_require__(138) +const PassThrough = Stream.PassThrough +const slice = Array.prototype.slice - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs.lstat(base, function(err) { - if (err) return cb(err); - knownHard[base] = true; - LOOP(); - }); - } else { - process.nextTick(LOOP); - } +module.exports = merge2 + +function merge2 () { + const streamsQueue = [] + const args = slice.call(arguments) + let merging = false + let options = args[args.length - 1] + + if (options && !Array.isArray(options) && options.pipe == null) { + args.pop() + } else { + options = {} } - // walk down the path, swapping out linked pathparts for their real - // values - function LOOP() { - // stop if scanned past end of path - if (pos >= p.length) { - if (cache) cache[original] = p; - return cb(null, p); + const doEnd = options.end !== false + const doPipeError = options.pipeError === true + if (options.objectMode == null) { + options.objectMode = true + } + if (options.highWaterMark == null) { + options.highWaterMark = 64 * 1024 + } + const mergedStream = PassThrough(options) + + function addStream () { + for (let i = 0, len = arguments.length; i < len; i++) { + streamsQueue.push(pauseStreams(arguments[i], options)) } + mergeStream() + return this + } - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; + function mergeStream () { + if (merging) { + return + } + merging = true - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - return process.nextTick(LOOP); + let streams = streamsQueue.shift() + if (!streams) { + process.nextTick(endStream) + return + } + if (!Array.isArray(streams)) { + streams = [streams] } - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // known symbolic link. no need to stat again. - return gotResolvedLink(cache[base]); + let pipesCount = streams.length + 1 + + function next () { + if (--pipesCount > 0) { + return + } + merging = false + mergeStream() } - return fs.lstat(base, gotStat); - } + function pipe (stream) { + function onend () { + stream.removeListener('merge2UnpipeEnd', onend) + stream.removeListener('end', onend) + if (doPipeError) { + stream.removeListener('error', onerror) + } + next() + } + function onerror (err) { + mergedStream.emit('error', err) + } + // skip ended stream + if (stream._readableState.endEmitted) { + return next() + } - function gotStat(err, stat) { - if (err) return cb(err); + stream.on('merge2UnpipeEnd', onend) + stream.on('end', onend) - // if not a symlink, skip to the next path part - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - return process.nextTick(LOOP); + if (doPipeError) { + stream.on('error', onerror) + } + + stream.pipe(mergedStream, { end: false }) + // compatible for old stream + stream.resume() } - // stat & read the link if not read before - // call gotTarget as soon as the link target is known - // dev/ino always return 0 on windows, so skip the check. - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - return gotTarget(null, seenLinks[id], base); - } + for (let i = 0; i < streams.length; i++) { + pipe(streams[i]) } - fs.stat(base, function(err) { - if (err) return cb(err); - fs.readlink(base, function(err, target) { - if (!isWindows) seenLinks[id] = target; - gotTarget(err, target); - }); - }); + next() } - function gotTarget(err, target, base) { - if (err) return cb(err); + function endStream () { + merging = false + // emit 'queueDrain' when all streams merged. + mergedStream.emit('queueDrain') + if (doEnd) { + mergedStream.end() + } + } - var resolvedLink = pathModule.resolve(previous, target); - if (cache) cache[base] = resolvedLink; - gotResolvedLink(resolvedLink); + mergedStream.setMaxListeners(0) + mergedStream.add = addStream + mergedStream.on('unpipe', function (stream) { + stream.emit('merge2UnpipeEnd') + }) + + if (args.length) { + addStream.apply(null, args) } + return mergedStream +} - function gotResolvedLink(resolvedLink) { - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); +// check and pause streams for pipe. +function pauseStreams (streams, options) { + if (!Array.isArray(streams)) { + // Backwards-compat with old-style streams + if (!streams._readableState && streams.pipe) { + streams = streams.pipe(PassThrough(options)) + } + if (!streams._readableState || !streams.pause || !streams.pipe) { + throw new Error('Only readable stream can be merged.') + } + streams.pause() + } else { + for (let i = 0, len = streams.length; i < len; i++) { + streams[i] = pauseStreams(streams[i], options) + } } -}; + return streams +} /***/ }), -/* 218 */ +/* 285 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = globSync -globSync.GlobSync = GlobSync - -var fs = __webpack_require__(3) -var rp = __webpack_require__(114) -var minimatch = __webpack_require__(60) -var Minimatch = minimatch.Minimatch -var Glob = __webpack_require__(75).Glob -var util = __webpack_require__(2) -var path = __webpack_require__(0) -var assert = __webpack_require__(22) -var isAbsolute = __webpack_require__(76) -var common = __webpack_require__(115) -var alphasort = common.alphasort -var alphasorti = common.alphasorti -var setopts = common.setopts -var ownProp = common.ownProp -var childrenIgnored = common.childrenIgnored -var isIgnored = common.isIgnored - -function globSync (pattern, options) { - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') +"use strict"; + +const taskManager = __webpack_require__(286); +const async_1 = __webpack_require__(315); +const stream_1 = __webpack_require__(350); +const sync_1 = __webpack_require__(351); +const settings_1 = __webpack_require__(353); +const utils = __webpack_require__(287); +async function FastGlob(source, options) { + assertPatternsInput(source); + const works = getWorks(source, async_1.default, options); + const result = await Promise.all(works); + return utils.array.flatten(result); +} +// https://github.com/typescript-eslint/typescript-eslint/issues/60 +// eslint-disable-next-line no-redeclare +(function (FastGlob) { + function sync(source, options) { + assertPatternsInput(source); + const works = getWorks(source, sync_1.default, options); + return utils.array.flatten(works); + } + FastGlob.sync = sync; + function stream(source, options) { + assertPatternsInput(source); + const works = getWorks(source, stream_1.default, options); + /** + * The stream returned by the provider cannot work with an asynchronous iterator. + * To support asynchronous iterators, regardless of the number of tasks, we always multiplex streams. + * This affects performance (+25%). I don't see best solution right now. + */ + return utils.stream.merge(works); + } + FastGlob.stream = stream; + function generateTasks(source, options) { + assertPatternsInput(source); + const patterns = [].concat(source); + const settings = new settings_1.default(options); + return taskManager.generate(patterns, settings); + } + FastGlob.generateTasks = generateTasks; + function isDynamicPattern(source, options) { + assertPatternsInput(source); + const settings = new settings_1.default(options); + return utils.pattern.isDynamicPattern(source, settings); + } + FastGlob.isDynamicPattern = isDynamicPattern; + function escapePath(source) { + assertPatternsInput(source); + return utils.path.escape(source); + } + FastGlob.escapePath = escapePath; +})(FastGlob || (FastGlob = {})); +function getWorks(source, _Provider, options) { + const patterns = [].concat(source); + const settings = new settings_1.default(options); + const tasks = taskManager.generate(patterns, settings); + const provider = new _Provider(settings); + return tasks.map(provider.read, provider); +} +function assertPatternsInput(input) { + const source = [].concat(input); + const isValidSource = source.every((item) => utils.string.isString(item) && !utils.string.isEmpty(item)); + if (!isValidSource) { + throw new TypeError('Patterns must be a string (non empty) or an array of strings'); + } +} +module.exports = FastGlob; - return new GlobSync(pattern, options).found -} -function GlobSync (pattern, options) { - if (!pattern) - throw new Error('must provide pattern') +/***/ }), +/* 286 */ +/***/ (function(module, exports, __webpack_require__) { - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const utils = __webpack_require__(287); +function generate(patterns, settings) { + const positivePatterns = getPositivePatterns(patterns); + const negativePatterns = getNegativePatternsAsPositive(patterns, settings.ignore); + const staticPatterns = positivePatterns.filter((pattern) => utils.pattern.isStaticPattern(pattern, settings)); + const dynamicPatterns = positivePatterns.filter((pattern) => utils.pattern.isDynamicPattern(pattern, settings)); + const staticTasks = convertPatternsToTasks(staticPatterns, negativePatterns, /* dynamic */ false); + const dynamicTasks = convertPatternsToTasks(dynamicPatterns, negativePatterns, /* dynamic */ true); + return staticTasks.concat(dynamicTasks); +} +exports.generate = generate; +function convertPatternsToTasks(positive, negative, dynamic) { + const positivePatternsGroup = groupPatternsByBaseDirectory(positive); + // When we have a global group – there is no reason to divide the patterns into independent tasks. + // In this case, the global task covers the rest. + if ('.' in positivePatternsGroup) { + const task = convertPatternGroupToTask('.', positive, negative, dynamic); + return [task]; + } + return convertPatternGroupsToTasks(positivePatternsGroup, negative, dynamic); +} +exports.convertPatternsToTasks = convertPatternsToTasks; +function getPositivePatterns(patterns) { + return utils.pattern.getPositivePatterns(patterns); +} +exports.getPositivePatterns = getPositivePatterns; +function getNegativePatternsAsPositive(patterns, ignore) { + const negative = utils.pattern.getNegativePatterns(patterns).concat(ignore); + const positive = negative.map(utils.pattern.convertToPositivePattern); + return positive; +} +exports.getNegativePatternsAsPositive = getNegativePatternsAsPositive; +function groupPatternsByBaseDirectory(patterns) { + const group = {}; + return patterns.reduce((collection, pattern) => { + const base = utils.pattern.getBaseDirectory(pattern); + if (base in collection) { + collection[base].push(pattern); + } + else { + collection[base] = [pattern]; + } + return collection; + }, group); +} +exports.groupPatternsByBaseDirectory = groupPatternsByBaseDirectory; +function convertPatternGroupsToTasks(positive, negative, dynamic) { + return Object.keys(positive).map((base) => { + return convertPatternGroupToTask(base, positive[base], negative, dynamic); + }); +} +exports.convertPatternGroupsToTasks = convertPatternGroupsToTasks; +function convertPatternGroupToTask(base, positive, negative, dynamic) { + return { + dynamic, + positive, + negative, + base, + patterns: [].concat(positive, negative.map(utils.pattern.convertToNegativePattern)) + }; +} +exports.convertPatternGroupToTask = convertPatternGroupToTask; - if (!(this instanceof GlobSync)) - return new GlobSync(pattern, options) - setopts(this, pattern, options) +/***/ }), +/* 287 */ +/***/ (function(module, exports, __webpack_require__) { - if (this.noprocess) - return this +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const array = __webpack_require__(288); +exports.array = array; +const errno = __webpack_require__(289); +exports.errno = errno; +const fs = __webpack_require__(290); +exports.fs = fs; +const path = __webpack_require__(291); +exports.path = path; +const pattern = __webpack_require__(292); +exports.pattern = pattern; +const stream = __webpack_require__(313); +exports.stream = stream; +const string = __webpack_require__(314); +exports.string = string; - var n = this.minimatch.set.length - this.matches = new Array(n) - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false) - } - this._finish() -} -GlobSync.prototype._finish = function () { - assert(this instanceof GlobSync) - if (this.realpath) { - var self = this - this.matches.forEach(function (matchset, index) { - var set = self.matches[index] = Object.create(null) - for (var p in matchset) { - try { - p = self._makeAbs(p) - var real = rp.realpathSync(p, self.realpathCache) - set[real] = true - } catch (er) { - if (er.syscall === 'stat') - set[self._makeAbs(p)] = true - else - throw er - } - } - }) - } - common.finish(this) -} +/***/ }), +/* 288 */ +/***/ (function(module, exports, __webpack_require__) { +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +function flatten(items) { + return items.reduce((collection, item) => [].concat(collection, item), []); +} +exports.flatten = flatten; +function splitWhen(items, predicate) { + const result = [[]]; + let groupIndex = 0; + for (const item of items) { + if (predicate(item)) { + groupIndex++; + result[groupIndex] = []; + } + else { + result[groupIndex].push(item); + } + } + return result; +} +exports.splitWhen = splitWhen; -GlobSync.prototype._process = function (pattern, index, inGlobStar) { - assert(this instanceof GlobSync) - // Get the first [n] parts of pattern that are all strings. - var n = 0 - while (typeof pattern[n] === 'string') { - n ++ - } - // now n is the index of the first one that is *not* a string. +/***/ }), +/* 289 */ +/***/ (function(module, exports, __webpack_require__) { - // See if there's anything else - var prefix - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index) - return +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +function isEnoentCodeError(error) { + return error.code === 'ENOENT'; +} +exports.isEnoentCodeError = isEnoentCodeError; - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null - break - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/') - break - } +/***/ }), +/* 290 */ +/***/ (function(module, exports, __webpack_require__) { - var remain = pattern.slice(n) +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +class DirentFromStats { + constructor(name, stats) { + this.name = name; + this.isBlockDevice = stats.isBlockDevice.bind(stats); + this.isCharacterDevice = stats.isCharacterDevice.bind(stats); + this.isDirectory = stats.isDirectory.bind(stats); + this.isFIFO = stats.isFIFO.bind(stats); + this.isFile = stats.isFile.bind(stats); + this.isSocket = stats.isSocket.bind(stats); + this.isSymbolicLink = stats.isSymbolicLink.bind(stats); + } +} +function createDirentFromStats(name, stats) { + return new DirentFromStats(name, stats); +} +exports.createDirentFromStats = createDirentFromStats; - // get the list of entries. - var read - if (prefix === null) - read = '.' - else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { - if (!prefix || !isAbsolute(prefix)) - prefix = '/' + prefix - read = prefix - } else - read = prefix - var abs = this._makeAbs(read) +/***/ }), +/* 291 */ +/***/ (function(module, exports, __webpack_require__) { - //if ignored, skip processing - if (childrenIgnored(this, read)) - return +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const path = __webpack_require__(4); +const LEADING_DOT_SEGMENT_CHARACTERS_COUNT = 2; // ./ or .\\ +const UNESCAPED_GLOB_SYMBOLS_RE = /(\\?)([()*?[\]{|}]|^!|[!+@](?=\())/g; +/** + * Designed to work only with simple paths: `dir\\file`. + */ +function unixify(filepath) { + return filepath.replace(/\\/g, '/'); +} +exports.unixify = unixify; +function makeAbsolute(cwd, filepath) { + return path.resolve(cwd, filepath); +} +exports.makeAbsolute = makeAbsolute; +function escape(pattern) { + return pattern.replace(UNESCAPED_GLOB_SYMBOLS_RE, '\\$2'); +} +exports.escape = escape; +function removeLeadingDotSegment(entry) { + // We do not use `startsWith` because this is 10x slower than current implementation for some cases. + // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with + if (entry.charAt(0) === '.') { + const secondCharactery = entry.charAt(1); + if (secondCharactery === '/' || secondCharactery === '\\') { + return entry.slice(LEADING_DOT_SEGMENT_CHARACTERS_COUNT); + } + } + return entry; +} +exports.removeLeadingDotSegment = removeLeadingDotSegment; - var isGlobStar = remain[0] === minimatch.GLOBSTAR - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar) -} +/***/ }), +/* 292 */ +/***/ (function(module, exports, __webpack_require__) { -GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { - var entries = this._readdir(abs, inGlobStar) +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const path = __webpack_require__(4); +const globParent = __webpack_require__(293); +const micromatch = __webpack_require__(296); +const picomatch = __webpack_require__(307); +const GLOBSTAR = '**'; +const ESCAPE_SYMBOL = '\\'; +const COMMON_GLOB_SYMBOLS_RE = /[*?]|^!/; +const REGEX_CHARACTER_CLASS_SYMBOLS_RE = /\[.*]/; +const REGEX_GROUP_SYMBOLS_RE = /(?:^|[^!*+?@])\(.*\|.*\)/; +const GLOB_EXTENSION_SYMBOLS_RE = /[!*+?@]\(.*\)/; +const BRACE_EXPANSIONS_SYMBOLS_RE = /{.*(?:,|\.\.).*}/; +function isStaticPattern(pattern, options = {}) { + return !isDynamicPattern(pattern, options); +} +exports.isStaticPattern = isStaticPattern; +function isDynamicPattern(pattern, options = {}) { + /** + * When the `caseSensitiveMatch` option is disabled, all patterns must be marked as dynamic, because we cannot check + * filepath directly (without read directory). + */ + if (options.caseSensitiveMatch === false || pattern.includes(ESCAPE_SYMBOL)) { + return true; + } + if (COMMON_GLOB_SYMBOLS_RE.test(pattern) || REGEX_CHARACTER_CLASS_SYMBOLS_RE.test(pattern) || REGEX_GROUP_SYMBOLS_RE.test(pattern)) { + return true; + } + if (options.extglob !== false && GLOB_EXTENSION_SYMBOLS_RE.test(pattern)) { + return true; + } + if (options.braceExpansion !== false && BRACE_EXPANSIONS_SYMBOLS_RE.test(pattern)) { + return true; + } + return false; +} +exports.isDynamicPattern = isDynamicPattern; +function convertToPositivePattern(pattern) { + return isNegativePattern(pattern) ? pattern.slice(1) : pattern; +} +exports.convertToPositivePattern = convertToPositivePattern; +function convertToNegativePattern(pattern) { + return '!' + pattern; +} +exports.convertToNegativePattern = convertToNegativePattern; +function isNegativePattern(pattern) { + return pattern.startsWith('!') && pattern[1] !== '('; +} +exports.isNegativePattern = isNegativePattern; +function isPositivePattern(pattern) { + return !isNegativePattern(pattern); +} +exports.isPositivePattern = isPositivePattern; +function getNegativePatterns(patterns) { + return patterns.filter(isNegativePattern); +} +exports.getNegativePatterns = getNegativePatterns; +function getPositivePatterns(patterns) { + return patterns.filter(isPositivePattern); +} +exports.getPositivePatterns = getPositivePatterns; +function getBaseDirectory(pattern) { + return globParent(pattern, { flipBackslashes: false }); +} +exports.getBaseDirectory = getBaseDirectory; +function hasGlobStar(pattern) { + return pattern.includes(GLOBSTAR); +} +exports.hasGlobStar = hasGlobStar; +function endsWithSlashGlobStar(pattern) { + return pattern.endsWith('/' + GLOBSTAR); +} +exports.endsWithSlashGlobStar = endsWithSlashGlobStar; +function isAffectDepthOfReadingPattern(pattern) { + const basename = path.basename(pattern); + return endsWithSlashGlobStar(pattern) || isStaticPattern(basename); +} +exports.isAffectDepthOfReadingPattern = isAffectDepthOfReadingPattern; +function expandPatternsWithBraceExpansion(patterns) { + return patterns.reduce((collection, pattern) => { + return collection.concat(expandBraceExpansion(pattern)); + }, []); +} +exports.expandPatternsWithBraceExpansion = expandPatternsWithBraceExpansion; +function expandBraceExpansion(pattern) { + return micromatch.braces(pattern, { + expand: true, + nodupes: true + }); +} +exports.expandBraceExpansion = expandBraceExpansion; +function getPatternParts(pattern, options) { + const info = picomatch.scan(pattern, Object.assign(Object.assign({}, options), { parts: true })); + // See micromatch/picomatch#58 for more details + if (info.parts.length === 0) { + return [pattern]; + } + return info.parts; +} +exports.getPatternParts = getPatternParts; +function makeRe(pattern, options) { + return micromatch.makeRe(pattern, options); +} +exports.makeRe = makeRe; +function convertPatternsToRe(patterns, options) { + return patterns.map((pattern) => makeRe(pattern, options)); +} +exports.convertPatternsToRe = convertPatternsToRe; +function matchAny(entry, patternsRe) { + return patternsRe.some((patternRe) => patternRe.test(entry)); +} +exports.matchAny = matchAny; - // if the abs isn't a dir, then nothing can match! - if (!entries) - return - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0] - var negate = !!this.minimatch.negate - var rawGlob = pn._glob - var dotOk = this.dot || rawGlob.charAt(0) === '.' +/***/ }), +/* 293 */ +/***/ (function(module, exports, __webpack_require__) { - var matchedEntries = [] - for (var i = 0; i < entries.length; i++) { - var e = entries[i] - if (e.charAt(0) !== '.' || dotOk) { - var m - if (negate && !prefix) { - m = !e.match(pn) - } else { - m = e.match(pn) - } - if (m) - matchedEntries.push(e) - } - } +"use strict"; - var len = matchedEntries.length - // If there are no matched entries, then nothing matches. - if (len === 0) - return - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. +var isGlob = __webpack_require__(294); +var pathPosixDirname = __webpack_require__(4).posix.dirname; +var isWin32 = __webpack_require__(121).platform() === 'win32'; - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null) +var slash = '/'; +var backslash = /\\/g; +var enclosure = /[\{\[].*[\/]*.*[\}\]]$/; +var globby = /(^|[^\\])([\{\[]|\([^\)]+$)/; +var escaped = /\\([\!\*\?\|\[\]\(\)\{\}])/g; - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - if (prefix) { - if (prefix.slice(-1) !== '/') - e = prefix + '/' + e - else - e = prefix + e - } +/** + * @param {string} str + * @param {Object} opts + * @param {boolean} [opts.flipBackslashes=true] + */ +module.exports = function globParent(str, opts) { + var options = Object.assign({ flipBackslashes: true }, opts); - if (e.charAt(0) === '/' && !this.nomount) { - e = path.join(this.root, e) - } - this._emitMatch(index, e) - } - // This was the last one, and no stats were needed - return + // flip windows path separators + if (options.flipBackslashes && isWin32 && str.indexOf(slash) < 0) { + str = str.replace(backslash, slash); } - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift() - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i] - var newPattern - if (prefix) - newPattern = [prefix, e] - else - newPattern = [e] - this._process(newPattern.concat(remain), index, inGlobStar) + // special case for strings ending in enclosure containing path separator + if (enclosure.test(str)) { + str += slash; } -} - -GlobSync.prototype._emitMatch = function (index, e) { - if (isIgnored(this, e)) - return + // preserves full path in case of trailing path separator + str += 'a'; - var abs = this._makeAbs(e) + // remove path parts that are globby + do { + str = pathPosixDirname(str); + } while (isGlob(str) || globby.test(str)); - if (this.mark) - e = this._mark(e) + // remove escape chars and return result + return str.replace(escaped, '$1'); +}; - if (this.absolute) { - e = abs - } - if (this.matches[index][e]) - return +/***/ }), +/* 294 */ +/***/ (function(module, exports, __webpack_require__) { - if (this.nodir) { - var c = this.cache[abs] - if (c === 'DIR' || Array.isArray(c)) - return - } +/*! + * is-glob + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */ - this.matches[index][e] = true +var isExtglob = __webpack_require__(295); +var chars = { '{': '}', '(': ')', '[': ']'}; +var strictRegex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; +var relaxedRegex = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; - if (this.stat) - this._stat(e) -} +module.exports = function isGlob(str, options) { + if (typeof str !== 'string' || str === '') { + return false; + } + if (isExtglob(str)) { + return true; + } -GlobSync.prototype._readdirInGlobStar = function (abs) { - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false) + var regex = strictRegex; + var match; - var entries - var lstat - var stat - try { - lstat = fs.lstatSync(abs) - } catch (er) { - if (er.code === 'ENOENT') { - // lstat failed, doesn't exist - return null - } + // optionally relax regex + if (options && options.strict === false) { + regex = relaxedRegex; } - var isSym = lstat && lstat.isSymbolicLink() - this.symlinks[abs] = isSym - - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && lstat && !lstat.isDirectory()) - this.cache[abs] = 'FILE' - else - entries = this._readdir(abs, false) + while ((match = regex.exec(str))) { + if (match[2]) return true; + var idx = match.index + match[0].length; - return entries -} + // if an open bracket/brace/paren is escaped, + // set the index to the next closing character + var open = match[1]; + var close = open ? chars[open] : null; + if (open && close) { + var n = str.indexOf(close, idx); + if (n !== -1) { + idx = n + 1; + } + } -GlobSync.prototype._readdir = function (abs, inGlobStar) { - var entries + str = str.slice(idx); + } + return false; +}; - if (inGlobStar && !ownProp(this.symlinks, abs)) - return this._readdirInGlobStar(abs) - if (ownProp(this.cache, abs)) { - var c = this.cache[abs] - if (!c || c === 'FILE') - return null +/***/ }), +/* 295 */ +/***/ (function(module, exports) { - if (Array.isArray(c)) - return c - } +/*! + * is-extglob + * + * Copyright (c) 2014-2016, Jon Schlinkert. + * Licensed under the MIT License. + */ - try { - return this._readdirEntries(abs, fs.readdirSync(abs)) - } catch (er) { - this._readdirError(abs, er) - return null +module.exports = function isExtglob(str) { + if (typeof str !== 'string' || str === '') { + return false; } -} -GlobSync.prototype._readdirEntries = function (abs, entries) { - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i] - if (abs === '/') - e = abs + e - else - e = abs + '/' + e - this.cache[e] = true - } + var match; + while ((match = /(\\).|([@?!+*]\(.*\))/g.exec(str))) { + if (match[2]) return true; + str = str.slice(match.index + match[0].length); } - this.cache[abs] = entries - - // mark and cache dir-ness - return entries -} + return false; +}; -GlobSync.prototype._readdirError = function (f, er) { - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - var abs = this._makeAbs(f) - this.cache[abs] = 'FILE' - if (abs === this.cwdAbs) { - var error = new Error(er.code + ' invalid cwd ' + this.cwd) - error.path = this.cwd - error.code = er.code - throw error - } - break - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false - break +/***/ }), +/* 296 */ +/***/ (function(module, exports, __webpack_require__) { - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false - if (this.strict) - throw er - if (!this.silent) - console.error('glob error', er) - break - } -} +"use strict"; -GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { - var entries = this._readdir(abs, inGlobStar) +const util = __webpack_require__(112); +const braces = __webpack_require__(297); +const picomatch = __webpack_require__(307); +const utils = __webpack_require__(310); +const isEmptyString = val => typeof val === 'string' && (val === '' || val === './'); - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return +/** + * Returns an array of strings that match one or more glob patterns. + * + * ```js + * const mm = require('micromatch'); + * // mm(list, patterns[, options]); + * + * console.log(mm(['a.js', 'a.txt'], ['*.js'])); + * //=> [ 'a.js' ] + * ``` + * @param {String|Array} list List of strings to match. + * @param {String|Array} patterns One or more glob patterns to use for matching. + * @param {Object} options See available [options](#options) + * @return {Array} Returns an array of matches + * @summary false + * @api public + */ - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1) - var gspref = prefix ? [ prefix ] : [] - var noGlobStar = gspref.concat(remainWithoutGlobStar) +const micromatch = (list, patterns, options) => { + patterns = [].concat(patterns); + list = [].concat(list); - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false) + let omit = new Set(); + let keep = new Set(); + let items = new Set(); + let negatives = 0; - var len = entries.length - var isSym = this.symlinks[abs] + let onResult = state => { + items.add(state.output); + if (options && options.onResult) { + options.onResult(state); + } + }; - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return + for (let i = 0; i < patterns.length; i++) { + let isMatch = picomatch(String(patterns[i]), { ...options, onResult }, true); + let negated = isMatch.state.negated || isMatch.state.negatedExtglob; + if (negated) negatives++; - for (var i = 0; i < len; i++) { - var e = entries[i] - if (e.charAt(0) === '.' && !this.dot) - continue + for (let item of list) { + let matched = isMatch(item, true); - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar) - this._process(instead, index, true) + let match = negated ? !matched.isMatch : matched.isMatch; + if (!match) continue; - var below = gspref.concat(entries[i], remain) - this._process(below, index, true) + if (negated) { + omit.add(matched.output); + } else { + omit.delete(matched.output); + keep.add(matched.output); + } + } } -} -GlobSync.prototype._processSimple = function (prefix, index) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var exists = this._stat(prefix) + let result = negatives === patterns.length ? [...items] : [...keep]; + let matches = result.filter(item => !omit.has(item)); - if (!this.matches[index]) - this.matches[index] = Object.create(null) + if (options && matches.length === 0) { + if (options.failglob === true) { + throw new Error(`No matches found for "${patterns.join(', ')}"`); + } - // If it doesn't exist, then just mark the lack of results - if (!exists) - return - - if (prefix && isAbsolute(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix) - if (prefix.charAt(0) === '/') { - prefix = path.join(this.root, prefix) - } else { - prefix = path.resolve(this.root, prefix) - if (trail) - prefix += '/' + if (options.nonull === true || options.nullglob === true) { + return options.unescape ? patterns.map(p => p.replace(/\\/g, '')) : patterns; } } - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/') - - // Mark this as a match - this._emitMatch(index, prefix) -} - -// Returns either 'DIR', 'FILE', or false -GlobSync.prototype._stat = function (f) { - var abs = this._makeAbs(f) - var needDir = f.slice(-1) === '/' - - if (f.length > this.maxLength) - return false - - if (!this.stat && ownProp(this.cache, abs)) { - var c = this.cache[abs] + return matches; +}; - if (Array.isArray(c)) - c = 'DIR' +/** + * Backwards compatibility + */ - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return c +micromatch.match = micromatch; - if (needDir && c === 'FILE') - return false +/** + * Returns a matcher function from the given glob `pattern` and `options`. + * The returned function takes a string to match as its only argument and returns + * true if the string is a match. + * + * ```js + * const mm = require('micromatch'); + * // mm.matcher(pattern[, options]); + * + * const isMatch = mm.matcher('*.!(*a)'); + * console.log(isMatch('a.a')); //=> false + * console.log(isMatch('a.b')); //=> true + * ``` + * @param {String} `pattern` Glob pattern + * @param {Object} `options` + * @return {Function} Returns a matcher function. + * @api public + */ - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. - } +micromatch.matcher = (pattern, options) => picomatch(pattern, options); - var exists - var stat = this.statCache[abs] - if (!stat) { - var lstat - try { - lstat = fs.lstatSync(abs) - } catch (er) { - if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { - this.statCache[abs] = false - return false - } - } +/** + * Returns true if **any** of the given glob `patterns` match the specified `string`. + * + * ```js + * const mm = require('micromatch'); + * // mm.isMatch(string, patterns[, options]); + * + * console.log(mm.isMatch('a.a', ['b.*', '*.a'])); //=> true + * console.log(mm.isMatch('a.a', 'b.*')); //=> false + * ``` + * @param {String} str The string to test. + * @param {String|Array} patterns One or more glob patterns to use for matching. + * @param {Object} [options] See available [options](#options). + * @return {Boolean} Returns true if any patterns match `str` + * @api public + */ - if (lstat && lstat.isSymbolicLink()) { - try { - stat = fs.statSync(abs) - } catch (er) { - stat = lstat - } - } else { - stat = lstat - } - } +micromatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); - this.statCache[abs] = stat +/** + * Backwards compatibility + */ - var c = true - if (stat) - c = stat.isDirectory() ? 'DIR' : 'FILE' +micromatch.any = micromatch.isMatch; - this.cache[abs] = this.cache[abs] || c +/** + * Returns a list of strings that _**do not match any**_ of the given `patterns`. + * + * ```js + * const mm = require('micromatch'); + * // mm.not(list, patterns[, options]); + * + * console.log(mm.not(['a.a', 'b.b', 'c.c'], '*.a')); + * //=> ['b.b', 'c.c'] + * ``` + * @param {Array} `list` Array of strings to match. + * @param {String|Array} `patterns` One or more glob pattern to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Array} Returns an array of strings that **do not match** the given patterns. + * @api public + */ - if (needDir && c === 'FILE') - return false +micromatch.not = (list, patterns, options = {}) => { + patterns = [].concat(patterns).map(String); + let result = new Set(); + let items = []; - return c -} + let onResult = state => { + if (options.onResult) options.onResult(state); + items.push(state.output); + }; -GlobSync.prototype._mark = function (p) { - return common.mark(this, p) -} + let matches = micromatch(list, patterns, { ...options, onResult }); -GlobSync.prototype._makeAbs = function (f) { - return common.makeAbs(this, f) -} + for (let item of items) { + if (!matches.includes(item)) { + result.add(item); + } + } + return [...result]; +}; +/** + * Returns true if the given `string` contains the given pattern. Similar + * to [.isMatch](#isMatch) but the pattern can match any part of the string. + * + * ```js + * var mm = require('micromatch'); + * // mm.contains(string, pattern[, options]); + * + * console.log(mm.contains('aa/bb/cc', '*b')); + * //=> true + * console.log(mm.contains('aa/bb/cc', '*d')); + * //=> false + * ``` + * @param {String} `str` The string to match. + * @param {String|Array} `patterns` Glob pattern to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Boolean} Returns true if the patter matches any part of `str`. + * @api public + */ -/***/ }), -/* 219 */, -/* 220 */, -/* 221 */ -/***/ (function(module, exports, __webpack_require__) { +micromatch.contains = (str, pattern, options) => { + if (typeof str !== 'string') { + throw new TypeError(`Expected a string: "${util.inspect(str)}"`); + } -"use strict"; + if (Array.isArray(pattern)) { + return pattern.some(p => micromatch.contains(str, p, options)); + } -module.exports = function (flag, argv) { - argv = argv || process.argv; + if (typeof pattern === 'string') { + if (isEmptyString(str) || isEmptyString(pattern)) { + return false; + } - var terminatorPos = argv.indexOf('--'); - var prefix = /^--/.test(flag) ? '' : '--'; - var pos = argv.indexOf(prefix + flag); + if (str.includes(pattern) || (str.startsWith('./') && str.slice(2).includes(pattern))) { + return true; + } + } - return pos !== -1 && (terminatorPos !== -1 ? pos < terminatorPos : true); + return micromatch.isMatch(str, pattern, { ...options, contains: true }); }; +/** + * Filter the keys of the given object with the given `glob` pattern + * and `options`. Does not attempt to match nested keys. If you need this feature, + * use [glob-object][] instead. + * + * ```js + * const mm = require('micromatch'); + * // mm.matchKeys(object, patterns[, options]); + * + * const obj = { aa: 'a', ab: 'b', ac: 'c' }; + * console.log(mm.matchKeys(obj, '*b')); + * //=> { ab: 'b' } + * ``` + * @param {Object} `object` The object with keys to filter. + * @param {String|Array} `patterns` One or more glob patterns to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Object} Returns an object with only keys that match the given patterns. + * @api public + */ -/***/ }), -/* 222 */, -/* 223 */ -/***/ (function(module, exports, __webpack_require__) { - -var wrappy = __webpack_require__(123) -var reqs = Object.create(null) -var once = __webpack_require__(61) - -module.exports = wrappy(inflight) - -function inflight (key, cb) { - if (reqs[key]) { - reqs[key].push(cb) - return null - } else { - reqs[key] = [cb] - return makeres(key) +micromatch.matchKeys = (obj, patterns, options) => { + if (!utils.isObject(obj)) { + throw new TypeError('Expected the first argument to be an object'); } -} + let keys = micromatch(Object.keys(obj), patterns, options); + let res = {}; + for (let key of keys) res[key] = obj[key]; + return res; +}; -function makeres (key) { - return once(function RES () { - var cbs = reqs[key] - var len = cbs.length - var args = slice(arguments) +/** + * Returns true if some of the strings in the given `list` match any of the given glob `patterns`. + * + * ```js + * const mm = require('micromatch'); + * // mm.some(list, patterns[, options]); + * + * console.log(mm.some(['foo.js', 'bar.js'], ['*.js', '!foo.js'])); + * // true + * console.log(mm.some(['foo.js'], ['*.js', '!foo.js'])); + * // false + * ``` + * @param {String|Array} `list` The string or array of strings to test. Returns as soon as the first match is found. + * @param {String|Array} `patterns` One or more glob patterns to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Boolean} Returns true if any patterns match `str` + * @api public + */ - // XXX It's somewhat ambiguous whether a new callback added in this - // pass should be queued for later execution if something in the - // list of callbacks throws, or if it should just be discarded. - // However, it's such an edge case that it hardly matters, and either - // choice is likely as surprising as the other. - // As it happens, we do go ahead and schedule it for later execution. - try { - for (var i = 0; i < len; i++) { - cbs[i].apply(null, args) - } - } finally { - if (cbs.length > len) { - // added more in the interim. - // de-zalgo, just in case, but don't call again. - cbs.splice(0, len) - process.nextTick(function () { - RES.apply(null, args) - }) - } else { - delete reqs[key] - } +micromatch.some = (list, patterns, options) => { + let items = [].concat(list); + + for (let pattern of [].concat(patterns)) { + let isMatch = picomatch(String(pattern), options); + if (items.some(item => isMatch(item))) { + return true; } - }) -} + } + return false; +}; -function slice (args) { - var length = args.length - var array = [] +/** + * Returns true if every string in the given `list` matches + * any of the given glob `patterns`. + * + * ```js + * const mm = require('micromatch'); + * // mm.every(list, patterns[, options]); + * + * console.log(mm.every('foo.js', ['foo.js'])); + * // true + * console.log(mm.every(['foo.js', 'bar.js'], ['*.js'])); + * // true + * console.log(mm.every(['foo.js', 'bar.js'], ['*.js', '!foo.js'])); + * // false + * console.log(mm.every(['foo.js'], ['*.js', '!foo.js'])); + * // false + * ``` + * @param {String|Array} `list` The string or array of strings to test. + * @param {String|Array} `patterns` One or more glob patterns to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Boolean} Returns true if any patterns match `str` + * @api public + */ - for (var i = 0; i < length; i++) array[i] = args[i] - return array -} +micromatch.every = (list, patterns, options) => { + let items = [].concat(list); + for (let pattern of [].concat(patterns)) { + let isMatch = picomatch(String(pattern), options); + if (!items.every(item => isMatch(item))) { + return false; + } + } + return true; +}; -/***/ }), -/* 224 */ -/***/ (function(module, exports) { +/** + * Returns true if **all** of the given `patterns` match + * the specified string. + * + * ```js + * const mm = require('micromatch'); + * // mm.all(string, patterns[, options]); + * + * console.log(mm.all('foo.js', ['foo.js'])); + * // true + * + * console.log(mm.all('foo.js', ['*.js', '!foo.js'])); + * // false + * + * console.log(mm.all('foo.js', ['*.js', 'foo.js'])); + * // true + * + * console.log(mm.all('foo.js', ['*.js', 'f*', '*o*', '*o.js'])); + * // true + * ``` + * @param {String|Array} `str` The string to test. + * @param {String|Array} `patterns` One or more glob patterns to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Boolean} Returns true if any patterns match `str` + * @api public + */ -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor +micromatch.all = (str, patterns, options) => { + if (typeof str !== 'string') { + throw new TypeError(`Expected a string: "${util.inspect(str)}"`); } -} + return [].concat(patterns).every(p => picomatch(p, options)(str)); +}; -/***/ }), -/* 225 */, -/* 226 */, -/* 227 */ -/***/ (function(module, exports, __webpack_require__) { - -// @flow +/** + * Returns an array of matches captured by `pattern` in `string, or `null` if the pattern did not match. + * + * ```js + * const mm = require('micromatch'); + * // mm.capture(pattern, string[, options]); + * + * console.log(mm.capture('test/*.js', 'test/foo.js')); + * //=> ['foo'] + * console.log(mm.capture('test/*.js', 'foo/bar.css')); + * //=> null + * ``` + * @param {String} `glob` Glob pattern to use for matching. + * @param {String} `input` String to match + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Boolean} Returns an array of captures if the input matches the glob pattern, otherwise `null`. + * @api public + */ -/*:: -declare var __webpack_require__: mixed; -*/ +micromatch.capture = (glob, input, options) => { + let posix = utils.isWindows(options); + let regex = picomatch.makeRe(String(glob), { ...options, capture: true }); + let match = regex.exec(posix ? utils.toPosixSlashes(input) : input); -module.exports = typeof __webpack_require__ !== "undefined"; + if (match) { + return match.slice(1).map(v => v === void 0 ? '' : v); + } +}; +/** + * Create a regular expression from the given glob `pattern`. + * + * ```js + * const mm = require('micromatch'); + * // mm.makeRe(pattern[, options]); + * + * console.log(mm.makeRe('*.js')); + * //=> /^(?:(\.[\\\/])?(?!\.)(?=.)[^\/]*?\.js)$/ + * ``` + * @param {String} `pattern` A glob pattern to convert to regex. + * @param {Object} `options` + * @return {RegExp} Returns a regex created from the given pattern. + * @api public + */ -/***/ }), -/* 228 */, -/* 229 */ -/***/ (function(module, exports) { +micromatch.makeRe = (...args) => picomatch.makeRe(...args); /** - * Helpers. + * Scan a glob pattern to separate the pattern into segments. Used + * by the [split](#split) method. + * + * ```js + * const mm = require('micromatch'); + * const state = mm.scan(pattern[, options]); + * ``` + * @param {String} `pattern` + * @param {Object} `options` + * @return {Object} Returns an object with + * @api public */ -var s = 1000; -var m = s * 60; -var h = m * 60; -var d = h * 24; -var y = d * 365.25; +micromatch.scan = (...args) => picomatch.scan(...args); /** - * Parse or format the given `val`. - * - * Options: - * - * - `long` verbose formatting [false] + * Parse a glob pattern to create the source string for a regular + * expression. * - * @param {String|Number} val - * @param {Object} [options] - * @throws {Error} throw an error if val is not a non-empty string or a number - * @return {String|Number} + * ```js + * const mm = require('micromatch'); + * const state = mm(pattern[, options]); + * ``` + * @param {String} `glob` + * @param {Object} `options` + * @return {Object} Returns an object with useful properties and output to be used as regex source string. * @api public */ -module.exports = function(val, options) { - options = options || {}; - var type = typeof val; - if (type === 'string' && val.length > 0) { - return parse(val); - } else if (type === 'number' && isNaN(val) === false) { - return options.long ? fmtLong(val) : fmtShort(val); +micromatch.parse = (patterns, options) => { + let res = []; + for (let pattern of [].concat(patterns || [])) { + for (let str of braces(String(pattern), options)) { + res.push(picomatch.parse(str, options)); + } } - throw new Error( - 'val is not a non-empty string or a valid number. val=' + - JSON.stringify(val) - ); + return res; }; /** - * Parse the given `str` and return milliseconds. + * Process the given brace `pattern`. * - * @param {String} str - * @return {Number} - * @api private + * ```js + * const { braces } = require('micromatch'); + * console.log(braces('foo/{a,b,c}/bar')); + * //=> [ 'foo/(a|b|c)/bar' ] + * + * console.log(braces('foo/{a,b,c}/bar', { expand: true })); + * //=> [ 'foo/a/bar', 'foo/b/bar', 'foo/c/bar' ] + * ``` + * @param {String} `pattern` String with brace pattern to process. + * @param {Object} `options` Any [options](#options) to change how expansion is performed. See the [braces][] library for all available options. + * @return {Array} + * @api public */ -function parse(str) { - str = String(str); - if (str.length > 100) { - return; - } - var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec( - str - ); - if (!match) { - return; - } - var n = parseFloat(match[1]); - var type = (match[2] || 'ms').toLowerCase(); - switch (type) { - case 'years': - case 'year': - case 'yrs': - case 'yr': - case 'y': - return n * y; - case 'days': - case 'day': - case 'd': - return n * d; - case 'hours': - case 'hour': - case 'hrs': - case 'hr': - case 'h': - return n * h; - case 'minutes': - case 'minute': - case 'mins': - case 'min': - case 'm': - return n * m; - case 'seconds': - case 'second': - case 'secs': - case 'sec': - case 's': - return n * s; - case 'milliseconds': - case 'millisecond': - case 'msecs': - case 'msec': - case 'ms': - return n; - default: - return undefined; +micromatch.braces = (pattern, options) => { + if (typeof pattern !== 'string') throw new TypeError('Expected a string'); + if ((options && options.nobrace === true) || !/\{.*\}/.test(pattern)) { + return [pattern]; } -} + return braces(pattern, options); +}; /** - * Short format for `ms`. + * Expand braces + */ + +micromatch.braceExpand = (pattern, options) => { + if (typeof pattern !== 'string') throw new TypeError('Expected a string'); + return micromatch.braces(pattern, { ...options, expand: true }); +}; + +/** + * Expose micromatch + */ + +module.exports = micromatch; + + +/***/ }), +/* 297 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const stringify = __webpack_require__(298); +const compile = __webpack_require__(300); +const expand = __webpack_require__(304); +const parse = __webpack_require__(305); + +/** + * Expand the given pattern or create a regex-compatible string. * - * @param {Number} ms + * ```js + * const braces = require('braces'); + * console.log(braces('{a,b,c}', { compile: true })); //=> ['(a|b|c)'] + * console.log(braces('{a,b,c}')); //=> ['a', 'b', 'c'] + * ``` + * @param {String} `str` + * @param {Object} `options` * @return {String} - * @api private + * @api public */ -function fmtShort(ms) { - if (ms >= d) { - return Math.round(ms / d) + 'd'; - } - if (ms >= h) { - return Math.round(ms / h) + 'h'; - } - if (ms >= m) { - return Math.round(ms / m) + 'm'; +const braces = (input, options = {}) => { + let output = []; + + if (Array.isArray(input)) { + for (let pattern of input) { + let result = braces.create(pattern, options); + if (Array.isArray(result)) { + output.push(...result); + } else { + output.push(result); + } + } + } else { + output = [].concat(braces.create(input, options)); } - if (ms >= s) { - return Math.round(ms / s) + 's'; + + if (options && options.expand === true && options.nodupes === true) { + output = [...new Set(output)]; } - return ms + 'ms'; -} + return output; +}; /** - * Long format for `ms`. + * Parse the given `str` with the given `options`. * - * @param {Number} ms - * @return {String} - * @api private + * ```js + * // braces.parse(pattern, [, options]); + * const ast = braces.parse('a/{b,c}/d'); + * console.log(ast); + * ``` + * @param {String} pattern Brace pattern to parse + * @param {Object} options + * @return {Object} Returns an AST + * @api public */ -function fmtLong(ms) { - return plural(ms, d, 'day') || - plural(ms, h, 'hour') || - plural(ms, m, 'minute') || - plural(ms, s, 'second') || - ms + ' ms'; -} +braces.parse = (input, options = {}) => parse(input, options); /** - * Pluralization helper. + * Creates a braces string from an AST, or an AST node. + * + * ```js + * const braces = require('braces'); + * let ast = braces.parse('foo/{a,b}/bar'); + * console.log(stringify(ast.nodes[2])); //=> '{a,b}' + * ``` + * @param {String} `input` Brace pattern or AST. + * @param {Object} `options` + * @return {Array} Returns an array of expanded values. + * @api public */ -function plural(ms, n, name) { - if (ms < n) { - return; - } - if (ms < n * 1.5) { - return Math.floor(ms / n) + ' ' + name; +braces.stringify = (input, options = {}) => { + if (typeof input === 'string') { + return stringify(braces.parse(input, options), options); } - return Math.ceil(ms / n) + ' ' + name + 's'; -} - - -/***/ }), -/* 230 */, -/* 231 */, -/* 232 */, -/* 233 */ -/***/ (function(module, exports, __webpack_require__) { - -module.exports = rimraf -rimraf.sync = rimrafSync + return stringify(input, options); +}; -var assert = __webpack_require__(22) -var path = __webpack_require__(0) -var fs = __webpack_require__(3) -var glob = __webpack_require__(75) -var _0666 = parseInt('666', 8) +/** + * Compiles a brace pattern into a regex-compatible, optimized string. + * This method is called by the main [braces](#braces) function by default. + * + * ```js + * const braces = require('braces'); + * console.log(braces.compile('a/{b,c}/d')); + * //=> ['a/(b|c)/d'] + * ``` + * @param {String} `input` Brace pattern or AST. + * @param {Object} `options` + * @return {Array} Returns an array of expanded values. + * @api public + */ -var defaultGlobOpts = { - nosort: true, - silent: true -} +braces.compile = (input, options = {}) => { + if (typeof input === 'string') { + input = braces.parse(input, options); + } + return compile(input, options); +}; -// for EMFILE handling -var timeout = 0 +/** + * Expands a brace pattern into an array. This method is called by the + * main [braces](#braces) function when `options.expand` is true. Before + * using this method it's recommended that you read the [performance notes](#performance)) + * and advantages of using [.compile](#compile) instead. + * + * ```js + * const braces = require('braces'); + * console.log(braces.expand('a/{b,c}/d')); + * //=> ['a/b/d', 'a/c/d']; + * ``` + * @param {String} `pattern` Brace pattern + * @param {Object} `options` + * @return {Array} Returns an array of expanded values. + * @api public + */ -var isWindows = (process.platform === "win32") +braces.expand = (input, options = {}) => { + if (typeof input === 'string') { + input = braces.parse(input, options); + } -function defaults (options) { - var methods = [ - 'unlink', - 'chmod', - 'stat', - 'lstat', - 'rmdir', - 'readdir' - ] - methods.forEach(function(m) { - options[m] = options[m] || fs[m] - m = m + 'Sync' - options[m] = options[m] || fs[m] - }) + let result = expand(input, options); - options.maxBusyTries = options.maxBusyTries || 3 - options.emfileWait = options.emfileWait || 1000 - if (options.glob === false) { - options.disableGlob = true + // filter out empty strings if specified + if (options.noempty === true) { + result = result.filter(Boolean); } - options.disableGlob = options.disableGlob || false - options.glob = options.glob || defaultGlobOpts -} -function rimraf (p, options, cb) { - if (typeof options === 'function') { - cb = options - options = {} + // filter out duplicates if specified + if (options.nodupes === true) { + result = [...new Set(result)]; } - assert(p, 'rimraf: missing path') - assert.equal(typeof p, 'string', 'rimraf: path should be a string') - assert.equal(typeof cb, 'function', 'rimraf: callback function required') - assert(options, 'rimraf: invalid options argument provided') - assert.equal(typeof options, 'object', 'rimraf: options should be object') + return result; +}; - defaults(options) +/** + * Processes a brace pattern and returns either an expanded array + * (if `options.expand` is true), a highly optimized regex-compatible string. + * This method is called by the main [braces](#braces) function. + * + * ```js + * const braces = require('braces'); + * console.log(braces.create('user-{200..300}/project-{a,b,c}-{1..10}')) + * //=> 'user-(20[0-9]|2[1-9][0-9]|300)/project-(a|b|c)-([1-9]|10)' + * ``` + * @param {String} `pattern` Brace pattern + * @param {Object} `options` + * @return {Array} Returns an array of expanded values. + * @api public + */ - var busyTries = 0 - var errState = null - var n = 0 +braces.create = (input, options = {}) => { + if (input === '' || input.length < 3) { + return [input]; + } - if (options.disableGlob || !glob.hasMagic(p)) - return afterGlob(null, [p]) + return options.expand !== true + ? braces.compile(input, options) + : braces.expand(input, options); +}; - options.lstat(p, function (er, stat) { - if (!er) - return afterGlob(null, [p]) +/** + * Expose "braces" + */ - glob(p, options.glob, afterGlob) - }) +module.exports = braces; - function next (er) { - errState = errState || er - if (--n === 0) - cb(errState) - } - function afterGlob (er, results) { - if (er) - return cb(er) +/***/ }), +/* 298 */ +/***/ (function(module, exports, __webpack_require__) { - n = results.length - if (n === 0) - return cb() +"use strict"; - results.forEach(function (p) { - rimraf_(p, options, function CB (er) { - if (er) { - if ((er.code === "EBUSY" || er.code === "ENOTEMPTY" || er.code === "EPERM") && - busyTries < options.maxBusyTries) { - busyTries ++ - var time = busyTries * 100 - // try again, with the same exact callback as this one. - return setTimeout(function () { - rimraf_(p, options, CB) - }, time) - } - // this one won't happen if graceful-fs is used. - if (er.code === "EMFILE" && timeout < options.emfileWait) { - return setTimeout(function () { - rimraf_(p, options, CB) - }, timeout ++) - } +const utils = __webpack_require__(299); - // already gone - if (er.code === "ENOENT") er = null - } +module.exports = (ast, options = {}) => { + let stringify = (node, parent = {}) => { + let invalidBlock = options.escapeInvalid && utils.isInvalidBrace(parent); + let invalidNode = node.invalid === true && options.escapeInvalid === true; + let output = ''; - timeout = 0 - next(er) - }) - }) - } -} + if (node.value) { + if ((invalidBlock || invalidNode) && utils.isOpenOrClose(node)) { + return '\\' + node.value; + } + return node.value; + } -// Two possible strategies. -// 1. Assume it's a file. unlink it, then do the dir stuff on EPERM or EISDIR -// 2. Assume it's a directory. readdir, then do the file stuff on ENOTDIR -// -// Both result in an extra syscall when you guess wrong. However, there -// are likely far more normal files in the world than directories. This -// is based on the assumption that a the average number of files per -// directory is >= 1. -// -// If anyone ever complains about this, then I guess the strategy could -// be made configurable somehow. But until then, YAGNI. -function rimraf_ (p, options, cb) { - assert(p) - assert(options) - assert(typeof cb === 'function') + if (node.value) { + return node.value; + } - // sunos lets the root user unlink directories, which is... weird. - // so we have to lstat here and make sure it's not a dir. - options.lstat(p, function (er, st) { - if (er && er.code === "ENOENT") - return cb(null) + if (node.nodes) { + for (let child of node.nodes) { + output += stringify(child); + } + } + return output; + }; - // Windows can EPERM on stat. Life is suffering. - if (er && er.code === "EPERM" && isWindows) - fixWinEPERM(p, options, er, cb) + return stringify(ast); +}; - if (st && st.isDirectory()) - return rmdir(p, options, er, cb) - options.unlink(p, function (er) { - if (er) { - if (er.code === "ENOENT") - return cb(null) - if (er.code === "EPERM") - return (isWindows) - ? fixWinEPERM(p, options, er, cb) - : rmdir(p, options, er, cb) - if (er.code === "EISDIR") - return rmdir(p, options, er, cb) - } - return cb(er) - }) - }) -} -function fixWinEPERM (p, options, er, cb) { - assert(p) - assert(options) - assert(typeof cb === 'function') - if (er) - assert(er instanceof Error) +/***/ }), +/* 299 */ +/***/ (function(module, exports, __webpack_require__) { - options.chmod(p, _0666, function (er2) { - if (er2) - cb(er2.code === "ENOENT" ? null : er) - else - options.stat(p, function(er3, stats) { - if (er3) - cb(er3.code === "ENOENT" ? null : er) - else if (stats.isDirectory()) - rmdir(p, options, er, cb) - else - options.unlink(p, cb) - }) - }) -} +"use strict"; -function fixWinEPERMSync (p, options, er) { - assert(p) - assert(options) - if (er) - assert(er instanceof Error) - try { - options.chmodSync(p, _0666) - } catch (er2) { - if (er2.code === "ENOENT") - return - else - throw er +exports.isInteger = num => { + if (typeof num === 'number') { + return Number.isInteger(num); } - - try { - var stats = options.statSync(p) - } catch (er3) { - if (er3.code === "ENOENT") - return - else - throw er + if (typeof num === 'string' && num.trim() !== '') { + return Number.isInteger(Number(num)); } + return false; +}; - if (stats.isDirectory()) - rmdirSync(p, options, er) - else - options.unlinkSync(p) -} +/** + * Find a node of the given type + */ -function rmdir (p, options, originalEr, cb) { - assert(p) - assert(options) - if (originalEr) - assert(originalEr instanceof Error) - assert(typeof cb === 'function') +exports.find = (node, type) => node.nodes.find(node => node.type === type); - // try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS) - // if we guessed wrong, and it's not a directory, then - // raise the original error. - options.rmdir(p, function (er) { - if (er && (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM")) - rmkids(p, options, cb) - else if (er && er.code === "ENOTDIR") - cb(originalEr) - else - cb(er) - }) -} +/** + * Find a node of the given type + */ -function rmkids(p, options, cb) { - assert(p) - assert(options) - assert(typeof cb === 'function') - - options.readdir(p, function (er, files) { - if (er) - return cb(er) - var n = files.length - if (n === 0) - return options.rmdir(p, cb) - var errState - files.forEach(function (f) { - rimraf(path.join(p, f), options, function (er) { - if (errState) - return - if (er) - return cb(errState = er) - if (--n === 0) - options.rmdir(p, cb) - }) - }) - }) -} - -// this looks simpler, and is strictly *faster*, but will -// tie up the JavaScript thread and fail on excessively -// deep directory trees. -function rimrafSync (p, options) { - options = options || {} - defaults(options) +exports.exceedsLimit = (min, max, step = 1, limit) => { + if (limit === false) return false; + if (!exports.isInteger(min) || !exports.isInteger(max)) return false; + return ((Number(max) - Number(min)) / Number(step)) >= limit; +}; - assert(p, 'rimraf: missing path') - assert.equal(typeof p, 'string', 'rimraf: path should be a string') - assert(options, 'rimraf: missing options') - assert.equal(typeof options, 'object', 'rimraf: options should be object') +/** + * Escape the given node with '\\' before node.value + */ - var results +exports.escapeNode = (block, n = 0, type) => { + let node = block.nodes[n]; + if (!node) return; - if (options.disableGlob || !glob.hasMagic(p)) { - results = [p] - } else { - try { - options.lstatSync(p) - results = [p] - } catch (er) { - results = glob.sync(p, options.glob) + if ((type && node.type === type) || node.type === 'open' || node.type === 'close') { + if (node.escaped !== true) { + node.value = '\\' + node.value; + node.escaped = true; } } +}; - if (!results.length) - return +/** + * Returns true if the given brace node should be enclosed in literal braces + */ - for (var i = 0; i < results.length; i++) { - var p = results[i] +exports.encloseBrace = node => { + if (node.type !== 'brace') return false; + if ((node.commas >> 0 + node.ranges >> 0) === 0) { + node.invalid = true; + return true; + } + return false; +}; - try { - var st = options.lstatSync(p) - } catch (er) { - if (er.code === "ENOENT") - return +/** + * Returns true if a brace node is invalid. + */ - // Windows can EPERM on stat. Life is suffering. - if (er.code === "EPERM" && isWindows) - fixWinEPERMSync(p, options, er) - } +exports.isInvalidBrace = block => { + if (block.type !== 'brace') return false; + if (block.invalid === true || block.dollar) return true; + if ((block.commas >> 0 + block.ranges >> 0) === 0) { + block.invalid = true; + return true; + } + if (block.open !== true || block.close !== true) { + block.invalid = true; + return true; + } + return false; +}; - try { - // sunos lets the root user unlink directories, which is... weird. - if (st && st.isDirectory()) - rmdirSync(p, options, null) - else - options.unlinkSync(p) - } catch (er) { - if (er.code === "ENOENT") - return - if (er.code === "EPERM") - return isWindows ? fixWinEPERMSync(p, options, er) : rmdirSync(p, options, er) - if (er.code !== "EISDIR") - throw er +/** + * Returns true if a node is an open or close node + */ - rmdirSync(p, options, er) - } +exports.isOpenOrClose = node => { + if (node.type === 'open' || node.type === 'close') { + return true; } -} + return node.open === true || node.close === true; +}; -function rmdirSync (p, options, originalEr) { - assert(p) - assert(options) - if (originalEr) - assert(originalEr instanceof Error) +/** + * Reduce an array of text nodes. + */ - try { - options.rmdirSync(p) - } catch (er) { - if (er.code === "ENOENT") - return - if (er.code === "ENOTDIR") - throw originalEr - if (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM") - rmkidsSync(p, options) - } -} +exports.reduce = nodes => nodes.reduce((acc, node) => { + if (node.type === 'text') acc.push(node.value); + if (node.type === 'range') node.type = 'text'; + return acc; +}, []); -function rmkidsSync (p, options) { - assert(p) - assert(options) - options.readdirSync(p).forEach(function (f) { - rimrafSync(path.join(p, f), options) - }) +/** + * Flatten an array + */ - // We only end up here once we got ENOTEMPTY at least once, and - // at this point, we are guaranteed to have removed all the kids. - // So, we know that it won't be ENOENT or ENOTDIR or anything else. - // try really hard to delete stuff on windows, because it has a - // PROFOUNDLY annoying habit of not closing handles promptly when - // files are deleted, resulting in spurious ENOTEMPTY errors. - var retries = isWindows ? 100 : 1 - var i = 0 - do { - var threw = true - try { - var ret = options.rmdirSync(p, options) - threw = false - return ret - } finally { - if (++i < retries && threw) - continue +exports.flatten = (...args) => { + const result = []; + const flat = arr => { + for (let i = 0; i < arr.length; i++) { + let ele = arr[i]; + Array.isArray(ele) ? flat(ele, result) : ele !== void 0 && result.push(ele); } - } while (true) -} + return result; + }; + flat(args); + return result; +}; /***/ }), -/* 234 */, -/* 235 */, -/* 236 */, -/* 237 */, -/* 238 */, -/* 239 */ +/* 300 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var hasFlag = __webpack_require__(221); -var support = function (level) { - if (level === 0) { - return false; - } +const fill = __webpack_require__(301); +const utils = __webpack_require__(299); - return { - level: level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3 - }; -}; +const compile = (ast, options = {}) => { + let walk = (node, parent = {}) => { + let invalidBlock = utils.isInvalidBrace(parent); + let invalidNode = node.invalid === true && options.escapeInvalid === true; + let invalid = invalidBlock === true || invalidNode === true; + let prefix = options.escapeInvalid === true ? '\\' : ''; + let output = ''; -var supportLevel = (function () { - if (hasFlag('no-color') || - hasFlag('no-colors') || - hasFlag('color=false')) { - return 0; - } + if (node.isOpen === true) { + return prefix + node.value; + } + if (node.isClose === true) { + return prefix + node.value; + } - if (hasFlag('color=16m') || - hasFlag('color=full') || - hasFlag('color=truecolor')) { - return 3; - } + if (node.type === 'open') { + return invalid ? (prefix + node.value) : '('; + } - if (hasFlag('color=256')) { - return 2; - } + if (node.type === 'close') { + return invalid ? (prefix + node.value) : ')'; + } - if (hasFlag('color') || - hasFlag('colors') || - hasFlag('color=true') || - hasFlag('color=always')) { - return 1; - } + if (node.type === 'comma') { + return node.prev.type === 'comma' ? '' : (invalid ? node.value : '|'); + } - if (process.stdout && !process.stdout.isTTY) { - return 0; - } + if (node.value) { + return node.value; + } - if (process.platform === 'win32') { - return 1; - } + if (node.nodes && node.ranges > 0) { + let args = utils.reduce(node.nodes); + let range = fill(...args, { ...options, wrap: false, toRegex: true }); - if ('CI' in process.env) { - if ('TRAVIS' in process.env || process.env.CI === 'Travis') { - return 1; - } + if (range.length !== 0) { + return args.length > 1 && range.length > 1 ? `(${range})` : range; + } + } - return 0; - } + if (node.nodes) { + for (let child of node.nodes) { + output += walk(child, node); + } + } + return output; + }; - if ('TEAMCITY_VERSION' in process.env) { - return process.env.TEAMCITY_VERSION.match(/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/) === null ? 0 : 1; - } + return walk(ast); +}; - if (/^(screen|xterm)-256(?:color)?/.test(process.env.TERM)) { - return 2; - } +module.exports = compile; - if (/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i.test(process.env.TERM)) { - return 1; - } - if ('COLORTERM' in process.env) { - return 1; - } +/***/ }), +/* 301 */ +/***/ (function(module, exports, __webpack_require__) { - if (process.env.TERM === 'dumb') { - return 0; - } +"use strict"; +/*! + * fill-range + * + * Copyright (c) 2014-present, Jon Schlinkert. + * Licensed under the MIT License. + */ - return 0; -})(); -if (supportLevel === 0 && 'FORCE_COLOR' in process.env) { - supportLevel = 1; -} -module.exports = process && support(supportLevel); +const util = __webpack_require__(112); +const toRegexRange = __webpack_require__(302); +const isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); -/***/ }) -/******/ ]); +const transform = toNumber => { + return value => toNumber === true ? Number(value) : String(value); +}; -/***/ }), -/* 285 */ -/***/ (function(module, exports) { +const isValidValue = value => { + return typeof value === 'number' || (typeof value === 'string' && value !== ''); +}; -module.exports = require("buffer"); +const isNumber = num => Number.isInteger(+num); -/***/ }), -/* 286 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +const zeros = input => { + let value = `${input}`; + let index = -1; + if (value[0] === '-') value = value.slice(1); + if (value === '0') return false; + while (value[++index] === '0'); + return index > 0; +}; -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BootstrapCacheFile", function() { return BootstrapCacheFile; }); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(133); -/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__); -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; } +const stringify = (start, end, options) => { + if (typeof start === 'string' || typeof end === 'string') { + return true; + } + return options.stringify === true; +}; -/* - * 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 pad = (input, maxLength, toNumber) => { + if (maxLength > 0) { + let dash = input[0] === '-' ? '-' : ''; + if (dash) input = input.slice(1); + input = (dash + input.padStart(dash ? maxLength - 1 : maxLength, '0')); + } + if (toNumber === false) { + return String(input); + } + return input; +}; + +const toMaxLen = (input, maxLength) => { + let negative = input[0] === '-' ? '-' : ''; + if (negative) { + input = input.slice(1); + maxLength--; + } + while (input.length < maxLength) input = '0' + input; + return negative ? ('-' + input) : input; +}; +const toSequence = (parts, options) => { + parts.negatives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); + parts.positives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); -class BootstrapCacheFile { - constructor(kbn, project, checksums) { - _defineProperty(this, "path", void 0); + let prefix = options.capture ? '' : '?:'; + let positives = ''; + let negatives = ''; + let result; - _defineProperty(this, "expectedValue", void 0); + if (parts.positives.length) { + positives = parts.positives.join('|'); + } - this.path = path__WEBPACK_IMPORTED_MODULE_1___default.a.resolve(project.targetLocation, '.bootstrap-cache'); + if (parts.negatives.length) { + negatives = `-(${prefix}${parts.negatives.join('|')})`; + } - if (!checksums) { - return; - } + if (positives && negatives) { + result = `${positives}|${negatives}`; + } else { + result = positives || negatives; + } - const projectAndDepCacheKeys = Array.from(kbn.getProjectAndDeps(project.name).values()) // sort deps by name so that the key is stable - .sort((a, b) => a.name.localeCompare(b.name)) // get the cacheKey for each project, return undefined if the cache key couldn't be determined - .map(p => { - const cacheKey = checksums.get(p.name); + if (options.wrap) { + return `(${prefix}${result})`; + } - if (cacheKey) { - return `${p.name}:${cacheKey}`; - } - }); // if any of the relevant cache keys are undefined then the projectCacheKey must be too + return result; +}; - this.expectedValue = projectAndDepCacheKeys.some(k => !k) ? undefined : [`# this is only human readable for debugging, please don't try to parse this`, ...projectAndDepCacheKeys].join('\n'); +const toRange = (a, b, isNumbers, options) => { + if (isNumbers) { + return toRegexRange(a, b, { wrap: false, ...options }); } - isValid() { - if (!this.expectedValue) { - return false; - } + let start = String.fromCharCode(a); + if (a === b) return start; - try { - return fs__WEBPACK_IMPORTED_MODULE_0___default.a.readFileSync(this.path, 'utf8') === this.expectedValue; - } catch (error) { - if (error.code === 'ENOENT') { - return false; - } + let stop = String.fromCharCode(b); + return `[${start}-${stop}]`; +}; - throw error; - } +const toRegex = (start, end, options) => { + if (Array.isArray(start)) { + let wrap = options.wrap === true; + let prefix = options.capture ? '' : '?:'; + return wrap ? `(${prefix}${start.join('|')})` : start.join('|'); } + return toRegexRange(start, end, options); +}; - delete() { - try { - fs__WEBPACK_IMPORTED_MODULE_0___default.a.unlinkSync(this.path); - } catch (error) { - if (error.code !== 'ENOENT') { - throw error; - } - } +const rangeError = (...args) => { + return new RangeError('Invalid range arguments: ' + util.inspect(...args)); +}; + +const invalidRange = (start, end, options) => { + if (options.strictRanges === true) throw rangeError([start, end]); + return []; +}; + +const invalidStep = (step, options) => { + if (options.strictRanges === true) { + throw new TypeError(`Expected step "${step}" to be a number`); } + return []; +}; - write() { - if (!this.expectedValue) { - return; - } +const fillNumbers = (start, end, step = 1, options = {}) => { + let a = Number(start); + let b = Number(end); - fs__WEBPACK_IMPORTED_MODULE_0___default.a.mkdirSync(path__WEBPACK_IMPORTED_MODULE_1___default.a.dirname(this.path), { - recursive: true - }); - fs__WEBPACK_IMPORTED_MODULE_0___default.a.writeFileSync(this.path, this.expectedValue); + if (!Number.isInteger(a) || !Number.isInteger(b)) { + if (options.strictRanges === true) throw rangeError([start, end]); + return []; } -} + // fix negative zero + if (a === 0) a = 0; + if (b === 0) b = 0; -/***/ }), -/* 287 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + let descending = a > b; + let startString = String(start); + let endString = String(end); + let stepString = String(step); + step = Math.max(Math.abs(step), 1); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "validateYarnLock", function() { return validateYarnLock; }); -/* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(284); -/* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var dedent__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2); -/* harmony import */ var dedent__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(dedent__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _fs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(130); -/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(143); -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -// @ts-expect-error published types are useless + let padded = zeros(startString) || zeros(endString) || zeros(stepString); + let maxLen = padded ? Math.max(startString.length, endString.length, stepString.length) : 0; + let toNumber = padded === false && stringify(start, end, options) === false; + let format = options.transform || transform(toNumber); + if (options.toRegex && step === 1) { + return toRange(toMaxLen(start, maxLen), toMaxLen(end, maxLen), true, options); + } + let parts = { negatives: [], positives: [] }; + let push = num => parts[num < 0 ? 'negatives' : 'positives'].push(Math.abs(num)); + let range = []; + let index = 0; + while (descending ? a >= b : a <= b) { + if (options.toRegex === true && step > 1) { + push(a); + } else { + range.push(pad(format(a, index), maxLen, toNumber)); + } + a = descending ? a - step : a + step; + index++; + } -async function validateYarnLock(kbn, yarnLock) { - // look through all of the packages in the yarn.lock file to see if - // we have accidentally installed multiple lodash v4 versions - const lodash4Versions = new Set(); - const lodash4Reqs = new Set(); + if (options.toRegex === true) { + return step > 1 + ? toSequence(parts, options) + : toRegex(range, null, { wrap: false, ...options }); + } - for (const [req, dep] of Object.entries(yarnLock)) { - if (req.startsWith('lodash@') && dep.version.startsWith('4.')) { - lodash4Reqs.add(req); - lodash4Versions.add(dep.version); - } - } // if we find more than one lodash v4 version installed then delete - // lodash v4 requests from the yarn.lock file and prompt the user to - // retry bootstrap so that a single v4 version will be installed + return range; +}; +const fillLetters = (start, end, step = 1, options = {}) => { + if ((!isNumber(start) && start.length > 1) || (!isNumber(end) && end.length > 1)) { + return invalidRange(start, end, options); + } - if (lodash4Versions.size > 1) { - for (const req of lodash4Reqs) { - delete yarnLock[req]; - } - await Object(_fs__WEBPACK_IMPORTED_MODULE_2__["writeFile"])(kbn.getAbsolute('yarn.lock'), Object(_yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__["stringify"])(yarnLock), 'utf8'); - _log__WEBPACK_IMPORTED_MODULE_3__["log"].error(dedent__WEBPACK_IMPORTED_MODULE_1___default.a` + let format = options.transform || (val => String.fromCharCode(val)); + let a = `${start}`.charCodeAt(0); + let b = `${end}`.charCodeAt(0); - Multiple version of lodash v4 were detected, so they have been removed - from the yarn.lock file. Please rerun yarn kbn bootstrap to coalese the - lodash versions installed. + let descending = a > b; + let min = Math.min(a, b); + let max = Math.max(a, b); - If you still see this error when you re-bootstrap then you might need - to force a new dependency to use the latest version of lodash via the - "resolutions" field in package.json. + if (options.toRegex && step === 1) { + return toRange(min, max, false, options); + } - If you have questions about this please reach out to the operations team. + let range = []; + let index = 0; - `); - process.exit(1); - } // look through all the dependencies of production packages and production - // dependencies of those packages to determine if we're shipping any versions - // of lodash v3 in the distributable + while (descending ? a >= b : a <= b) { + range.push(format(a, index)); + a = descending ? a - step : a + step; + index++; + } + if (options.toRegex === true) { + return toRegex(range, null, { wrap: false, options }); + } - const prodDependencies = kbn.resolveAllProductionDependencies(yarnLock, _log__WEBPACK_IMPORTED_MODULE_3__["log"]); - const lodash3Versions = new Set(); + return range; +}; - for (const dep of prodDependencies.values()) { - if (dep.name === 'lodash' && dep.version.startsWith('3.')) { - lodash3Versions.add(dep.version); - } - } // if any lodash v3 packages were found we abort and tell the user to fix things +const fill = (start, end, step, options = {}) => { + if (end == null && isValidValue(start)) { + return [start]; + } + if (!isValidValue(start) || !isValidValue(end)) { + return invalidRange(start, end, options); + } - if (lodash3Versions.size) { - _log__WEBPACK_IMPORTED_MODULE_3__["log"].error(dedent__WEBPACK_IMPORTED_MODULE_1___default.a` + if (typeof step === 'function') { + return fill(start, end, 1, { transform: step }); + } - Due to changes in the yarn.lock file and/or package.json files a version of - lodash 3 is now included in the production dependencies. To reduce the size of - our distributable and especially our front-end bundles we have decided to - prevent adding any new instances of lodash 3. + if (isObject(step)) { + return fill(start, end, 0, step); + } - Please inspect the changes to yarn.lock or package.json files to identify where - the lodash 3 version is coming from and remove it. + let opts = { ...options }; + if (opts.capture === true) opts.wrap = true; + step = step || opts.step || 1; - If you have questions about this please reack out to the operations team. + if (!isNumber(step)) { + if (step != null && !isObject(step)) return invalidStep(step, opts); + return fill(start, end, 1, step); + } - `); - process.exit(1); + if (isNumber(start) && isNumber(end)) { + return fillNumbers(start, end, step, opts); } - _log__WEBPACK_IMPORTED_MODULE_3__["log"].success('yarn.lock analysis completed without any issues'); -} + return fillLetters(start, end, Math.max(Math.abs(step), 1), opts); +}; + +module.exports = fill; + /***/ }), -/* 288 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 302 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CleanCommand", function() { return CleanCommand; }); -/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(289); -/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(del__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(376); -/* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(ora__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(130); -/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(143); -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/*! + * to-regex-range * - * 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. + * Copyright (c) 2015-present, Jon Schlinkert. + * Released under the MIT License. */ +const isNumber = __webpack_require__(303); +const toRegexRange = (min, max, options) => { + if (isNumber(min) === false) { + throw new TypeError('toRegexRange: expected the first argument to be a number'); + } -const CleanCommand = { - description: 'Remove the node_modules and target directories from all projects.', - name: 'clean', - - async run(projects) { - const toDelete = []; - - for (const project of projects.values()) { - if (await Object(_utils_fs__WEBPACK_IMPORTED_MODULE_3__["isDirectory"])(project.nodeModulesLocation)) { - toDelete.push({ - cwd: project.path, - pattern: Object(path__WEBPACK_IMPORTED_MODULE_2__["relative"])(project.path, project.nodeModulesLocation) - }); - } - - if (await Object(_utils_fs__WEBPACK_IMPORTED_MODULE_3__["isDirectory"])(project.targetLocation)) { - toDelete.push({ - cwd: project.path, - pattern: Object(path__WEBPACK_IMPORTED_MODULE_2__["relative"])(project.path, project.targetLocation) - }); - } + if (max === void 0 || min === max) { + return String(min); + } - const { - extraPatterns - } = project.getCleanConfig(); + if (isNumber(max) === false) { + throw new TypeError('toRegexRange: expected the second argument to be a number.'); + } - if (extraPatterns) { - toDelete.push({ - cwd: project.path, - pattern: extraPatterns - }); - } - } + let opts = { relaxZeros: true, ...options }; + if (typeof opts.strictZeros === 'boolean') { + opts.relaxZeros = opts.strictZeros === false; + } - if (toDelete.length === 0) { - _utils_log__WEBPACK_IMPORTED_MODULE_4__["log"].success('Nothing to delete'); - } else { - /** - * 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(); + let relax = String(opts.relaxZeros); + let shorthand = String(opts.shorthand); + let capture = String(opts.capture); + let wrap = String(opts.wrap); + let cacheKey = min + ':' + max + '=' + relax + shorthand + capture + wrap; - try { - for (const { - pattern, - cwd - } of toDelete) { - process.chdir(cwd); - const promise = del__WEBPACK_IMPORTED_MODULE_0___default()(pattern); + if (toRegexRange.cache.hasOwnProperty(cacheKey)) { + return toRegexRange.cache[cacheKey].result; + } - if (_utils_log__WEBPACK_IMPORTED_MODULE_4__["log"].wouldLogLevel('info')) { - ora__WEBPACK_IMPORTED_MODULE_1___default.a.promise(promise, Object(path__WEBPACK_IMPORTED_MODULE_2__["relative"])(originalCwd, Object(path__WEBPACK_IMPORTED_MODULE_2__["join"])(cwd, String(pattern)))); - } + let a = Math.min(min, max); + let b = Math.max(min, max); - await promise; - } - } finally { - process.chdir(originalCwd); - } + if (Math.abs(a - b) === 1) { + let result = min + '|' + max; + if (opts.capture) { + return `(${result})`; + } + if (opts.wrap === false) { + return result; } + return `(?:${result})`; } -}; + let isPadded = hasPadding(min) || hasPadding(max); + let state = { min, max, a, b }; + let positives = []; + let negatives = []; -/***/ }), -/* 289 */ -/***/ (function(module, exports, __webpack_require__) { + if (isPadded) { + state.isPadded = isPadded; + state.maxLen = String(state.max).length; + } -"use strict"; + if (a < 0) { + let newMin = b < 0 ? Math.abs(b) : 1; + negatives = splitToPatterns(newMin, Math.abs(a), state, opts); + a = state.a = 0; + } -const {promisify} = __webpack_require__(111); -const path = __webpack_require__(4); -const globby = __webpack_require__(290); -const isGlob = __webpack_require__(368); -const slash = __webpack_require__(366); -const gracefulFs = __webpack_require__(132); -const isPathCwd = __webpack_require__(369); -const isPathInside = __webpack_require__(370); -const rimraf = __webpack_require__(371); -const pMap = __webpack_require__(372); + if (b >= 0) { + positives = splitToPatterns(a, b, state, opts); + } -const rimrafP = promisify(rimraf); + state.negatives = negatives; + state.positives = positives; + state.result = collatePatterns(negatives, positives, opts); -const rimrafOptions = { - glob: false, - unlink: gracefulFs.unlink, - unlinkSync: gracefulFs.unlinkSync, - chmod: gracefulFs.chmod, - chmodSync: gracefulFs.chmodSync, - stat: gracefulFs.stat, - statSync: gracefulFs.statSync, - lstat: gracefulFs.lstat, - lstatSync: gracefulFs.lstatSync, - rmdir: gracefulFs.rmdir, - rmdirSync: gracefulFs.rmdirSync, - readdir: gracefulFs.readdir, - readdirSync: gracefulFs.readdirSync -}; + if (opts.capture === true) { + state.result = `(${state.result})`; + } else if (opts.wrap !== false && (positives.length + negatives.length) > 1) { + state.result = `(?:${state.result})`; + } -function safeCheck(file, cwd) { - if (isPathCwd(file)) { - throw new Error('Cannot delete the current working directory. Can be overridden with the `force` option.'); - } + toRegexRange.cache[cacheKey] = state; + return state.result; +}; - if (!isPathInside(file, cwd)) { - throw new Error('Cannot delete files/directories outside the current working directory. Can be overridden with the `force` option.'); - } +function collatePatterns(neg, pos, options) { + let onlyNegative = filterPatterns(neg, pos, '-', false, options) || []; + let onlyPositive = filterPatterns(pos, neg, '', false, options) || []; + let intersected = filterPatterns(neg, pos, '-?', true, options) || []; + let subpatterns = onlyNegative.concat(intersected).concat(onlyPositive); + return subpatterns.join('|'); } -function normalizePatterns(patterns) { - patterns = Array.isArray(patterns) ? patterns : [patterns]; +function splitToRanges(min, max) { + let nines = 1; + let zeros = 1; - patterns = patterns.map(pattern => { - if (process.platform === 'win32' && isGlob(pattern) === false) { - return slash(pattern); - } + let stop = countNines(min, nines); + let stops = new Set([max]); - return pattern; - }); + while (min <= stop && stop <= max) { + stops.add(stop); + nines += 1; + stop = countNines(min, nines); + } - return patterns; + stop = countZeros(max + 1, zeros) - 1; + + while (min < stop && stop <= max) { + stops.add(stop); + zeros += 1; + stop = countZeros(max + 1, zeros) - 1; + } + + stops = [...stops]; + stops.sort(compare); + return stops; } -module.exports = async (patterns, {force, dryRun, cwd = process.cwd(), ...options} = {}) => { - options = { - expandDirectories: false, - onlyFiles: false, - followSymbolicLinks: false, - cwd, - ...options - }; +/** + * Convert a range to a regex pattern + * @param {Number} `start` + * @param {Number} `stop` + * @return {String} + */ - patterns = normalizePatterns(patterns); +function rangeToPattern(start, stop, options) { + if (start === stop) { + return { pattern: start, count: [], digits: 0 }; + } - const files = (await globby(patterns, options)) - .sort((a, b) => b.localeCompare(a)); + let zipped = zip(start, stop); + let digits = zipped.length; + let pattern = ''; + let count = 0; - const mapper = async file => { - file = path.resolve(cwd, file); + for (let i = 0; i < digits; i++) { + let [startDigit, stopDigit] = zipped[i]; - if (!force) { - safeCheck(file, cwd); - } + if (startDigit === stopDigit) { + pattern += startDigit; - if (!dryRun) { - await rimrafP(file, rimrafOptions); - } + } else if (startDigit !== '0' || stopDigit !== '9') { + pattern += toCharacterClass(startDigit, stopDigit, options); - return file; - }; + } else { + count++; + } + } - const removedFiles = await pMap(files, mapper, options); + if (count) { + pattern += options.shorthand === true ? '\\d' : '[0-9]'; + } - removedFiles.sort((a, b) => a.localeCompare(b)); + return { pattern, count: [count], digits }; +} - return removedFiles; -}; +function splitToPatterns(min, max, tok, options) { + let ranges = splitToRanges(min, max); + let tokens = []; + let start = min; + let prev; -module.exports.sync = (patterns, {force, dryRun, cwd = process.cwd(), ...options} = {}) => { - options = { - expandDirectories: false, - onlyFiles: false, - followSymbolicLinks: false, - cwd, - ...options - }; + for (let i = 0; i < ranges.length; i++) { + let max = ranges[i]; + let obj = rangeToPattern(String(start), String(max), options); + let zeros = ''; - patterns = normalizePatterns(patterns); + if (!tok.isPadded && prev && prev.pattern === obj.pattern) { + if (prev.count.length > 1) { + prev.count.pop(); + } - const files = globby.sync(patterns, options) - .sort((a, b) => b.localeCompare(a)); + prev.count.push(obj.count[0]); + prev.string = prev.pattern + toQuantifier(prev.count); + start = max + 1; + continue; + } - const removedFiles = files.map(file => { - file = path.resolve(cwd, file); + if (tok.isPadded) { + zeros = padZeros(max, tok, options); + } - if (!force) { - safeCheck(file, cwd); - } + obj.string = zeros + obj.pattern + toQuantifier(obj.count); + tokens.push(obj); + start = max + 1; + prev = obj; + } - if (!dryRun) { - rimraf.sync(file, rimrafOptions); - } + return tokens; +} - return file; - }); +function filterPatterns(arr, comparison, prefix, intersection, options) { + let result = []; - removedFiles.sort((a, b) => a.localeCompare(b)); + for (let ele of arr) { + let { string } = ele; - return removedFiles; -}; + // only push if _both_ are negative... + if (!intersection && !contains(comparison, 'string', string)) { + result.push(prefix + string); + } + // or _both_ are positive + if (intersection && contains(comparison, 'string', string)) { + result.push(prefix + string); + } + } + return result; +} -/***/ }), -/* 290 */ -/***/ (function(module, exports, __webpack_require__) { +/** + * Zip strings + */ -"use strict"; +function zip(a, b) { + let arr = []; + for (let i = 0; i < a.length; i++) arr.push([a[i], b[i]]); + return arr; +} -const fs = __webpack_require__(133); -const arrayUnion = __webpack_require__(291); -const merge2 = __webpack_require__(292); -const glob = __webpack_require__(146); -const fastGlob = __webpack_require__(293); -const dirGlob = __webpack_require__(362); -const gitignore = __webpack_require__(364); -const {FilterStream, UniqueStream} = __webpack_require__(367); +function compare(a, b) { + return a > b ? 1 : b > a ? -1 : 0; +} -const DEFAULT_FILTER = () => false; +function contains(arr, key, val) { + return arr.some(ele => ele[key] === val); +} -const isNegative = pattern => pattern[0] === '!'; +function countNines(min, len) { + return Number(String(min).slice(0, -len) + '9'.repeat(len)); +} -const assertPatternsInput = patterns => { - if (!patterns.every(pattern => typeof pattern === 'string')) { - throw new TypeError('Patterns must be a string or an array of strings'); - } -}; +function countZeros(integer, zeros) { + return integer - (integer % Math.pow(10, zeros)); +} -const checkCwdOption = (options = {}) => { - if (!options.cwd) { - return; - } - - let stat; - try { - stat = fs.statSync(options.cwd); - } catch (_) { - return; - } +function toQuantifier(digits) { + let [start = 0, stop = ''] = digits; + if (stop || start > 1) { + return `{${start + (stop ? ',' + stop : '')}}`; + } + return ''; +} - if (!stat.isDirectory()) { - throw new Error('The `cwd` option must be a path to a directory'); - } -}; +function toCharacterClass(a, b, options) { + return `[${a}${(b - a === 1) ? '' : '-'}${b}]`; +} -const getPathString = p => p.stats instanceof fs.Stats ? p.path : p; +function hasPadding(str) { + return /^-?(0+)\d/.test(str); +} -const generateGlobTasks = (patterns, taskOptions) => { - patterns = arrayUnion([].concat(patterns)); - assertPatternsInput(patterns); - checkCwdOption(taskOptions); +function padZeros(value, tok, options) { + if (!tok.isPadded) { + return value; + } - const globTasks = []; + let diff = Math.abs(tok.maxLen - String(value).length); + let relax = options.relaxZeros !== false; - taskOptions = { - ignore: [], - expandDirectories: true, - ...taskOptions - }; + switch (diff) { + case 0: + return ''; + case 1: + return relax ? '0?' : '0'; + case 2: + return relax ? '0{0,2}' : '00'; + default: { + return relax ? `0{0,${diff}}` : `0{${diff}}`; + } + } +} - for (const [index, pattern] of patterns.entries()) { - if (isNegative(pattern)) { - continue; - } +/** + * Cache + */ - const ignore = patterns - .slice(index) - .filter(isNegative) - .map(pattern => pattern.slice(1)); +toRegexRange.cache = {}; +toRegexRange.clearCache = () => (toRegexRange.cache = {}); - const options = { - ...taskOptions, - ignore: taskOptions.ignore.concat(ignore) - }; +/** + * Expose `toRegexRange` + */ - globTasks.push({pattern, options}); - } +module.exports = toRegexRange; - return globTasks; -}; -const globDirs = (task, fn) => { - let options = {}; - if (task.options.cwd) { - options.cwd = task.options.cwd; - } +/***/ }), +/* 303 */ +/***/ (function(module, exports, __webpack_require__) { - if (Array.isArray(task.options.expandDirectories)) { - options = { - ...options, - files: task.options.expandDirectories - }; - } else if (typeof task.options.expandDirectories === 'object') { - options = { - ...options, - ...task.options.expandDirectories - }; - } +"use strict"; +/*! + * is-number + * + * Copyright (c) 2014-present, Jon Schlinkert. + * Released under the MIT License. + */ - return fn(task.pattern, options); -}; -const getPattern = (task, fn) => task.options.expandDirectories ? globDirs(task, fn) : [task.pattern]; -const getFilterSync = options => { - return options && options.gitignore ? - gitignore.sync({cwd: options.cwd, ignore: options.ignore}) : - DEFAULT_FILTER; +module.exports = function(num) { + if (typeof num === 'number') { + return num - num === 0; + } + if (typeof num === 'string' && num.trim() !== '') { + return Number.isFinite ? Number.isFinite(+num) : isFinite(+num); + } + return false; }; -const globToTask = task => glob => { - const {options} = task; - if (options.ignore && Array.isArray(options.ignore) && options.expandDirectories) { - options.ignore = dirGlob.sync(options.ignore); - } - return { - pattern: glob, - options - }; -}; +/***/ }), +/* 304 */ +/***/ (function(module, exports, __webpack_require__) { -module.exports = async (patterns, options) => { - const globTasks = generateGlobTasks(patterns, options); +"use strict"; - const getFilter = async () => { - return options && options.gitignore ? - gitignore({cwd: options.cwd, ignore: options.ignore}) : - DEFAULT_FILTER; - }; - const getTasks = async () => { - const tasks = await Promise.all(globTasks.map(async task => { - const globs = await getPattern(task, dirGlob); - return Promise.all(globs.map(globToTask(task))); - })); +const fill = __webpack_require__(301); +const stringify = __webpack_require__(298); +const utils = __webpack_require__(299); - return arrayUnion(...tasks); - }; +const append = (queue = '', stash = '', enclose = false) => { + let result = []; - const [filter, tasks] = await Promise.all([getFilter(), getTasks()]); - const paths = await Promise.all(tasks.map(task => fastGlob(task.pattern, task.options))); + queue = [].concat(queue); + stash = [].concat(stash); - return arrayUnion(...paths).filter(path_ => !filter(getPathString(path_))); + if (!stash.length) return queue; + if (!queue.length) { + return enclose ? utils.flatten(stash).map(ele => `{${ele}}`) : stash; + } + + for (let item of queue) { + if (Array.isArray(item)) { + for (let value of item) { + result.push(append(value, stash, enclose)); + } + } else { + for (let ele of stash) { + if (enclose === true && typeof ele === 'string') ele = `{${ele}}`; + result.push(Array.isArray(ele) ? append(item, ele, enclose) : (item + ele)); + } + } + } + return utils.flatten(result); }; -module.exports.sync = (patterns, options) => { - const globTasks = generateGlobTasks(patterns, options); +const expand = (ast, options = {}) => { + let rangeLimit = options.rangeLimit === void 0 ? 1000 : options.rangeLimit; - const tasks = globTasks.reduce((tasks, task) => { - const newTask = getPattern(task, dirGlob.sync).map(globToTask(task)); - return tasks.concat(newTask); - }, []); + let walk = (node, parent = {}) => { + node.queue = []; - const filter = getFilterSync(options); + let p = parent; + let q = parent.queue; - return tasks.reduce( - (matches, task) => arrayUnion(matches, fastGlob.sync(task.pattern, task.options)), - [] - ).filter(path_ => !filter(path_)); -}; + while (p.type !== 'brace' && p.type !== 'root' && p.parent) { + p = p.parent; + q = p.queue; + } -module.exports.stream = (patterns, options) => { - const globTasks = generateGlobTasks(patterns, options); + if (node.invalid || node.dollar) { + q.push(append(q.pop(), stringify(node, options))); + return; + } - const tasks = globTasks.reduce((tasks, task) => { - const newTask = getPattern(task, dirGlob.sync).map(globToTask(task)); - return tasks.concat(newTask); - }, []); + if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) { + q.push(append(q.pop(), ['{}'])); + return; + } - const filter = getFilterSync(options); - const filterStream = new FilterStream(p => !filter(p)); - const uniqueStream = new UniqueStream(); + if (node.nodes && node.ranges > 0) { + let args = utils.reduce(node.nodes); - return merge2(tasks.map(task => fastGlob.stream(task.pattern, task.options))) - .pipe(filterStream) - .pipe(uniqueStream); -}; + if (utils.exceedsLimit(...args, options.step, rangeLimit)) { + throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.'); + } -module.exports.generateGlobTasks = generateGlobTasks; + let range = fill(...args, options); + if (range.length === 0) { + range = stringify(node, options); + } -module.exports.hasMagic = (patterns, options) => [] - .concat(patterns) - .some(pattern => glob.hasMagic(pattern, options)); + q.push(append(q.pop(), range)); + node.nodes = []; + return; + } -module.exports.gitignore = gitignore; + let enclose = utils.encloseBrace(node); + let queue = node.queue; + let block = node; + while (block.type !== 'brace' && block.type !== 'root' && block.parent) { + block = block.parent; + queue = block.queue; + } -/***/ }), -/* 291 */ -/***/ (function(module, exports, __webpack_require__) { + for (let i = 0; i < node.nodes.length; i++) { + let child = node.nodes[i]; -"use strict"; + if (child.type === 'comma' && node.type === 'brace') { + if (i === 1) queue.push(''); + queue.push(''); + continue; + } + + if (child.type === 'close') { + q.push(append(q.pop(), queue, enclose)); + continue; + } + + if (child.value && child.type !== 'open') { + queue.push(append(queue.pop(), child.value)); + continue; + } + if (child.nodes) { + walk(child, node); + } + } -module.exports = (...arguments_) => { - return [...new Set([].concat(...arguments_))]; + return queue; + }; + + return utils.flatten(walk(ast)); }; +module.exports = expand; + /***/ }), -/* 292 */ +/* 305 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/* - * merge2 - * https://github.com/teambition/merge2 - * - * Copyright (c) 2014-2020 Teambition - * Licensed under the MIT license. + +const stringify = __webpack_require__(298); + +/** + * Constants */ -const Stream = __webpack_require__(137) -const PassThrough = Stream.PassThrough -const slice = Array.prototype.slice -module.exports = merge2 +const { + MAX_LENGTH, + CHAR_BACKSLASH, /* \ */ + CHAR_BACKTICK, /* ` */ + CHAR_COMMA, /* , */ + CHAR_DOT, /* . */ + CHAR_LEFT_PARENTHESES, /* ( */ + CHAR_RIGHT_PARENTHESES, /* ) */ + CHAR_LEFT_CURLY_BRACE, /* { */ + CHAR_RIGHT_CURLY_BRACE, /* } */ + CHAR_LEFT_SQUARE_BRACKET, /* [ */ + CHAR_RIGHT_SQUARE_BRACKET, /* ] */ + CHAR_DOUBLE_QUOTE, /* " */ + CHAR_SINGLE_QUOTE, /* ' */ + CHAR_NO_BREAK_SPACE, + CHAR_ZERO_WIDTH_NOBREAK_SPACE +} = __webpack_require__(306); -function merge2 () { - const streamsQueue = [] - const args = slice.call(arguments) - let merging = false - let options = args[args.length - 1] +/** + * parse + */ - if (options && !Array.isArray(options) && options.pipe == null) { - args.pop() - } else { - options = {} +const parse = (input, options = {}) => { + if (typeof input !== 'string') { + throw new TypeError('Expected a string'); } - const doEnd = options.end !== false - const doPipeError = options.pipeError === true - if (options.objectMode == null) { - options.objectMode = true - } - if (options.highWaterMark == null) { - options.highWaterMark = 64 * 1024 + let opts = options || {}; + let max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; + if (input.length > max) { + throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`); } - const mergedStream = PassThrough(options) - function addStream () { - for (let i = 0, len = arguments.length; i < len; i++) { - streamsQueue.push(pauseStreams(arguments[i], options)) + let ast = { type: 'root', input, nodes: [] }; + let stack = [ast]; + let block = ast; + let prev = ast; + let brackets = 0; + let length = input.length; + let index = 0; + let depth = 0; + let value; + let memo = {}; + + /** + * Helpers + */ + + const advance = () => input[index++]; + const push = node => { + if (node.type === 'text' && prev.type === 'dot') { + prev.type = 'text'; } - mergeStream() - return this - } - function mergeStream () { - if (merging) { - return + if (prev && prev.type === 'text' && node.type === 'text') { + prev.value += node.value; + return; } - merging = true - let streams = streamsQueue.shift() - if (!streams) { - process.nextTick(endStream) - return + block.nodes.push(node); + node.parent = block; + node.prev = prev; + prev = node; + return node; + }; + + push({ type: 'bos' }); + + while (index < length) { + block = stack[stack.length - 1]; + value = advance(); + + /** + * Invalid chars + */ + + if (value === CHAR_ZERO_WIDTH_NOBREAK_SPACE || value === CHAR_NO_BREAK_SPACE) { + continue; } - if (!Array.isArray(streams)) { - streams = [streams] + + /** + * Escaped chars + */ + + if (value === CHAR_BACKSLASH) { + push({ type: 'text', value: (options.keepEscaping ? value : '') + advance() }); + continue; } - let pipesCount = streams.length + 1 + /** + * Right square bracket (literal): ']' + */ - function next () { - if (--pipesCount > 0) { - return - } - merging = false - mergeStream() + if (value === CHAR_RIGHT_SQUARE_BRACKET) { + push({ type: 'text', value: '\\' + value }); + continue; } - function pipe (stream) { - function onend () { - stream.removeListener('merge2UnpipeEnd', onend) - stream.removeListener('end', onend) - if (doPipeError) { - stream.removeListener('error', onerror) + /** + * Left square bracket: '[' + */ + + if (value === CHAR_LEFT_SQUARE_BRACKET) { + brackets++; + + let closed = true; + let next; + + while (index < length && (next = advance())) { + value += next; + + if (next === CHAR_LEFT_SQUARE_BRACKET) { + brackets++; + continue; } - next() - } - function onerror (err) { - mergedStream.emit('error', err) - } - // skip ended stream - if (stream._readableState.endEmitted) { - return next() - } - stream.on('merge2UnpipeEnd', onend) - stream.on('end', onend) + if (next === CHAR_BACKSLASH) { + value += advance(); + continue; + } - if (doPipeError) { - stream.on('error', onerror) + if (next === CHAR_RIGHT_SQUARE_BRACKET) { + brackets--; + + if (brackets === 0) { + break; + } + } } - stream.pipe(mergedStream, { end: false }) - // compatible for old stream - stream.resume() + push({ type: 'text', value }); + continue; } - for (let i = 0; i < streams.length; i++) { - pipe(streams[i]) - } + /** + * Parentheses + */ - next() - } + if (value === CHAR_LEFT_PARENTHESES) { + block = push({ type: 'paren', nodes: [] }); + stack.push(block); + push({ type: 'text', value }); + continue; + } - function endStream () { - merging = false - // emit 'queueDrain' when all streams merged. - mergedStream.emit('queueDrain') - if (doEnd) { - mergedStream.end() + if (value === CHAR_RIGHT_PARENTHESES) { + if (block.type !== 'paren') { + push({ type: 'text', value }); + continue; + } + block = stack.pop(); + push({ type: 'text', value }); + block = stack[stack.length - 1]; + continue; } - } - mergedStream.setMaxListeners(0) - mergedStream.add = addStream - mergedStream.on('unpipe', function (stream) { - stream.emit('merge2UnpipeEnd') - }) + /** + * Quotes: '|"|` + */ - if (args.length) { - addStream.apply(null, args) - } - return mergedStream -} + if (value === CHAR_DOUBLE_QUOTE || value === CHAR_SINGLE_QUOTE || value === CHAR_BACKTICK) { + let open = value; + let next; -// check and pause streams for pipe. -function pauseStreams (streams, options) { - if (!Array.isArray(streams)) { - // Backwards-compat with old-style streams - if (!streams._readableState && streams.pipe) { - streams = streams.pipe(PassThrough(options)) + if (options.keepQuotes !== true) { + value = ''; + } + + while (index < length && (next = advance())) { + if (next === CHAR_BACKSLASH) { + value += next + advance(); + continue; + } + + if (next === open) { + if (options.keepQuotes === true) value += next; + break; + } + + value += next; + } + + push({ type: 'text', value }); + continue; } - if (!streams._readableState || !streams.pause || !streams.pipe) { - throw new Error('Only readable stream can be merged.') + + /** + * Left curly brace: '{' + */ + + if (value === CHAR_LEFT_CURLY_BRACE) { + depth++; + + let dollar = prev.value && prev.value.slice(-1) === '$' || block.dollar === true; + let brace = { + type: 'brace', + open: true, + close: false, + dollar, + depth, + commas: 0, + ranges: 0, + nodes: [] + }; + + block = push(brace); + stack.push(block); + push({ type: 'open', value }); + continue; } - streams.pause() - } else { - for (let i = 0, len = streams.length; i < len; i++) { - streams[i] = pauseStreams(streams[i], options) + + /** + * Right curly brace: '}' + */ + + if (value === CHAR_RIGHT_CURLY_BRACE) { + if (block.type !== 'brace') { + push({ type: 'text', value }); + continue; + } + + let type = 'close'; + block = stack.pop(); + block.close = true; + + push({ type, value }); + depth--; + + block = stack[stack.length - 1]; + continue; + } + + /** + * Comma: ',' + */ + + if (value === CHAR_COMMA && depth > 0) { + if (block.ranges > 0) { + block.ranges = 0; + let open = block.nodes.shift(); + block.nodes = [open, { type: 'text', value: stringify(block) }]; + } + + push({ type: 'comma', value }); + block.commas++; + continue; + } + + /** + * Dot: '.' + */ + + if (value === CHAR_DOT && depth > 0 && block.commas === 0) { + let siblings = block.nodes; + + if (depth === 0 || siblings.length === 0) { + push({ type: 'text', value }); + continue; + } + + if (prev.type === 'dot') { + block.range = []; + prev.value += value; + prev.type = 'range'; + + if (block.nodes.length !== 3 && block.nodes.length !== 5) { + block.invalid = true; + block.ranges = 0; + prev.type = 'text'; + continue; + } + + block.ranges++; + block.args = []; + continue; + } + + if (prev.type === 'range') { + siblings.pop(); + + let before = siblings[siblings.length - 1]; + before.value += prev.value + value; + prev = before; + block.ranges--; + continue; + } + + push({ type: 'dot', value }); + continue; } + + /** + * Text + */ + + push({ type: 'text', value }); } - return streams -} + // Mark imbalanced braces and brackets as invalid + do { + block = stack.pop(); -/***/ }), -/* 293 */ -/***/ (function(module, exports, __webpack_require__) { + if (block.type !== 'root') { + block.nodes.forEach(node => { + if (!node.nodes) { + if (node.type === 'open') node.isOpen = true; + if (node.type === 'close') node.isClose = true; + if (!node.nodes) node.type = 'text'; + node.invalid = true; + } + }); -"use strict"; - -const taskManager = __webpack_require__(294); -const async_1 = __webpack_require__(323); -const stream_1 = __webpack_require__(358); -const sync_1 = __webpack_require__(359); -const settings_1 = __webpack_require__(361); -const utils = __webpack_require__(295); -async function FastGlob(source, options) { - assertPatternsInput(source); - const works = getWorks(source, async_1.default, options); - const result = await Promise.all(works); - return utils.array.flatten(result); -} -// https://github.com/typescript-eslint/typescript-eslint/issues/60 -// eslint-disable-next-line no-redeclare -(function (FastGlob) { - function sync(source, options) { - assertPatternsInput(source); - const works = getWorks(source, sync_1.default, options); - return utils.array.flatten(works); - } - FastGlob.sync = sync; - function stream(source, options) { - assertPatternsInput(source); - const works = getWorks(source, stream_1.default, options); - /** - * The stream returned by the provider cannot work with an asynchronous iterator. - * To support asynchronous iterators, regardless of the number of tasks, we always multiplex streams. - * This affects performance (+25%). I don't see best solution right now. - */ - return utils.stream.merge(works); - } - FastGlob.stream = stream; - function generateTasks(source, options) { - assertPatternsInput(source); - const patterns = [].concat(source); - const settings = new settings_1.default(options); - return taskManager.generate(patterns, settings); - } - FastGlob.generateTasks = generateTasks; - function isDynamicPattern(source, options) { - assertPatternsInput(source); - const settings = new settings_1.default(options); - return utils.pattern.isDynamicPattern(source, settings); - } - FastGlob.isDynamicPattern = isDynamicPattern; - function escapePath(source) { - assertPatternsInput(source); - return utils.path.escape(source); - } - FastGlob.escapePath = escapePath; -})(FastGlob || (FastGlob = {})); -function getWorks(source, _Provider, options) { - const patterns = [].concat(source); - const settings = new settings_1.default(options); - const tasks = taskManager.generate(patterns, settings); - const provider = new _Provider(settings); - return tasks.map(provider.read, provider); -} -function assertPatternsInput(input) { - const source = [].concat(input); - const isValidSource = source.every((item) => utils.string.isString(item) && !utils.string.isEmpty(item)); - if (!isValidSource) { - throw new TypeError('Patterns must be a string (non empty) or an array of strings'); - } -} -module.exports = FastGlob; + // get the location of the block on parent.nodes (block's siblings) + let parent = stack[stack.length - 1]; + let index = parent.nodes.indexOf(block); + // replace the (invalid) block with it's nodes + parent.nodes.splice(index, 1, ...block.nodes); + } + } while (stack.length > 0); + + push({ type: 'eos' }); + return ast; +}; + +module.exports = parse; /***/ }), -/* 294 */ +/* 306 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(295); -function generate(patterns, settings) { - const positivePatterns = getPositivePatterns(patterns); - const negativePatterns = getNegativePatternsAsPositive(patterns, settings.ignore); - const staticPatterns = positivePatterns.filter((pattern) => utils.pattern.isStaticPattern(pattern, settings)); - const dynamicPatterns = positivePatterns.filter((pattern) => utils.pattern.isDynamicPattern(pattern, settings)); - const staticTasks = convertPatternsToTasks(staticPatterns, negativePatterns, /* dynamic */ false); - const dynamicTasks = convertPatternsToTasks(dynamicPatterns, negativePatterns, /* dynamic */ true); - return staticTasks.concat(dynamicTasks); -} -exports.generate = generate; -function convertPatternsToTasks(positive, negative, dynamic) { - const positivePatternsGroup = groupPatternsByBaseDirectory(positive); - // When we have a global group – there is no reason to divide the patterns into independent tasks. - // In this case, the global task covers the rest. - if ('.' in positivePatternsGroup) { - const task = convertPatternGroupToTask('.', positive, negative, dynamic); - return [task]; - } - return convertPatternGroupsToTasks(positivePatternsGroup, negative, dynamic); -} -exports.convertPatternsToTasks = convertPatternsToTasks; -function getPositivePatterns(patterns) { - return utils.pattern.getPositivePatterns(patterns); -} -exports.getPositivePatterns = getPositivePatterns; -function getNegativePatternsAsPositive(patterns, ignore) { - const negative = utils.pattern.getNegativePatterns(patterns).concat(ignore); - const positive = negative.map(utils.pattern.convertToPositivePattern); - return positive; -} -exports.getNegativePatternsAsPositive = getNegativePatternsAsPositive; -function groupPatternsByBaseDirectory(patterns) { - const group = {}; - return patterns.reduce((collection, pattern) => { - const base = utils.pattern.getBaseDirectory(pattern); - if (base in collection) { - collection[base].push(pattern); - } - else { - collection[base] = [pattern]; - } - return collection; - }, group); -} -exports.groupPatternsByBaseDirectory = groupPatternsByBaseDirectory; -function convertPatternGroupsToTasks(positive, negative, dynamic) { - return Object.keys(positive).map((base) => { - return convertPatternGroupToTask(base, positive[base], negative, dynamic); - }); -} -exports.convertPatternGroupsToTasks = convertPatternGroupsToTasks; -function convertPatternGroupToTask(base, positive, negative, dynamic) { - return { - dynamic, - positive, - negative, - base, - patterns: [].concat(positive, negative.map(utils.pattern.convertToNegativePattern)) - }; -} -exports.convertPatternGroupToTask = convertPatternGroupToTask; -/***/ }), -/* 295 */ -/***/ (function(module, exports, __webpack_require__) { +module.exports = { + MAX_LENGTH: 1024 * 64, -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const array = __webpack_require__(296); -exports.array = array; -const errno = __webpack_require__(297); -exports.errno = errno; -const fs = __webpack_require__(298); -exports.fs = fs; -const path = __webpack_require__(299); -exports.path = path; -const pattern = __webpack_require__(300); -exports.pattern = pattern; -const stream = __webpack_require__(321); -exports.stream = stream; -const string = __webpack_require__(322); -exports.string = string; + // Digits + CHAR_0: '0', /* 0 */ + CHAR_9: '9', /* 9 */ + + // Alphabet chars. + CHAR_UPPERCASE_A: 'A', /* A */ + CHAR_LOWERCASE_A: 'a', /* a */ + CHAR_UPPERCASE_Z: 'Z', /* Z */ + CHAR_LOWERCASE_Z: 'z', /* z */ + CHAR_LEFT_PARENTHESES: '(', /* ( */ + CHAR_RIGHT_PARENTHESES: ')', /* ) */ -/***/ }), -/* 296 */ -/***/ (function(module, exports, __webpack_require__) { + CHAR_ASTERISK: '*', /* * */ -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -function flatten(items) { - return items.reduce((collection, item) => [].concat(collection, item), []); -} -exports.flatten = flatten; -function splitWhen(items, predicate) { - const result = [[]]; - let groupIndex = 0; - for (const item of items) { - if (predicate(item)) { - groupIndex++; - result[groupIndex] = []; - } - else { - result[groupIndex].push(item); - } - } - return result; -} -exports.splitWhen = splitWhen; + // Non-alphabetic chars. + CHAR_AMPERSAND: '&', /* & */ + CHAR_AT: '@', /* @ */ + CHAR_BACKSLASH: '\\', /* \ */ + CHAR_BACKTICK: '`', /* ` */ + CHAR_CARRIAGE_RETURN: '\r', /* \r */ + CHAR_CIRCUMFLEX_ACCENT: '^', /* ^ */ + CHAR_COLON: ':', /* : */ + CHAR_COMMA: ',', /* , */ + CHAR_DOLLAR: '$', /* . */ + CHAR_DOT: '.', /* . */ + CHAR_DOUBLE_QUOTE: '"', /* " */ + CHAR_EQUAL: '=', /* = */ + CHAR_EXCLAMATION_MARK: '!', /* ! */ + CHAR_FORM_FEED: '\f', /* \f */ + CHAR_FORWARD_SLASH: '/', /* / */ + CHAR_HASH: '#', /* # */ + CHAR_HYPHEN_MINUS: '-', /* - */ + CHAR_LEFT_ANGLE_BRACKET: '<', /* < */ + CHAR_LEFT_CURLY_BRACE: '{', /* { */ + CHAR_LEFT_SQUARE_BRACKET: '[', /* [ */ + CHAR_LINE_FEED: '\n', /* \n */ + CHAR_NO_BREAK_SPACE: '\u00A0', /* \u00A0 */ + CHAR_PERCENT: '%', /* % */ + CHAR_PLUS: '+', /* + */ + CHAR_QUESTION_MARK: '?', /* ? */ + CHAR_RIGHT_ANGLE_BRACKET: '>', /* > */ + CHAR_RIGHT_CURLY_BRACE: '}', /* } */ + CHAR_RIGHT_SQUARE_BRACKET: ']', /* ] */ + CHAR_SEMICOLON: ';', /* ; */ + CHAR_SINGLE_QUOTE: '\'', /* ' */ + CHAR_SPACE: ' ', /* */ + CHAR_TAB: '\t', /* \t */ + CHAR_UNDERSCORE: '_', /* _ */ + CHAR_VERTICAL_LINE: '|', /* | */ + CHAR_ZERO_WIDTH_NOBREAK_SPACE: '\uFEFF' /* \uFEFF */ +}; /***/ }), -/* 297 */ +/* 307 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -function isEnoentCodeError(error) { - return error.code === 'ENOENT'; -} -exports.isEnoentCodeError = isEnoentCodeError; + + +module.exports = __webpack_require__(308); /***/ }), -/* 298 */ +/* 308 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -class DirentFromStats { - constructor(name, stats) { - this.name = name; - this.isBlockDevice = stats.isBlockDevice.bind(stats); - this.isCharacterDevice = stats.isCharacterDevice.bind(stats); - this.isDirectory = stats.isDirectory.bind(stats); - this.isFIFO = stats.isFIFO.bind(stats); - this.isFile = stats.isFile.bind(stats); - this.isSocket = stats.isSocket.bind(stats); - this.isSymbolicLink = stats.isSymbolicLink.bind(stats); - } -} -function createDirentFromStats(name, stats) { - return new DirentFromStats(name, stats); -} -exports.createDirentFromStats = createDirentFromStats; -/***/ }), -/* 299 */ -/***/ (function(module, exports, __webpack_require__) { +const path = __webpack_require__(4); +const scan = __webpack_require__(309); +const parse = __webpack_require__(312); +const utils = __webpack_require__(310); +const constants = __webpack_require__(311); +const isObject = val => val && typeof val === 'object' && !Array.isArray(val); -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const path = __webpack_require__(4); -const LEADING_DOT_SEGMENT_CHARACTERS_COUNT = 2; // ./ or .\\ -const UNESCAPED_GLOB_SYMBOLS_RE = /(\\?)([()*?[\]{|}]|^!|[!+@](?=\())/g; -/** - * Designed to work only with simple paths: `dir\\file`. - */ -function unixify(filepath) { - return filepath.replace(/\\/g, '/'); -} -exports.unixify = unixify; -function makeAbsolute(cwd, filepath) { - return path.resolve(cwd, filepath); -} -exports.makeAbsolute = makeAbsolute; -function escape(pattern) { - return pattern.replace(UNESCAPED_GLOB_SYMBOLS_RE, '\\$2'); -} -exports.escape = escape; -function removeLeadingDotSegment(entry) { - // We do not use `startsWith` because this is 10x slower than current implementation for some cases. - // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with - if (entry.charAt(0) === '.') { - const secondCharactery = entry.charAt(1); - if (secondCharactery === '/' || secondCharactery === '\\') { - return entry.slice(LEADING_DOT_SEGMENT_CHARACTERS_COUNT); - } - } - return entry; -} -exports.removeLeadingDotSegment = removeLeadingDotSegment; +/** + * Creates a matcher function from one or more glob patterns. The + * returned function takes a string to match as its first argument, + * and returns true if the string is a match. The returned matcher + * function also takes a boolean as the second argument that, when true, + * returns an object with additional information. + * + * ```js + * const picomatch = require('picomatch'); + * // picomatch(glob[, options]); + * + * const isMatch = picomatch('*.!(*a)'); + * console.log(isMatch('a.a')); //=> false + * console.log(isMatch('a.b')); //=> true + * ``` + * @name picomatch + * @param {String|Array} `globs` One or more glob patterns. + * @param {Object=} `options` + * @return {Function=} Returns a matcher function. + * @api public + */ +const picomatch = (glob, options, returnState = false) => { + if (Array.isArray(glob)) { + const fns = glob.map(input => picomatch(input, options, returnState)); + const arrayMatcher = str => { + for (const isMatch of fns) { + const state = isMatch(str); + if (state) return state; + } + return false; + }; + return arrayMatcher; + } -/***/ }), -/* 300 */ -/***/ (function(module, exports, __webpack_require__) { + const isState = isObject(glob) && glob.tokens && glob.input; -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const path = __webpack_require__(4); -const globParent = __webpack_require__(301); -const micromatch = __webpack_require__(304); -const picomatch = __webpack_require__(315); -const GLOBSTAR = '**'; -const ESCAPE_SYMBOL = '\\'; -const COMMON_GLOB_SYMBOLS_RE = /[*?]|^!/; -const REGEX_CHARACTER_CLASS_SYMBOLS_RE = /\[.*]/; -const REGEX_GROUP_SYMBOLS_RE = /(?:^|[^!*+?@])\(.*\|.*\)/; -const GLOB_EXTENSION_SYMBOLS_RE = /[!*+?@]\(.*\)/; -const BRACE_EXPANSIONS_SYMBOLS_RE = /{.*(?:,|\.\.).*}/; -function isStaticPattern(pattern, options = {}) { - return !isDynamicPattern(pattern, options); -} -exports.isStaticPattern = isStaticPattern; -function isDynamicPattern(pattern, options = {}) { - /** - * When the `caseSensitiveMatch` option is disabled, all patterns must be marked as dynamic, because we cannot check - * filepath directly (without read directory). - */ - if (options.caseSensitiveMatch === false || pattern.includes(ESCAPE_SYMBOL)) { - return true; - } - if (COMMON_GLOB_SYMBOLS_RE.test(pattern) || REGEX_CHARACTER_CLASS_SYMBOLS_RE.test(pattern) || REGEX_GROUP_SYMBOLS_RE.test(pattern)) { - return true; - } - if (options.extglob !== false && GLOB_EXTENSION_SYMBOLS_RE.test(pattern)) { - return true; - } - if (options.braceExpansion !== false && BRACE_EXPANSIONS_SYMBOLS_RE.test(pattern)) { - return true; - } - return false; -} -exports.isDynamicPattern = isDynamicPattern; -function convertToPositivePattern(pattern) { - return isNegativePattern(pattern) ? pattern.slice(1) : pattern; -} -exports.convertToPositivePattern = convertToPositivePattern; -function convertToNegativePattern(pattern) { - return '!' + pattern; -} -exports.convertToNegativePattern = convertToNegativePattern; -function isNegativePattern(pattern) { - return pattern.startsWith('!') && pattern[1] !== '('; -} -exports.isNegativePattern = isNegativePattern; -function isPositivePattern(pattern) { - return !isNegativePattern(pattern); -} -exports.isPositivePattern = isPositivePattern; -function getNegativePatterns(patterns) { - return patterns.filter(isNegativePattern); -} -exports.getNegativePatterns = getNegativePatterns; -function getPositivePatterns(patterns) { - return patterns.filter(isPositivePattern); -} -exports.getPositivePatterns = getPositivePatterns; -function getBaseDirectory(pattern) { - return globParent(pattern, { flipBackslashes: false }); -} -exports.getBaseDirectory = getBaseDirectory; -function hasGlobStar(pattern) { - return pattern.includes(GLOBSTAR); -} -exports.hasGlobStar = hasGlobStar; -function endsWithSlashGlobStar(pattern) { - return pattern.endsWith('/' + GLOBSTAR); -} -exports.endsWithSlashGlobStar = endsWithSlashGlobStar; -function isAffectDepthOfReadingPattern(pattern) { - const basename = path.basename(pattern); - return endsWithSlashGlobStar(pattern) || isStaticPattern(basename); -} -exports.isAffectDepthOfReadingPattern = isAffectDepthOfReadingPattern; -function expandPatternsWithBraceExpansion(patterns) { - return patterns.reduce((collection, pattern) => { - return collection.concat(expandBraceExpansion(pattern)); - }, []); -} -exports.expandPatternsWithBraceExpansion = expandPatternsWithBraceExpansion; -function expandBraceExpansion(pattern) { - return micromatch.braces(pattern, { - expand: true, - nodupes: true - }); -} -exports.expandBraceExpansion = expandBraceExpansion; -function getPatternParts(pattern, options) { - const info = picomatch.scan(pattern, Object.assign(Object.assign({}, options), { parts: true })); - // See micromatch/picomatch#58 for more details - if (info.parts.length === 0) { - return [pattern]; - } - return info.parts; -} -exports.getPatternParts = getPatternParts; -function makeRe(pattern, options) { - return micromatch.makeRe(pattern, options); -} -exports.makeRe = makeRe; -function convertPatternsToRe(patterns, options) { - return patterns.map((pattern) => makeRe(pattern, options)); -} -exports.convertPatternsToRe = convertPatternsToRe; -function matchAny(entry, patternsRe) { - return patternsRe.some((patternRe) => patternRe.test(entry)); -} -exports.matchAny = matchAny; - - -/***/ }), -/* 301 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var isGlob = __webpack_require__(302); -var pathPosixDirname = __webpack_require__(4).posix.dirname; -var isWin32 = __webpack_require__(120).platform() === 'win32'; - -var slash = '/'; -var backslash = /\\/g; -var enclosure = /[\{\[].*[\/]*.*[\}\]]$/; -var globby = /(^|[^\\])([\{\[]|\([^\)]+$)/; -var escaped = /\\([\!\*\?\|\[\]\(\)\{\}])/g; - -/** - * @param {string} str - * @param {Object} opts - * @param {boolean} [opts.flipBackslashes=true] - */ -module.exports = function globParent(str, opts) { - var options = Object.assign({ flipBackslashes: true }, opts); - - // flip windows path separators - if (options.flipBackslashes && isWin32 && str.indexOf(slash) < 0) { - str = str.replace(backslash, slash); - } - - // special case for strings ending in enclosure containing path separator - if (enclosure.test(str)) { - str += slash; + if (glob === '' || (typeof glob !== 'string' && !isState)) { + throw new TypeError('Expected pattern to be a non-empty string'); } - // preserves full path in case of trailing path separator - str += 'a'; - - // remove path parts that are globby - do { - str = pathPosixDirname(str); - } while (isGlob(str) || globby.test(str)); - - // remove escape chars and return result - return str.replace(escaped, '$1'); -}; - - -/***/ }), -/* 302 */ -/***/ (function(module, exports, __webpack_require__) { - -/*! - * is-glob - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ - -var isExtglob = __webpack_require__(303); -var chars = { '{': '}', '(': ')', '[': ']'}; -var strictRegex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; -var relaxedRegex = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; + const opts = options || {}; + const posix = utils.isWindows(options); + const regex = isState + ? picomatch.compileRe(glob, options) + : picomatch.makeRe(glob, options, false, true); -module.exports = function isGlob(str, options) { - if (typeof str !== 'string' || str === '') { - return false; - } + const state = regex.state; + delete regex.state; - if (isExtglob(str)) { - return true; + let isIgnored = () => false; + if (opts.ignore) { + const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null }; + isIgnored = picomatch(opts.ignore, ignoreOpts, returnState); } - var regex = strictRegex; - var match; + const matcher = (input, returnObject = false) => { + const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix }); + const result = { glob, state, regex, posix, input, output, match, isMatch }; - // optionally relax regex - if (options && options.strict === false) { - regex = relaxedRegex; - } + if (typeof opts.onResult === 'function') { + opts.onResult(result); + } - while ((match = regex.exec(str))) { - if (match[2]) return true; - var idx = match.index + match[0].length; + if (isMatch === false) { + result.isMatch = false; + return returnObject ? result : false; + } - // if an open bracket/brace/paren is escaped, - // set the index to the next closing character - var open = match[1]; - var close = open ? chars[open] : null; - if (open && close) { - var n = str.indexOf(close, idx); - if (n !== -1) { - idx = n + 1; + if (isIgnored(input)) { + if (typeof opts.onIgnore === 'function') { + opts.onIgnore(result); } + result.isMatch = false; + return returnObject ? result : false; } - str = str.slice(idx); - } - return false; -}; - - -/***/ }), -/* 303 */ -/***/ (function(module, exports) { - -/*! - * is-extglob - * - * Copyright (c) 2014-2016, Jon Schlinkert. - * Licensed under the MIT License. - */ - -module.exports = function isExtglob(str) { - if (typeof str !== 'string' || str === '') { - return false; - } + if (typeof opts.onMatch === 'function') { + opts.onMatch(result); + } + return returnObject ? result : true; + }; - var match; - while ((match = /(\\).|([@?!+*]\(.*\))/g.exec(str))) { - if (match[2]) return true; - str = str.slice(match.index + match[0].length); + if (returnState) { + matcher.state = state; } - return false; + return matcher; }; - -/***/ }), -/* 304 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -const util = __webpack_require__(111); -const braces = __webpack_require__(305); -const picomatch = __webpack_require__(315); -const utils = __webpack_require__(318); -const isEmptyString = val => typeof val === 'string' && (val === '' || val === './'); - /** - * Returns an array of strings that match one or more glob patterns. + * Test `input` with the given `regex`. This is used by the main + * `picomatch()` function to test the input string. * * ```js - * const mm = require('micromatch'); - * // mm(list, patterns[, options]); + * const picomatch = require('picomatch'); + * // picomatch.test(input, regex[, options]); * - * console.log(mm(['a.js', 'a.txt'], ['*.js'])); - * //=> [ 'a.js' ] + * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/)); + * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' } * ``` - * @param {String|Array} list List of strings to match. - * @param {String|Array} patterns One or more glob patterns to use for matching. - * @param {Object} options See available [options](#options) - * @return {Array} Returns an array of matches - * @summary false + * @param {String} `input` String to test. + * @param {RegExp} `regex` + * @return {Object} Returns an object with matching info. * @api public */ -const micromatch = (list, patterns, options) => { - patterns = [].concat(patterns); - list = [].concat(list); - - let omit = new Set(); - let keep = new Set(); - let items = new Set(); - let negatives = 0; - - let onResult = state => { - items.add(state.output); - if (options && options.onResult) { - options.onResult(state); - } - }; - - for (let i = 0; i < patterns.length; i++) { - let isMatch = picomatch(String(patterns[i]), { ...options, onResult }, true); - let negated = isMatch.state.negated || isMatch.state.negatedExtglob; - if (negated) negatives++; - - for (let item of list) { - let matched = isMatch(item, true); - - let match = negated ? !matched.isMatch : matched.isMatch; - if (!match) continue; +picomatch.test = (input, regex, options, { glob, posix } = {}) => { + if (typeof input !== 'string') { + throw new TypeError('Expected input to be a string'); + } - if (negated) { - omit.add(matched.output); - } else { - omit.delete(matched.output); - keep.add(matched.output); - } - } + if (input === '') { + return { isMatch: false, output: '' }; } - let result = negatives === patterns.length ? [...items] : [...keep]; - let matches = result.filter(item => !omit.has(item)); + const opts = options || {}; + const format = opts.format || (posix ? utils.toPosixSlashes : null); + let match = input === glob; + let output = (match && format) ? format(input) : input; - if (options && matches.length === 0) { - if (options.failglob === true) { - throw new Error(`No matches found for "${patterns.join(', ')}"`); - } + if (match === false) { + output = format ? format(input) : input; + match = output === glob; + } - if (options.nonull === true || options.nullglob === true) { - return options.unescape ? patterns.map(p => p.replace(/\\/g, '')) : patterns; + if (match === false || opts.capture === true) { + if (opts.matchBase === true || opts.basename === true) { + match = picomatch.matchBase(input, regex, options, posix); + } else { + match = regex.exec(output); } } - return matches; + return { isMatch: Boolean(match), match, output }; }; /** - * Backwards compatibility - */ - -micromatch.match = micromatch; - -/** - * Returns a matcher function from the given glob `pattern` and `options`. - * The returned function takes a string to match as its only argument and returns - * true if the string is a match. + * Match the basename of a filepath. * * ```js - * const mm = require('micromatch'); - * // mm.matcher(pattern[, options]); - * - * const isMatch = mm.matcher('*.!(*a)'); - * console.log(isMatch('a.a')); //=> false - * console.log(isMatch('a.b')); //=> true + * const picomatch = require('picomatch'); + * // picomatch.matchBase(input, glob[, options]); + * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true * ``` - * @param {String} `pattern` Glob pattern - * @param {Object} `options` - * @return {Function} Returns a matcher function. + * @param {String} `input` String to test. + * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe). + * @return {Boolean} * @api public */ -micromatch.matcher = (pattern, options) => picomatch(pattern, options); +picomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => { + const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options); + return regex.test(path.basename(input)); +}; /** * Returns true if **any** of the given glob `patterns` match the specified `string`. * * ```js - * const mm = require('micromatch'); - * // mm.isMatch(string, patterns[, options]); + * const picomatch = require('picomatch'); + * // picomatch.isMatch(string, patterns[, options]); * - * console.log(mm.isMatch('a.a', ['b.*', '*.a'])); //=> true - * console.log(mm.isMatch('a.a', 'b.*')); //=> false + * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true + * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false * ``` - * @param {String} str The string to test. + * @param {String|Array} str The string to test. * @param {String|Array} patterns One or more glob patterns to use for matching. * @param {Object} [options] See available [options](#options). * @return {Boolean} Returns true if any patterns match `str` * @api public */ -micromatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); +picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); /** - * Backwards compatibility + * Parse a glob pattern to create the source string for a regular + * expression. + * + * ```js + * const picomatch = require('picomatch'); + * const result = picomatch.parse(pattern[, options]); + * ``` + * @param {String} `pattern` + * @param {Object} `options` + * @return {Object} Returns an object with useful properties and output to be used as a regex source string. + * @api public */ -micromatch.any = micromatch.isMatch; +picomatch.parse = (pattern, options) => { + if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options)); + return parse(pattern, { ...options, fastpaths: false }); +}; /** - * Returns a list of strings that _**do not match any**_ of the given `patterns`. + * Scan a glob pattern to separate the pattern into segments. * * ```js - * const mm = require('micromatch'); - * // mm.not(list, patterns[, options]); + * const picomatch = require('picomatch'); + * // picomatch.scan(input[, options]); * - * console.log(mm.not(['a.a', 'b.b', 'c.c'], '*.a')); - * //=> ['b.b', 'c.c'] + * const result = picomatch.scan('!./foo/*.js'); + * console.log(result); + * { prefix: '!./', + * input: '!./foo/*.js', + * start: 3, + * base: 'foo', + * glob: '*.js', + * isBrace: false, + * isBracket: false, + * isGlob: true, + * isExtglob: false, + * isGlobstar: false, + * negated: true } * ``` - * @param {Array} `list` Array of strings to match. - * @param {String|Array} `patterns` One or more glob pattern to use for matching. - * @param {Object} `options` See available [options](#options) for changing how matches are performed - * @return {Array} Returns an array of strings that **do not match** the given patterns. + * @param {String} `input` Glob pattern to scan. + * @param {Object} `options` + * @return {Object} Returns an object with * @api public */ -micromatch.not = (list, patterns, options = {}) => { - patterns = [].concat(patterns).map(String); - let result = new Set(); - let items = []; - - let onResult = state => { - if (options.onResult) options.onResult(state); - items.push(state.output); - }; - - let matches = micromatch(list, patterns, { ...options, onResult }); - - for (let item of items) { - if (!matches.includes(item)) { - result.add(item); - } - } - return [...result]; -}; +picomatch.scan = (input, options) => scan(input, options); /** - * Returns true if the given `string` contains the given pattern. Similar - * to [.isMatch](#isMatch) but the pattern can match any part of the string. + * Create a regular expression from a parsed glob pattern. * * ```js - * var mm = require('micromatch'); - * // mm.contains(string, pattern[, options]); + * const picomatch = require('picomatch'); + * const state = picomatch.parse('*.js'); + * // picomatch.compileRe(state[, options]); * - * console.log(mm.contains('aa/bb/cc', '*b')); - * //=> true - * console.log(mm.contains('aa/bb/cc', '*d')); - * //=> false + * console.log(picomatch.compileRe(state)); + * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ * ``` - * @param {String} `str` The string to match. - * @param {String|Array} `patterns` Glob pattern to use for matching. - * @param {Object} `options` See available [options](#options) for changing how matches are performed - * @return {Boolean} Returns true if the patter matches any part of `str`. + * @param {String} `state` The object returned from the `.parse` method. + * @param {Object} `options` + * @return {RegExp} Returns a regex created from the given pattern. * @api public */ -micromatch.contains = (str, pattern, options) => { - if (typeof str !== 'string') { - throw new TypeError(`Expected a string: "${util.inspect(str)}"`); +picomatch.compileRe = (parsed, options, returnOutput = false, returnState = false) => { + if (returnOutput === true) { + return parsed.output; } - if (Array.isArray(pattern)) { - return pattern.some(p => micromatch.contains(str, p, options)); + const opts = options || {}; + const prepend = opts.contains ? '' : '^'; + const append = opts.contains ? '' : '$'; + + let source = `${prepend}(?:${parsed.output})${append}`; + if (parsed && parsed.negated === true) { + source = `^(?!${source}).*$`; } - if (typeof pattern === 'string') { - if (isEmptyString(str) || isEmptyString(pattern)) { - return false; - } + const regex = picomatch.toRegex(source, options); + if (returnState === true) { + regex.state = parsed; + } - if (str.includes(pattern) || (str.startsWith('./') && str.slice(2).includes(pattern))) { - return true; - } + return regex; +}; + +picomatch.makeRe = (input, options, returnOutput = false, returnState = false) => { + if (!input || typeof input !== 'string') { + throw new TypeError('Expected a non-empty string'); } - return micromatch.isMatch(str, pattern, { ...options, contains: true }); + const opts = options || {}; + let parsed = { negated: false, fastpaths: true }; + let prefix = ''; + let output; + + if (input.startsWith('./')) { + input = input.slice(2); + prefix = parsed.prefix = './'; + } + + if (opts.fastpaths !== false && (input[0] === '.' || input[0] === '*')) { + output = parse.fastpaths(input, options); + } + + if (output === undefined) { + parsed = parse(input, options); + parsed.prefix = prefix + (parsed.prefix || ''); + } else { + parsed.output = output; + } + + return picomatch.compileRe(parsed, options, returnOutput, returnState); }; /** - * Filter the keys of the given object with the given `glob` pattern - * and `options`. Does not attempt to match nested keys. If you need this feature, - * use [glob-object][] instead. + * Create a regular expression from the given regex source string. * * ```js - * const mm = require('micromatch'); - * // mm.matchKeys(object, patterns[, options]); + * const picomatch = require('picomatch'); + * // picomatch.toRegex(source[, options]); * - * const obj = { aa: 'a', ab: 'b', ac: 'c' }; - * console.log(mm.matchKeys(obj, '*b')); - * //=> { ab: 'b' } + * const { output } = picomatch.parse('*.js'); + * console.log(picomatch.toRegex(output)); + * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ * ``` - * @param {Object} `object` The object with keys to filter. - * @param {String|Array} `patterns` One or more glob patterns to use for matching. - * @param {Object} `options` See available [options](#options) for changing how matches are performed - * @return {Object} Returns an object with only keys that match the given patterns. + * @param {String} `source` Regular expression source string. + * @param {Object} `options` + * @return {RegExp} * @api public */ -micromatch.matchKeys = (obj, patterns, options) => { - if (!utils.isObject(obj)) { - throw new TypeError('Expected the first argument to be an object'); +picomatch.toRegex = (source, options) => { + try { + const opts = options || {}; + return new RegExp(source, opts.flags || (opts.nocase ? 'i' : '')); + } catch (err) { + if (options && options.debug === true) throw err; + return /$^/; } - let keys = micromatch(Object.keys(obj), patterns, options); - let res = {}; - for (let key of keys) res[key] = obj[key]; - return res; }; /** - * Returns true if some of the strings in the given `list` match any of the given glob `patterns`. - * - * ```js - * const mm = require('micromatch'); - * // mm.some(list, patterns[, options]); - * - * console.log(mm.some(['foo.js', 'bar.js'], ['*.js', '!foo.js'])); - * // true - * console.log(mm.some(['foo.js'], ['*.js', '!foo.js'])); - * // false - * ``` - * @param {String|Array} `list` The string or array of strings to test. Returns as soon as the first match is found. - * @param {String|Array} `patterns` One or more glob patterns to use for matching. - * @param {Object} `options` See available [options](#options) for changing how matches are performed - * @return {Boolean} Returns true if any patterns match `str` - * @api public + * Picomatch constants. + * @return {Object} */ -micromatch.some = (list, patterns, options) => { - let items = [].concat(list); - - for (let pattern of [].concat(patterns)) { - let isMatch = picomatch(String(pattern), options); - if (items.some(item => isMatch(item))) { - return true; - } - } - return false; -}; +picomatch.constants = constants; /** - * Returns true if every string in the given `list` matches - * any of the given glob `patterns`. - * - * ```js - * const mm = require('micromatch'); - * // mm.every(list, patterns[, options]); - * - * console.log(mm.every('foo.js', ['foo.js'])); - * // true - * console.log(mm.every(['foo.js', 'bar.js'], ['*.js'])); - * // true - * console.log(mm.every(['foo.js', 'bar.js'], ['*.js', '!foo.js'])); - * // false - * console.log(mm.every(['foo.js'], ['*.js', '!foo.js'])); - * // false - * ``` - * @param {String|Array} `list` The string or array of strings to test. - * @param {String|Array} `patterns` One or more glob patterns to use for matching. - * @param {Object} `options` See available [options](#options) for changing how matches are performed - * @return {Boolean} Returns true if any patterns match `str` - * @api public + * Expose "picomatch" */ -micromatch.every = (list, patterns, options) => { - let items = [].concat(list); +module.exports = picomatch; - for (let pattern of [].concat(patterns)) { - let isMatch = picomatch(String(pattern), options); - if (!items.every(item => isMatch(item))) { - return false; - } - } - return true; -}; -/** - * Returns true if **all** of the given `patterns` match - * the specified string. - * - * ```js - * const mm = require('micromatch'); - * // mm.all(string, patterns[, options]); - * - * console.log(mm.all('foo.js', ['foo.js'])); - * // true - * - * console.log(mm.all('foo.js', ['*.js', '!foo.js'])); - * // false - * - * console.log(mm.all('foo.js', ['*.js', 'foo.js'])); - * // true - * - * console.log(mm.all('foo.js', ['*.js', 'f*', '*o*', '*o.js'])); - * // true - * ``` - * @param {String|Array} `str` The string to test. - * @param {String|Array} `patterns` One or more glob patterns to use for matching. - * @param {Object} `options` See available [options](#options) for changing how matches are performed - * @return {Boolean} Returns true if any patterns match `str` - * @api public - */ +/***/ }), +/* 309 */ +/***/ (function(module, exports, __webpack_require__) { -micromatch.all = (str, patterns, options) => { - if (typeof str !== 'string') { - throw new TypeError(`Expected a string: "${util.inspect(str)}"`); - } +"use strict"; - return [].concat(patterns).every(p => picomatch(p, options)(str)); -}; -/** - * Returns an array of matches captured by `pattern` in `string, or `null` if the pattern did not match. - * - * ```js - * const mm = require('micromatch'); - * // mm.capture(pattern, string[, options]); - * - * console.log(mm.capture('test/*.js', 'test/foo.js')); - * //=> ['foo'] - * console.log(mm.capture('test/*.js', 'foo/bar.css')); - * //=> null - * ``` - * @param {String} `glob` Glob pattern to use for matching. - * @param {String} `input` String to match - * @param {Object} `options` See available [options](#options) for changing how matches are performed - * @return {Boolean} Returns an array of captures if the input matches the glob pattern, otherwise `null`. - * @api public - */ +const utils = __webpack_require__(310); +const { + CHAR_ASTERISK, /* * */ + CHAR_AT, /* @ */ + CHAR_BACKWARD_SLASH, /* \ */ + CHAR_COMMA, /* , */ + CHAR_DOT, /* . */ + CHAR_EXCLAMATION_MARK, /* ! */ + CHAR_FORWARD_SLASH, /* / */ + CHAR_LEFT_CURLY_BRACE, /* { */ + CHAR_LEFT_PARENTHESES, /* ( */ + CHAR_LEFT_SQUARE_BRACKET, /* [ */ + CHAR_PLUS, /* + */ + CHAR_QUESTION_MARK, /* ? */ + CHAR_RIGHT_CURLY_BRACE, /* } */ + CHAR_RIGHT_PARENTHESES, /* ) */ + CHAR_RIGHT_SQUARE_BRACKET /* ] */ +} = __webpack_require__(311); -micromatch.capture = (glob, input, options) => { - let posix = utils.isWindows(options); - let regex = picomatch.makeRe(String(glob), { ...options, capture: true }); - let match = regex.exec(posix ? utils.toPosixSlashes(input) : input); +const isPathSeparator = code => { + return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; +}; - if (match) { - return match.slice(1).map(v => v === void 0 ? '' : v); +const depth = token => { + if (token.isPrefix !== true) { + token.depth = token.isGlobstar ? Infinity : 1; } }; /** - * Create a regular expression from the given glob `pattern`. + * Quickly scans a glob pattern and returns an object with a handful of + * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists), + * `glob` (the actual pattern), and `negated` (true if the path starts with `!`). * * ```js - * const mm = require('micromatch'); - * // mm.makeRe(pattern[, options]); - * - * console.log(mm.makeRe('*.js')); - * //=> /^(?:(\.[\\\/])?(?!\.)(?=.)[^\/]*?\.js)$/ + * const pm = require('picomatch'); + * console.log(pm.scan('foo/bar/*.js')); + * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' } * ``` - * @param {String} `pattern` A glob pattern to convert to regex. + * @param {String} `str` * @param {Object} `options` - * @return {RegExp} Returns a regex created from the given pattern. + * @return {Object} Returns an object with tokens and regex source string. * @api public */ -micromatch.makeRe = (...args) => picomatch.makeRe(...args); +const scan = (input, options) => { + const opts = options || {}; -/** - * Scan a glob pattern to separate the pattern into segments. Used - * by the [split](#split) method. - * - * ```js - * const mm = require('micromatch'); - * const state = mm.scan(pattern[, options]); - * ``` - * @param {String} `pattern` - * @param {Object} `options` - * @return {Object} Returns an object with - * @api public - */ + const length = input.length - 1; + const scanToEnd = opts.parts === true || opts.scanToEnd === true; + const slashes = []; + const tokens = []; + const parts = []; -micromatch.scan = (...args) => picomatch.scan(...args); + let str = input; + let index = -1; + let start = 0; + let lastIndex = 0; + let isBrace = false; + let isBracket = false; + let isGlob = false; + let isExtglob = false; + let isGlobstar = false; + let braceEscaped = false; + let backslashes = false; + let negated = false; + let finished = false; + let braces = 0; + let prev; + let code; + let token = { value: '', depth: 0, isGlob: false }; -/** - * Parse a glob pattern to create the source string for a regular - * expression. - * - * ```js - * const mm = require('micromatch'); - * const state = mm(pattern[, options]); - * ``` - * @param {String} `glob` - * @param {Object} `options` - * @return {Object} Returns an object with useful properties and output to be used as regex source string. - * @api public - */ + const eos = () => index >= length; + const peek = () => str.charCodeAt(index + 1); + const advance = () => { + prev = code; + return str.charCodeAt(++index); + }; -micromatch.parse = (patterns, options) => { - let res = []; - for (let pattern of [].concat(patterns || [])) { - for (let str of braces(String(pattern), options)) { - res.push(picomatch.parse(str, options)); - } - } - return res; -}; + while (index < length) { + code = advance(); + let next; -/** - * Process the given brace `pattern`. - * - * ```js - * const { braces } = require('micromatch'); - * console.log(braces('foo/{a,b,c}/bar')); - * //=> [ 'foo/(a|b|c)/bar' ] - * - * console.log(braces('foo/{a,b,c}/bar', { expand: true })); - * //=> [ 'foo/a/bar', 'foo/b/bar', 'foo/c/bar' ] - * ``` - * @param {String} `pattern` String with brace pattern to process. - * @param {Object} `options` Any [options](#options) to change how expansion is performed. See the [braces][] library for all available options. - * @return {Array} - * @api public - */ + if (code === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + code = advance(); -micromatch.braces = (pattern, options) => { - if (typeof pattern !== 'string') throw new TypeError('Expected a string'); - if ((options && options.nobrace === true) || !/\{.*\}/.test(pattern)) { - return [pattern]; - } - return braces(pattern, options); -}; + if (code === CHAR_LEFT_CURLY_BRACE) { + braceEscaped = true; + } + continue; + } -/** - * Expand braces - */ + if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) { + braces++; -micromatch.braceExpand = (pattern, options) => { - if (typeof pattern !== 'string') throw new TypeError('Expected a string'); - return micromatch.braces(pattern, { ...options, expand: true }); -}; + while (eos() !== true && (code = advance())) { + if (code === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + advance(); + continue; + } -/** - * Expose micromatch - */ + if (code === CHAR_LEFT_CURLY_BRACE) { + braces++; + continue; + } -module.exports = micromatch; + if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) { + isBrace = token.isBrace = true; + isGlob = token.isGlob = true; + finished = true; + if (scanToEnd === true) { + continue; + } -/***/ }), -/* 305 */ -/***/ (function(module, exports, __webpack_require__) { + break; + } -"use strict"; + if (braceEscaped !== true && code === CHAR_COMMA) { + isBrace = token.isBrace = true; + isGlob = token.isGlob = true; + finished = true; + if (scanToEnd === true) { + continue; + } -const stringify = __webpack_require__(306); -const compile = __webpack_require__(308); -const expand = __webpack_require__(312); -const parse = __webpack_require__(313); + break; + } -/** - * Expand the given pattern or create a regex-compatible string. - * - * ```js - * const braces = require('braces'); - * console.log(braces('{a,b,c}', { compile: true })); //=> ['(a|b|c)'] - * console.log(braces('{a,b,c}')); //=> ['a', 'b', 'c'] - * ``` - * @param {String} `str` - * @param {Object} `options` - * @return {String} - * @api public - */ + if (code === CHAR_RIGHT_CURLY_BRACE) { + braces--; -const braces = (input, options = {}) => { - let output = []; + if (braces === 0) { + braceEscaped = false; + isBrace = token.isBrace = true; + finished = true; + break; + } + } + } - if (Array.isArray(input)) { - for (let pattern of input) { - let result = braces.create(pattern, options); - if (Array.isArray(result)) { - output.push(...result); - } else { - output.push(result); + if (scanToEnd === true) { + continue; } + + break; } - } else { - output = [].concat(braces.create(input, options)); - } - if (options && options.expand === true && options.nodupes === true) { - output = [...new Set(output)]; - } - return output; -}; + if (code === CHAR_FORWARD_SLASH) { + slashes.push(index); + tokens.push(token); + token = { value: '', depth: 0, isGlob: false }; -/** - * Parse the given `str` with the given `options`. - * - * ```js - * // braces.parse(pattern, [, options]); - * const ast = braces.parse('a/{b,c}/d'); - * console.log(ast); - * ``` - * @param {String} pattern Brace pattern to parse - * @param {Object} options - * @return {Object} Returns an AST - * @api public - */ + if (finished === true) continue; + if (prev === CHAR_DOT && index === (start + 1)) { + start += 2; + continue; + } -braces.parse = (input, options = {}) => parse(input, options); + lastIndex = index + 1; + continue; + } -/** - * Creates a braces string from an AST, or an AST node. - * - * ```js - * const braces = require('braces'); - * let ast = braces.parse('foo/{a,b}/bar'); - * console.log(stringify(ast.nodes[2])); //=> '{a,b}' - * ``` - * @param {String} `input` Brace pattern or AST. - * @param {Object} `options` - * @return {Array} Returns an array of expanded values. - * @api public - */ + if (opts.noext !== true) { + const isExtglobChar = code === CHAR_PLUS + || code === CHAR_AT + || code === CHAR_ASTERISK + || code === CHAR_QUESTION_MARK + || code === CHAR_EXCLAMATION_MARK; -braces.stringify = (input, options = {}) => { - if (typeof input === 'string') { - return stringify(braces.parse(input, options), options); - } - return stringify(input, options); -}; + if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) { + isGlob = token.isGlob = true; + isExtglob = token.isExtglob = true; + finished = true; -/** - * Compiles a brace pattern into a regex-compatible, optimized string. - * This method is called by the main [braces](#braces) function by default. - * - * ```js - * const braces = require('braces'); - * console.log(braces.compile('a/{b,c}/d')); - * //=> ['a/(b|c)/d'] - * ``` - * @param {String} `input` Brace pattern or AST. - * @param {Object} `options` - * @return {Array} Returns an array of expanded values. - * @api public - */ + if (scanToEnd === true) { + while (eos() !== true && (code = advance())) { + if (code === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + code = advance(); + continue; + } -braces.compile = (input, options = {}) => { - if (typeof input === 'string') { - input = braces.parse(input, options); - } - return compile(input, options); -}; + if (code === CHAR_RIGHT_PARENTHESES) { + isGlob = token.isGlob = true; + finished = true; + break; + } + } + continue; + } + break; + } + } -/** - * Expands a brace pattern into an array. This method is called by the - * main [braces](#braces) function when `options.expand` is true. Before - * using this method it's recommended that you read the [performance notes](#performance)) - * and advantages of using [.compile](#compile) instead. - * - * ```js - * const braces = require('braces'); - * console.log(braces.expand('a/{b,c}/d')); - * //=> ['a/b/d', 'a/c/d']; - * ``` - * @param {String} `pattern` Brace pattern - * @param {Object} `options` - * @return {Array} Returns an array of expanded values. - * @api public - */ + if (code === CHAR_ASTERISK) { + if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true; + isGlob = token.isGlob = true; + finished = true; -braces.expand = (input, options = {}) => { - if (typeof input === 'string') { - input = braces.parse(input, options); - } + if (scanToEnd === true) { + continue; + } + break; + } - let result = expand(input, options); + if (code === CHAR_QUESTION_MARK) { + isGlob = token.isGlob = true; + finished = true; - // filter out empty strings if specified - if (options.noempty === true) { - result = result.filter(Boolean); - } + if (scanToEnd === true) { + continue; + } + break; + } - // filter out duplicates if specified - if (options.nodupes === true) { - result = [...new Set(result)]; - } + if (code === CHAR_LEFT_SQUARE_BRACKET) { + while (eos() !== true && (next = advance())) { + if (next === CHAR_BACKWARD_SLASH) { + backslashes = token.backslashes = true; + advance(); + continue; + } - return result; -}; + if (next === CHAR_RIGHT_SQUARE_BRACKET) { + isBracket = token.isBracket = true; + isGlob = token.isGlob = true; + finished = true; -/** - * Processes a brace pattern and returns either an expanded array - * (if `options.expand` is true), a highly optimized regex-compatible string. - * This method is called by the main [braces](#braces) function. - * - * ```js - * const braces = require('braces'); - * console.log(braces.create('user-{200..300}/project-{a,b,c}-{1..10}')) - * //=> 'user-(20[0-9]|2[1-9][0-9]|300)/project-(a|b|c)-([1-9]|10)' - * ``` - * @param {String} `pattern` Brace pattern - * @param {Object} `options` - * @return {Array} Returns an array of expanded values. - * @api public - */ + if (scanToEnd === true) { + continue; + } + break; + } + } + } -braces.create = (input, options = {}) => { - if (input === '' || input.length < 3) { - return [input]; - } + if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) { + negated = token.negated = true; + start++; + continue; + } - return options.expand !== true - ? braces.compile(input, options) - : braces.expand(input, options); -}; + if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) { + isGlob = token.isGlob = true; -/** - * Expose "braces" - */ + if (scanToEnd === true) { + while (eos() !== true && (code = advance())) { + if (code === CHAR_LEFT_PARENTHESES) { + backslashes = token.backslashes = true; + code = advance(); + continue; + } -module.exports = braces; + if (code === CHAR_RIGHT_PARENTHESES) { + finished = true; + break; + } + } + continue; + } + break; + } + if (isGlob === true) { + finished = true; -/***/ }), -/* 306 */ -/***/ (function(module, exports, __webpack_require__) { + if (scanToEnd === true) { + continue; + } -"use strict"; + break; + } + } + if (opts.noext === true) { + isExtglob = false; + isGlob = false; + } -const utils = __webpack_require__(307); + let base = str; + let prefix = ''; + let glob = ''; -module.exports = (ast, options = {}) => { - let stringify = (node, parent = {}) => { - let invalidBlock = options.escapeInvalid && utils.isInvalidBrace(parent); - let invalidNode = node.invalid === true && options.escapeInvalid === true; - let output = ''; + if (start > 0) { + prefix = str.slice(0, start); + str = str.slice(start); + lastIndex -= start; + } - if (node.value) { - if ((invalidBlock || invalidNode) && utils.isOpenOrClose(node)) { - return '\\' + node.value; - } - return node.value; - } + if (base && isGlob === true && lastIndex > 0) { + base = str.slice(0, lastIndex); + glob = str.slice(lastIndex); + } else if (isGlob === true) { + base = ''; + glob = str; + } else { + base = str; + } - if (node.value) { - return node.value; + if (base && base !== '' && base !== '/' && base !== str) { + if (isPathSeparator(base.charCodeAt(base.length - 1))) { + base = base.slice(0, -1); } + } - if (node.nodes) { - for (let child of node.nodes) { - output += stringify(child); - } + if (opts.unescape === true) { + if (glob) glob = utils.removeBackslashes(glob); + + if (base && backslashes === true) { + base = utils.removeBackslashes(base); } - return output; - }; + } - return stringify(ast); -}; + const state = { + prefix, + input, + start, + base, + glob, + isBrace, + isBracket, + isGlob, + isExtglob, + isGlobstar, + negated + }; + if (opts.tokens === true) { + state.maxDepth = 0; + if (!isPathSeparator(code)) { + tokens.push(token); + } + state.tokens = tokens; + } + if (opts.parts === true || opts.tokens === true) { + let prevIndex; -/***/ }), -/* 307 */ -/***/ (function(module, exports, __webpack_require__) { + for (let idx = 0; idx < slashes.length; idx++) { + const n = prevIndex ? prevIndex + 1 : start; + const i = slashes[idx]; + const value = input.slice(n, i); + if (opts.tokens) { + if (idx === 0 && start !== 0) { + tokens[idx].isPrefix = true; + tokens[idx].value = prefix; + } else { + tokens[idx].value = value; + } + depth(tokens[idx]); + state.maxDepth += tokens[idx].depth; + } + if (idx !== 0 || value !== '') { + parts.push(value); + } + prevIndex = i; + } -"use strict"; + if (prevIndex && prevIndex + 1 < input.length) { + const value = input.slice(prevIndex + 1); + parts.push(value); + if (opts.tokens) { + tokens[tokens.length - 1].value = value; + depth(tokens[tokens.length - 1]); + state.maxDepth += tokens[tokens.length - 1].depth; + } + } -exports.isInteger = num => { - if (typeof num === 'number') { - return Number.isInteger(num); - } - if (typeof num === 'string' && num.trim() !== '') { - return Number.isInteger(Number(num)); + state.slashes = slashes; + state.parts = parts; } - return false; + + return state; }; -/** - * Find a node of the given type - */ +module.exports = scan; -exports.find = (node, type) => node.nodes.find(node => node.type === type); -/** - * Find a node of the given type - */ +/***/ }), +/* 310 */ +/***/ (function(module, exports, __webpack_require__) { -exports.exceedsLimit = (min, max, step = 1, limit) => { - if (limit === false) return false; - if (!exports.isInteger(min) || !exports.isInteger(max)) return false; - return ((Number(max) - Number(min)) / Number(step)) >= limit; -}; +"use strict"; -/** - * Escape the given node with '\\' before node.value - */ -exports.escapeNode = (block, n = 0, type) => { - let node = block.nodes[n]; - if (!node) return; +const path = __webpack_require__(4); +const win32 = process.platform === 'win32'; +const { + REGEX_BACKSLASH, + REGEX_REMOVE_BACKSLASH, + REGEX_SPECIAL_CHARS, + REGEX_SPECIAL_CHARS_GLOBAL +} = __webpack_require__(311); - if ((type && node.type === type) || node.type === 'open' || node.type === 'close') { - if (node.escaped !== true) { - node.value = '\\' + node.value; - node.escaped = true; - } - } -}; +exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); +exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); +exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str); +exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1'); +exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/'); -/** - * Returns true if the given brace node should be enclosed in literal braces - */ +exports.removeBackslashes = str => { + return str.replace(REGEX_REMOVE_BACKSLASH, match => { + return match === '\\' ? '' : match; + }); +}; -exports.encloseBrace = node => { - if (node.type !== 'brace') return false; - if ((node.commas >> 0 + node.ranges >> 0) === 0) { - node.invalid = true; +exports.supportsLookbehinds = () => { + const segs = process.version.slice(1).split('.').map(Number); + if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) { return true; } return false; }; -/** - * Returns true if a brace node is invalid. - */ - -exports.isInvalidBrace = block => { - if (block.type !== 'brace') return false; - if (block.invalid === true || block.dollar) return true; - if ((block.commas >> 0 + block.ranges >> 0) === 0) { - block.invalid = true; - return true; - } - if (block.open !== true || block.close !== true) { - block.invalid = true; - return true; +exports.isWindows = options => { + if (options && typeof options.windows === 'boolean') { + return options.windows; } - return false; + return win32 === true || path.sep === '\\'; }; -/** - * Returns true if a node is an open or close node - */ +exports.escapeLast = (input, char, lastIdx) => { + const idx = input.lastIndexOf(char, lastIdx); + if (idx === -1) return input; + if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1); + return `${input.slice(0, idx)}\\${input.slice(idx)}`; +}; -exports.isOpenOrClose = node => { - if (node.type === 'open' || node.type === 'close') { - return true; +exports.removePrefix = (input, state = {}) => { + let output = input; + if (output.startsWith('./')) { + output = output.slice(2); + state.prefix = './'; } - return node.open === true || node.close === true; + return output; }; -/** - * Reduce an array of text nodes. - */ - -exports.reduce = nodes => nodes.reduce((acc, node) => { - if (node.type === 'text') acc.push(node.value); - if (node.type === 'range') node.type = 'text'; - return acc; -}, []); - -/** - * Flatten an array - */ +exports.wrapOutput = (input, state = {}, options = {}) => { + const prepend = options.contains ? '' : '^'; + const append = options.contains ? '' : '$'; -exports.flatten = (...args) => { - const result = []; - const flat = arr => { - for (let i = 0; i < arr.length; i++) { - let ele = arr[i]; - Array.isArray(ele) ? flat(ele, result) : ele !== void 0 && result.push(ele); - } - return result; - }; - flat(args); - return result; + let output = `${prepend}(?:${input})${append}`; + if (state.negated === true) { + output = `(?:^(?!${output}).*$)`; + } + return output; }; /***/ }), -/* 308 */ +/* 311 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fill = __webpack_require__(309); -const utils = __webpack_require__(307); - -const compile = (ast, options = {}) => { - let walk = (node, parent = {}) => { - let invalidBlock = utils.isInvalidBrace(parent); - let invalidNode = node.invalid === true && options.escapeInvalid === true; - let invalid = invalidBlock === true || invalidNode === true; - let prefix = options.escapeInvalid === true ? '\\' : ''; - let output = ''; - - if (node.isOpen === true) { - return prefix + node.value; - } - if (node.isClose === true) { - return prefix + node.value; - } - - if (node.type === 'open') { - return invalid ? (prefix + node.value) : '('; - } - - if (node.type === 'close') { - return invalid ? (prefix + node.value) : ')'; - } - - if (node.type === 'comma') { - return node.prev.type === 'comma' ? '' : (invalid ? node.value : '|'); - } - - if (node.value) { - return node.value; - } - - if (node.nodes && node.ranges > 0) { - let args = utils.reduce(node.nodes); - let range = fill(...args, { ...options, wrap: false, toRegex: true }); +const path = __webpack_require__(4); +const WIN_SLASH = '\\\\/'; +const WIN_NO_SLASH = `[^${WIN_SLASH}]`; - if (range.length !== 0) { - return args.length > 1 && range.length > 1 ? `(${range})` : range; - } - } +/** + * Posix glob regex + */ - if (node.nodes) { - for (let child of node.nodes) { - output += walk(child, node); - } - } - return output; - }; +const DOT_LITERAL = '\\.'; +const PLUS_LITERAL = '\\+'; +const QMARK_LITERAL = '\\?'; +const SLASH_LITERAL = '\\/'; +const ONE_CHAR = '(?=.)'; +const QMARK = '[^/]'; +const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`; +const START_ANCHOR = `(?:^|${SLASH_LITERAL})`; +const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`; +const NO_DOT = `(?!${DOT_LITERAL})`; +const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`; +const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`; +const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`; +const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`; +const STAR = `${QMARK}*?`; - return walk(ast); +const POSIX_CHARS = { + DOT_LITERAL, + PLUS_LITERAL, + QMARK_LITERAL, + SLASH_LITERAL, + ONE_CHAR, + QMARK, + END_ANCHOR, + DOTS_SLASH, + NO_DOT, + NO_DOTS, + NO_DOT_SLASH, + NO_DOTS_SLASH, + QMARK_NO_DOT, + STAR, + START_ANCHOR }; -module.exports = compile; +/** + * Windows glob regex + */ +const WINDOWS_CHARS = { + ...POSIX_CHARS, -/***/ }), -/* 309 */ -/***/ (function(module, exports, __webpack_require__) { + SLASH_LITERAL: `[${WIN_SLASH}]`, + QMARK: WIN_NO_SLASH, + STAR: `${WIN_NO_SLASH}*?`, + DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`, + NO_DOT: `(?!${DOT_LITERAL})`, + NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, + NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`, + NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, + QMARK_NO_DOT: `[^.${WIN_SLASH}]`, + START_ANCHOR: `(?:^|[${WIN_SLASH}])`, + END_ANCHOR: `(?:[${WIN_SLASH}]|$)` +}; -"use strict"; -/*! - * fill-range - * - * Copyright (c) 2014-present, Jon Schlinkert. - * Licensed under the MIT License. +/** + * POSIX Bracket Regex */ +const POSIX_REGEX_SOURCE = { + alnum: 'a-zA-Z0-9', + alpha: 'a-zA-Z', + ascii: '\\x00-\\x7F', + blank: ' \\t', + cntrl: '\\x00-\\x1F\\x7F', + digit: '0-9', + graph: '\\x21-\\x7E', + lower: 'a-z', + print: '\\x20-\\x7E ', + punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~', + space: ' \\t\\r\\n\\v\\f', + upper: 'A-Z', + word: 'A-Za-z0-9_', + xdigit: 'A-Fa-f0-9' +}; +module.exports = { + MAX_LENGTH: 1024 * 64, + POSIX_REGEX_SOURCE, -const util = __webpack_require__(111); -const toRegexRange = __webpack_require__(310); + // regular expressions + REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g, + REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/, + REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/, + REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g, + REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g, + REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g, -const isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); + // Replace globs with equivalent patterns to reduce parsing time. + REPLACEMENTS: { + '***': '*', + '**/**': '**', + '**/**/**': '**' + }, -const transform = toNumber => { - return value => toNumber === true ? Number(value) : String(value); -}; + // Digits + CHAR_0: 48, /* 0 */ + CHAR_9: 57, /* 9 */ -const isValidValue = value => { - return typeof value === 'number' || (typeof value === 'string' && value !== ''); -}; + // Alphabet chars. + CHAR_UPPERCASE_A: 65, /* A */ + CHAR_LOWERCASE_A: 97, /* a */ + CHAR_UPPERCASE_Z: 90, /* Z */ + CHAR_LOWERCASE_Z: 122, /* z */ -const isNumber = num => Number.isInteger(+num); + CHAR_LEFT_PARENTHESES: 40, /* ( */ + CHAR_RIGHT_PARENTHESES: 41, /* ) */ -const zeros = input => { - let value = `${input}`; - let index = -1; - if (value[0] === '-') value = value.slice(1); - if (value === '0') return false; - while (value[++index] === '0'); - return index > 0; -}; + CHAR_ASTERISK: 42, /* * */ -const stringify = (start, end, options) => { - if (typeof start === 'string' || typeof end === 'string') { - return true; - } - return options.stringify === true; -}; + // Non-alphabetic chars. + CHAR_AMPERSAND: 38, /* & */ + CHAR_AT: 64, /* @ */ + CHAR_BACKWARD_SLASH: 92, /* \ */ + CHAR_CARRIAGE_RETURN: 13, /* \r */ + CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */ + CHAR_COLON: 58, /* : */ + CHAR_COMMA: 44, /* , */ + CHAR_DOT: 46, /* . */ + CHAR_DOUBLE_QUOTE: 34, /* " */ + CHAR_EQUAL: 61, /* = */ + CHAR_EXCLAMATION_MARK: 33, /* ! */ + CHAR_FORM_FEED: 12, /* \f */ + CHAR_FORWARD_SLASH: 47, /* / */ + CHAR_GRAVE_ACCENT: 96, /* ` */ + CHAR_HASH: 35, /* # */ + CHAR_HYPHEN_MINUS: 45, /* - */ + CHAR_LEFT_ANGLE_BRACKET: 60, /* < */ + CHAR_LEFT_CURLY_BRACE: 123, /* { */ + CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */ + CHAR_LINE_FEED: 10, /* \n */ + CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */ + CHAR_PERCENT: 37, /* % */ + CHAR_PLUS: 43, /* + */ + CHAR_QUESTION_MARK: 63, /* ? */ + CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */ + CHAR_RIGHT_CURLY_BRACE: 125, /* } */ + CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */ + CHAR_SEMICOLON: 59, /* ; */ + CHAR_SINGLE_QUOTE: 39, /* ' */ + CHAR_SPACE: 32, /* */ + CHAR_TAB: 9, /* \t */ + CHAR_UNDERSCORE: 95, /* _ */ + CHAR_VERTICAL_LINE: 124, /* | */ + CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */ -const pad = (input, maxLength, toNumber) => { - if (maxLength > 0) { - let dash = input[0] === '-' ? '-' : ''; - if (dash) input = input.slice(1); - input = (dash + input.padStart(dash ? maxLength - 1 : maxLength, '0')); - } - if (toNumber === false) { - return String(input); - } - return input; -}; + SEP: path.sep, -const toMaxLen = (input, maxLength) => { - let negative = input[0] === '-' ? '-' : ''; - if (negative) { - input = input.slice(1); - maxLength--; + /** + * Create EXTGLOB_CHARS + */ + + extglobChars(chars) { + return { + '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` }, + '?': { type: 'qmark', open: '(?:', close: ')?' }, + '+': { type: 'plus', open: '(?:', close: ')+' }, + '*': { type: 'star', open: '(?:', close: ')*' }, + '@': { type: 'at', open: '(?:', close: ')' } + }; + }, + + /** + * Create GLOB_CHARS + */ + + globChars(win32) { + return win32 === true ? WINDOWS_CHARS : POSIX_CHARS; } - while (input.length < maxLength) input = '0' + input; - return negative ? ('-' + input) : input; }; -const toSequence = (parts, options) => { - parts.negatives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); - parts.positives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); - let prefix = options.capture ? '' : '?:'; - let positives = ''; - let negatives = ''; - let result; +/***/ }), +/* 312 */ +/***/ (function(module, exports, __webpack_require__) { - if (parts.positives.length) { - positives = parts.positives.join('|'); - } +"use strict"; - if (parts.negatives.length) { - negatives = `-(${prefix}${parts.negatives.join('|')})`; - } - if (positives && negatives) { - result = `${positives}|${negatives}`; - } else { - result = positives || negatives; - } +const constants = __webpack_require__(311); +const utils = __webpack_require__(310); - if (options.wrap) { - return `(${prefix}${result})`; - } +/** + * Constants + */ - return result; -}; +const { + MAX_LENGTH, + POSIX_REGEX_SOURCE, + REGEX_NON_SPECIAL_CHARS, + REGEX_SPECIAL_CHARS_BACKREF, + REPLACEMENTS +} = constants; -const toRange = (a, b, isNumbers, options) => { - if (isNumbers) { - return toRegexRange(a, b, { wrap: false, ...options }); - } +/** + * Helpers + */ - let start = String.fromCharCode(a); - if (a === b) return start; +const expandRange = (args, options) => { + if (typeof options.expandRange === 'function') { + return options.expandRange(...args, options); + } - let stop = String.fromCharCode(b); - return `[${start}-${stop}]`; -}; + args.sort(); + const value = `[${args.join('-')}]`; -const toRegex = (start, end, options) => { - if (Array.isArray(start)) { - let wrap = options.wrap === true; - let prefix = options.capture ? '' : '?:'; - return wrap ? `(${prefix}${start.join('|')})` : start.join('|'); + try { + /* eslint-disable-next-line no-new */ + new RegExp(value); + } catch (ex) { + return args.map(v => utils.escapeRegex(v)).join('..'); } - return toRegexRange(start, end, options); -}; -const rangeError = (...args) => { - return new RangeError('Invalid range arguments: ' + util.inspect(...args)); + return value; }; -const invalidRange = (start, end, options) => { - if (options.strictRanges === true) throw rangeError([start, end]); - return []; -}; +/** + * Create the message for a syntax error + */ -const invalidStep = (step, options) => { - if (options.strictRanges === true) { - throw new TypeError(`Expected step "${step}" to be a number`); - } - return []; +const syntaxError = (type, char) => { + return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`; }; -const fillNumbers = (start, end, step = 1, options = {}) => { - let a = Number(start); - let b = Number(end); +/** + * Parse the given input string. + * @param {String} input + * @param {Object} options + * @return {Object} + */ - if (!Number.isInteger(a) || !Number.isInteger(b)) { - if (options.strictRanges === true) throw rangeError([start, end]); - return []; +const parse = (input, options) => { + if (typeof input !== 'string') { + throw new TypeError('Expected a string'); } - // fix negative zero - if (a === 0) a = 0; - if (b === 0) b = 0; - - let descending = a > b; - let startString = String(start); - let endString = String(end); - let stepString = String(step); - step = Math.max(Math.abs(step), 1); - - let padded = zeros(startString) || zeros(endString) || zeros(stepString); - let maxLen = padded ? Math.max(startString.length, endString.length, stepString.length) : 0; - let toNumber = padded === false && stringify(start, end, options) === false; - let format = options.transform || transform(toNumber); - - if (options.toRegex && step === 1) { - return toRange(toMaxLen(start, maxLen), toMaxLen(end, maxLen), true, options); - } + input = REPLACEMENTS[input] || input; - let parts = { negatives: [], positives: [] }; - let push = num => parts[num < 0 ? 'negatives' : 'positives'].push(Math.abs(num)); - let range = []; - let index = 0; + const opts = { ...options }; + const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; - while (descending ? a >= b : a <= b) { - if (options.toRegex === true && step > 1) { - push(a); - } else { - range.push(pad(format(a, index), maxLen, toNumber)); - } - a = descending ? a - step : a + step; - index++; + let len = input.length; + if (len > max) { + throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); } - if (options.toRegex === true) { - return step > 1 - ? toSequence(parts, options) - : toRegex(range, null, { wrap: false, ...options }); - } + const bos = { type: 'bos', value: '', output: opts.prepend || '' }; + const tokens = [bos]; - return range; -}; + const capture = opts.capture ? '' : '?:'; + const win32 = utils.isWindows(options); -const fillLetters = (start, end, step = 1, options = {}) => { - if ((!isNumber(start) && start.length > 1) || (!isNumber(end) && end.length > 1)) { - return invalidRange(start, end, options); - } + // create constants based on platform, for windows or posix + const PLATFORM_CHARS = constants.globChars(win32); + const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS); + const { + DOT_LITERAL, + PLUS_LITERAL, + SLASH_LITERAL, + ONE_CHAR, + DOTS_SLASH, + NO_DOT, + NO_DOT_SLASH, + NO_DOTS_SLASH, + QMARK, + QMARK_NO_DOT, + STAR, + START_ANCHOR + } = PLATFORM_CHARS; - let format = options.transform || (val => String.fromCharCode(val)); - let a = `${start}`.charCodeAt(0); - let b = `${end}`.charCodeAt(0); + const globstar = (opts) => { + return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; + }; - let descending = a > b; - let min = Math.min(a, b); - let max = Math.max(a, b); + const nodot = opts.dot ? '' : NO_DOT; + const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT; + let star = opts.bash === true ? globstar(opts) : STAR; - if (options.toRegex && step === 1) { - return toRange(min, max, false, options); + if (opts.capture) { + star = `(${star})`; } - let range = []; - let index = 0; - - while (descending ? a >= b : a <= b) { - range.push(format(a, index)); - a = descending ? a - step : a + step; - index++; + // minimatch options support + if (typeof opts.noext === 'boolean') { + opts.noextglob = opts.noext; } - if (options.toRegex === true) { - return toRegex(range, null, { wrap: false, options }); - } + const state = { + input, + index: -1, + start: 0, + dot: opts.dot === true, + consumed: '', + output: '', + prefix: '', + backtrack: false, + negated: false, + brackets: 0, + braces: 0, + parens: 0, + quotes: 0, + globstar: false, + tokens + }; - return range; -}; + input = utils.removePrefix(input, state); + len = input.length; -const fill = (start, end, step, options = {}) => { - if (end == null && isValidValue(start)) { - return [start]; - } + const extglobs = []; + const braces = []; + const stack = []; + let prev = bos; + let value; - if (!isValidValue(start) || !isValidValue(end)) { - return invalidRange(start, end, options); - } + /** + * Tokenizing helpers + */ - if (typeof step === 'function') { - return fill(start, end, 1, { transform: step }); - } + const eos = () => state.index === len - 1; + const peek = state.peek = (n = 1) => input[state.index + n]; + const advance = state.advance = () => input[++state.index]; + const remaining = () => input.slice(state.index + 1); + const consume = (value = '', num = 0) => { + state.consumed += value; + state.index += num; + }; + const append = token => { + state.output += token.output != null ? token.output : token.value; + consume(token.value); + }; - if (isObject(step)) { - return fill(start, end, 0, step); - } + const negate = () => { + let count = 1; - let opts = { ...options }; - if (opts.capture === true) opts.wrap = true; - step = step || opts.step || 1; + while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) { + advance(); + state.start++; + count++; + } - if (!isNumber(step)) { - if (step != null && !isObject(step)) return invalidStep(step, opts); - return fill(start, end, 1, step); - } + if (count % 2 === 0) { + return false; + } - if (isNumber(start) && isNumber(end)) { - return fillNumbers(start, end, step, opts); - } + state.negated = true; + state.start++; + return true; + }; - return fillLetters(start, end, Math.max(Math.abs(step), 1), opts); -}; + const increment = type => { + state[type]++; + stack.push(type); + }; -module.exports = fill; + const decrement = type => { + state[type]--; + stack.pop(); + }; + /** + * Push tokens onto the tokens array. This helper speeds up + * tokenizing by 1) helping us avoid backtracking as much as possible, + * and 2) helping us avoid creating extra tokens when consecutive + * characters are plain text. This improves performance and simplifies + * lookbehinds. + */ -/***/ }), -/* 310 */ -/***/ (function(module, exports, __webpack_require__) { + const push = tok => { + if (prev.type === 'globstar') { + const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace'); + const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren')); -"use strict"; -/*! - * to-regex-range - * - * Copyright (c) 2015-present, Jon Schlinkert. - * Released under the MIT License. - */ + if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) { + state.output = state.output.slice(0, -prev.output.length); + prev.type = 'star'; + prev.value = '*'; + prev.output = star; + state.output += prev.output; + } + } + if (extglobs.length && tok.type !== 'paren' && !EXTGLOB_CHARS[tok.value]) { + extglobs[extglobs.length - 1].inner += tok.value; + } + if (tok.value || tok.output) append(tok); + if (prev && prev.type === 'text' && tok.type === 'text') { + prev.value += tok.value; + prev.output = (prev.output || '') + tok.value; + return; + } -const isNumber = __webpack_require__(311); + tok.prev = prev; + tokens.push(tok); + prev = tok; + }; -const toRegexRange = (min, max, options) => { - if (isNumber(min) === false) { - throw new TypeError('toRegexRange: expected the first argument to be a number'); - } + const extglobOpen = (type, value) => { + const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' }; - if (max === void 0 || min === max) { - return String(min); - } + token.prev = prev; + token.parens = state.parens; + token.output = state.output; + const output = (opts.capture ? '(' : '') + token.open; - if (isNumber(max) === false) { - throw new TypeError('toRegexRange: expected the second argument to be a number.'); - } + increment('parens'); + push({ type, value, output: state.output ? '' : ONE_CHAR }); + push({ type: 'paren', extglob: true, value: advance(), output }); + extglobs.push(token); + }; - let opts = { relaxZeros: true, ...options }; - if (typeof opts.strictZeros === 'boolean') { - opts.relaxZeros = opts.strictZeros === false; - } + const extglobClose = token => { + let output = token.close + (opts.capture ? ')' : ''); - let relax = String(opts.relaxZeros); - let shorthand = String(opts.shorthand); - let capture = String(opts.capture); - let wrap = String(opts.wrap); - let cacheKey = min + ':' + max + '=' + relax + shorthand + capture + wrap; + if (token.type === 'negate') { + let extglobStar = star; - if (toRegexRange.cache.hasOwnProperty(cacheKey)) { - return toRegexRange.cache[cacheKey].result; - } + if (token.inner && token.inner.length > 1 && token.inner.includes('/')) { + extglobStar = globstar(opts); + } - let a = Math.min(min, max); - let b = Math.max(min, max); + if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) { + output = token.close = `)$))${extglobStar}`; + } - if (Math.abs(a - b) === 1) { - let result = min + '|' + max; - if (opts.capture) { - return `(${result})`; - } - if (opts.wrap === false) { - return result; + if (token.prev.type === 'bos' && eos()) { + state.negatedExtglob = true; + } } - return `(?:${result})`; - } - let isPadded = hasPadding(min) || hasPadding(max); - let state = { min, max, a, b }; - let positives = []; - let negatives = []; + push({ type: 'paren', extglob: true, value, output }); + decrement('parens'); + }; - if (isPadded) { - state.isPadded = isPadded; - state.maxLen = String(state.max).length; - } + /** + * Fast paths + */ - if (a < 0) { - let newMin = b < 0 ? Math.abs(b) : 1; - negatives = splitToPatterns(newMin, Math.abs(a), state, opts); - a = state.a = 0; - } + if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) { + let backslashes = false; - if (b >= 0) { - positives = splitToPatterns(a, b, state, opts); - } + let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => { + if (first === '\\') { + backslashes = true; + return m; + } - state.negatives = negatives; - state.positives = positives; - state.result = collatePatterns(negatives, positives, opts); + if (first === '?') { + if (esc) { + return esc + first + (rest ? QMARK.repeat(rest.length) : ''); + } + if (index === 0) { + return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : ''); + } + return QMARK.repeat(chars.length); + } - if (opts.capture === true) { - state.result = `(${state.result})`; - } else if (opts.wrap !== false && (positives.length + negatives.length) > 1) { - state.result = `(?:${state.result})`; - } + if (first === '.') { + return DOT_LITERAL.repeat(chars.length); + } - toRegexRange.cache[cacheKey] = state; - return state.result; -}; - -function collatePatterns(neg, pos, options) { - let onlyNegative = filterPatterns(neg, pos, '-', false, options) || []; - let onlyPositive = filterPatterns(pos, neg, '', false, options) || []; - let intersected = filterPatterns(neg, pos, '-?', true, options) || []; - let subpatterns = onlyNegative.concat(intersected).concat(onlyPositive); - return subpatterns.join('|'); -} + if (first === '*') { + if (esc) { + return esc + first + (rest ? star : ''); + } + return star; + } + return esc ? m : `\\${m}`; + }); -function splitToRanges(min, max) { - let nines = 1; - let zeros = 1; + if (backslashes === true) { + if (opts.unescape === true) { + output = output.replace(/\\/g, ''); + } else { + output = output.replace(/\\+/g, m => { + return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : ''); + }); + } + } - let stop = countNines(min, nines); - let stops = new Set([max]); + if (output === input && opts.contains === true) { + state.output = input; + return state; + } - while (min <= stop && stop <= max) { - stops.add(stop); - nines += 1; - stop = countNines(min, nines); + state.output = utils.wrapOutput(output, state, options); + return state; } - stop = countZeros(max + 1, zeros) - 1; + /** + * Tokenize input until we reach end-of-string + */ - while (min < stop && stop <= max) { - stops.add(stop); - zeros += 1; - stop = countZeros(max + 1, zeros) - 1; - } + while (!eos()) { + value = advance(); - stops = [...stops]; - stops.sort(compare); - return stops; -} + if (value === '\u0000') { + continue; + } -/** - * Convert a range to a regex pattern - * @param {Number} `start` - * @param {Number} `stop` - * @return {String} - */ + /** + * Escaped characters + */ -function rangeToPattern(start, stop, options) { - if (start === stop) { - return { pattern: start, count: [], digits: 0 }; - } + if (value === '\\') { + const next = peek(); - let zipped = zip(start, stop); - let digits = zipped.length; - let pattern = ''; - let count = 0; + if (next === '/' && opts.bash !== true) { + continue; + } - for (let i = 0; i < digits; i++) { - let [startDigit, stopDigit] = zipped[i]; + if (next === '.' || next === ';') { + continue; + } - if (startDigit === stopDigit) { - pattern += startDigit; + if (!next) { + value += '\\'; + push({ type: 'text', value }); + continue; + } - } else if (startDigit !== '0' || stopDigit !== '9') { - pattern += toCharacterClass(startDigit, stopDigit, options); + // collapse slashes to reduce potential for exploits + const match = /^\\+/.exec(remaining()); + let slashes = 0; - } else { - count++; + if (match && match[0].length > 2) { + slashes = match[0].length; + state.index += slashes; + if (slashes % 2 !== 0) { + value += '\\'; + } + } + + if (opts.unescape === true) { + value = advance() || ''; + } else { + value += advance() || ''; + } + + if (state.brackets === 0) { + push({ type: 'text', value }); + continue; + } } - } - if (count) { - pattern += options.shorthand === true ? '\\d' : '[0-9]'; - } + /** + * If we're inside a regex character class, continue + * until we reach the closing bracket. + */ - return { pattern, count: [count], digits }; -} + if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) { + if (opts.posix !== false && value === ':') { + const inner = prev.value.slice(1); + if (inner.includes('[')) { + prev.posix = true; -function splitToPatterns(min, max, tok, options) { - let ranges = splitToRanges(min, max); - let tokens = []; - let start = min; - let prev; + if (inner.includes(':')) { + const idx = prev.value.lastIndexOf('['); + const pre = prev.value.slice(0, idx); + const rest = prev.value.slice(idx + 2); + const posix = POSIX_REGEX_SOURCE[rest]; + if (posix) { + prev.value = pre + posix; + state.backtrack = true; + advance(); - for (let i = 0; i < ranges.length; i++) { - let max = ranges[i]; - let obj = rangeToPattern(String(start), String(max), options); - let zeros = ''; + if (!bos.output && tokens.indexOf(prev) === 1) { + bos.output = ONE_CHAR; + } + continue; + } + } + } + } - if (!tok.isPadded && prev && prev.pattern === obj.pattern) { - if (prev.count.length > 1) { - prev.count.pop(); + if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) { + value = `\\${value}`; } - prev.count.push(obj.count[0]); - prev.string = prev.pattern + toQuantifier(prev.count); - start = max + 1; - continue; - } + if (value === ']' && (prev.value === '[' || prev.value === '[^')) { + value = `\\${value}`; + } - if (tok.isPadded) { - zeros = padZeros(max, tok, options); - } + if (opts.posix === true && value === '!' && prev.value === '[') { + value = '^'; + } - obj.string = zeros + obj.pattern + toQuantifier(obj.count); - tokens.push(obj); - start = max + 1; - prev = obj; - } + prev.value += value; + append({ value }); + continue; + } - return tokens; -} + /** + * If we're inside a quoted string, continue + * until we reach the closing double quote. + */ -function filterPatterns(arr, comparison, prefix, intersection, options) { - let result = []; + if (state.quotes === 1 && value !== '"') { + value = utils.escapeRegex(value); + prev.value += value; + append({ value }); + continue; + } - for (let ele of arr) { - let { string } = ele; + /** + * Double quotes + */ - // only push if _both_ are negative... - if (!intersection && !contains(comparison, 'string', string)) { - result.push(prefix + string); + if (value === '"') { + state.quotes = state.quotes === 1 ? 0 : 1; + if (opts.keepQuotes === true) { + push({ type: 'text', value }); + } + continue; } - // or _both_ are positive - if (intersection && contains(comparison, 'string', string)) { - result.push(prefix + string); + /** + * Parentheses + */ + + if (value === '(') { + increment('parens'); + push({ type: 'paren', value }); + continue; } - } - return result; -} -/** - * Zip strings - */ + if (value === ')') { + if (state.parens === 0 && opts.strictBrackets === true) { + throw new SyntaxError(syntaxError('opening', '(')); + } -function zip(a, b) { - let arr = []; - for (let i = 0; i < a.length; i++) arr.push([a[i], b[i]]); - return arr; -} + const extglob = extglobs[extglobs.length - 1]; + if (extglob && state.parens === extglob.parens + 1) { + extglobClose(extglobs.pop()); + continue; + } -function compare(a, b) { - return a > b ? 1 : b > a ? -1 : 0; -} + push({ type: 'paren', value, output: state.parens ? ')' : '\\)' }); + decrement('parens'); + continue; + } -function contains(arr, key, val) { - return arr.some(ele => ele[key] === val); -} + /** + * Square brackets + */ -function countNines(min, len) { - return Number(String(min).slice(0, -len) + '9'.repeat(len)); -} + if (value === '[') { + if (opts.nobracket === true || !remaining().includes(']')) { + if (opts.nobracket !== true && opts.strictBrackets === true) { + throw new SyntaxError(syntaxError('closing', ']')); + } -function countZeros(integer, zeros) { - return integer - (integer % Math.pow(10, zeros)); -} + value = `\\${value}`; + } else { + increment('brackets'); + } -function toQuantifier(digits) { - let [start = 0, stop = ''] = digits; - if (stop || start > 1) { - return `{${start + (stop ? ',' + stop : '')}}`; - } - return ''; -} + push({ type: 'bracket', value }); + continue; + } -function toCharacterClass(a, b, options) { - return `[${a}${(b - a === 1) ? '' : '-'}${b}]`; -} + if (value === ']') { + if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) { + push({ type: 'text', value, output: `\\${value}` }); + continue; + } -function hasPadding(str) { - return /^-?(0+)\d/.test(str); -} + if (state.brackets === 0) { + if (opts.strictBrackets === true) { + throw new SyntaxError(syntaxError('opening', '[')); + } -function padZeros(value, tok, options) { - if (!tok.isPadded) { - return value; - } + push({ type: 'text', value, output: `\\${value}` }); + continue; + } - let diff = Math.abs(tok.maxLen - String(value).length); - let relax = options.relaxZeros !== false; + decrement('brackets'); - switch (diff) { - case 0: - return ''; - case 1: - return relax ? '0?' : '0'; - case 2: - return relax ? '0{0,2}' : '00'; - default: { - return relax ? `0{0,${diff}}` : `0{${diff}}`; - } - } -} + const prevValue = prev.value.slice(1); + if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) { + value = `/${value}`; + } -/** - * Cache - */ + prev.value += value; + append({ value }); -toRegexRange.cache = {}; -toRegexRange.clearCache = () => (toRegexRange.cache = {}); + // when literal brackets are explicitly disabled + // assume we should match with a regex character class + if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) { + continue; + } -/** - * Expose `toRegexRange` - */ + const escaped = utils.escapeRegex(prev.value); + state.output = state.output.slice(0, -prev.value.length); -module.exports = toRegexRange; + // when literal brackets are explicitly enabled + // assume we should escape the brackets to match literal characters + if (opts.literalBrackets === true) { + state.output += escaped; + prev.value = escaped; + continue; + } + // when the user specifies nothing, try to match both + prev.value = `(${capture}${escaped}|${prev.value})`; + state.output += prev.value; + continue; + } -/***/ }), -/* 311 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Braces + */ -"use strict"; -/*! - * is-number - * - * Copyright (c) 2014-present, Jon Schlinkert. - * Released under the MIT License. - */ + if (value === '{' && opts.nobrace !== true) { + increment('braces'); + const open = { + type: 'brace', + value, + output: '(', + outputIndex: state.output.length, + tokensIndex: state.tokens.length + }; + braces.push(open); + push(open); + continue; + } -module.exports = function(num) { - if (typeof num === 'number') { - return num - num === 0; - } - if (typeof num === 'string' && num.trim() !== '') { - return Number.isFinite ? Number.isFinite(+num) : isFinite(+num); - } - return false; -}; + if (value === '}') { + const brace = braces[braces.length - 1]; + if (opts.nobrace === true || !brace) { + push({ type: 'text', value, output: value }); + continue; + } -/***/ }), -/* 312 */ -/***/ (function(module, exports, __webpack_require__) { + let output = ')'; -"use strict"; + if (brace.dots === true) { + const arr = tokens.slice(); + const range = []; + for (let i = arr.length - 1; i >= 0; i--) { + tokens.pop(); + if (arr[i].type === 'brace') { + break; + } + if (arr[i].type !== 'dots') { + range.unshift(arr[i].value); + } + } -const fill = __webpack_require__(309); -const stringify = __webpack_require__(306); -const utils = __webpack_require__(307); + output = expandRange(range, opts); + state.backtrack = true; + } -const append = (queue = '', stash = '', enclose = false) => { - let result = []; + if (brace.comma !== true && brace.dots !== true) { + const out = state.output.slice(0, brace.outputIndex); + const toks = state.tokens.slice(brace.tokensIndex); + brace.value = brace.output = '\\{'; + value = output = '\\}'; + state.output = out; + for (const t of toks) { + state.output += (t.output || t.value); + } + } - queue = [].concat(queue); - stash = [].concat(stash); + push({ type: 'brace', value, output }); + decrement('braces'); + braces.pop(); + continue; + } - if (!stash.length) return queue; - if (!queue.length) { - return enclose ? utils.flatten(stash).map(ele => `{${ele}}`) : stash; - } + /** + * Pipes + */ - for (let item of queue) { - if (Array.isArray(item)) { - for (let value of item) { - result.push(append(value, stash, enclose)); - } - } else { - for (let ele of stash) { - if (enclose === true && typeof ele === 'string') ele = `{${ele}}`; - result.push(Array.isArray(ele) ? append(item, ele, enclose) : (item + ele)); + if (value === '|') { + if (extglobs.length > 0) { + extglobs[extglobs.length - 1].conditions++; } + push({ type: 'text', value }); + continue; } - } - return utils.flatten(result); -}; -const expand = (ast, options = {}) => { - let rangeLimit = options.rangeLimit === void 0 ? 1000 : options.rangeLimit; + /** + * Commas + */ - let walk = (node, parent = {}) => { - node.queue = []; + if (value === ',') { + let output = value; - let p = parent; - let q = parent.queue; + const brace = braces[braces.length - 1]; + if (brace && stack[stack.length - 1] === 'braces') { + brace.comma = true; + output = '|'; + } - while (p.type !== 'brace' && p.type !== 'root' && p.parent) { - p = p.parent; - q = p.queue; + push({ type: 'comma', value, output }); + continue; } - if (node.invalid || node.dollar) { - q.push(append(q.pop(), stringify(node, options))); - return; - } + /** + * Slashes + */ - if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) { - q.push(append(q.pop(), ['{}'])); - return; + if (value === '/') { + // if the beginning of the glob is "./", advance the start + // to the current index, and don't add the "./" characters + // to the state. This greatly simplifies lookbehinds when + // checking for BOS characters like "!" and "." (not "./") + if (prev.type === 'dot' && state.index === state.start + 1) { + state.start = state.index + 1; + state.consumed = ''; + state.output = ''; + tokens.pop(); + prev = bos; // reset "prev" to the first token + continue; + } + + push({ type: 'slash', value, output: SLASH_LITERAL }); + continue; } - if (node.nodes && node.ranges > 0) { - let args = utils.reduce(node.nodes); + /** + * Dots + */ - if (utils.exceedsLimit(...args, options.step, rangeLimit)) { - throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.'); + if (value === '.') { + if (state.braces > 0 && prev.type === 'dot') { + if (prev.value === '.') prev.output = DOT_LITERAL; + const brace = braces[braces.length - 1]; + prev.type = 'dots'; + prev.output += value; + prev.value += value; + brace.dots = true; + continue; } - let range = fill(...args, options); - if (range.length === 0) { - range = stringify(node, options); + if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') { + push({ type: 'text', value, output: DOT_LITERAL }); + continue; } - q.push(append(q.pop(), range)); - node.nodes = []; - return; - } - - let enclose = utils.encloseBrace(node); - let queue = node.queue; - let block = node; - - while (block.type !== 'brace' && block.type !== 'root' && block.parent) { - block = block.parent; - queue = block.queue; + push({ type: 'dot', value, output: DOT_LITERAL }); + continue; } - for (let i = 0; i < node.nodes.length; i++) { - let child = node.nodes[i]; + /** + * Question marks + */ - if (child.type === 'comma' && node.type === 'brace') { - if (i === 1) queue.push(''); - queue.push(''); + if (value === '?') { + const isGroup = prev && prev.value === '('; + if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + extglobOpen('qmark', value); continue; } - if (child.type === 'close') { - q.push(append(q.pop(), queue, enclose)); + if (prev && prev.type === 'paren') { + const next = peek(); + let output = value; + + if (next === '<' && !utils.supportsLookbehinds()) { + throw new Error('Node.js v10 or higher is required for regex lookbehinds'); + } + + if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) { + output = `\\${value}`; + } + + push({ type: 'text', value, output }); continue; } - if (child.value && child.type !== 'open') { - queue.push(append(queue.pop(), child.value)); + if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) { + push({ type: 'qmark', value, output: QMARK_NO_DOT }); continue; } - if (child.nodes) { - walk(child, node); - } + push({ type: 'qmark', value, output: QMARK }); + continue; } - return queue; - }; - - return utils.flatten(walk(ast)); -}; - -module.exports = expand; - - -/***/ }), -/* 313 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -const stringify = __webpack_require__(306); - -/** - * Constants - */ - -const { - MAX_LENGTH, - CHAR_BACKSLASH, /* \ */ - CHAR_BACKTICK, /* ` */ - CHAR_COMMA, /* , */ - CHAR_DOT, /* . */ - CHAR_LEFT_PARENTHESES, /* ( */ - CHAR_RIGHT_PARENTHESES, /* ) */ - CHAR_LEFT_CURLY_BRACE, /* { */ - CHAR_RIGHT_CURLY_BRACE, /* } */ - CHAR_LEFT_SQUARE_BRACKET, /* [ */ - CHAR_RIGHT_SQUARE_BRACKET, /* ] */ - CHAR_DOUBLE_QUOTE, /* " */ - CHAR_SINGLE_QUOTE, /* ' */ - CHAR_NO_BREAK_SPACE, - CHAR_ZERO_WIDTH_NOBREAK_SPACE -} = __webpack_require__(314); - -/** - * parse - */ - -const parse = (input, options = {}) => { - if (typeof input !== 'string') { - throw new TypeError('Expected a string'); - } - - let opts = options || {}; - let max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; - if (input.length > max) { - throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`); - } - - let ast = { type: 'root', input, nodes: [] }; - let stack = [ast]; - let block = ast; - let prev = ast; - let brackets = 0; - let length = input.length; - let index = 0; - let depth = 0; - let value; - let memo = {}; - - /** - * Helpers - */ + /** + * Exclamation + */ - const advance = () => input[index++]; - const push = node => { - if (node.type === 'text' && prev.type === 'dot') { - prev.type = 'text'; - } + if (value === '!') { + if (opts.noextglob !== true && peek() === '(') { + if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) { + extglobOpen('negate', value); + continue; + } + } - if (prev && prev.type === 'text' && node.type === 'text') { - prev.value += node.value; - return; + if (opts.nonegate !== true && state.index === 0) { + negate(); + continue; + } } - block.nodes.push(node); - node.parent = block; - node.prev = prev; - prev = node; - return node; - }; - - push({ type: 'bos' }); - - while (index < length) { - block = stack[stack.length - 1]; - value = advance(); - /** - * Invalid chars + * Plus */ - if (value === CHAR_ZERO_WIDTH_NOBREAK_SPACE || value === CHAR_NO_BREAK_SPACE) { - continue; - } + if (value === '+') { + if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + extglobOpen('plus', value); + continue; + } - /** - * Escaped chars - */ + if ((prev && prev.value === '(') || opts.regex === false) { + push({ type: 'plus', value, output: PLUS_LITERAL }); + continue; + } - if (value === CHAR_BACKSLASH) { - push({ type: 'text', value: (options.keepEscaping ? value : '') + advance() }); + if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) { + push({ type: 'plus', value }); + continue; + } + + push({ type: 'plus', value: PLUS_LITERAL }); continue; } /** - * Right square bracket (literal): ']' + * Plain text */ - if (value === CHAR_RIGHT_SQUARE_BRACKET) { - push({ type: 'text', value: '\\' + value }); + if (value === '@') { + if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { + push({ type: 'at', extglob: true, value, output: '' }); + continue; + } + + push({ type: 'text', value }); continue; } /** - * Left square bracket: '[' + * Plain text */ - if (value === CHAR_LEFT_SQUARE_BRACKET) { - brackets++; - - let closed = true; - let next; - - while (index < length && (next = advance())) { - value += next; - - if (next === CHAR_LEFT_SQUARE_BRACKET) { - brackets++; - continue; - } - - if (next === CHAR_BACKSLASH) { - value += advance(); - continue; - } - - if (next === CHAR_RIGHT_SQUARE_BRACKET) { - brackets--; + if (value !== '*') { + if (value === '$' || value === '^') { + value = `\\${value}`; + } - if (brackets === 0) { - break; - } - } + const match = REGEX_NON_SPECIAL_CHARS.exec(remaining()); + if (match) { + value += match[0]; + state.index += match[0].length; } push({ type: 'text', value }); @@ -42522,5935 +42971,5874 @@ const parse = (input, options = {}) => { } /** - * Parentheses + * Stars */ - if (value === CHAR_LEFT_PARENTHESES) { - block = push({ type: 'paren', nodes: [] }); - stack.push(block); - push({ type: 'text', value }); + if (prev && (prev.type === 'globstar' || prev.star === true)) { + prev.type = 'star'; + prev.star = true; + prev.value += value; + prev.output = star; + state.backtrack = true; + state.globstar = true; + consume(value); continue; } - if (value === CHAR_RIGHT_PARENTHESES) { - if (block.type !== 'paren') { - push({ type: 'text', value }); - continue; - } - block = stack.pop(); - push({ type: 'text', value }); - block = stack[stack.length - 1]; + let rest = remaining(); + if (opts.noextglob !== true && /^\([^?]/.test(rest)) { + extglobOpen('star', value); continue; } - /** - * Quotes: '|"|` - */ + if (prev.type === 'star') { + if (opts.noglobstar === true) { + consume(value); + continue; + } - if (value === CHAR_DOUBLE_QUOTE || value === CHAR_SINGLE_QUOTE || value === CHAR_BACKTICK) { - let open = value; - let next; + const prior = prev.prev; + const before = prior.prev; + const isStart = prior.type === 'slash' || prior.type === 'bos'; + const afterStar = before && (before.type === 'star' || before.type === 'globstar'); - if (options.keepQuotes !== true) { - value = ''; + if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) { + push({ type: 'star', value, output: '' }); + continue; } - while (index < length && (next = advance())) { - if (next === CHAR_BACKSLASH) { - value += next + advance(); - continue; - } + const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace'); + const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren'); + if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) { + push({ type: 'star', value, output: '' }); + continue; + } - if (next === open) { - if (options.keepQuotes === true) value += next; + // strip consecutive `/**/` + while (rest.slice(0, 3) === '/**') { + const after = input[state.index + 4]; + if (after && after !== '/') { break; } + rest = rest.slice(3); + consume('/**', 3); + } - value += next; + if (prior.type === 'bos' && eos()) { + prev.type = 'globstar'; + prev.value += value; + prev.output = globstar(opts); + state.output = prev.output; + state.globstar = true; + consume(value); + continue; } - push({ type: 'text', value }); - continue; - } + if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) { + state.output = state.output.slice(0, -(prior.output + prev.output).length); + prior.output = `(?:${prior.output}`; - /** - * Left curly brace: '{' - */ + prev.type = 'globstar'; + prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)'); + prev.value += value; + state.globstar = true; + state.output += prior.output + prev.output; + consume(value); + continue; + } - if (value === CHAR_LEFT_CURLY_BRACE) { - depth++; + if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') { + const end = rest[1] !== void 0 ? '|$' : ''; - let dollar = prev.value && prev.value.slice(-1) === '$' || block.dollar === true; - let brace = { - type: 'brace', - open: true, - close: false, - dollar, - depth, - commas: 0, - ranges: 0, - nodes: [] - }; + state.output = state.output.slice(0, -(prior.output + prev.output).length); + prior.output = `(?:${prior.output}`; - block = push(brace); - stack.push(block); - push({ type: 'open', value }); - continue; - } + prev.type = 'globstar'; + prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`; + prev.value += value; - /** - * Right curly brace: '}' - */ + state.output += prior.output + prev.output; + state.globstar = true; - if (value === CHAR_RIGHT_CURLY_BRACE) { - if (block.type !== 'brace') { - push({ type: 'text', value }); + consume(value + advance()); + + push({ type: 'slash', value: '/', output: '' }); continue; } - let type = 'close'; - block = stack.pop(); - block.close = true; + if (prior.type === 'bos' && rest[0] === '/') { + prev.type = 'globstar'; + prev.value += value; + prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`; + state.output = prev.output; + state.globstar = true; + consume(value + advance()); + push({ type: 'slash', value: '/', output: '' }); + continue; + } - push({ type, value }); - depth--; + // remove single star from output + state.output = state.output.slice(0, -prev.output.length); - block = stack[stack.length - 1]; + // reset previous token to globstar + prev.type = 'globstar'; + prev.output = globstar(opts); + prev.value += value; + + // reset output with globstar + state.output += prev.output; + state.globstar = true; + consume(value); continue; } - /** - * Comma: ',' - */ + const token = { type: 'star', value, output: star }; - if (value === CHAR_COMMA && depth > 0) { - if (block.ranges > 0) { - block.ranges = 0; - let open = block.nodes.shift(); - block.nodes = [open, { type: 'text', value: stringify(block) }]; + if (opts.bash === true) { + token.output = '.*?'; + if (prev.type === 'bos' || prev.type === 'slash') { + token.output = nodot + token.output; } - - push({ type: 'comma', value }); - block.commas++; + push(token); continue; } - /** - * Dot: '.' - */ - - if (value === CHAR_DOT && depth > 0 && block.commas === 0) { - let siblings = block.nodes; - - if (depth === 0 || siblings.length === 0) { - push({ type: 'text', value }); - continue; - } + if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) { + token.output = value; + push(token); + continue; + } + if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') { if (prev.type === 'dot') { - block.range = []; - prev.value += value; - prev.type = 'range'; + state.output += NO_DOT_SLASH; + prev.output += NO_DOT_SLASH; - if (block.nodes.length !== 3 && block.nodes.length !== 5) { - block.invalid = true; - block.ranges = 0; - prev.type = 'text'; - continue; - } + } else if (opts.dot === true) { + state.output += NO_DOTS_SLASH; + prev.output += NO_DOTS_SLASH; - block.ranges++; - block.args = []; - continue; + } else { + state.output += nodot; + prev.output += nodot; } - if (prev.type === 'range') { - siblings.pop(); - - let before = siblings[siblings.length - 1]; - before.value += prev.value + value; - prev = before; - block.ranges--; - continue; + if (peek() !== '*') { + state.output += ONE_CHAR; + prev.output += ONE_CHAR; } - - push({ type: 'dot', value }); - continue; } - /** - * Text - */ + push(token); + } - push({ type: 'text', value }); + while (state.brackets > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']')); + state.output = utils.escapeLast(state.output, '['); + decrement('brackets'); } - // Mark imbalanced braces and brackets as invalid - do { - block = stack.pop(); + while (state.parens > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')')); + state.output = utils.escapeLast(state.output, '('); + decrement('parens'); + } - if (block.type !== 'root') { - block.nodes.forEach(node => { - if (!node.nodes) { - if (node.type === 'open') node.isOpen = true; - if (node.type === 'close') node.isClose = true; - if (!node.nodes) node.type = 'text'; - node.invalid = true; - } - }); + while (state.braces > 0) { + if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}')); + state.output = utils.escapeLast(state.output, '{'); + decrement('braces'); + } - // get the location of the block on parent.nodes (block's siblings) - let parent = stack[stack.length - 1]; - let index = parent.nodes.indexOf(block); - // replace the (invalid) block with it's nodes - parent.nodes.splice(index, 1, ...block.nodes); - } - } while (stack.length > 0); + if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) { + push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` }); + } - push({ type: 'eos' }); - return ast; -}; + // rebuild the output if we had to backtrack at any point + if (state.backtrack === true) { + state.output = ''; -module.exports = parse; + for (const token of state.tokens) { + state.output += token.output != null ? token.output : token.value; - -/***/ }), -/* 314 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = { - MAX_LENGTH: 1024 * 64, - - // Digits - CHAR_0: '0', /* 0 */ - CHAR_9: '9', /* 9 */ - - // Alphabet chars. - CHAR_UPPERCASE_A: 'A', /* A */ - CHAR_LOWERCASE_A: 'a', /* a */ - CHAR_UPPERCASE_Z: 'Z', /* Z */ - CHAR_LOWERCASE_Z: 'z', /* z */ - - CHAR_LEFT_PARENTHESES: '(', /* ( */ - CHAR_RIGHT_PARENTHESES: ')', /* ) */ - - CHAR_ASTERISK: '*', /* * */ - - // Non-alphabetic chars. - CHAR_AMPERSAND: '&', /* & */ - CHAR_AT: '@', /* @ */ - CHAR_BACKSLASH: '\\', /* \ */ - CHAR_BACKTICK: '`', /* ` */ - CHAR_CARRIAGE_RETURN: '\r', /* \r */ - CHAR_CIRCUMFLEX_ACCENT: '^', /* ^ */ - CHAR_COLON: ':', /* : */ - CHAR_COMMA: ',', /* , */ - CHAR_DOLLAR: '$', /* . */ - CHAR_DOT: '.', /* . */ - CHAR_DOUBLE_QUOTE: '"', /* " */ - CHAR_EQUAL: '=', /* = */ - CHAR_EXCLAMATION_MARK: '!', /* ! */ - CHAR_FORM_FEED: '\f', /* \f */ - CHAR_FORWARD_SLASH: '/', /* / */ - CHAR_HASH: '#', /* # */ - CHAR_HYPHEN_MINUS: '-', /* - */ - CHAR_LEFT_ANGLE_BRACKET: '<', /* < */ - CHAR_LEFT_CURLY_BRACE: '{', /* { */ - CHAR_LEFT_SQUARE_BRACKET: '[', /* [ */ - CHAR_LINE_FEED: '\n', /* \n */ - CHAR_NO_BREAK_SPACE: '\u00A0', /* \u00A0 */ - CHAR_PERCENT: '%', /* % */ - CHAR_PLUS: '+', /* + */ - CHAR_QUESTION_MARK: '?', /* ? */ - CHAR_RIGHT_ANGLE_BRACKET: '>', /* > */ - CHAR_RIGHT_CURLY_BRACE: '}', /* } */ - CHAR_RIGHT_SQUARE_BRACKET: ']', /* ] */ - CHAR_SEMICOLON: ';', /* ; */ - CHAR_SINGLE_QUOTE: '\'', /* ' */ - CHAR_SPACE: ' ', /* */ - CHAR_TAB: '\t', /* \t */ - CHAR_UNDERSCORE: '_', /* _ */ - CHAR_VERTICAL_LINE: '|', /* | */ - CHAR_ZERO_WIDTH_NOBREAK_SPACE: '\uFEFF' /* \uFEFF */ -}; - - -/***/ }), -/* 315 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -module.exports = __webpack_require__(316); - - -/***/ }), -/* 316 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -const path = __webpack_require__(4); -const scan = __webpack_require__(317); -const parse = __webpack_require__(320); -const utils = __webpack_require__(318); -const constants = __webpack_require__(319); -const isObject = val => val && typeof val === 'object' && !Array.isArray(val); - -/** - * Creates a matcher function from one or more glob patterns. The - * returned function takes a string to match as its first argument, - * and returns true if the string is a match. The returned matcher - * function also takes a boolean as the second argument that, when true, - * returns an object with additional information. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch(glob[, options]); - * - * const isMatch = picomatch('*.!(*a)'); - * console.log(isMatch('a.a')); //=> false - * console.log(isMatch('a.b')); //=> true - * ``` - * @name picomatch - * @param {String|Array} `globs` One or more glob patterns. - * @param {Object=} `options` - * @return {Function=} Returns a matcher function. - * @api public - */ - -const picomatch = (glob, options, returnState = false) => { - if (Array.isArray(glob)) { - const fns = glob.map(input => picomatch(input, options, returnState)); - const arrayMatcher = str => { - for (const isMatch of fns) { - const state = isMatch(str); - if (state) return state; - } - return false; - }; - return arrayMatcher; - } - - const isState = isObject(glob) && glob.tokens && glob.input; - - if (glob === '' || (typeof glob !== 'string' && !isState)) { - throw new TypeError('Expected pattern to be a non-empty string'); - } - - const opts = options || {}; - const posix = utils.isWindows(options); - const regex = isState - ? picomatch.compileRe(glob, options) - : picomatch.makeRe(glob, options, false, true); - - const state = regex.state; - delete regex.state; - - let isIgnored = () => false; - if (opts.ignore) { - const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null }; - isIgnored = picomatch(opts.ignore, ignoreOpts, returnState); - } - - const matcher = (input, returnObject = false) => { - const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix }); - const result = { glob, state, regex, posix, input, output, match, isMatch }; - - if (typeof opts.onResult === 'function') { - opts.onResult(result); - } - - if (isMatch === false) { - result.isMatch = false; - return returnObject ? result : false; - } - - if (isIgnored(input)) { - if (typeof opts.onIgnore === 'function') { - opts.onIgnore(result); + if (token.suffix) { + state.output += token.suffix; } - result.isMatch = false; - return returnObject ? result : false; } - - if (typeof opts.onMatch === 'function') { - opts.onMatch(result); - } - return returnObject ? result : true; - }; - - if (returnState) { - matcher.state = state; } - return matcher; + return state; }; /** - * Test `input` with the given `regex`. This is used by the main - * `picomatch()` function to test the input string. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch.test(input, regex[, options]); - * - * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/)); - * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' } - * ``` - * @param {String} `input` String to test. - * @param {RegExp} `regex` - * @return {Object} Returns an object with matching info. - * @api public + * Fast paths for creating regular expressions for common glob patterns. + * This can significantly speed up processing and has very little downside + * impact when none of the fast paths match. */ -picomatch.test = (input, regex, options, { glob, posix } = {}) => { - if (typeof input !== 'string') { - throw new TypeError('Expected input to be a string'); +parse.fastpaths = (input, options) => { + const opts = { ...options }; + const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; + const len = input.length; + if (len > max) { + throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); } - if (input === '') { - return { isMatch: false, output: '' }; - } + input = REPLACEMENTS[input] || input; + const win32 = utils.isWindows(options); - const opts = options || {}; - const format = opts.format || (posix ? utils.toPosixSlashes : null); - let match = input === glob; - let output = (match && format) ? format(input) : input; + // create constants based on platform, for windows or posix + const { + DOT_LITERAL, + SLASH_LITERAL, + ONE_CHAR, + DOTS_SLASH, + NO_DOT, + NO_DOTS, + NO_DOTS_SLASH, + STAR, + START_ANCHOR + } = constants.globChars(win32); - if (match === false) { - output = format ? format(input) : input; - match = output === glob; - } + const nodot = opts.dot ? NO_DOTS : NO_DOT; + const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT; + const capture = opts.capture ? '' : '?:'; + const state = { negated: false, prefix: '' }; + let star = opts.bash === true ? '.*?' : STAR; - if (match === false || opts.capture === true) { - if (opts.matchBase === true || opts.basename === true) { - match = picomatch.matchBase(input, regex, options, posix); - } else { - match = regex.exec(output); - } + if (opts.capture) { + star = `(${star})`; } - return { isMatch: Boolean(match), match, output }; -}; + const globstar = (opts) => { + if (opts.noglobstar === true) return star; + return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; + }; -/** - * Match the basename of a filepath. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch.matchBase(input, glob[, options]); - * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true - * ``` - * @param {String} `input` String to test. - * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe). - * @return {Boolean} - * @api public - */ + const create = str => { + switch (str) { + case '*': + return `${nodot}${ONE_CHAR}${star}`; -picomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => { - const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options); - return regex.test(path.basename(input)); -}; + case '.*': + return `${DOT_LITERAL}${ONE_CHAR}${star}`; -/** - * Returns true if **any** of the given glob `patterns` match the specified `string`. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch.isMatch(string, patterns[, options]); - * - * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true - * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false - * ``` - * @param {String|Array} str The string to test. - * @param {String|Array} patterns One or more glob patterns to use for matching. - * @param {Object} [options] See available [options](#options). - * @return {Boolean} Returns true if any patterns match `str` - * @api public - */ + case '*.*': + return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; -picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); + case '*/*': + return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`; -/** - * Parse a glob pattern to create the source string for a regular - * expression. - * - * ```js - * const picomatch = require('picomatch'); - * const result = picomatch.parse(pattern[, options]); - * ``` - * @param {String} `pattern` - * @param {Object} `options` - * @return {Object} Returns an object with useful properties and output to be used as a regex source string. - * @api public - */ + case '**': + return nodot + globstar(opts); -picomatch.parse = (pattern, options) => { - if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options)); - return parse(pattern, { ...options, fastpaths: false }); -}; + case '**/*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`; -/** - * Scan a glob pattern to separate the pattern into segments. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch.scan(input[, options]); - * - * const result = picomatch.scan('!./foo/*.js'); - * console.log(result); - * { prefix: '!./', - * input: '!./foo/*.js', - * start: 3, - * base: 'foo', - * glob: '*.js', - * isBrace: false, - * isBracket: false, - * isGlob: true, - * isExtglob: false, - * isGlobstar: false, - * negated: true } - * ``` - * @param {String} `input` Glob pattern to scan. - * @param {Object} `options` - * @return {Object} Returns an object with - * @api public - */ + case '**/*.*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; -picomatch.scan = (input, options) => scan(input, options); + case '**/.*': + return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`; -/** - * Create a regular expression from a parsed glob pattern. - * - * ```js - * const picomatch = require('picomatch'); - * const state = picomatch.parse('*.js'); - * // picomatch.compileRe(state[, options]); - * - * console.log(picomatch.compileRe(state)); - * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ - * ``` - * @param {String} `state` The object returned from the `.parse` method. - * @param {Object} `options` - * @return {RegExp} Returns a regex created from the given pattern. - * @api public - */ + default: { + const match = /^(.*?)\.(\w+)$/.exec(str); + if (!match) return; -picomatch.compileRe = (parsed, options, returnOutput = false, returnState = false) => { - if (returnOutput === true) { - return parsed.output; - } + const source = create(match[1]); + if (!source) return; - const opts = options || {}; - const prepend = opts.contains ? '' : '^'; - const append = opts.contains ? '' : '$'; + return source + DOT_LITERAL + match[2]; + } + } + }; - let source = `${prepend}(?:${parsed.output})${append}`; - if (parsed && parsed.negated === true) { - source = `^(?!${source}).*$`; - } + const output = utils.removePrefix(input, state); + let source = create(output); - const regex = picomatch.toRegex(source, options); - if (returnState === true) { - regex.state = parsed; + if (source && opts.strictSlashes !== true) { + source += `${SLASH_LITERAL}?`; } - return regex; + return source; }; -picomatch.makeRe = (input, options, returnOutput = false, returnState = false) => { - if (!input || typeof input !== 'string') { - throw new TypeError('Expected a non-empty string'); - } - - const opts = options || {}; - let parsed = { negated: false, fastpaths: true }; - let prefix = ''; - let output; - - if (input.startsWith('./')) { - input = input.slice(2); - prefix = parsed.prefix = './'; - } +module.exports = parse; - if (opts.fastpaths !== false && (input[0] === '.' || input[0] === '*')) { - output = parse.fastpaths(input, options); - } - if (output === undefined) { - parsed = parse(input, options); - parsed.prefix = prefix + (parsed.prefix || ''); - } else { - parsed.output = output; - } +/***/ }), +/* 313 */ +/***/ (function(module, exports, __webpack_require__) { - return picomatch.compileRe(parsed, options, returnOutput, returnState); -}; +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const merge2 = __webpack_require__(284); +function merge(streams) { + const mergedStream = merge2(streams); + streams.forEach((stream) => { + stream.once('error', (error) => mergedStream.emit('error', error)); + }); + mergedStream.once('close', () => propagateCloseEventToSources(streams)); + mergedStream.once('end', () => propagateCloseEventToSources(streams)); + return mergedStream; +} +exports.merge = merge; +function propagateCloseEventToSources(streams) { + streams.forEach((stream) => stream.emit('close')); +} -/** - * Create a regular expression from the given regex source string. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch.toRegex(source[, options]); - * - * const { output } = picomatch.parse('*.js'); - * console.log(picomatch.toRegex(output)); - * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ - * ``` - * @param {String} `source` Regular expression source string. - * @param {Object} `options` - * @return {RegExp} - * @api public - */ -picomatch.toRegex = (source, options) => { - try { - const opts = options || {}; - return new RegExp(source, opts.flags || (opts.nocase ? 'i' : '')); - } catch (err) { - if (options && options.debug === true) throw err; - return /$^/; - } -}; +/***/ }), +/* 314 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Picomatch constants. - * @return {Object} - */ +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +function isString(input) { + return typeof input === 'string'; +} +exports.isString = isString; +function isEmpty(input) { + return input === ''; +} +exports.isEmpty = isEmpty; -picomatch.constants = constants; -/** - * Expose "picomatch" - */ +/***/ }), +/* 315 */ +/***/ (function(module, exports, __webpack_require__) { -module.exports = picomatch; +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const stream_1 = __webpack_require__(316); +const provider_1 = __webpack_require__(343); +class ProviderAsync extends provider_1.default { + constructor() { + super(...arguments); + this._reader = new stream_1.default(this._settings); + } + read(task) { + const root = this._getRootDirectory(task); + const options = this._getReaderOptions(task); + const entries = []; + return new Promise((resolve, reject) => { + const stream = this.api(root, task, options); + stream.once('error', reject); + stream.on('data', (entry) => entries.push(options.transform(entry))); + stream.once('end', () => resolve(entries)); + }); + } + api(root, task, options) { + if (task.dynamic) { + return this._reader.dynamic(root, options); + } + return this._reader.static(task.patterns, options); + } +} +exports.default = ProviderAsync; /***/ }), -/* 317 */ +/* 316 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const stream_1 = __webpack_require__(138); +const fsStat = __webpack_require__(317); +const fsWalk = __webpack_require__(322); +const reader_1 = __webpack_require__(342); +class ReaderStream extends reader_1.default { + constructor() { + super(...arguments); + this._walkStream = fsWalk.walkStream; + this._stat = fsStat.stat; + } + dynamic(root, options) { + return this._walkStream(root, options); + } + static(patterns, options) { + const filepaths = patterns.map(this._getFullEntryPath, this); + const stream = new stream_1.PassThrough({ objectMode: true }); + stream._write = (index, _enc, done) => { + return this._getEntry(filepaths[index], patterns[index], options) + .then((entry) => { + if (entry !== null && options.entryFilter(entry)) { + stream.push(entry); + } + if (index === filepaths.length - 1) { + stream.end(); + } + done(); + }) + .catch(done); + }; + for (let i = 0; i < filepaths.length; i++) { + stream.write(i); + } + return stream; + } + _getEntry(filepath, pattern, options) { + return this._getStat(filepath) + .then((stats) => this._makeEntry(stats, pattern)) + .catch((error) => { + if (options.errorFilter(error)) { + return null; + } + throw error; + }); + } + _getStat(filepath) { + return new Promise((resolve, reject) => { + this._stat(filepath, this._fsStatSettings, (error, stats) => { + return error === null ? resolve(stats) : reject(error); + }); + }); + } +} +exports.default = ReaderStream; -const utils = __webpack_require__(318); -const { - CHAR_ASTERISK, /* * */ - CHAR_AT, /* @ */ - CHAR_BACKWARD_SLASH, /* \ */ - CHAR_COMMA, /* , */ - CHAR_DOT, /* . */ - CHAR_EXCLAMATION_MARK, /* ! */ - CHAR_FORWARD_SLASH, /* / */ - CHAR_LEFT_CURLY_BRACE, /* { */ - CHAR_LEFT_PARENTHESES, /* ( */ - CHAR_LEFT_SQUARE_BRACKET, /* [ */ - CHAR_PLUS, /* + */ - CHAR_QUESTION_MARK, /* ? */ - CHAR_RIGHT_CURLY_BRACE, /* } */ - CHAR_RIGHT_PARENTHESES, /* ) */ - CHAR_RIGHT_SQUARE_BRACKET /* ] */ -} = __webpack_require__(319); - -const isPathSeparator = code => { - return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; -}; - -const depth = token => { - if (token.isPrefix !== true) { - token.depth = token.isGlobstar ? Infinity : 1; - } -}; - -/** - * Quickly scans a glob pattern and returns an object with a handful of - * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists), - * `glob` (the actual pattern), and `negated` (true if the path starts with `!`). - * - * ```js - * const pm = require('picomatch'); - * console.log(pm.scan('foo/bar/*.js')); - * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' } - * ``` - * @param {String} `str` - * @param {Object} `options` - * @return {Object} Returns an object with tokens and regex source string. - * @api public - */ +/***/ }), +/* 317 */ +/***/ (function(module, exports, __webpack_require__) { -const scan = (input, options) => { - const opts = options || {}; +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const async = __webpack_require__(318); +const sync = __webpack_require__(319); +const settings_1 = __webpack_require__(320); +exports.Settings = settings_1.default; +function stat(path, optionsOrSettingsOrCallback, callback) { + if (typeof optionsOrSettingsOrCallback === 'function') { + return async.read(path, getSettings(), optionsOrSettingsOrCallback); + } + async.read(path, getSettings(optionsOrSettingsOrCallback), callback); +} +exports.stat = stat; +function statSync(path, optionsOrSettings) { + const settings = getSettings(optionsOrSettings); + return sync.read(path, settings); +} +exports.statSync = statSync; +function getSettings(settingsOrOptions = {}) { + if (settingsOrOptions instanceof settings_1.default) { + return settingsOrOptions; + } + return new settings_1.default(settingsOrOptions); +} - const length = input.length - 1; - const scanToEnd = opts.parts === true || opts.scanToEnd === true; - const slashes = []; - const tokens = []; - const parts = []; - let str = input; - let index = -1; - let start = 0; - let lastIndex = 0; - let isBrace = false; - let isBracket = false; - let isGlob = false; - let isExtglob = false; - let isGlobstar = false; - let braceEscaped = false; - let backslashes = false; - let negated = false; - let finished = false; - let braces = 0; - let prev; - let code; - let token = { value: '', depth: 0, isGlob: false }; +/***/ }), +/* 318 */ +/***/ (function(module, exports, __webpack_require__) { - const eos = () => index >= length; - const peek = () => str.charCodeAt(index + 1); - const advance = () => { - prev = code; - return str.charCodeAt(++index); - }; +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +function read(path, settings, callback) { + settings.fs.lstat(path, (lstatError, lstat) => { + if (lstatError !== null) { + return callFailureCallback(callback, lstatError); + } + if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) { + return callSuccessCallback(callback, lstat); + } + settings.fs.stat(path, (statError, stat) => { + if (statError !== null) { + if (settings.throwErrorOnBrokenSymbolicLink) { + return callFailureCallback(callback, statError); + } + return callSuccessCallback(callback, lstat); + } + if (settings.markSymbolicLink) { + stat.isSymbolicLink = () => true; + } + callSuccessCallback(callback, stat); + }); + }); +} +exports.read = read; +function callFailureCallback(callback, error) { + callback(error); +} +function callSuccessCallback(callback, result) { + callback(null, result); +} - while (index < length) { - code = advance(); - let next; - if (code === CHAR_BACKWARD_SLASH) { - backslashes = token.backslashes = true; - code = advance(); +/***/ }), +/* 319 */ +/***/ (function(module, exports, __webpack_require__) { - if (code === CHAR_LEFT_CURLY_BRACE) { - braceEscaped = true; - } - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +function read(path, settings) { + const lstat = settings.fs.lstatSync(path); + if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) { + return lstat; + } + try { + const stat = settings.fs.statSync(path); + if (settings.markSymbolicLink) { + stat.isSymbolicLink = () => true; + } + return stat; + } + catch (error) { + if (!settings.throwErrorOnBrokenSymbolicLink) { + return lstat; + } + throw error; + } +} +exports.read = read; - if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) { - braces++; - while (eos() !== true && (code = advance())) { - if (code === CHAR_BACKWARD_SLASH) { - backslashes = token.backslashes = true; - advance(); - continue; - } +/***/ }), +/* 320 */ +/***/ (function(module, exports, __webpack_require__) { - if (code === CHAR_LEFT_CURLY_BRACE) { - braces++; - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const fs = __webpack_require__(321); +class Settings { + constructor(_options = {}) { + this._options = _options; + this.followSymbolicLink = this._getValue(this._options.followSymbolicLink, true); + this.fs = fs.createFileSystemAdapter(this._options.fs); + this.markSymbolicLink = this._getValue(this._options.markSymbolicLink, false); + this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true); + } + _getValue(option, value) { + return option === undefined ? value : option; + } +} +exports.default = Settings; - if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) { - isBrace = token.isBrace = true; - isGlob = token.isGlob = true; - finished = true; - if (scanToEnd === true) { - continue; - } +/***/ }), +/* 321 */ +/***/ (function(module, exports, __webpack_require__) { - break; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const fs = __webpack_require__(134); +exports.FILE_SYSTEM_ADAPTER = { + lstat: fs.lstat, + stat: fs.stat, + lstatSync: fs.lstatSync, + statSync: fs.statSync +}; +function createFileSystemAdapter(fsMethods) { + if (fsMethods === undefined) { + return exports.FILE_SYSTEM_ADAPTER; + } + return Object.assign(Object.assign({}, exports.FILE_SYSTEM_ADAPTER), fsMethods); +} +exports.createFileSystemAdapter = createFileSystemAdapter; - if (braceEscaped !== true && code === CHAR_COMMA) { - isBrace = token.isBrace = true; - isGlob = token.isGlob = true; - finished = true; - if (scanToEnd === true) { - continue; - } +/***/ }), +/* 322 */ +/***/ (function(module, exports, __webpack_require__) { - break; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const async_1 = __webpack_require__(323); +const stream_1 = __webpack_require__(338); +const sync_1 = __webpack_require__(339); +const settings_1 = __webpack_require__(341); +exports.Settings = settings_1.default; +function walk(directory, optionsOrSettingsOrCallback, callback) { + if (typeof optionsOrSettingsOrCallback === 'function') { + return new async_1.default(directory, getSettings()).read(optionsOrSettingsOrCallback); + } + new async_1.default(directory, getSettings(optionsOrSettingsOrCallback)).read(callback); +} +exports.walk = walk; +function walkSync(directory, optionsOrSettings) { + const settings = getSettings(optionsOrSettings); + const provider = new sync_1.default(directory, settings); + return provider.read(); +} +exports.walkSync = walkSync; +function walkStream(directory, optionsOrSettings) { + const settings = getSettings(optionsOrSettings); + const provider = new stream_1.default(directory, settings); + return provider.read(); +} +exports.walkStream = walkStream; +function getSettings(settingsOrOptions = {}) { + if (settingsOrOptions instanceof settings_1.default) { + return settingsOrOptions; + } + return new settings_1.default(settingsOrOptions); +} - if (code === CHAR_RIGHT_CURLY_BRACE) { - braces--; - if (braces === 0) { - braceEscaped = false; - isBrace = token.isBrace = true; - finished = true; - break; - } - } - } +/***/ }), +/* 323 */ +/***/ (function(module, exports, __webpack_require__) { - if (scanToEnd === true) { - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const async_1 = __webpack_require__(324); +class AsyncProvider { + constructor(_root, _settings) { + this._root = _root; + this._settings = _settings; + this._reader = new async_1.default(this._root, this._settings); + this._storage = new Set(); + } + read(callback) { + this._reader.onError((error) => { + callFailureCallback(callback, error); + }); + this._reader.onEntry((entry) => { + this._storage.add(entry); + }); + this._reader.onEnd(() => { + callSuccessCallback(callback, [...this._storage]); + }); + this._reader.read(); + } +} +exports.default = AsyncProvider; +function callFailureCallback(callback, error) { + callback(error); +} +function callSuccessCallback(callback, entries) { + callback(null, entries); +} - break; - } - if (code === CHAR_FORWARD_SLASH) { - slashes.push(index); - tokens.push(token); - token = { value: '', depth: 0, isGlob: false }; +/***/ }), +/* 324 */ +/***/ (function(module, exports, __webpack_require__) { - if (finished === true) continue; - if (prev === CHAR_DOT && index === (start + 1)) { - start += 2; - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const events_1 = __webpack_require__(156); +const fsScandir = __webpack_require__(325); +const fastq = __webpack_require__(334); +const common = __webpack_require__(336); +const reader_1 = __webpack_require__(337); +class AsyncReader extends reader_1.default { + constructor(_root, _settings) { + super(_root, _settings); + this._settings = _settings; + this._scandir = fsScandir.scandir; + this._emitter = new events_1.EventEmitter(); + this._queue = fastq(this._worker.bind(this), this._settings.concurrency); + this._isFatalError = false; + this._isDestroyed = false; + this._queue.drain = () => { + if (!this._isFatalError) { + this._emitter.emit('end'); + } + }; + } + read() { + this._isFatalError = false; + this._isDestroyed = false; + setImmediate(() => { + this._pushToQueue(this._root, this._settings.basePath); + }); + return this._emitter; + } + destroy() { + if (this._isDestroyed) { + throw new Error('The reader is already destroyed'); + } + this._isDestroyed = true; + this._queue.killAndDrain(); + } + onEntry(callback) { + this._emitter.on('entry', callback); + } + onError(callback) { + this._emitter.once('error', callback); + } + onEnd(callback) { + this._emitter.once('end', callback); + } + _pushToQueue(directory, base) { + const queueItem = { directory, base }; + this._queue.push(queueItem, (error) => { + if (error !== null) { + this._handleError(error); + } + }); + } + _worker(item, done) { + this._scandir(item.directory, this._settings.fsScandirSettings, (error, entries) => { + if (error !== null) { + return done(error, undefined); + } + for (const entry of entries) { + this._handleEntry(entry, item.base); + } + done(null, undefined); + }); + } + _handleError(error) { + if (!common.isFatalError(this._settings, error)) { + return; + } + this._isFatalError = true; + this._isDestroyed = true; + this._emitter.emit('error', error); + } + _handleEntry(entry, base) { + if (this._isDestroyed || this._isFatalError) { + return; + } + const fullpath = entry.path; + if (base !== undefined) { + entry.path = common.joinPathSegments(base, entry.name, this._settings.pathSegmentSeparator); + } + if (common.isAppliedFilter(this._settings.entryFilter, entry)) { + this._emitEntry(entry); + } + if (entry.dirent.isDirectory() && common.isAppliedFilter(this._settings.deepFilter, entry)) { + this._pushToQueue(fullpath, entry.path); + } + } + _emitEntry(entry) { + this._emitter.emit('entry', entry); + } +} +exports.default = AsyncReader; - lastIndex = index + 1; - continue; - } - if (opts.noext !== true) { - const isExtglobChar = code === CHAR_PLUS - || code === CHAR_AT - || code === CHAR_ASTERISK - || code === CHAR_QUESTION_MARK - || code === CHAR_EXCLAMATION_MARK; +/***/ }), +/* 325 */ +/***/ (function(module, exports, __webpack_require__) { - if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) { - isGlob = token.isGlob = true; - isExtglob = token.isExtglob = true; - finished = true; +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const async = __webpack_require__(326); +const sync = __webpack_require__(331); +const settings_1 = __webpack_require__(332); +exports.Settings = settings_1.default; +function scandir(path, optionsOrSettingsOrCallback, callback) { + if (typeof optionsOrSettingsOrCallback === 'function') { + return async.read(path, getSettings(), optionsOrSettingsOrCallback); + } + async.read(path, getSettings(optionsOrSettingsOrCallback), callback); +} +exports.scandir = scandir; +function scandirSync(path, optionsOrSettings) { + const settings = getSettings(optionsOrSettings); + return sync.read(path, settings); +} +exports.scandirSync = scandirSync; +function getSettings(settingsOrOptions = {}) { + if (settingsOrOptions instanceof settings_1.default) { + return settingsOrOptions; + } + return new settings_1.default(settingsOrOptions); +} - if (scanToEnd === true) { - while (eos() !== true && (code = advance())) { - if (code === CHAR_BACKWARD_SLASH) { - backslashes = token.backslashes = true; - code = advance(); - continue; - } - if (code === CHAR_RIGHT_PARENTHESES) { - isGlob = token.isGlob = true; - finished = true; - break; - } - } - continue; - } - break; - } - } - - if (code === CHAR_ASTERISK) { - if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true; - isGlob = token.isGlob = true; - finished = true; - - if (scanToEnd === true) { - continue; - } - break; - } - - if (code === CHAR_QUESTION_MARK) { - isGlob = token.isGlob = true; - finished = true; - - if (scanToEnd === true) { - continue; - } - break; - } - - if (code === CHAR_LEFT_SQUARE_BRACKET) { - while (eos() !== true && (next = advance())) { - if (next === CHAR_BACKWARD_SLASH) { - backslashes = token.backslashes = true; - advance(); - continue; - } - - if (next === CHAR_RIGHT_SQUARE_BRACKET) { - isBracket = token.isBracket = true; - isGlob = token.isGlob = true; - finished = true; - - if (scanToEnd === true) { - continue; - } - break; - } - } - } - - if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) { - negated = token.negated = true; - start++; - continue; - } - - if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) { - isGlob = token.isGlob = true; - - if (scanToEnd === true) { - while (eos() !== true && (code = advance())) { - if (code === CHAR_LEFT_PARENTHESES) { - backslashes = token.backslashes = true; - code = advance(); - continue; - } - - if (code === CHAR_RIGHT_PARENTHESES) { - finished = true; - break; - } - } - continue; - } - break; - } - - if (isGlob === true) { - finished = true; +/***/ }), +/* 326 */ +/***/ (function(module, exports, __webpack_require__) { - if (scanToEnd === true) { - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const fsStat = __webpack_require__(317); +const rpl = __webpack_require__(327); +const constants_1 = __webpack_require__(328); +const utils = __webpack_require__(329); +function read(directory, settings, callback) { + if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { + return readdirWithFileTypes(directory, settings, callback); + } + return readdir(directory, settings, callback); +} +exports.read = read; +function readdirWithFileTypes(directory, settings, callback) { + settings.fs.readdir(directory, { withFileTypes: true }, (readdirError, dirents) => { + if (readdirError !== null) { + return callFailureCallback(callback, readdirError); + } + const entries = dirents.map((dirent) => ({ + dirent, + name: dirent.name, + path: `${directory}${settings.pathSegmentSeparator}${dirent.name}` + })); + if (!settings.followSymbolicLinks) { + return callSuccessCallback(callback, entries); + } + const tasks = entries.map((entry) => makeRplTaskEntry(entry, settings)); + rpl(tasks, (rplError, rplEntries) => { + if (rplError !== null) { + return callFailureCallback(callback, rplError); + } + callSuccessCallback(callback, rplEntries); + }); + }); +} +exports.readdirWithFileTypes = readdirWithFileTypes; +function makeRplTaskEntry(entry, settings) { + return (done) => { + if (!entry.dirent.isSymbolicLink()) { + return done(null, entry); + } + settings.fs.stat(entry.path, (statError, stats) => { + if (statError !== null) { + if (settings.throwErrorOnBrokenSymbolicLink) { + return done(statError); + } + return done(null, entry); + } + entry.dirent = utils.fs.createDirentFromStats(entry.name, stats); + return done(null, entry); + }); + }; +} +function readdir(directory, settings, callback) { + settings.fs.readdir(directory, (readdirError, names) => { + if (readdirError !== null) { + return callFailureCallback(callback, readdirError); + } + const filepaths = names.map((name) => `${directory}${settings.pathSegmentSeparator}${name}`); + const tasks = filepaths.map((filepath) => { + return (done) => fsStat.stat(filepath, settings.fsStatSettings, done); + }); + rpl(tasks, (rplError, results) => { + if (rplError !== null) { + return callFailureCallback(callback, rplError); + } + const entries = []; + names.forEach((name, index) => { + const stats = results[index]; + const entry = { + name, + path: filepaths[index], + dirent: utils.fs.createDirentFromStats(name, stats) + }; + if (settings.stats) { + entry.stats = stats; + } + entries.push(entry); + }); + callSuccessCallback(callback, entries); + }); + }); +} +exports.readdir = readdir; +function callFailureCallback(callback, error) { + callback(error); +} +function callSuccessCallback(callback, result) { + callback(null, result); +} - break; - } - } - if (opts.noext === true) { - isExtglob = false; - isGlob = false; - } +/***/ }), +/* 327 */ +/***/ (function(module, exports) { - let base = str; - let prefix = ''; - let glob = ''; +module.exports = runParallel - if (start > 0) { - prefix = str.slice(0, start); - str = str.slice(start); - lastIndex -= start; - } +function runParallel (tasks, cb) { + var results, pending, keys + var isSync = true - if (base && isGlob === true && lastIndex > 0) { - base = str.slice(0, lastIndex); - glob = str.slice(lastIndex); - } else if (isGlob === true) { - base = ''; - glob = str; + if (Array.isArray(tasks)) { + results = [] + pending = tasks.length } else { - base = str; + keys = Object.keys(tasks) + results = {} + pending = keys.length } - if (base && base !== '' && base !== '/' && base !== str) { - if (isPathSeparator(base.charCodeAt(base.length - 1))) { - base = base.slice(0, -1); + function done (err) { + function end () { + if (cb) cb(err, results) + cb = null } + if (isSync) process.nextTick(end) + else end() } - if (opts.unescape === true) { - if (glob) glob = utils.removeBackslashes(glob); - - if (base && backslashes === true) { - base = utils.removeBackslashes(base); + function each (i, err, result) { + results[i] = result + if (--pending === 0 || err) { + done(err) } } - const state = { - prefix, - input, - start, - base, - glob, - isBrace, - isBracket, - isGlob, - isExtglob, - isGlobstar, - negated - }; - - if (opts.tokens === true) { - state.maxDepth = 0; - if (!isPathSeparator(code)) { - tokens.push(token); - } - state.tokens = tokens; + if (!pending) { + // empty + done(null) + } else if (keys) { + // object + keys.forEach(function (key) { + tasks[key](function (err, result) { each(key, err, result) }) + }) + } else { + // array + tasks.forEach(function (task, i) { + task(function (err, result) { each(i, err, result) }) + }) } - if (opts.parts === true || opts.tokens === true) { - let prevIndex; + isSync = false +} - for (let idx = 0; idx < slashes.length; idx++) { - const n = prevIndex ? prevIndex + 1 : start; - const i = slashes[idx]; - const value = input.slice(n, i); - if (opts.tokens) { - if (idx === 0 && start !== 0) { - tokens[idx].isPrefix = true; - tokens[idx].value = prefix; - } else { - tokens[idx].value = value; - } - depth(tokens[idx]); - state.maxDepth += tokens[idx].depth; - } - if (idx !== 0 || value !== '') { - parts.push(value); - } - prevIndex = i; - } - if (prevIndex && prevIndex + 1 < input.length) { - const value = input.slice(prevIndex + 1); - parts.push(value); +/***/ }), +/* 328 */ +/***/ (function(module, exports, __webpack_require__) { - if (opts.tokens) { - tokens[tokens.length - 1].value = value; - depth(tokens[tokens.length - 1]); - state.maxDepth += tokens[tokens.length - 1].depth; - } - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const NODE_PROCESS_VERSION_PARTS = process.versions.node.split('.'); +const MAJOR_VERSION = parseInt(NODE_PROCESS_VERSION_PARTS[0], 10); +const MINOR_VERSION = parseInt(NODE_PROCESS_VERSION_PARTS[1], 10); +const SUPPORTED_MAJOR_VERSION = 10; +const SUPPORTED_MINOR_VERSION = 10; +const IS_MATCHED_BY_MAJOR = MAJOR_VERSION > SUPPORTED_MAJOR_VERSION; +const IS_MATCHED_BY_MAJOR_AND_MINOR = MAJOR_VERSION === SUPPORTED_MAJOR_VERSION && MINOR_VERSION >= SUPPORTED_MINOR_VERSION; +/** + * IS `true` for Node.js 10.10 and greater. + */ +exports.IS_SUPPORT_READDIR_WITH_FILE_TYPES = IS_MATCHED_BY_MAJOR || IS_MATCHED_BY_MAJOR_AND_MINOR; - state.slashes = slashes; - state.parts = parts; - } - return state; -}; +/***/ }), +/* 329 */ +/***/ (function(module, exports, __webpack_require__) { -module.exports = scan; +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const fs = __webpack_require__(330); +exports.fs = fs; /***/ }), -/* 318 */ +/* 330 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +class DirentFromStats { + constructor(name, stats) { + this.name = name; + this.isBlockDevice = stats.isBlockDevice.bind(stats); + this.isCharacterDevice = stats.isCharacterDevice.bind(stats); + this.isDirectory = stats.isDirectory.bind(stats); + this.isFIFO = stats.isFIFO.bind(stats); + this.isFile = stats.isFile.bind(stats); + this.isSocket = stats.isSocket.bind(stats); + this.isSymbolicLink = stats.isSymbolicLink.bind(stats); + } +} +function createDirentFromStats(name, stats) { + return new DirentFromStats(name, stats); +} +exports.createDirentFromStats = createDirentFromStats; -const path = __webpack_require__(4); -const win32 = process.platform === 'win32'; -const { - REGEX_BACKSLASH, - REGEX_REMOVE_BACKSLASH, - REGEX_SPECIAL_CHARS, - REGEX_SPECIAL_CHARS_GLOBAL -} = __webpack_require__(319); - -exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); -exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); -exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str); -exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1'); -exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/'); +/***/ }), +/* 331 */ +/***/ (function(module, exports, __webpack_require__) { -exports.removeBackslashes = str => { - return str.replace(REGEX_REMOVE_BACKSLASH, match => { - return match === '\\' ? '' : match; - }); -}; +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const fsStat = __webpack_require__(317); +const constants_1 = __webpack_require__(328); +const utils = __webpack_require__(329); +function read(directory, settings) { + if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { + return readdirWithFileTypes(directory, settings); + } + return readdir(directory, settings); +} +exports.read = read; +function readdirWithFileTypes(directory, settings) { + const dirents = settings.fs.readdirSync(directory, { withFileTypes: true }); + return dirents.map((dirent) => { + const entry = { + dirent, + name: dirent.name, + path: `${directory}${settings.pathSegmentSeparator}${dirent.name}` + }; + if (entry.dirent.isSymbolicLink() && settings.followSymbolicLinks) { + try { + const stats = settings.fs.statSync(entry.path); + entry.dirent = utils.fs.createDirentFromStats(entry.name, stats); + } + catch (error) { + if (settings.throwErrorOnBrokenSymbolicLink) { + throw error; + } + } + } + return entry; + }); +} +exports.readdirWithFileTypes = readdirWithFileTypes; +function readdir(directory, settings) { + const names = settings.fs.readdirSync(directory); + return names.map((name) => { + const entryPath = `${directory}${settings.pathSegmentSeparator}${name}`; + const stats = fsStat.statSync(entryPath, settings.fsStatSettings); + const entry = { + name, + path: entryPath, + dirent: utils.fs.createDirentFromStats(name, stats) + }; + if (settings.stats) { + entry.stats = stats; + } + return entry; + }); +} +exports.readdir = readdir; -exports.supportsLookbehinds = () => { - const segs = process.version.slice(1).split('.').map(Number); - if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) { - return true; - } - return false; -}; -exports.isWindows = options => { - if (options && typeof options.windows === 'boolean') { - return options.windows; - } - return win32 === true || path.sep === '\\'; -}; +/***/ }), +/* 332 */ +/***/ (function(module, exports, __webpack_require__) { -exports.escapeLast = (input, char, lastIdx) => { - const idx = input.lastIndexOf(char, lastIdx); - if (idx === -1) return input; - if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1); - return `${input.slice(0, idx)}\\${input.slice(idx)}`; -}; +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const path = __webpack_require__(4); +const fsStat = __webpack_require__(317); +const fs = __webpack_require__(333); +class Settings { + constructor(_options = {}) { + this._options = _options; + this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, false); + this.fs = fs.createFileSystemAdapter(this._options.fs); + this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path.sep); + this.stats = this._getValue(this._options.stats, false); + this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true); + this.fsStatSettings = new fsStat.Settings({ + followSymbolicLink: this.followSymbolicLinks, + fs: this.fs, + throwErrorOnBrokenSymbolicLink: this.throwErrorOnBrokenSymbolicLink + }); + } + _getValue(option, value) { + return option === undefined ? value : option; + } +} +exports.default = Settings; -exports.removePrefix = (input, state = {}) => { - let output = input; - if (output.startsWith('./')) { - output = output.slice(2); - state.prefix = './'; - } - return output; -}; -exports.wrapOutput = (input, state = {}, options = {}) => { - const prepend = options.contains ? '' : '^'; - const append = options.contains ? '' : '$'; +/***/ }), +/* 333 */ +/***/ (function(module, exports, __webpack_require__) { - let output = `${prepend}(?:${input})${append}`; - if (state.negated === true) { - output = `(?:^(?!${output}).*$)`; - } - return output; -}; +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const fs = __webpack_require__(134); +exports.FILE_SYSTEM_ADAPTER = { + lstat: fs.lstat, + stat: fs.stat, + lstatSync: fs.lstatSync, + statSync: fs.statSync, + readdir: fs.readdir, + readdirSync: fs.readdirSync +}; +function createFileSystemAdapter(fsMethods) { + if (fsMethods === undefined) { + return exports.FILE_SYSTEM_ADAPTER; + } + return Object.assign(Object.assign({}, exports.FILE_SYSTEM_ADAPTER), fsMethods); +} +exports.createFileSystemAdapter = createFileSystemAdapter; /***/ }), -/* 319 */ +/* 334 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const path = __webpack_require__(4); -const WIN_SLASH = '\\\\/'; -const WIN_NO_SLASH = `[^${WIN_SLASH}]`; +var reusify = __webpack_require__(335) -/** - * Posix glob regex - */ +function fastqueue (context, worker, concurrency) { + if (typeof context === 'function') { + concurrency = worker + worker = context + context = null + } -const DOT_LITERAL = '\\.'; -const PLUS_LITERAL = '\\+'; -const QMARK_LITERAL = '\\?'; -const SLASH_LITERAL = '\\/'; -const ONE_CHAR = '(?=.)'; -const QMARK = '[^/]'; -const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`; -const START_ANCHOR = `(?:^|${SLASH_LITERAL})`; -const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`; -const NO_DOT = `(?!${DOT_LITERAL})`; -const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`; -const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`; -const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`; -const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`; -const STAR = `${QMARK}*?`; + var cache = reusify(Task) + var queueHead = null + var queueTail = null + var _running = 0 -const POSIX_CHARS = { - DOT_LITERAL, - PLUS_LITERAL, - QMARK_LITERAL, - SLASH_LITERAL, - ONE_CHAR, - QMARK, - END_ANCHOR, - DOTS_SLASH, - NO_DOT, - NO_DOTS, - NO_DOT_SLASH, - NO_DOTS_SLASH, - QMARK_NO_DOT, - STAR, - START_ANCHOR -}; + var self = { + push: push, + drain: noop, + saturated: noop, + pause: pause, + paused: false, + concurrency: concurrency, + running: running, + resume: resume, + idle: idle, + length: length, + unshift: unshift, + empty: noop, + kill: kill, + killAndDrain: killAndDrain + } -/** - * Windows glob regex - */ + return self -const WINDOWS_CHARS = { - ...POSIX_CHARS, + function running () { + return _running + } - SLASH_LITERAL: `[${WIN_SLASH}]`, - QMARK: WIN_NO_SLASH, - STAR: `${WIN_NO_SLASH}*?`, - DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`, - NO_DOT: `(?!${DOT_LITERAL})`, - NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, - NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`, - NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, - QMARK_NO_DOT: `[^.${WIN_SLASH}]`, - START_ANCHOR: `(?:^|[${WIN_SLASH}])`, - END_ANCHOR: `(?:[${WIN_SLASH}]|$)` -}; + function pause () { + self.paused = true + } -/** - * POSIX Bracket Regex - */ + function length () { + var current = queueHead + var counter = 0 -const POSIX_REGEX_SOURCE = { - alnum: 'a-zA-Z0-9', - alpha: 'a-zA-Z', - ascii: '\\x00-\\x7F', - blank: ' \\t', - cntrl: '\\x00-\\x1F\\x7F', - digit: '0-9', - graph: '\\x21-\\x7E', - lower: 'a-z', - print: '\\x20-\\x7E ', - punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~', - space: ' \\t\\r\\n\\v\\f', - upper: 'A-Z', - word: 'A-Za-z0-9_', - xdigit: 'A-Fa-f0-9' -}; + while (current) { + current = current.next + counter++ + } -module.exports = { - MAX_LENGTH: 1024 * 64, - POSIX_REGEX_SOURCE, + return counter + } - // regular expressions - REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g, - REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/, - REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/, - REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g, - REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g, - REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g, + function resume () { + if (!self.paused) return + self.paused = false + for (var i = 0; i < self.concurrency; i++) { + _running++ + release() + } + } - // Replace globs with equivalent patterns to reduce parsing time. - REPLACEMENTS: { - '***': '*', - '**/**': '**', - '**/**/**': '**' - }, + function idle () { + return _running === 0 && self.length() === 0 + } - // Digits - CHAR_0: 48, /* 0 */ - CHAR_9: 57, /* 9 */ + function push (value, done) { + var current = cache.get() - // Alphabet chars. - CHAR_UPPERCASE_A: 65, /* A */ - CHAR_LOWERCASE_A: 97, /* a */ - CHAR_UPPERCASE_Z: 90, /* Z */ - CHAR_LOWERCASE_Z: 122, /* z */ + current.context = context + current.release = release + current.value = value + current.callback = done || noop - CHAR_LEFT_PARENTHESES: 40, /* ( */ - CHAR_RIGHT_PARENTHESES: 41, /* ) */ + if (_running === self.concurrency || self.paused) { + if (queueTail) { + queueTail.next = current + queueTail = current + } else { + queueHead = current + queueTail = current + self.saturated() + } + } else { + _running++ + worker.call(context, current.value, current.worked) + } + } - CHAR_ASTERISK: 42, /* * */ + function unshift (value, done) { + var current = cache.get() - // Non-alphabetic chars. - CHAR_AMPERSAND: 38, /* & */ - CHAR_AT: 64, /* @ */ - CHAR_BACKWARD_SLASH: 92, /* \ */ - CHAR_CARRIAGE_RETURN: 13, /* \r */ - CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */ - CHAR_COLON: 58, /* : */ - CHAR_COMMA: 44, /* , */ - CHAR_DOT: 46, /* . */ - CHAR_DOUBLE_QUOTE: 34, /* " */ - CHAR_EQUAL: 61, /* = */ - CHAR_EXCLAMATION_MARK: 33, /* ! */ - CHAR_FORM_FEED: 12, /* \f */ - CHAR_FORWARD_SLASH: 47, /* / */ - CHAR_GRAVE_ACCENT: 96, /* ` */ - CHAR_HASH: 35, /* # */ - CHAR_HYPHEN_MINUS: 45, /* - */ - CHAR_LEFT_ANGLE_BRACKET: 60, /* < */ - CHAR_LEFT_CURLY_BRACE: 123, /* { */ - CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */ - CHAR_LINE_FEED: 10, /* \n */ - CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */ - CHAR_PERCENT: 37, /* % */ - CHAR_PLUS: 43, /* + */ - CHAR_QUESTION_MARK: 63, /* ? */ - CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */ - CHAR_RIGHT_CURLY_BRACE: 125, /* } */ - CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */ - CHAR_SEMICOLON: 59, /* ; */ - CHAR_SINGLE_QUOTE: 39, /* ' */ - CHAR_SPACE: 32, /* */ - CHAR_TAB: 9, /* \t */ - CHAR_UNDERSCORE: 95, /* _ */ - CHAR_VERTICAL_LINE: 124, /* | */ - CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */ + current.context = context + current.release = release + current.value = value + current.callback = done || noop - SEP: path.sep, + if (_running === self.concurrency || self.paused) { + if (queueHead) { + current.next = queueHead + queueHead = current + } else { + queueHead = current + queueTail = current + self.saturated() + } + } else { + _running++ + worker.call(context, current.value, current.worked) + } + } - /** - * Create EXTGLOB_CHARS - */ + function release (holder) { + if (holder) { + cache.release(holder) + } + var next = queueHead + if (next) { + if (!self.paused) { + if (queueTail === queueHead) { + queueTail = null + } + queueHead = next.next + next.next = null + worker.call(context, next.value, next.worked) + if (queueTail === null) { + self.empty() + } + } else { + _running-- + } + } else if (--_running === 0) { + self.drain() + } + } - extglobChars(chars) { - return { - '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` }, - '?': { type: 'qmark', open: '(?:', close: ')?' }, - '+': { type: 'plus', open: '(?:', close: ')+' }, - '*': { type: 'star', open: '(?:', close: ')*' }, - '@': { type: 'at', open: '(?:', close: ')' } - }; - }, + function kill () { + queueHead = null + queueTail = null + self.drain = noop + } - /** - * Create GLOB_CHARS - */ + function killAndDrain () { + queueHead = null + queueTail = null + self.drain() + self.drain = noop + } +} - globChars(win32) { - return win32 === true ? WINDOWS_CHARS : POSIX_CHARS; +function noop () {} + +function Task () { + this.value = null + this.callback = noop + this.next = null + this.release = noop + this.context = null + + var self = this + + this.worked = function worked (err, result) { + var callback = self.callback + self.value = null + self.callback = noop + callback.call(self.context, err, result) + self.release(self) } -}; +} + +module.exports = fastqueue /***/ }), -/* 320 */ +/* 335 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const constants = __webpack_require__(319); -const utils = __webpack_require__(318); +function reusify (Constructor) { + var head = new Constructor() + var tail = head -/** - * Constants - */ + function get () { + var current = head -const { - MAX_LENGTH, - POSIX_REGEX_SOURCE, - REGEX_NON_SPECIAL_CHARS, - REGEX_SPECIAL_CHARS_BACKREF, - REPLACEMENTS -} = constants; + if (current.next) { + head = current.next + } else { + head = new Constructor() + tail = head + } -/** - * Helpers - */ + current.next = null -const expandRange = (args, options) => { - if (typeof options.expandRange === 'function') { - return options.expandRange(...args, options); + return current } - args.sort(); - const value = `[${args.join('-')}]`; - - try { - /* eslint-disable-next-line no-new */ - new RegExp(value); - } catch (ex) { - return args.map(v => utils.escapeRegex(v)).join('..'); + function release (obj) { + tail.next = obj + tail = obj } - return value; -}; - -/** - * Create the message for a syntax error - */ - -const syntaxError = (type, char) => { - return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`; -}; + return { + get: get, + release: release + } +} -/** - * Parse the given input string. - * @param {String} input - * @param {Object} options - * @return {Object} - */ +module.exports = reusify -const parse = (input, options) => { - if (typeof input !== 'string') { - throw new TypeError('Expected a string'); - } - input = REPLACEMENTS[input] || input; +/***/ }), +/* 336 */ +/***/ (function(module, exports, __webpack_require__) { - const opts = { ...options }; - const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +function isFatalError(settings, error) { + if (settings.errorFilter === null) { + return true; + } + return !settings.errorFilter(error); +} +exports.isFatalError = isFatalError; +function isAppliedFilter(filter, value) { + return filter === null || filter(value); +} +exports.isAppliedFilter = isAppliedFilter; +function replacePathSegmentSeparator(filepath, separator) { + return filepath.split(/[\\/]/).join(separator); +} +exports.replacePathSegmentSeparator = replacePathSegmentSeparator; +function joinPathSegments(a, b, separator) { + if (a === '') { + return b; + } + return a + separator + b; +} +exports.joinPathSegments = joinPathSegments; - let len = input.length; - if (len > max) { - throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); - } - const bos = { type: 'bos', value: '', output: opts.prepend || '' }; - const tokens = [bos]; +/***/ }), +/* 337 */ +/***/ (function(module, exports, __webpack_require__) { - const capture = opts.capture ? '' : '?:'; - const win32 = utils.isWindows(options); +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const common = __webpack_require__(336); +class Reader { + constructor(_root, _settings) { + this._root = _root; + this._settings = _settings; + this._root = common.replacePathSegmentSeparator(_root, _settings.pathSegmentSeparator); + } +} +exports.default = Reader; - // create constants based on platform, for windows or posix - const PLATFORM_CHARS = constants.globChars(win32); - const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS); - const { - DOT_LITERAL, - PLUS_LITERAL, - SLASH_LITERAL, - ONE_CHAR, - DOTS_SLASH, - NO_DOT, - NO_DOT_SLASH, - NO_DOTS_SLASH, - QMARK, - QMARK_NO_DOT, - STAR, - START_ANCHOR - } = PLATFORM_CHARS; +/***/ }), +/* 338 */ +/***/ (function(module, exports, __webpack_require__) { - const globstar = (opts) => { - return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; - }; +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const stream_1 = __webpack_require__(138); +const async_1 = __webpack_require__(324); +class StreamProvider { + constructor(_root, _settings) { + this._root = _root; + this._settings = _settings; + this._reader = new async_1.default(this._root, this._settings); + this._stream = new stream_1.Readable({ + objectMode: true, + read: () => { }, + destroy: this._reader.destroy.bind(this._reader) + }); + } + read() { + this._reader.onError((error) => { + this._stream.emit('error', error); + }); + this._reader.onEntry((entry) => { + this._stream.push(entry); + }); + this._reader.onEnd(() => { + this._stream.push(null); + }); + this._reader.read(); + return this._stream; + } +} +exports.default = StreamProvider; - const nodot = opts.dot ? '' : NO_DOT; - const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT; - let star = opts.bash === true ? globstar(opts) : STAR; - if (opts.capture) { - star = `(${star})`; - } +/***/ }), +/* 339 */ +/***/ (function(module, exports, __webpack_require__) { - // minimatch options support - if (typeof opts.noext === 'boolean') { - opts.noextglob = opts.noext; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const sync_1 = __webpack_require__(340); +class SyncProvider { + constructor(_root, _settings) { + this._root = _root; + this._settings = _settings; + this._reader = new sync_1.default(this._root, this._settings); + } + read() { + return this._reader.read(); + } +} +exports.default = SyncProvider; - const state = { - input, - index: -1, - start: 0, - dot: opts.dot === true, - consumed: '', - output: '', - prefix: '', - backtrack: false, - negated: false, - brackets: 0, - braces: 0, - parens: 0, - quotes: 0, - globstar: false, - tokens - }; - input = utils.removePrefix(input, state); - len = input.length; +/***/ }), +/* 340 */ +/***/ (function(module, exports, __webpack_require__) { - const extglobs = []; - const braces = []; - const stack = []; - let prev = bos; - let value; +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const fsScandir = __webpack_require__(325); +const common = __webpack_require__(336); +const reader_1 = __webpack_require__(337); +class SyncReader extends reader_1.default { + constructor() { + super(...arguments); + this._scandir = fsScandir.scandirSync; + this._storage = new Set(); + this._queue = new Set(); + } + read() { + this._pushToQueue(this._root, this._settings.basePath); + this._handleQueue(); + return [...this._storage]; + } + _pushToQueue(directory, base) { + this._queue.add({ directory, base }); + } + _handleQueue() { + for (const item of this._queue.values()) { + this._handleDirectory(item.directory, item.base); + } + } + _handleDirectory(directory, base) { + try { + const entries = this._scandir(directory, this._settings.fsScandirSettings); + for (const entry of entries) { + this._handleEntry(entry, base); + } + } + catch (error) { + this._handleError(error); + } + } + _handleError(error) { + if (!common.isFatalError(this._settings, error)) { + return; + } + throw error; + } + _handleEntry(entry, base) { + const fullpath = entry.path; + if (base !== undefined) { + entry.path = common.joinPathSegments(base, entry.name, this._settings.pathSegmentSeparator); + } + if (common.isAppliedFilter(this._settings.entryFilter, entry)) { + this._pushToStorage(entry); + } + if (entry.dirent.isDirectory() && common.isAppliedFilter(this._settings.deepFilter, entry)) { + this._pushToQueue(fullpath, entry.path); + } + } + _pushToStorage(entry) { + this._storage.add(entry); + } +} +exports.default = SyncReader; - /** - * Tokenizing helpers - */ - const eos = () => state.index === len - 1; - const peek = state.peek = (n = 1) => input[state.index + n]; - const advance = state.advance = () => input[++state.index]; - const remaining = () => input.slice(state.index + 1); - const consume = (value = '', num = 0) => { - state.consumed += value; - state.index += num; - }; - const append = token => { - state.output += token.output != null ? token.output : token.value; - consume(token.value); - }; +/***/ }), +/* 341 */ +/***/ (function(module, exports, __webpack_require__) { - const negate = () => { - let count = 1; +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const path = __webpack_require__(4); +const fsScandir = __webpack_require__(325); +class Settings { + constructor(_options = {}) { + this._options = _options; + this.basePath = this._getValue(this._options.basePath, undefined); + this.concurrency = this._getValue(this._options.concurrency, Infinity); + this.deepFilter = this._getValue(this._options.deepFilter, null); + this.entryFilter = this._getValue(this._options.entryFilter, null); + this.errorFilter = this._getValue(this._options.errorFilter, null); + this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path.sep); + this.fsScandirSettings = new fsScandir.Settings({ + followSymbolicLinks: this._options.followSymbolicLinks, + fs: this._options.fs, + pathSegmentSeparator: this._options.pathSegmentSeparator, + stats: this._options.stats, + throwErrorOnBrokenSymbolicLink: this._options.throwErrorOnBrokenSymbolicLink + }); + } + _getValue(option, value) { + return option === undefined ? value : option; + } +} +exports.default = Settings; - while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) { - advance(); - state.start++; - count++; - } - if (count % 2 === 0) { - return false; - } +/***/ }), +/* 342 */ +/***/ (function(module, exports, __webpack_require__) { - state.negated = true; - state.start++; - return true; - }; +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const path = __webpack_require__(4); +const fsStat = __webpack_require__(317); +const utils = __webpack_require__(287); +class Reader { + constructor(_settings) { + this._settings = _settings; + this._fsStatSettings = new fsStat.Settings({ + followSymbolicLink: this._settings.followSymbolicLinks, + fs: this._settings.fs, + throwErrorOnBrokenSymbolicLink: this._settings.followSymbolicLinks + }); + } + _getFullEntryPath(filepath) { + return path.resolve(this._settings.cwd, filepath); + } + _makeEntry(stats, pattern) { + const entry = { + name: pattern, + path: pattern, + dirent: utils.fs.createDirentFromStats(pattern, stats) + }; + if (this._settings.stats) { + entry.stats = stats; + } + return entry; + } + _isFatalError(error) { + return !utils.errno.isEnoentCodeError(error) && !this._settings.suppressErrors; + } +} +exports.default = Reader; - const increment = type => { - state[type]++; - stack.push(type); - }; - const decrement = type => { - state[type]--; - stack.pop(); - }; +/***/ }), +/* 343 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Push tokens onto the tokens array. This helper speeds up - * tokenizing by 1) helping us avoid backtracking as much as possible, - * and 2) helping us avoid creating extra tokens when consecutive - * characters are plain text. This improves performance and simplifies - * lookbehinds. - */ +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const path = __webpack_require__(4); +const deep_1 = __webpack_require__(344); +const entry_1 = __webpack_require__(347); +const error_1 = __webpack_require__(348); +const entry_2 = __webpack_require__(349); +class Provider { + constructor(_settings) { + this._settings = _settings; + this.errorFilter = new error_1.default(this._settings); + this.entryFilter = new entry_1.default(this._settings, this._getMicromatchOptions()); + this.deepFilter = new deep_1.default(this._settings, this._getMicromatchOptions()); + this.entryTransformer = new entry_2.default(this._settings); + } + _getRootDirectory(task) { + return path.resolve(this._settings.cwd, task.base); + } + _getReaderOptions(task) { + const basePath = task.base === '.' ? '' : task.base; + return { + basePath, + pathSegmentSeparator: '/', + concurrency: this._settings.concurrency, + deepFilter: this.deepFilter.getFilter(basePath, task.positive, task.negative), + entryFilter: this.entryFilter.getFilter(task.positive, task.negative), + errorFilter: this.errorFilter.getFilter(), + followSymbolicLinks: this._settings.followSymbolicLinks, + fs: this._settings.fs, + stats: this._settings.stats, + throwErrorOnBrokenSymbolicLink: this._settings.throwErrorOnBrokenSymbolicLink, + transform: this.entryTransformer.getTransformer() + }; + } + _getMicromatchOptions() { + return { + dot: this._settings.dot, + matchBase: this._settings.baseNameMatch, + nobrace: !this._settings.braceExpansion, + nocase: !this._settings.caseSensitiveMatch, + noext: !this._settings.extglob, + noglobstar: !this._settings.globstar, + posix: true, + strictSlashes: false + }; + } +} +exports.default = Provider; - const push = tok => { - if (prev.type === 'globstar') { - const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace'); - const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren')); - if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) { - state.output = state.output.slice(0, -prev.output.length); - prev.type = 'star'; - prev.value = '*'; - prev.output = star; - state.output += prev.output; - } - } +/***/ }), +/* 344 */ +/***/ (function(module, exports, __webpack_require__) { - if (extglobs.length && tok.type !== 'paren' && !EXTGLOB_CHARS[tok.value]) { - extglobs[extglobs.length - 1].inner += tok.value; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const utils = __webpack_require__(287); +const partial_1 = __webpack_require__(345); +class DeepFilter { + constructor(_settings, _micromatchOptions) { + this._settings = _settings; + this._micromatchOptions = _micromatchOptions; + } + getFilter(basePath, positive, negative) { + const matcher = this._getMatcher(positive); + const negativeRe = this._getNegativePatternsRe(negative); + return (entry) => this._filter(basePath, entry, matcher, negativeRe); + } + _getMatcher(patterns) { + return new partial_1.default(patterns, this._settings, this._micromatchOptions); + } + _getNegativePatternsRe(patterns) { + const affectDepthOfReadingPatterns = patterns.filter(utils.pattern.isAffectDepthOfReadingPattern); + return utils.pattern.convertPatternsToRe(affectDepthOfReadingPatterns, this._micromatchOptions); + } + _filter(basePath, entry, matcher, negativeRe) { + const depth = this._getEntryLevel(basePath, entry.path); + if (this._isSkippedByDeep(depth)) { + return false; + } + if (this._isSkippedSymbolicLink(entry)) { + return false; + } + const filepath = utils.path.removeLeadingDotSegment(entry.path); + if (this._isSkippedByPositivePatterns(filepath, matcher)) { + return false; + } + return this._isSkippedByNegativePatterns(filepath, negativeRe); + } + _isSkippedByDeep(entryDepth) { + return entryDepth >= this._settings.deep; + } + _isSkippedSymbolicLink(entry) { + return !this._settings.followSymbolicLinks && entry.dirent.isSymbolicLink(); + } + _getEntryLevel(basePath, entryPath) { + const basePathDepth = basePath.split('/').length; + const entryPathDepth = entryPath.split('/').length; + return entryPathDepth - (basePath === '' ? 0 : basePathDepth); + } + _isSkippedByPositivePatterns(entryPath, matcher) { + return !this._settings.baseNameMatch && !matcher.match(entryPath); + } + _isSkippedByNegativePatterns(entryPath, negativeRe) { + return !utils.pattern.matchAny(entryPath, negativeRe); + } +} +exports.default = DeepFilter; - if (tok.value || tok.output) append(tok); - if (prev && prev.type === 'text' && tok.type === 'text') { - prev.value += tok.value; - prev.output = (prev.output || '') + tok.value; - return; - } - tok.prev = prev; - tokens.push(tok); - prev = tok; - }; +/***/ }), +/* 345 */ +/***/ (function(module, exports, __webpack_require__) { - const extglobOpen = (type, value) => { - const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' }; +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const matcher_1 = __webpack_require__(346); +class PartialMatcher extends matcher_1.default { + match(filepath) { + const parts = filepath.split('/'); + const levels = parts.length; + const patterns = this._storage.filter((info) => !info.complete || info.segments.length > levels); + for (const pattern of patterns) { + const section = pattern.sections[0]; + /** + * In this case, the pattern has a globstar and we must read all directories unconditionally, + * but only if the level has reached the end of the first group. + * + * fixtures/{a,b}/** + * ^ true/false ^ always true + */ + if (!pattern.complete && levels > section.length) { + return true; + } + const match = parts.every((part, index) => { + const segment = pattern.segments[index]; + if (segment.dynamic && segment.patternRe.test(part)) { + return true; + } + if (!segment.dynamic && segment.pattern === part) { + return true; + } + return false; + }); + if (match) { + return true; + } + } + return false; + } +} +exports.default = PartialMatcher; - token.prev = prev; - token.parens = state.parens; - token.output = state.output; - const output = (opts.capture ? '(' : '') + token.open; - increment('parens'); - push({ type, value, output: state.output ? '' : ONE_CHAR }); - push({ type: 'paren', extglob: true, value: advance(), output }); - extglobs.push(token); - }; +/***/ }), +/* 346 */ +/***/ (function(module, exports, __webpack_require__) { - const extglobClose = token => { - let output = token.close + (opts.capture ? ')' : ''); +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const utils = __webpack_require__(287); +class Matcher { + constructor(_patterns, _settings, _micromatchOptions) { + this._patterns = _patterns; + this._settings = _settings; + this._micromatchOptions = _micromatchOptions; + this._storage = []; + this._fillStorage(); + } + _fillStorage() { + /** + * The original pattern may include `{,*,**,a/*}`, which will lead to problems with matching (unresolved level). + * So, before expand patterns with brace expansion into separated patterns. + */ + const patterns = utils.pattern.expandPatternsWithBraceExpansion(this._patterns); + for (const pattern of patterns) { + const segments = this._getPatternSegments(pattern); + const sections = this._splitSegmentsIntoSections(segments); + this._storage.push({ + complete: sections.length <= 1, + pattern, + segments, + sections + }); + } + } + _getPatternSegments(pattern) { + const parts = utils.pattern.getPatternParts(pattern, this._micromatchOptions); + return parts.map((part) => { + const dynamic = utils.pattern.isDynamicPattern(part, this._settings); + if (!dynamic) { + return { + dynamic: false, + pattern: part + }; + } + return { + dynamic: true, + pattern: part, + patternRe: utils.pattern.makeRe(part, this._micromatchOptions) + }; + }); + } + _splitSegmentsIntoSections(segments) { + return utils.array.splitWhen(segments, (segment) => segment.dynamic && utils.pattern.hasGlobStar(segment.pattern)); + } +} +exports.default = Matcher; - if (token.type === 'negate') { - let extglobStar = star; - if (token.inner && token.inner.length > 1 && token.inner.includes('/')) { - extglobStar = globstar(opts); - } +/***/ }), +/* 347 */ +/***/ (function(module, exports, __webpack_require__) { - if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) { - output = token.close = `)$))${extglobStar}`; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const utils = __webpack_require__(287); +class EntryFilter { + constructor(_settings, _micromatchOptions) { + this._settings = _settings; + this._micromatchOptions = _micromatchOptions; + this.index = new Map(); + } + getFilter(positive, negative) { + const positiveRe = utils.pattern.convertPatternsToRe(positive, this._micromatchOptions); + const negativeRe = utils.pattern.convertPatternsToRe(negative, this._micromatchOptions); + return (entry) => this._filter(entry, positiveRe, negativeRe); + } + _filter(entry, positiveRe, negativeRe) { + if (this._settings.unique) { + if (this._isDuplicateEntry(entry)) { + return false; + } + this._createIndexRecord(entry); + } + if (this._onlyFileFilter(entry) || this._onlyDirectoryFilter(entry)) { + return false; + } + if (this._isSkippedByAbsoluteNegativePatterns(entry, negativeRe)) { + return false; + } + const filepath = this._settings.baseNameMatch ? entry.name : entry.path; + return this._isMatchToPatterns(filepath, positiveRe) && !this._isMatchToPatterns(entry.path, negativeRe); + } + _isDuplicateEntry(entry) { + return this.index.has(entry.path); + } + _createIndexRecord(entry) { + this.index.set(entry.path, undefined); + } + _onlyFileFilter(entry) { + return this._settings.onlyFiles && !entry.dirent.isFile(); + } + _onlyDirectoryFilter(entry) { + return this._settings.onlyDirectories && !entry.dirent.isDirectory(); + } + _isSkippedByAbsoluteNegativePatterns(entry, negativeRe) { + if (!this._settings.absolute) { + return false; + } + const fullpath = utils.path.makeAbsolute(this._settings.cwd, entry.path); + return this._isMatchToPatterns(fullpath, negativeRe); + } + _isMatchToPatterns(entryPath, patternsRe) { + const filepath = utils.path.removeLeadingDotSegment(entryPath); + return utils.pattern.matchAny(filepath, patternsRe); + } +} +exports.default = EntryFilter; - if (token.prev.type === 'bos' && eos()) { - state.negatedExtglob = true; - } - } - push({ type: 'paren', extglob: true, value, output }); - decrement('parens'); - }; +/***/ }), +/* 348 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Fast paths - */ +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const utils = __webpack_require__(287); +class ErrorFilter { + constructor(_settings) { + this._settings = _settings; + } + getFilter() { + return (error) => this._isNonFatalError(error); + } + _isNonFatalError(error) { + return utils.errno.isEnoentCodeError(error) || this._settings.suppressErrors; + } +} +exports.default = ErrorFilter; - if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) { - let backslashes = false; - let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => { - if (first === '\\') { - backslashes = true; - return m; - } +/***/ }), +/* 349 */ +/***/ (function(module, exports, __webpack_require__) { - if (first === '?') { - if (esc) { - return esc + first + (rest ? QMARK.repeat(rest.length) : ''); - } - if (index === 0) { - return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : ''); - } - return QMARK.repeat(chars.length); - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const utils = __webpack_require__(287); +class EntryTransformer { + constructor(_settings) { + this._settings = _settings; + } + getTransformer() { + return (entry) => this._transform(entry); + } + _transform(entry) { + let filepath = entry.path; + if (this._settings.absolute) { + filepath = utils.path.makeAbsolute(this._settings.cwd, filepath); + filepath = utils.path.unixify(filepath); + } + if (this._settings.markDirectories && entry.dirent.isDirectory()) { + filepath += '/'; + } + if (!this._settings.objectMode) { + return filepath; + } + return Object.assign(Object.assign({}, entry), { path: filepath }); + } +} +exports.default = EntryTransformer; - if (first === '.') { - return DOT_LITERAL.repeat(chars.length); - } - if (first === '*') { - if (esc) { - return esc + first + (rest ? star : ''); - } - return star; - } - return esc ? m : `\\${m}`; - }); +/***/ }), +/* 350 */ +/***/ (function(module, exports, __webpack_require__) { - if (backslashes === true) { - if (opts.unescape === true) { - output = output.replace(/\\/g, ''); - } else { - output = output.replace(/\\+/g, m => { - return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : ''); - }); - } - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const stream_1 = __webpack_require__(138); +const stream_2 = __webpack_require__(316); +const provider_1 = __webpack_require__(343); +class ProviderStream extends provider_1.default { + constructor() { + super(...arguments); + this._reader = new stream_2.default(this._settings); + } + read(task) { + const root = this._getRootDirectory(task); + const options = this._getReaderOptions(task); + const source = this.api(root, task, options); + const destination = new stream_1.Readable({ objectMode: true, read: () => { } }); + source + .once('error', (error) => destination.emit('error', error)) + .on('data', (entry) => destination.emit('data', options.transform(entry))) + .once('end', () => destination.emit('end')); + destination + .once('close', () => source.destroy()); + return destination; + } + api(root, task, options) { + if (task.dynamic) { + return this._reader.dynamic(root, options); + } + return this._reader.static(task.patterns, options); + } +} +exports.default = ProviderStream; - if (output === input && opts.contains === true) { - state.output = input; - return state; - } - state.output = utils.wrapOutput(output, state, options); - return state; - } +/***/ }), +/* 351 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Tokenize input until we reach end-of-string - */ +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const sync_1 = __webpack_require__(352); +const provider_1 = __webpack_require__(343); +class ProviderSync extends provider_1.default { + constructor() { + super(...arguments); + this._reader = new sync_1.default(this._settings); + } + read(task) { + const root = this._getRootDirectory(task); + const options = this._getReaderOptions(task); + const entries = this.api(root, task, options); + return entries.map(options.transform); + } + api(root, task, options) { + if (task.dynamic) { + return this._reader.dynamic(root, options); + } + return this._reader.static(task.patterns, options); + } +} +exports.default = ProviderSync; - while (!eos()) { - value = advance(); - if (value === '\u0000') { - continue; - } +/***/ }), +/* 352 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Escaped characters - */ +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const fsStat = __webpack_require__(317); +const fsWalk = __webpack_require__(322); +const reader_1 = __webpack_require__(342); +class ReaderSync extends reader_1.default { + constructor() { + super(...arguments); + this._walkSync = fsWalk.walkSync; + this._statSync = fsStat.statSync; + } + dynamic(root, options) { + return this._walkSync(root, options); + } + static(patterns, options) { + const entries = []; + for (const pattern of patterns) { + const filepath = this._getFullEntryPath(pattern); + const entry = this._getEntry(filepath, pattern, options); + if (entry === null || !options.entryFilter(entry)) { + continue; + } + entries.push(entry); + } + return entries; + } + _getEntry(filepath, pattern, options) { + try { + const stats = this._getStat(filepath); + return this._makeEntry(stats, pattern); + } + catch (error) { + if (options.errorFilter(error)) { + return null; + } + throw error; + } + } + _getStat(filepath) { + return this._statSync(filepath, this._fsStatSettings); + } +} +exports.default = ReaderSync; - if (value === '\\') { - const next = peek(); - if (next === '/' && opts.bash !== true) { - continue; - } +/***/ }), +/* 353 */ +/***/ (function(module, exports, __webpack_require__) { - if (next === '.' || next === ';') { - continue; - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const fs = __webpack_require__(134); +const os = __webpack_require__(121); +const CPU_COUNT = os.cpus().length; +exports.DEFAULT_FILE_SYSTEM_ADAPTER = { + lstat: fs.lstat, + lstatSync: fs.lstatSync, + stat: fs.stat, + statSync: fs.statSync, + readdir: fs.readdir, + readdirSync: fs.readdirSync +}; +class Settings { + constructor(_options = {}) { + this._options = _options; + this.absolute = this._getValue(this._options.absolute, false); + this.baseNameMatch = this._getValue(this._options.baseNameMatch, false); + this.braceExpansion = this._getValue(this._options.braceExpansion, true); + this.caseSensitiveMatch = this._getValue(this._options.caseSensitiveMatch, true); + this.concurrency = this._getValue(this._options.concurrency, CPU_COUNT); + this.cwd = this._getValue(this._options.cwd, process.cwd()); + this.deep = this._getValue(this._options.deep, Infinity); + this.dot = this._getValue(this._options.dot, false); + this.extglob = this._getValue(this._options.extglob, true); + this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, true); + this.fs = this._getFileSystemMethods(this._options.fs); + this.globstar = this._getValue(this._options.globstar, true); + this.ignore = this._getValue(this._options.ignore, []); + this.markDirectories = this._getValue(this._options.markDirectories, false); + this.objectMode = this._getValue(this._options.objectMode, false); + this.onlyDirectories = this._getValue(this._options.onlyDirectories, false); + this.onlyFiles = this._getValue(this._options.onlyFiles, true); + this.stats = this._getValue(this._options.stats, false); + this.suppressErrors = this._getValue(this._options.suppressErrors, false); + this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, false); + this.unique = this._getValue(this._options.unique, true); + if (this.onlyDirectories) { + this.onlyFiles = false; + } + if (this.stats) { + this.objectMode = true; + } + } + _getValue(option, value) { + return option === undefined ? value : option; + } + _getFileSystemMethods(methods = {}) { + return Object.assign(Object.assign({}, exports.DEFAULT_FILE_SYSTEM_ADAPTER), methods); + } +} +exports.default = Settings; - if (!next) { - value += '\\'; - push({ type: 'text', value }); - continue; - } - // collapse slashes to reduce potential for exploits - const match = /^\\+/.exec(remaining()); - let slashes = 0; +/***/ }), +/* 354 */ +/***/ (function(module, exports, __webpack_require__) { - if (match && match[0].length > 2) { - slashes = match[0].length; - state.index += slashes; - if (slashes % 2 !== 0) { - value += '\\'; - } - } +"use strict"; - if (opts.unescape === true) { - value = advance() || ''; - } else { - value += advance() || ''; - } +const path = __webpack_require__(4); +const pathType = __webpack_require__(355); - if (state.brackets === 0) { - push({ type: 'text', value }); - continue; - } - } +const getExtensions = extensions => extensions.length > 1 ? `{${extensions.join(',')}}` : extensions[0]; - /** - * If we're inside a regex character class, continue - * until we reach the closing bracket. - */ +const getPath = (filepath, cwd) => { + const pth = filepath[0] === '!' ? filepath.slice(1) : filepath; + return path.isAbsolute(pth) ? pth : path.join(cwd, pth); +}; - if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) { - if (opts.posix !== false && value === ':') { - const inner = prev.value.slice(1); - if (inner.includes('[')) { - prev.posix = true; +const addExtensions = (file, extensions) => { + if (path.extname(file)) { + return `**/${file}`; + } - if (inner.includes(':')) { - const idx = prev.value.lastIndexOf('['); - const pre = prev.value.slice(0, idx); - const rest = prev.value.slice(idx + 2); - const posix = POSIX_REGEX_SOURCE[rest]; - if (posix) { - prev.value = pre + posix; - state.backtrack = true; - advance(); + return `**/${file}.${getExtensions(extensions)}`; +}; - if (!bos.output && tokens.indexOf(prev) === 1) { - bos.output = ONE_CHAR; - } - continue; - } - } - } - } +const getGlob = (directory, options) => { + if (options.files && !Array.isArray(options.files)) { + throw new TypeError(`Expected \`files\` to be of type \`Array\` but received type \`${typeof options.files}\``); + } - if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) { - value = `\\${value}`; - } + if (options.extensions && !Array.isArray(options.extensions)) { + throw new TypeError(`Expected \`extensions\` to be of type \`Array\` but received type \`${typeof options.extensions}\``); + } - if (value === ']' && (prev.value === '[' || prev.value === '[^')) { - value = `\\${value}`; - } + if (options.files && options.extensions) { + return options.files.map(x => path.posix.join(directory, addExtensions(x, options.extensions))); + } - if (opts.posix === true && value === '!' && prev.value === '[') { - value = '^'; - } + if (options.files) { + return options.files.map(x => path.posix.join(directory, `**/${x}`)); + } - prev.value += value; - append({ value }); - continue; - } + if (options.extensions) { + return [path.posix.join(directory, `**/*.${getExtensions(options.extensions)}`)]; + } - /** - * If we're inside a quoted string, continue - * until we reach the closing double quote. - */ + return [path.posix.join(directory, '**')]; +}; - if (state.quotes === 1 && value !== '"') { - value = utils.escapeRegex(value); - prev.value += value; - append({ value }); - continue; - } +module.exports = async (input, options) => { + options = { + cwd: process.cwd(), + ...options + }; - /** - * Double quotes - */ + if (typeof options.cwd !== 'string') { + throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof options.cwd}\``); + } - if (value === '"') { - state.quotes = state.quotes === 1 ? 0 : 1; - if (opts.keepQuotes === true) { - push({ type: 'text', value }); - } - continue; - } + const globs = await Promise.all([].concat(input).map(async x => { + const isDirectory = await pathType.isDirectory(getPath(x, options.cwd)); + return isDirectory ? getGlob(x, options) : x; + })); - /** - * Parentheses - */ + return [].concat.apply([], globs); // eslint-disable-line prefer-spread +}; - if (value === '(') { - increment('parens'); - push({ type: 'paren', value }); - continue; - } +module.exports.sync = (input, options) => { + options = { + cwd: process.cwd(), + ...options + }; - if (value === ')') { - if (state.parens === 0 && opts.strictBrackets === true) { - throw new SyntaxError(syntaxError('opening', '(')); - } + if (typeof options.cwd !== 'string') { + throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof options.cwd}\``); + } - const extglob = extglobs[extglobs.length - 1]; - if (extglob && state.parens === extglob.parens + 1) { - extglobClose(extglobs.pop()); - continue; - } + const globs = [].concat(input).map(x => pathType.isDirectorySync(getPath(x, options.cwd)) ? getGlob(x, options) : x); - push({ type: 'paren', value, output: state.parens ? ')' : '\\)' }); - decrement('parens'); - continue; - } + return [].concat.apply([], globs); // eslint-disable-line prefer-spread +}; - /** - * Square brackets - */ - if (value === '[') { - if (opts.nobracket === true || !remaining().includes(']')) { - if (opts.nobracket !== true && opts.strictBrackets === true) { - throw new SyntaxError(syntaxError('closing', ']')); - } +/***/ }), +/* 355 */ +/***/ (function(module, exports, __webpack_require__) { - value = `\\${value}`; - } else { - increment('brackets'); - } +"use strict"; - push({ type: 'bracket', value }); - continue; - } +const {promisify} = __webpack_require__(112); +const fs = __webpack_require__(134); - if (value === ']') { - if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) { - push({ type: 'text', value, output: `\\${value}` }); - continue; - } +async function isType(fsStatType, statsMethodName, filePath) { + if (typeof filePath !== 'string') { + throw new TypeError(`Expected a string, got ${typeof filePath}`); + } - if (state.brackets === 0) { - if (opts.strictBrackets === true) { - throw new SyntaxError(syntaxError('opening', '[')); - } + try { + const stats = await promisify(fs[fsStatType])(filePath); + return stats[statsMethodName](); + } catch (error) { + if (error.code === 'ENOENT') { + return false; + } - push({ type: 'text', value, output: `\\${value}` }); - continue; - } + throw error; + } +} - decrement('brackets'); +function isTypeSync(fsStatType, statsMethodName, filePath) { + if (typeof filePath !== 'string') { + throw new TypeError(`Expected a string, got ${typeof filePath}`); + } - const prevValue = prev.value.slice(1); - if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) { - value = `/${value}`; - } + try { + return fs[fsStatType](filePath)[statsMethodName](); + } catch (error) { + if (error.code === 'ENOENT') { + return false; + } - prev.value += value; - append({ value }); + throw error; + } +} - // when literal brackets are explicitly disabled - // assume we should match with a regex character class - if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) { - continue; - } +exports.isFile = isType.bind(null, 'stat', 'isFile'); +exports.isDirectory = isType.bind(null, 'stat', 'isDirectory'); +exports.isSymlink = isType.bind(null, 'lstat', 'isSymbolicLink'); +exports.isFileSync = isTypeSync.bind(null, 'statSync', 'isFile'); +exports.isDirectorySync = isTypeSync.bind(null, 'statSync', 'isDirectory'); +exports.isSymlinkSync = isTypeSync.bind(null, 'lstatSync', 'isSymbolicLink'); - const escaped = utils.escapeRegex(prev.value); - state.output = state.output.slice(0, -prev.value.length); - // when literal brackets are explicitly enabled - // assume we should escape the brackets to match literal characters - if (opts.literalBrackets === true) { - state.output += escaped; - prev.value = escaped; - continue; - } +/***/ }), +/* 356 */ +/***/ (function(module, exports, __webpack_require__) { - // when the user specifies nothing, try to match both - prev.value = `(${capture}${escaped}|${prev.value})`; - state.output += prev.value; - continue; - } +"use strict"; - /** - * Braces - */ +const {promisify} = __webpack_require__(112); +const fs = __webpack_require__(134); +const path = __webpack_require__(4); +const fastGlob = __webpack_require__(285); +const gitIgnore = __webpack_require__(357); +const slash = __webpack_require__(358); - if (value === '{' && opts.nobrace !== true) { - increment('braces'); +const DEFAULT_IGNORE = [ + '**/node_modules/**', + '**/flow-typed/**', + '**/coverage/**', + '**/.git' +]; - const open = { - type: 'brace', - value, - output: '(', - outputIndex: state.output.length, - tokensIndex: state.tokens.length - }; +const readFileP = promisify(fs.readFile); - braces.push(open); - push(open); - continue; - } - - if (value === '}') { - const brace = braces[braces.length - 1]; +const mapGitIgnorePatternTo = base => ignore => { + if (ignore.startsWith('!')) { + return '!' + path.posix.join(base, ignore.slice(1)); + } - if (opts.nobrace === true || !brace) { - push({ type: 'text', value, output: value }); - continue; - } + return path.posix.join(base, ignore); +}; - let output = ')'; +const parseGitIgnore = (content, options) => { + const base = slash(path.relative(options.cwd, path.dirname(options.fileName))); - if (brace.dots === true) { - const arr = tokens.slice(); - const range = []; + return content + .split(/\r?\n/) + .filter(Boolean) + .filter(line => !line.startsWith('#')) + .map(mapGitIgnorePatternTo(base)); +}; - for (let i = arr.length - 1; i >= 0; i--) { - tokens.pop(); - if (arr[i].type === 'brace') { - break; - } - if (arr[i].type !== 'dots') { - range.unshift(arr[i].value); - } - } +const reduceIgnore = files => { + return files.reduce((ignores, file) => { + ignores.add(parseGitIgnore(file.content, { + cwd: file.cwd, + fileName: file.filePath + })); + return ignores; + }, gitIgnore()); +}; - output = expandRange(range, opts); - state.backtrack = true; - } +const ensureAbsolutePathForCwd = (cwd, p) => { + if (path.isAbsolute(p)) { + if (p.startsWith(cwd)) { + return p; + } - if (brace.comma !== true && brace.dots !== true) { - const out = state.output.slice(0, brace.outputIndex); - const toks = state.tokens.slice(brace.tokensIndex); - brace.value = brace.output = '\\{'; - value = output = '\\}'; - state.output = out; - for (const t of toks) { - state.output += (t.output || t.value); - } - } + throw new Error(`Path ${p} is not in cwd ${cwd}`); + } - push({ type: 'brace', value, output }); - decrement('braces'); - braces.pop(); - continue; - } + return path.join(cwd, p); +}; - /** - * Pipes - */ +const getIsIgnoredPredecate = (ignores, cwd) => { + return p => ignores.ignores(slash(path.relative(cwd, ensureAbsolutePathForCwd(cwd, p)))); +}; - if (value === '|') { - if (extglobs.length > 0) { - extglobs[extglobs.length - 1].conditions++; - } - push({ type: 'text', value }); - continue; - } +const getFile = async (file, cwd) => { + const filePath = path.join(cwd, file); + const content = await readFileP(filePath, 'utf8'); - /** - * Commas - */ + return { + cwd, + filePath, + content + }; +}; - if (value === ',') { - let output = value; +const getFileSync = (file, cwd) => { + const filePath = path.join(cwd, file); + const content = fs.readFileSync(filePath, 'utf8'); - const brace = braces[braces.length - 1]; - if (brace && stack[stack.length - 1] === 'braces') { - brace.comma = true; - output = '|'; - } + return { + cwd, + filePath, + content + }; +}; - push({ type: 'comma', value, output }); - continue; - } +const normalizeOptions = ({ + ignore = [], + cwd = slash(process.cwd()) +} = {}) => { + return {ignore, cwd}; +}; - /** - * Slashes - */ +module.exports = async options => { + options = normalizeOptions(options); - if (value === '/') { - // if the beginning of the glob is "./", advance the start - // to the current index, and don't add the "./" characters - // to the state. This greatly simplifies lookbehinds when - // checking for BOS characters like "!" and "." (not "./") - if (prev.type === 'dot' && state.index === state.start + 1) { - state.start = state.index + 1; - state.consumed = ''; - state.output = ''; - tokens.pop(); - prev = bos; // reset "prev" to the first token - continue; - } + const paths = await fastGlob('**/.gitignore', { + ignore: DEFAULT_IGNORE.concat(options.ignore), + cwd: options.cwd + }); - push({ type: 'slash', value, output: SLASH_LITERAL }); - continue; - } + const files = await Promise.all(paths.map(file => getFile(file, options.cwd))); + const ignores = reduceIgnore(files); - /** - * Dots - */ + return getIsIgnoredPredecate(ignores, options.cwd); +}; - if (value === '.') { - if (state.braces > 0 && prev.type === 'dot') { - if (prev.value === '.') prev.output = DOT_LITERAL; - const brace = braces[braces.length - 1]; - prev.type = 'dots'; - prev.output += value; - prev.value += value; - brace.dots = true; - continue; - } +module.exports.sync = options => { + options = normalizeOptions(options); - if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') { - push({ type: 'text', value, output: DOT_LITERAL }); - continue; - } + const paths = fastGlob.sync('**/.gitignore', { + ignore: DEFAULT_IGNORE.concat(options.ignore), + cwd: options.cwd + }); - push({ type: 'dot', value, output: DOT_LITERAL }); - continue; - } + const files = paths.map(file => getFileSync(file, options.cwd)); + const ignores = reduceIgnore(files); - /** - * Question marks - */ + return getIsIgnoredPredecate(ignores, options.cwd); +}; - if (value === '?') { - const isGroup = prev && prev.value === '('; - if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { - extglobOpen('qmark', value); - continue; - } - if (prev && prev.type === 'paren') { - const next = peek(); - let output = value; +/***/ }), +/* 357 */ +/***/ (function(module, exports) { - if (next === '<' && !utils.supportsLookbehinds()) { - throw new Error('Node.js v10 or higher is required for regex lookbehinds'); - } +// A simple implementation of make-array +function makeArray (subject) { + return Array.isArray(subject) + ? subject + : [subject] +} - if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) { - output = `\\${value}`; - } +const EMPTY = '' +const SPACE = ' ' +const ESCAPE = '\\' +const REGEX_TEST_BLANK_LINE = /^\s+$/ +const REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION = /^\\!/ +const REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\#/ +const REGEX_SPLITALL_CRLF = /\r?\n/g +// /foo, +// ./foo, +// ../foo, +// . +// .. +const REGEX_TEST_INVALID_PATH = /^\.*\/|^\.+$/ - push({ type: 'text', value, output }); - continue; - } +const SLASH = '/' +const KEY_IGNORE = typeof Symbol !== 'undefined' + ? Symbol.for('node-ignore') + /* istanbul ignore next */ + : 'node-ignore' - if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) { - push({ type: 'qmark', value, output: QMARK_NO_DOT }); - continue; - } +const define = (object, key, value) => + Object.defineProperty(object, key, {value}) - push({ type: 'qmark', value, output: QMARK }); - continue; - } +const REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g - /** - * Exclamation - */ +// Sanitize the range of a regular expression +// The cases are complicated, see test cases for details +const sanitizeRange = range => range.replace( + REGEX_REGEXP_RANGE, + (match, from, to) => from.charCodeAt(0) <= to.charCodeAt(0) + ? match + // Invalid range (out of order) which is ok for gitignore rules but + // fatal for JavaScript regular expression, so eliminate it. + : EMPTY +) - if (value === '!') { - if (opts.noextglob !== true && peek() === '(') { - if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) { - extglobOpen('negate', value); - continue; - } - } +// See fixtures #59 +const cleanRangeBackSlash = slashes => { + const {length} = slashes + return slashes.slice(0, length - length % 2) +} - if (opts.nonegate !== true && state.index === 0) { - negate(); - continue; - } - } +// > If the pattern ends with a slash, +// > it is removed for the purpose of the following description, +// > but it would only find a match with a directory. +// > In other words, foo/ will match a directory foo and paths underneath it, +// > but will not match a regular file or a symbolic link foo +// > (this is consistent with the way how pathspec works in general in Git). +// '`foo/`' will not match regular file '`foo`' or symbolic link '`foo`' +// -> ignore-rules will not deal with it, because it costs extra `fs.stat` call +// you could use option `mark: true` with `glob` - /** - * Plus - */ +// '`foo/`' should not continue with the '`..`' +const REPLACERS = [ - if (value === '+') { - if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { - extglobOpen('plus', value); - continue; - } + // > Trailing spaces are ignored unless they are quoted with backslash ("\") + [ + // (a\ ) -> (a ) + // (a ) -> (a) + // (a \ ) -> (a ) + /\\?\s+$/, + match => match.indexOf('\\') === 0 + ? SPACE + : EMPTY + ], - if ((prev && prev.value === '(') || opts.regex === false) { - push({ type: 'plus', value, output: PLUS_LITERAL }); - continue; - } + // replace (\ ) with ' ' + [ + /\\\s/g, + () => SPACE + ], - if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) { - push({ type: 'plus', value }); - continue; - } + // Escape metacharacters + // which is written down by users but means special for regular expressions. - push({ type: 'plus', value: PLUS_LITERAL }); - continue; - } + // > There are 12 characters with special meanings: + // > - the backslash \, + // > - the caret ^, + // > - the dollar sign $, + // > - the period or dot ., + // > - the vertical bar or pipe symbol |, + // > - the question mark ?, + // > - the asterisk or star *, + // > - the plus sign +, + // > - the opening parenthesis (, + // > - the closing parenthesis ), + // > - and the opening square bracket [, + // > - the opening curly brace {, + // > These special characters are often called "metacharacters". + [ + /[\\$.|*+(){^]/g, + match => `\\${match}` + ], - /** - * Plain text - */ + [ + // > a question mark (?) matches a single character + /(?!\\)\?/g, + () => '[^/]' + ], - if (value === '@') { - if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { - push({ type: 'at', extglob: true, value, output: '' }); - continue; - } + // leading slash + [ - push({ type: 'text', value }); - continue; - } + // > A leading slash matches the beginning of the pathname. + // > For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c". + // A leading slash matches the beginning of the pathname + /^\//, + () => '^' + ], - /** - * Plain text - */ + // replace special metacharacter slash after the leading slash + [ + /\//g, + () => '\\/' + ], - if (value !== '*') { - if (value === '$' || value === '^') { - value = `\\${value}`; - } + [ + // > A leading "**" followed by a slash means match in all directories. + // > For example, "**/foo" matches file or directory "foo" anywhere, + // > the same as pattern "foo". + // > "**/foo/bar" matches file or directory "bar" anywhere that is directly + // > under directory "foo". + // Notice that the '*'s have been replaced as '\\*' + /^\^*\\\*\\\*\\\//, - const match = REGEX_NON_SPECIAL_CHARS.exec(remaining()); - if (match) { - value += match[0]; - state.index += match[0].length; - } + // '**/foo' <-> 'foo' + () => '^(?:.*\\/)?' + ], - push({ type: 'text', value }); - continue; - } + // starting + [ + // there will be no leading '/' + // (which has been replaced by section "leading slash") + // If starts with '**', adding a '^' to the regular expression also works + /^(?=[^^])/, + function startingReplacer () { + // If has a slash `/` at the beginning or middle + return !/\/(?!$)/.test(this) + // > Prior to 2.22.1 + // > If the pattern does not contain a slash /, + // > Git treats it as a shell glob pattern + // Actually, if there is only a trailing slash, + // git also treats it as a shell glob pattern - /** - * Stars - */ + // After 2.22.1 (compatible but clearer) + // > If there is a separator at the beginning or middle (or both) + // > of the pattern, then the pattern is relative to the directory + // > level of the particular .gitignore file itself. + // > Otherwise the pattern may also match at any level below + // > the .gitignore level. + ? '(?:^|\\/)' - if (prev && (prev.type === 'globstar' || prev.star === true)) { - prev.type = 'star'; - prev.star = true; - prev.value += value; - prev.output = star; - state.backtrack = true; - state.globstar = true; - consume(value); - continue; + // > Otherwise, Git treats the pattern as a shell glob suitable for + // > consumption by fnmatch(3) + : '^' } + ], - let rest = remaining(); - if (opts.noextglob !== true && /^\([^?]/.test(rest)) { - extglobOpen('star', value); - continue; - } + // two globstars + [ + // Use lookahead assertions so that we could match more than one `'/**'` + /\\\/\\\*\\\*(?=\\\/|$)/g, - if (prev.type === 'star') { - if (opts.noglobstar === true) { - consume(value); - continue; - } + // Zero, one or several directories + // should not use '*', or it will be replaced by the next replacer - const prior = prev.prev; - const before = prior.prev; - const isStart = prior.type === 'slash' || prior.type === 'bos'; - const afterStar = before && (before.type === 'star' || before.type === 'globstar'); + // Check if it is not the last `'/**'` + (_, index, str) => index + 6 < str.length - if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) { - push({ type: 'star', value, output: '' }); - continue; - } + // case: /**/ + // > A slash followed by two consecutive asterisks then a slash matches + // > zero or more directories. + // > For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on. + // '/**/' + ? '(?:\\/[^\\/]+)*' - const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace'); - const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren'); - if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) { - push({ type: 'star', value, output: '' }); - continue; - } + // case: /** + // > A trailing `"/**"` matches everything inside. - // strip consecutive `/**/` - while (rest.slice(0, 3) === '/**') { - const after = input[state.index + 4]; - if (after && after !== '/') { - break; - } - rest = rest.slice(3); - consume('/**', 3); - } + // #21: everything inside but it should not include the current folder + : '\\/.+' + ], - if (prior.type === 'bos' && eos()) { - prev.type = 'globstar'; - prev.value += value; - prev.output = globstar(opts); - state.output = prev.output; - state.globstar = true; - consume(value); - continue; - } + // intermediate wildcards + [ + // Never replace escaped '*' + // ignore rule '\*' will match the path '*' - if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) { - state.output = state.output.slice(0, -(prior.output + prev.output).length); - prior.output = `(?:${prior.output}`; + // 'abc.*/' -> go + // 'abc.*' -> skip this rule + /(^|[^\\]+)\\\*(?=.+)/g, - prev.type = 'globstar'; - prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)'); - prev.value += value; - state.globstar = true; - state.output += prior.output + prev.output; - consume(value); - continue; - } + // '*.js' matches '.js' + // '*.js' doesn't match 'abc' + (_, p1) => `${p1}[^\\/]*` + ], - if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') { - const end = rest[1] !== void 0 ? '|$' : ''; + [ + // unescape, revert step 3 except for back slash + // For example, if a user escape a '\\*', + // after step 3, the result will be '\\\\\\*' + /\\\\\\(?=[$.|*+(){^])/g, + () => ESCAPE + ], - state.output = state.output.slice(0, -(prior.output + prev.output).length); - prior.output = `(?:${prior.output}`; + [ + // '\\\\' -> '\\' + /\\\\/g, + () => ESCAPE + ], - prev.type = 'globstar'; - prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`; - prev.value += value; + [ + // > The range notation, e.g. [a-zA-Z], + // > can be used to match one of the characters in a range. - state.output += prior.output + prev.output; - state.globstar = true; + // `\` is escaped by step 3 + /(\\)?\[([^\]/]*?)(\\*)($|\])/g, + (match, leadEscape, range, endEscape, close) => leadEscape === ESCAPE + // '\\[bar]' -> '\\\\[bar\\]' + ? `\\[${range}${cleanRangeBackSlash(endEscape)}${close}` + : close === ']' + ? endEscape.length % 2 === 0 + // A normal case, and it is a range notation + // '[bar]' + // '[bar\\\\]' + ? `[${sanitizeRange(range)}${endEscape}]` + // Invalid range notaton + // '[bar\\]' -> '[bar\\\\]' + : '[]' + : '[]' + ], - consume(value + advance()); + // ending + [ + // 'js' will not match 'js.' + // 'ab' will not match 'abc' + /(?:[^*])$/, - push({ type: 'slash', value: '/', output: '' }); - continue; - } + // WTF! + // https://git-scm.com/docs/gitignore + // changes in [2.22.1](https://git-scm.com/docs/gitignore/2.22.1) + // which re-fixes #24, #38 - if (prior.type === 'bos' && rest[0] === '/') { - prev.type = 'globstar'; - prev.value += value; - prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`; - state.output = prev.output; - state.globstar = true; - consume(value + advance()); - push({ type: 'slash', value: '/', output: '' }); - continue; - } + // > If there is a separator at the end of the pattern then the pattern + // > will only match directories, otherwise the pattern can match both + // > files and directories. - // remove single star from output - state.output = state.output.slice(0, -prev.output.length); + // 'js*' will not match 'a.js' + // 'js/' will not match 'a.js' + // 'js' will match 'a.js' and 'a.js/' + match => /\/$/.test(match) + // foo/ will not match 'foo' + ? `${match}$` + // foo matches 'foo' and 'foo/' + : `${match}(?=$|\\/$)` + ], - // reset previous token to globstar - prev.type = 'globstar'; - prev.output = globstar(opts); - prev.value += value; + // trailing wildcard + [ + /(\^|\\\/)?\\\*$/, + (_, p1) => { + const prefix = p1 + // '\^': + // '/*' does not match EMPTY + // '/*' does not match everything - // reset output with globstar - state.output += prev.output; - state.globstar = true; - consume(value); - continue; - } + // '\\\/': + // 'abc/*' does not match 'abc/' + ? `${p1}[^/]+` - const token = { type: 'star', value, output: star }; + // 'a*' matches 'a' + // 'a*' matches 'aa' + : '[^/]*' - if (opts.bash === true) { - token.output = '.*?'; - if (prev.type === 'bos' || prev.type === 'slash') { - token.output = nodot + token.output; - } - push(token); - continue; + return `${prefix}(?=$|\\/$)` } + ], +] - if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) { - token.output = value; - push(token); - continue; - } +// A simple cache, because an ignore rule only has only one certain meaning +const regexCache = Object.create(null) - if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') { - if (prev.type === 'dot') { - state.output += NO_DOT_SLASH; - prev.output += NO_DOT_SLASH; +// @param {pattern} +const makeRegex = (pattern, negative, ignorecase) => { + const r = regexCache[pattern] + if (r) { + return r + } - } else if (opts.dot === true) { - state.output += NO_DOTS_SLASH; - prev.output += NO_DOTS_SLASH; + // const replacers = negative + // ? NEGATIVE_REPLACERS + // : POSITIVE_REPLACERS - } else { - state.output += nodot; - prev.output += nodot; - } + const source = REPLACERS.reduce( + (prev, current) => prev.replace(current[0], current[1].bind(pattern)), + pattern + ) - if (peek() !== '*') { - state.output += ONE_CHAR; - prev.output += ONE_CHAR; - } - } + return regexCache[pattern] = ignorecase + ? new RegExp(source, 'i') + : new RegExp(source) +} - push(token); +const isString = subject => typeof subject === 'string' + +// > A blank line matches no files, so it can serve as a separator for readability. +const checkPattern = pattern => pattern + && isString(pattern) + && !REGEX_TEST_BLANK_LINE.test(pattern) + + // > A line starting with # serves as a comment. + && pattern.indexOf('#') !== 0 + +const splitPattern = pattern => pattern.split(REGEX_SPLITALL_CRLF) + +class IgnoreRule { + constructor ( + origin, + pattern, + negative, + regex + ) { + this.origin = origin + this.pattern = pattern + this.negative = negative + this.regex = regex } +} - while (state.brackets > 0) { - if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']')); - state.output = utils.escapeLast(state.output, '['); - decrement('brackets'); +const createRule = (pattern, ignorecase) => { + const origin = pattern + let negative = false + + // > An optional prefix "!" which negates the pattern; + if (pattern.indexOf('!') === 0) { + negative = true + pattern = pattern.substr(1) } - while (state.parens > 0) { - if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')')); - state.output = utils.escapeLast(state.output, '('); - decrement('parens'); + pattern = pattern + // > Put a backslash ("\") in front of the first "!" for patterns that + // > begin with a literal "!", for example, `"\!important!.txt"`. + .replace(REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION, '!') + // > Put a backslash ("\") in front of the first hash for patterns that + // > begin with a hash. + .replace(REGEX_REPLACE_LEADING_EXCAPED_HASH, '#') + + const regex = makeRegex(pattern, negative, ignorecase) + + return new IgnoreRule( + origin, + pattern, + negative, + regex + ) +} + +const throwError = (message, Ctor) => { + throw new Ctor(message) +} + +const checkPath = (path, originalPath, doThrow) => { + if (!isString(path)) { + return doThrow( + `path must be a string, but got \`${originalPath}\``, + TypeError + ) } - while (state.braces > 0) { - if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}')); - state.output = utils.escapeLast(state.output, '{'); - decrement('braces'); + // We don't know if we should ignore EMPTY, so throw + if (!path) { + return doThrow(`path must not be empty`, TypeError) } - if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) { - push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` }); + // Check if it is a relative path + if (checkPath.isNotRelative(path)) { + const r = '`path.relative()`d' + return doThrow( + `path should be a ${r} string, but got "${originalPath}"`, + RangeError + ) } - // rebuild the output if we had to backtrack at any point - if (state.backtrack === true) { - state.output = ''; + return true +} - for (const token of state.tokens) { - state.output += token.output != null ? token.output : token.value; +const isNotRelative = path => REGEX_TEST_INVALID_PATH.test(path) - if (token.suffix) { - state.output += token.suffix; - } - } +checkPath.isNotRelative = isNotRelative +checkPath.convert = p => p + +class Ignore { + constructor ({ + ignorecase = true + } = {}) { + this._rules = [] + this._ignorecase = ignorecase + define(this, KEY_IGNORE, true) + this._initCache() } - return state; -}; + _initCache () { + this._ignoreCache = Object.create(null) + this._testCache = Object.create(null) + } -/** - * Fast paths for creating regular expressions for common glob patterns. - * This can significantly speed up processing and has very little downside - * impact when none of the fast paths match. - */ + _addPattern (pattern) { + // #32 + if (pattern && pattern[KEY_IGNORE]) { + this._rules = this._rules.concat(pattern._rules) + this._added = true + return + } -parse.fastpaths = (input, options) => { - const opts = { ...options }; - const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; - const len = input.length; - if (len > max) { - throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); + if (checkPattern(pattern)) { + const rule = createRule(pattern, this._ignorecase) + this._added = true + this._rules.push(rule) + } } - input = REPLACEMENTS[input] || input; - const win32 = utils.isWindows(options); + // @param {Array | string | Ignore} pattern + add (pattern) { + this._added = false - // create constants based on platform, for windows or posix - const { - DOT_LITERAL, - SLASH_LITERAL, - ONE_CHAR, - DOTS_SLASH, - NO_DOT, - NO_DOTS, - NO_DOTS_SLASH, - STAR, - START_ANCHOR - } = constants.globChars(win32); + makeArray( + isString(pattern) + ? splitPattern(pattern) + : pattern + ).forEach(this._addPattern, this) - const nodot = opts.dot ? NO_DOTS : NO_DOT; - const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT; - const capture = opts.capture ? '' : '?:'; - const state = { negated: false, prefix: '' }; - let star = opts.bash === true ? '.*?' : STAR; + // Some rules have just added to the ignore, + // making the behavior changed. + if (this._added) { + this._initCache() + } - if (opts.capture) { - star = `(${star})`; + return this } - const globstar = (opts) => { - if (opts.noglobstar === true) return star; - return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; - }; + // legacy + addPattern (pattern) { + return this.add(pattern) + } - const create = str => { - switch (str) { - case '*': - return `${nodot}${ONE_CHAR}${star}`; + // | ignored : unignored + // negative | 0:0 | 0:1 | 1:0 | 1:1 + // -------- | ------- | ------- | ------- | -------- + // 0 | TEST | TEST | SKIP | X + // 1 | TESTIF | SKIP | TEST | X - case '.*': - return `${DOT_LITERAL}${ONE_CHAR}${star}`; + // - SKIP: always skip + // - TEST: always test + // - TESTIF: only test if checkUnignored + // - X: that never happen - case '*.*': - return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; + // @param {boolean} whether should check if the path is unignored, + // setting `checkUnignored` to `false` could reduce additional + // path matching. - case '*/*': - return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`; + // @returns {TestResult} true if a file is ignored + _testOne (path, checkUnignored) { + let ignored = false + let unignored = false - case '**': - return nodot + globstar(opts); + this._rules.forEach(rule => { + const {negative} = rule + if ( + unignored === negative && ignored !== unignored + || negative && !ignored && !unignored && !checkUnignored + ) { + return + } - case '**/*': - return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`; + const matched = rule.regex.test(path) - case '**/*.*': - return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; + if (matched) { + ignored = !negative + unignored = negative + } + }) - case '**/.*': - return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`; + return { + ignored, + unignored + } + } - default: { - const match = /^(.*?)\.(\w+)$/.exec(str); - if (!match) return; + // @returns {TestResult} + _test (originalPath, cache, checkUnignored, slices) { + const path = originalPath + // Supports nullable path + && checkPath.convert(originalPath) - const source = create(match[1]); - if (!source) return; + checkPath(path, originalPath, throwError) - return source + DOT_LITERAL + match[2]; - } + return this._t(path, cache, checkUnignored, slices) + } + + _t (path, cache, checkUnignored, slices) { + if (path in cache) { + return cache[path] } - }; - const output = utils.removePrefix(input, state); - let source = create(output); + if (!slices) { + // path/to/a.js + // ['path', 'to', 'a.js'] + slices = path.split(SLASH) + } - if (source && opts.strictSlashes !== true) { - source += `${SLASH_LITERAL}?`; + slices.pop() + + // If the path has no parent directory, just test it + if (!slices.length) { + return cache[path] = this._testOne(path, checkUnignored) + } + + const parent = this._t( + slices.join(SLASH) + SLASH, + cache, + checkUnignored, + slices + ) + + // If the path contains a parent directory, check the parent first + return cache[path] = parent.ignored + // > It is not possible to re-include a file if a parent directory of + // > that file is excluded. + ? parent + : this._testOne(path, checkUnignored) } - return source; -}; + ignores (path) { + return this._test(path, this._ignoreCache, false).ignored + } -module.exports = parse; + createFilter () { + return path => !this.ignores(path) + } + filter (paths) { + return makeArray(paths).filter(this.createFilter()) + } -/***/ }), -/* 321 */ -/***/ (function(module, exports, __webpack_require__) { + // @returns {TestResult} + test (path) { + return this._test(path, this._testCache, true) + } +} -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const merge2 = __webpack_require__(292); -function merge(streams) { - const mergedStream = merge2(streams); - streams.forEach((stream) => { - stream.once('error', (error) => mergedStream.emit('error', error)); - }); - mergedStream.once('close', () => propagateCloseEventToSources(streams)); - mergedStream.once('end', () => propagateCloseEventToSources(streams)); - return mergedStream; -} -exports.merge = merge; -function propagateCloseEventToSources(streams) { - streams.forEach((stream) => stream.emit('close')); -} +const factory = options => new Ignore(options) +const returnFalse = () => false -/***/ }), -/* 322 */ -/***/ (function(module, exports, __webpack_require__) { +const isPathValid = path => + checkPath(path && checkPath.convert(path), path, returnFalse) -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -function isString(input) { - return typeof input === 'string'; -} -exports.isString = isString; -function isEmpty(input) { - return input === ''; -} -exports.isEmpty = isEmpty; +factory.isPathValid = isPathValid +// Fixes typescript +factory.default = factory -/***/ }), -/* 323 */ -/***/ (function(module, exports, __webpack_require__) { +module.exports = factory -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const stream_1 = __webpack_require__(324); -const provider_1 = __webpack_require__(351); -class ProviderAsync extends provider_1.default { - constructor() { - super(...arguments); - this._reader = new stream_1.default(this._settings); - } - read(task) { - const root = this._getRootDirectory(task); - const options = this._getReaderOptions(task); - const entries = []; - return new Promise((resolve, reject) => { - const stream = this.api(root, task, options); - stream.once('error', reject); - stream.on('data', (entry) => entries.push(options.transform(entry))); - stream.once('end', () => resolve(entries)); - }); - } - api(root, task, options) { - if (task.dynamic) { - return this._reader.dynamic(root, options); - } - return this._reader.static(task.patterns, options); - } -} -exports.default = ProviderAsync; +// Windows +// -------------------------------------------------------------- +/* istanbul ignore if */ +if ( + // Detect `process` so that it can run in browsers. + typeof process !== 'undefined' + && ( + process.env && process.env.IGNORE_TEST_WIN32 + || process.platform === 'win32' + ) +) { + /* eslint no-control-regex: "off" */ + const makePosix = str => /^\\\\\?\\/.test(str) + || /["<>|\u0000-\u001F]+/u.test(str) + ? str + : str.replace(/\\/g, '/') + + checkPath.convert = makePosix + + // 'C:\\foo' <- 'C:\\foo' has been converted to 'C:/' + // 'd:\\foo' + const REGIX_IS_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i + checkPath.isNotRelative = path => + REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path) + || isNotRelative(path) +} /***/ }), -/* 324 */ +/* 358 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const stream_1 = __webpack_require__(137); -const fsStat = __webpack_require__(325); -const fsWalk = __webpack_require__(330); -const reader_1 = __webpack_require__(350); -class ReaderStream extends reader_1.default { - constructor() { - super(...arguments); - this._walkStream = fsWalk.walkStream; - this._stat = fsStat.stat; - } - dynamic(root, options) { - return this._walkStream(root, options); - } - static(patterns, options) { - const filepaths = patterns.map(this._getFullEntryPath, this); - const stream = new stream_1.PassThrough({ objectMode: true }); - stream._write = (index, _enc, done) => { - return this._getEntry(filepaths[index], patterns[index], options) - .then((entry) => { - if (entry !== null && options.entryFilter(entry)) { - stream.push(entry); - } - if (index === filepaths.length - 1) { - stream.end(); - } - done(); - }) - .catch(done); - }; - for (let i = 0; i < filepaths.length; i++) { - stream.write(i); - } - return stream; - } - _getEntry(filepath, pattern, options) { - return this._getStat(filepath) - .then((stats) => this._makeEntry(stats, pattern)) - .catch((error) => { - if (options.errorFilter(error)) { - return null; - } - throw error; - }); - } - _getStat(filepath) { - return new Promise((resolve, reject) => { - this._stat(filepath, this._fsStatSettings, (error, stats) => { - return error === null ? resolve(stats) : reject(error); - }); - }); - } -} -exports.default = ReaderStream; +module.exports = path => { + const isExtendedLengthPath = /^\\\\\?\\/.test(path); + const hasNonAscii = /[^\u0000-\u0080]+/.test(path); // eslint-disable-line no-control-regex -/***/ }), -/* 325 */ -/***/ (function(module, exports, __webpack_require__) { + if (isExtendedLengthPath || hasNonAscii) { + return path; + } -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const async = __webpack_require__(326); -const sync = __webpack_require__(327); -const settings_1 = __webpack_require__(328); -exports.Settings = settings_1.default; -function stat(path, optionsOrSettingsOrCallback, callback) { - if (typeof optionsOrSettingsOrCallback === 'function') { - return async.read(path, getSettings(), optionsOrSettingsOrCallback); - } - async.read(path, getSettings(optionsOrSettingsOrCallback), callback); -} -exports.stat = stat; -function statSync(path, optionsOrSettings) { - const settings = getSettings(optionsOrSettings); - return sync.read(path, settings); -} -exports.statSync = statSync; -function getSettings(settingsOrOptions = {}) { - if (settingsOrOptions instanceof settings_1.default) { - return settingsOrOptions; - } - return new settings_1.default(settingsOrOptions); -} + return path.replace(/\\/g, '/'); +}; /***/ }), -/* 326 */ +/* 359 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -function read(path, settings, callback) { - settings.fs.lstat(path, (lstatError, lstat) => { - if (lstatError !== null) { - return callFailureCallback(callback, lstatError); - } - if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) { - return callSuccessCallback(callback, lstat); - } - settings.fs.stat(path, (statError, stat) => { - if (statError !== null) { - if (settings.throwErrorOnBrokenSymbolicLink) { - return callFailureCallback(callback, statError); - } - return callSuccessCallback(callback, lstat); - } - if (settings.markSymbolicLink) { - stat.isSymbolicLink = () => true; - } - callSuccessCallback(callback, stat); - }); - }); -} -exports.read = read; -function callFailureCallback(callback, error) { - callback(error); -} -function callSuccessCallback(callback, result) { - callback(null, result); -} +const {Transform} = __webpack_require__(138); -/***/ }), -/* 327 */ -/***/ (function(module, exports, __webpack_require__) { +class ObjectTransform extends Transform { + constructor() { + super({ + objectMode: true + }); + } +} -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -function read(path, settings) { - const lstat = settings.fs.lstatSync(path); - if (!lstat.isSymbolicLink() || !settings.followSymbolicLink) { - return lstat; - } - try { - const stat = settings.fs.statSync(path); - if (settings.markSymbolicLink) { - stat.isSymbolicLink = () => true; - } - return stat; - } - catch (error) { - if (!settings.throwErrorOnBrokenSymbolicLink) { - return lstat; - } - throw error; - } -} -exports.read = read; +class FilterStream extends ObjectTransform { + constructor(filter) { + super(); + this._filter = filter; + } + _transform(data, encoding, callback) { + if (this._filter(data)) { + this.push(data); + } -/***/ }), -/* 328 */ -/***/ (function(module, exports, __webpack_require__) { + callback(); + } +} -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(329); -class Settings { - constructor(_options = {}) { - this._options = _options; - this.followSymbolicLink = this._getValue(this._options.followSymbolicLink, true); - this.fs = fs.createFileSystemAdapter(this._options.fs); - this.markSymbolicLink = this._getValue(this._options.markSymbolicLink, false); - this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true); - } - _getValue(option, value) { - return option === undefined ? value : option; - } -} -exports.default = Settings; +class UniqueStream extends ObjectTransform { + constructor() { + super(); + this._pushed = new Set(); + } + _transform(data, encoding, callback) { + if (!this._pushed.has(data)) { + this.push(data); + this._pushed.add(data); + } -/***/ }), -/* 329 */ -/***/ (function(module, exports, __webpack_require__) { + callback(); + } +} -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(133); -exports.FILE_SYSTEM_ADAPTER = { - lstat: fs.lstat, - stat: fs.stat, - lstatSync: fs.lstatSync, - statSync: fs.statSync -}; -function createFileSystemAdapter(fsMethods) { - if (fsMethods === undefined) { - return exports.FILE_SYSTEM_ADAPTER; - } - return Object.assign(Object.assign({}, exports.FILE_SYSTEM_ADAPTER), fsMethods); -} -exports.createFileSystemAdapter = createFileSystemAdapter; +module.exports = { + FilterStream, + UniqueStream +}; /***/ }), -/* 330 */ +/* 360 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const async_1 = __webpack_require__(331); -const stream_1 = __webpack_require__(346); -const sync_1 = __webpack_require__(347); -const settings_1 = __webpack_require__(349); -exports.Settings = settings_1.default; -function walk(directory, optionsOrSettingsOrCallback, callback) { - if (typeof optionsOrSettingsOrCallback === 'function') { - return new async_1.default(directory, getSettings()).read(optionsOrSettingsOrCallback); - } - new async_1.default(directory, getSettings(optionsOrSettingsOrCallback)).read(callback); -} -exports.walk = walk; -function walkSync(directory, optionsOrSettings) { - const settings = getSettings(optionsOrSettings); - const provider = new sync_1.default(directory, settings); - return provider.read(); -} -exports.walkSync = walkSync; -function walkStream(directory, optionsOrSettings) { - const settings = getSettings(optionsOrSettings); - const provider = new stream_1.default(directory, settings); - return provider.read(); -} -exports.walkStream = walkStream; -function getSettings(settingsOrOptions = {}) { - if (settingsOrOptions instanceof settings_1.default) { - return settingsOrOptions; - } - return new settings_1.default(settingsOrOptions); -} +const path = __webpack_require__(4); -/***/ }), -/* 331 */ -/***/ (function(module, exports, __webpack_require__) { +module.exports = path_ => { + let cwd = process.cwd(); -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const async_1 = __webpack_require__(332); -class AsyncProvider { - constructor(_root, _settings) { - this._root = _root; - this._settings = _settings; - this._reader = new async_1.default(this._root, this._settings); - this._storage = new Set(); - } - read(callback) { - this._reader.onError((error) => { - callFailureCallback(callback, error); - }); - this._reader.onEntry((entry) => { - this._storage.add(entry); - }); - this._reader.onEnd(() => { - callSuccessCallback(callback, [...this._storage]); - }); - this._reader.read(); - } -} -exports.default = AsyncProvider; -function callFailureCallback(callback, error) { - callback(error); -} -function callSuccessCallback(callback, entries) { - callback(null, entries); -} + path_ = path.resolve(path_); + + if (process.platform === 'win32') { + cwd = cwd.toLowerCase(); + path_ = path_.toLowerCase(); + } + + return path_ === cwd; +}; /***/ }), -/* 332 */ +/* 361 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const events_1 = __webpack_require__(155); -const fsScandir = __webpack_require__(333); -const fastq = __webpack_require__(342); -const common = __webpack_require__(344); -const reader_1 = __webpack_require__(345); -class AsyncReader extends reader_1.default { - constructor(_root, _settings) { - super(_root, _settings); - this._settings = _settings; - this._scandir = fsScandir.scandir; - this._emitter = new events_1.EventEmitter(); - this._queue = fastq(this._worker.bind(this), this._settings.concurrency); - this._isFatalError = false; - this._isDestroyed = false; - this._queue.drain = () => { - if (!this._isFatalError) { - this._emitter.emit('end'); - } - }; - } - read() { - this._isFatalError = false; - this._isDestroyed = false; - setImmediate(() => { - this._pushToQueue(this._root, this._settings.basePath); - }); - return this._emitter; - } - destroy() { - if (this._isDestroyed) { - throw new Error('The reader is already destroyed'); - } - this._isDestroyed = true; - this._queue.killAndDrain(); - } - onEntry(callback) { - this._emitter.on('entry', callback); - } - onError(callback) { - this._emitter.once('error', callback); - } - onEnd(callback) { - this._emitter.once('end', callback); - } - _pushToQueue(directory, base) { - const queueItem = { directory, base }; - this._queue.push(queueItem, (error) => { - if (error !== null) { - this._handleError(error); - } - }); - } - _worker(item, done) { - this._scandir(item.directory, this._settings.fsScandirSettings, (error, entries) => { - if (error !== null) { - return done(error, undefined); - } - for (const entry of entries) { - this._handleEntry(entry, item.base); - } - done(null, undefined); - }); - } - _handleError(error) { - if (!common.isFatalError(this._settings, error)) { - return; - } - this._isFatalError = true; - this._isDestroyed = true; - this._emitter.emit('error', error); - } - _handleEntry(entry, base) { - if (this._isDestroyed || this._isFatalError) { - return; - } - const fullpath = entry.path; - if (base !== undefined) { - entry.path = common.joinPathSegments(base, entry.name, this._settings.pathSegmentSeparator); - } - if (common.isAppliedFilter(this._settings.entryFilter, entry)) { - this._emitEntry(entry); - } - if (entry.dirent.isDirectory() && common.isAppliedFilter(this._settings.deepFilter, entry)) { - this._pushToQueue(fullpath, entry.path); - } - } - _emitEntry(entry) { - this._emitter.emit('entry', entry); - } -} -exports.default = AsyncReader; +const path = __webpack_require__(4); -/***/ }), -/* 333 */ -/***/ (function(module, exports, __webpack_require__) { +module.exports = (childPath, parentPath) => { + childPath = path.resolve(childPath); + parentPath = path.resolve(parentPath); -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const async = __webpack_require__(334); -const sync = __webpack_require__(339); -const settings_1 = __webpack_require__(340); -exports.Settings = settings_1.default; -function scandir(path, optionsOrSettingsOrCallback, callback) { - if (typeof optionsOrSettingsOrCallback === 'function') { - return async.read(path, getSettings(), optionsOrSettingsOrCallback); - } - async.read(path, getSettings(optionsOrSettingsOrCallback), callback); -} -exports.scandir = scandir; -function scandirSync(path, optionsOrSettings) { - const settings = getSettings(optionsOrSettings); - return sync.read(path, settings); -} -exports.scandirSync = scandirSync; -function getSettings(settingsOrOptions = {}) { - if (settingsOrOptions instanceof settings_1.default) { - return settingsOrOptions; - } - return new settings_1.default(settingsOrOptions); -} + if (process.platform === 'win32') { + childPath = childPath.toLowerCase(); + parentPath = parentPath.toLowerCase(); + } + + if (childPath === parentPath) { + return false; + } + + childPath += path.sep; + parentPath += path.sep; + + return childPath.startsWith(parentPath); +}; /***/ }), -/* 334 */ +/* 362 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const fsStat = __webpack_require__(325); -const rpl = __webpack_require__(335); -const constants_1 = __webpack_require__(336); -const utils = __webpack_require__(337); -function read(directory, settings, callback) { - if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { - return readdirWithFileTypes(directory, settings, callback); - } - return readdir(directory, settings, callback); -} -exports.read = read; -function readdirWithFileTypes(directory, settings, callback) { - settings.fs.readdir(directory, { withFileTypes: true }, (readdirError, dirents) => { - if (readdirError !== null) { - return callFailureCallback(callback, readdirError); - } - const entries = dirents.map((dirent) => ({ - dirent, - name: dirent.name, - path: `${directory}${settings.pathSegmentSeparator}${dirent.name}` - })); - if (!settings.followSymbolicLinks) { - return callSuccessCallback(callback, entries); - } - const tasks = entries.map((entry) => makeRplTaskEntry(entry, settings)); - rpl(tasks, (rplError, rplEntries) => { - if (rplError !== null) { - return callFailureCallback(callback, rplError); - } - callSuccessCallback(callback, rplEntries); - }); - }); -} -exports.readdirWithFileTypes = readdirWithFileTypes; -function makeRplTaskEntry(entry, settings) { - return (done) => { - if (!entry.dirent.isSymbolicLink()) { - return done(null, entry); - } - settings.fs.stat(entry.path, (statError, stats) => { - if (statError !== null) { - if (settings.throwErrorOnBrokenSymbolicLink) { - return done(statError); - } - return done(null, entry); - } - entry.dirent = utils.fs.createDirentFromStats(entry.name, stats); - return done(null, entry); - }); - }; -} -function readdir(directory, settings, callback) { - settings.fs.readdir(directory, (readdirError, names) => { - if (readdirError !== null) { - return callFailureCallback(callback, readdirError); - } - const filepaths = names.map((name) => `${directory}${settings.pathSegmentSeparator}${name}`); - const tasks = filepaths.map((filepath) => { - return (done) => fsStat.stat(filepath, settings.fsStatSettings, done); - }); - rpl(tasks, (rplError, results) => { - if (rplError !== null) { - return callFailureCallback(callback, rplError); - } - const entries = []; - names.forEach((name, index) => { - const stats = results[index]; - const entry = { - name, - path: filepaths[index], - dirent: utils.fs.createDirentFromStats(name, stats) - }; - if (settings.stats) { - entry.stats = stats; - } - entries.push(entry); - }); - callSuccessCallback(callback, entries); - }); - }); -} -exports.readdir = readdir; -function callFailureCallback(callback, error) { - callback(error); -} -function callSuccessCallback(callback, result) { - callback(null, result); -} - +const assert = __webpack_require__(140) +const path = __webpack_require__(4) +const fs = __webpack_require__(134) +let glob = undefined +try { + glob = __webpack_require__(147) +} catch (_err) { + // treat glob as optional. +} -/***/ }), -/* 335 */ -/***/ (function(module, exports) { +const defaultGlobOpts = { + nosort: true, + silent: true +} -module.exports = runParallel +// for EMFILE handling +let timeout = 0 -function runParallel (tasks, cb) { - var results, pending, keys - var isSync = true +const isWindows = (process.platform === "win32") - if (Array.isArray(tasks)) { - results = [] - pending = tasks.length - } else { - keys = Object.keys(tasks) - results = {} - pending = keys.length - } +const defaults = options => { + const methods = [ + 'unlink', + 'chmod', + 'stat', + 'lstat', + 'rmdir', + 'readdir' + ] + methods.forEach(m => { + options[m] = options[m] || fs[m] + m = m + 'Sync' + options[m] = options[m] || fs[m] + }) - function done (err) { - function end () { - if (cb) cb(err, results) - cb = null - } - if (isSync) process.nextTick(end) - else end() + options.maxBusyTries = options.maxBusyTries || 3 + options.emfileWait = options.emfileWait || 1000 + if (options.glob === false) { + options.disableGlob = true } - - function each (i, err, result) { - results[i] = result - if (--pending === 0 || err) { - done(err) - } + if (options.disableGlob !== true && glob === undefined) { + throw Error('glob dependency not found, set `options.disableGlob = true` if intentional') } + options.disableGlob = options.disableGlob || false + options.glob = options.glob || defaultGlobOpts +} - if (!pending) { - // empty - done(null) - } else if (keys) { - // object - keys.forEach(function (key) { - tasks[key](function (err, result) { each(key, err, result) }) - }) - } else { - // array - tasks.forEach(function (task, i) { - task(function (err, result) { each(i, err, result) }) - }) +const rimraf = (p, options, cb) => { + if (typeof options === 'function') { + cb = options + options = {} } - isSync = false -} - + assert(p, 'rimraf: missing path') + assert.equal(typeof p, 'string', 'rimraf: path should be a string') + assert.equal(typeof cb, 'function', 'rimraf: callback function required') + assert(options, 'rimraf: invalid options argument provided') + assert.equal(typeof options, 'object', 'rimraf: options should be object') -/***/ }), -/* 336 */ -/***/ (function(module, exports, __webpack_require__) { + defaults(options) -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const NODE_PROCESS_VERSION_PARTS = process.versions.node.split('.'); -const MAJOR_VERSION = parseInt(NODE_PROCESS_VERSION_PARTS[0], 10); -const MINOR_VERSION = parseInt(NODE_PROCESS_VERSION_PARTS[1], 10); -const SUPPORTED_MAJOR_VERSION = 10; -const SUPPORTED_MINOR_VERSION = 10; -const IS_MATCHED_BY_MAJOR = MAJOR_VERSION > SUPPORTED_MAJOR_VERSION; -const IS_MATCHED_BY_MAJOR_AND_MINOR = MAJOR_VERSION === SUPPORTED_MAJOR_VERSION && MINOR_VERSION >= SUPPORTED_MINOR_VERSION; -/** - * IS `true` for Node.js 10.10 and greater. - */ -exports.IS_SUPPORT_READDIR_WITH_FILE_TYPES = IS_MATCHED_BY_MAJOR || IS_MATCHED_BY_MAJOR_AND_MINOR; + let busyTries = 0 + let errState = null + let n = 0 + const next = (er) => { + errState = errState || er + if (--n === 0) + cb(errState) + } -/***/ }), -/* 337 */ -/***/ (function(module, exports, __webpack_require__) { + const afterGlob = (er, results) => { + if (er) + return cb(er) -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(338); -exports.fs = fs; + n = results.length + if (n === 0) + return cb() + results.forEach(p => { + const CB = (er) => { + if (er) { + if ((er.code === "EBUSY" || er.code === "ENOTEMPTY" || er.code === "EPERM") && + busyTries < options.maxBusyTries) { + busyTries ++ + // try again, with the same exact callback as this one. + return setTimeout(() => rimraf_(p, options, CB), busyTries * 100) + } -/***/ }), -/* 338 */ -/***/ (function(module, exports, __webpack_require__) { + // this one won't happen if graceful-fs is used. + if (er.code === "EMFILE" && timeout < options.emfileWait) { + return setTimeout(() => rimraf_(p, options, CB), timeout ++) + } -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -class DirentFromStats { - constructor(name, stats) { - this.name = name; - this.isBlockDevice = stats.isBlockDevice.bind(stats); - this.isCharacterDevice = stats.isCharacterDevice.bind(stats); - this.isDirectory = stats.isDirectory.bind(stats); - this.isFIFO = stats.isFIFO.bind(stats); - this.isFile = stats.isFile.bind(stats); - this.isSocket = stats.isSocket.bind(stats); - this.isSymbolicLink = stats.isSymbolicLink.bind(stats); - } -} -function createDirentFromStats(name, stats) { - return new DirentFromStats(name, stats); -} -exports.createDirentFromStats = createDirentFromStats; + // already gone + if (er.code === "ENOENT") er = null + } + timeout = 0 + next(er) + } + rimraf_(p, options, CB) + }) + } -/***/ }), -/* 339 */ -/***/ (function(module, exports, __webpack_require__) { + if (options.disableGlob || !glob.hasMagic(p)) + return afterGlob(null, [p]) -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const fsStat = __webpack_require__(325); -const constants_1 = __webpack_require__(336); -const utils = __webpack_require__(337); -function read(directory, settings) { - if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { - return readdirWithFileTypes(directory, settings); - } - return readdir(directory, settings); -} -exports.read = read; -function readdirWithFileTypes(directory, settings) { - const dirents = settings.fs.readdirSync(directory, { withFileTypes: true }); - return dirents.map((dirent) => { - const entry = { - dirent, - name: dirent.name, - path: `${directory}${settings.pathSegmentSeparator}${dirent.name}` - }; - if (entry.dirent.isSymbolicLink() && settings.followSymbolicLinks) { - try { - const stats = settings.fs.statSync(entry.path); - entry.dirent = utils.fs.createDirentFromStats(entry.name, stats); - } - catch (error) { - if (settings.throwErrorOnBrokenSymbolicLink) { - throw error; - } - } - } - return entry; - }); -} -exports.readdirWithFileTypes = readdirWithFileTypes; -function readdir(directory, settings) { - const names = settings.fs.readdirSync(directory); - return names.map((name) => { - const entryPath = `${directory}${settings.pathSegmentSeparator}${name}`; - const stats = fsStat.statSync(entryPath, settings.fsStatSettings); - const entry = { - name, - path: entryPath, - dirent: utils.fs.createDirentFromStats(name, stats) - }; - if (settings.stats) { - entry.stats = stats; - } - return entry; - }); -} -exports.readdir = readdir; + options.lstat(p, (er, stat) => { + if (!er) + return afterGlob(null, [p]) + glob(p, options.glob, afterGlob) + }) -/***/ }), -/* 340 */ -/***/ (function(module, exports, __webpack_require__) { +} -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const path = __webpack_require__(4); -const fsStat = __webpack_require__(325); -const fs = __webpack_require__(341); -class Settings { - constructor(_options = {}) { - this._options = _options; - this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, false); - this.fs = fs.createFileSystemAdapter(this._options.fs); - this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path.sep); - this.stats = this._getValue(this._options.stats, false); - this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true); - this.fsStatSettings = new fsStat.Settings({ - followSymbolicLink: this.followSymbolicLinks, - fs: this.fs, - throwErrorOnBrokenSymbolicLink: this.throwErrorOnBrokenSymbolicLink - }); - } - _getValue(option, value) { - return option === undefined ? value : option; - } -} -exports.default = Settings; +// Two possible strategies. +// 1. Assume it's a file. unlink it, then do the dir stuff on EPERM or EISDIR +// 2. Assume it's a directory. readdir, then do the file stuff on ENOTDIR +// +// Both result in an extra syscall when you guess wrong. However, there +// are likely far more normal files in the world than directories. This +// is based on the assumption that a the average number of files per +// directory is >= 1. +// +// If anyone ever complains about this, then I guess the strategy could +// be made configurable somehow. But until then, YAGNI. +const rimraf_ = (p, options, cb) => { + assert(p) + assert(options) + assert(typeof cb === 'function') + // sunos lets the root user unlink directories, which is... weird. + // so we have to lstat here and make sure it's not a dir. + options.lstat(p, (er, st) => { + if (er && er.code === "ENOENT") + return cb(null) -/***/ }), -/* 341 */ -/***/ (function(module, exports, __webpack_require__) { + // Windows can EPERM on stat. Life is suffering. + if (er && er.code === "EPERM" && isWindows) + fixWinEPERM(p, options, er, cb) -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(133); -exports.FILE_SYSTEM_ADAPTER = { - lstat: fs.lstat, - stat: fs.stat, - lstatSync: fs.lstatSync, - statSync: fs.statSync, - readdir: fs.readdir, - readdirSync: fs.readdirSync -}; -function createFileSystemAdapter(fsMethods) { - if (fsMethods === undefined) { - return exports.FILE_SYSTEM_ADAPTER; - } - return Object.assign(Object.assign({}, exports.FILE_SYSTEM_ADAPTER), fsMethods); -} -exports.createFileSystemAdapter = createFileSystemAdapter; + if (st && st.isDirectory()) + return rmdir(p, options, er, cb) + options.unlink(p, er => { + if (er) { + if (er.code === "ENOENT") + return cb(null) + if (er.code === "EPERM") + return (isWindows) + ? fixWinEPERM(p, options, er, cb) + : rmdir(p, options, er, cb) + if (er.code === "EISDIR") + return rmdir(p, options, er, cb) + } + return cb(er) + }) + }) +} -/***/ }), -/* 342 */ -/***/ (function(module, exports, __webpack_require__) { +const fixWinEPERM = (p, options, er, cb) => { + assert(p) + assert(options) + assert(typeof cb === 'function') -"use strict"; + options.chmod(p, 0o666, er2 => { + if (er2) + cb(er2.code === "ENOENT" ? null : er) + else + options.stat(p, (er3, stats) => { + if (er3) + cb(er3.code === "ENOENT" ? null : er) + else if (stats.isDirectory()) + rmdir(p, options, er, cb) + else + options.unlink(p, cb) + }) + }) +} +const fixWinEPERMSync = (p, options, er) => { + assert(p) + assert(options) -var reusify = __webpack_require__(343) + try { + options.chmodSync(p, 0o666) + } catch (er2) { + if (er2.code === "ENOENT") + return + else + throw er + } -function fastqueue (context, worker, concurrency) { - if (typeof context === 'function') { - concurrency = worker - worker = context - context = null + let stats + try { + stats = options.statSync(p) + } catch (er3) { + if (er3.code === "ENOENT") + return + else + throw er } - var cache = reusify(Task) - var queueHead = null - var queueTail = null - var _running = 0 + if (stats.isDirectory()) + rmdirSync(p, options, er) + else + options.unlinkSync(p) +} - var self = { - push: push, - drain: noop, - saturated: noop, - pause: pause, - paused: false, - concurrency: concurrency, - running: running, - resume: resume, - idle: idle, - length: length, - unshift: unshift, - empty: noop, - kill: kill, - killAndDrain: killAndDrain - } +const rmdir = (p, options, originalEr, cb) => { + assert(p) + assert(options) + assert(typeof cb === 'function') - return self + // try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS) + // if we guessed wrong, and it's not a directory, then + // raise the original error. + options.rmdir(p, er => { + if (er && (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM")) + rmkids(p, options, cb) + else if (er && er.code === "ENOTDIR") + cb(originalEr) + else + cb(er) + }) +} - function running () { - return _running - } +const rmkids = (p, options, cb) => { + assert(p) + assert(options) + assert(typeof cb === 'function') - function pause () { - self.paused = true - } + options.readdir(p, (er, files) => { + if (er) + return cb(er) + let n = files.length + if (n === 0) + return options.rmdir(p, cb) + let errState + files.forEach(f => { + rimraf(path.join(p, f), options, er => { + if (errState) + return + if (er) + return cb(errState = er) + if (--n === 0) + options.rmdir(p, cb) + }) + }) + }) +} - function length () { - var current = queueHead - var counter = 0 +// this looks simpler, and is strictly *faster*, but will +// tie up the JavaScript thread and fail on excessively +// deep directory trees. +const rimrafSync = (p, options) => { + options = options || {} + defaults(options) - while (current) { - current = current.next - counter++ - } + assert(p, 'rimraf: missing path') + assert.equal(typeof p, 'string', 'rimraf: path should be a string') + assert(options, 'rimraf: missing options') + assert.equal(typeof options, 'object', 'rimraf: options should be object') - return counter - } + let results - function resume () { - if (!self.paused) return - self.paused = false - for (var i = 0; i < self.concurrency; i++) { - _running++ - release() + if (options.disableGlob || !glob.hasMagic(p)) { + results = [p] + } else { + try { + options.lstatSync(p) + results = [p] + } catch (er) { + results = glob.sync(p, options.glob) } } - function idle () { - return _running === 0 && self.length() === 0 - } + if (!results.length) + return - function push (value, done) { - var current = cache.get() + for (let i = 0; i < results.length; i++) { + const p = results[i] - current.context = context - current.release = release - current.value = value - current.callback = done || noop + let st + try { + st = options.lstatSync(p) + } catch (er) { + if (er.code === "ENOENT") + return - if (_running === self.concurrency || self.paused) { - if (queueTail) { - queueTail.next = current - queueTail = current - } else { - queueHead = current - queueTail = current - self.saturated() - } - } else { - _running++ - worker.call(context, current.value, current.worked) + // Windows can EPERM on stat. Life is suffering. + if (er.code === "EPERM" && isWindows) + fixWinEPERMSync(p, options, er) } - } - - function unshift (value, done) { - var current = cache.get() - - current.context = context - current.release = release - current.value = value - current.callback = done || noop - if (_running === self.concurrency || self.paused) { - if (queueHead) { - current.next = queueHead - queueHead = current - } else { - queueHead = current - queueTail = current - self.saturated() - } - } else { - _running++ - worker.call(context, current.value, current.worked) - } - } + try { + // sunos lets the root user unlink directories, which is... weird. + if (st && st.isDirectory()) + rmdirSync(p, options, null) + else + options.unlinkSync(p) + } catch (er) { + if (er.code === "ENOENT") + return + if (er.code === "EPERM") + return isWindows ? fixWinEPERMSync(p, options, er) : rmdirSync(p, options, er) + if (er.code !== "EISDIR") + throw er - function release (holder) { - if (holder) { - cache.release(holder) - } - var next = queueHead - if (next) { - if (!self.paused) { - if (queueTail === queueHead) { - queueTail = null - } - queueHead = next.next - next.next = null - worker.call(context, next.value, next.worked) - if (queueTail === null) { - self.empty() - } - } else { - _running-- - } - } else if (--_running === 0) { - self.drain() + rmdirSync(p, options, er) } } +} - function kill () { - queueHead = null - queueTail = null - self.drain = noop - } +const rmdirSync = (p, options, originalEr) => { + assert(p) + assert(options) - function killAndDrain () { - queueHead = null - queueTail = null - self.drain() - self.drain = noop + try { + options.rmdirSync(p) + } catch (er) { + if (er.code === "ENOENT") + return + if (er.code === "ENOTDIR") + throw originalEr + if (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM") + rmkidsSync(p, options) } } -function noop () {} - -function Task () { - this.value = null - this.callback = noop - this.next = null - this.release = noop - this.context = null - - var self = this +const rmkidsSync = (p, options) => { + assert(p) + assert(options) + options.readdirSync(p).forEach(f => rimrafSync(path.join(p, f), options)) - this.worked = function worked (err, result) { - var callback = self.callback - self.value = null - self.callback = noop - callback.call(self.context, err, result) - self.release(self) - } + // We only end up here once we got ENOTEMPTY at least once, and + // at this point, we are guaranteed to have removed all the kids. + // So, we know that it won't be ENOENT or ENOTDIR or anything else. + // try really hard to delete stuff on windows, because it has a + // PROFOUNDLY annoying habit of not closing handles promptly when + // files are deleted, resulting in spurious ENOTEMPTY errors. + const retries = isWindows ? 100 : 1 + let i = 0 + do { + let threw = true + try { + const ret = options.rmdirSync(p, options) + threw = false + return ret + } finally { + if (++i < retries && threw) + continue + } + } while (true) } -module.exports = fastqueue +module.exports = rimraf +rimraf.sync = rimrafSync /***/ }), -/* 343 */ +/* 363 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +const AggregateError = __webpack_require__(364); -function reusify (Constructor) { - var head = new Constructor() - var tail = head +module.exports = async ( + iterable, + mapper, + { + concurrency = Infinity, + stopOnError = true + } = {} +) => { + return new Promise((resolve, reject) => { + if (typeof mapper !== 'function') { + throw new TypeError('Mapper function is required'); + } - function get () { - var current = head + if (!(typeof concurrency === 'number' && concurrency >= 1)) { + throw new TypeError(`Expected \`concurrency\` to be a number from 1 and up, got \`${concurrency}\` (${typeof concurrency})`); + } - if (current.next) { - head = current.next - } else { - head = new Constructor() - tail = head - } + const ret = []; + const errors = []; + const iterator = iterable[Symbol.iterator](); + let isRejected = false; + let isIterableDone = false; + let resolvingCount = 0; + let currentIndex = 0; - current.next = null + const next = () => { + if (isRejected) { + return; + } - return current - } + const nextItem = iterator.next(); + const i = currentIndex; + currentIndex++; - function release (obj) { - tail.next = obj - tail = obj - } + if (nextItem.done) { + isIterableDone = true; - return { - get: get, - release: release - } -} + if (resolvingCount === 0) { + if (!stopOnError && errors.length !== 0) { + reject(new AggregateError(errors)); + } else { + resolve(ret); + } + } -module.exports = reusify + return; + } + resolvingCount++; -/***/ }), -/* 344 */ -/***/ (function(module, exports, __webpack_require__) { + (async () => { + try { + const element = await nextItem.value; + ret[i] = await mapper(element, i); + resolvingCount--; + next(); + } catch (error) { + if (stopOnError) { + isRejected = true; + reject(error); + } else { + errors.push(error); + resolvingCount--; + next(); + } + } + })(); + }; -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -function isFatalError(settings, error) { - if (settings.errorFilter === null) { - return true; - } - return !settings.errorFilter(error); -} -exports.isFatalError = isFatalError; -function isAppliedFilter(filter, value) { - return filter === null || filter(value); -} -exports.isAppliedFilter = isAppliedFilter; -function replacePathSegmentSeparator(filepath, separator) { - return filepath.split(/[\\/]/).join(separator); -} -exports.replacePathSegmentSeparator = replacePathSegmentSeparator; -function joinPathSegments(a, b, separator) { - if (a === '') { - return b; - } - return a + separator + b; -} -exports.joinPathSegments = joinPathSegments; + for (let i = 0; i < concurrency; i++) { + next(); + + if (isIterableDone) { + break; + } + } + }); +}; /***/ }), -/* 345 */ +/* 364 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const common = __webpack_require__(344); -class Reader { - constructor(_root, _settings) { - this._root = _root; - this._settings = _settings; - this._root = common.replacePathSegmentSeparator(_root, _settings.pathSegmentSeparator); - } -} -exports.default = Reader; +const indentString = __webpack_require__(365); +const cleanStack = __webpack_require__(366); -/***/ }), -/* 346 */ -/***/ (function(module, exports, __webpack_require__) { +const cleanInternalStack = stack => stack.replace(/\s+at .*aggregate-error\/index.js:\d+:\d+\)?/g, ''); -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const stream_1 = __webpack_require__(137); -const async_1 = __webpack_require__(332); -class StreamProvider { - constructor(_root, _settings) { - this._root = _root; - this._settings = _settings; - this._reader = new async_1.default(this._root, this._settings); - this._stream = new stream_1.Readable({ - objectMode: true, - read: () => { }, - destroy: this._reader.destroy.bind(this._reader) - }); - } - read() { - this._reader.onError((error) => { - this._stream.emit('error', error); - }); - this._reader.onEntry((entry) => { - this._stream.push(entry); - }); - this._reader.onEnd(() => { - this._stream.push(null); - }); - this._reader.read(); - return this._stream; - } -} -exports.default = StreamProvider; +class AggregateError extends Error { + constructor(errors) { + if (!Array.isArray(errors)) { + throw new TypeError(`Expected input to be an Array, got ${typeof errors}`); + } + errors = [...errors].map(error => { + if (error instanceof Error) { + return error; + } -/***/ }), -/* 347 */ -/***/ (function(module, exports, __webpack_require__) { + if (error !== null && typeof error === 'object') { + // Handle plain error objects with message property and/or possibly other metadata + return Object.assign(new Error(error.message), error); + } -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const sync_1 = __webpack_require__(348); -class SyncProvider { - constructor(_root, _settings) { - this._root = _root; - this._settings = _settings; - this._reader = new sync_1.default(this._root, this._settings); - } - read() { - return this._reader.read(); - } -} -exports.default = SyncProvider; + return new Error(error); + }); + let message = errors + .map(error => { + // The `stack` property is not standardized, so we can't assume it exists + return typeof error.stack === 'string' ? cleanInternalStack(cleanStack(error.stack)) : String(error); + }) + .join('\n'); + message = '\n' + indentString(message, 4); + super(message); -/***/ }), -/* 348 */ -/***/ (function(module, exports, __webpack_require__) { + this.name = 'AggregateError'; -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const fsScandir = __webpack_require__(333); -const common = __webpack_require__(344); -const reader_1 = __webpack_require__(345); -class SyncReader extends reader_1.default { - constructor() { - super(...arguments); - this._scandir = fsScandir.scandirSync; - this._storage = new Set(); - this._queue = new Set(); - } - read() { - this._pushToQueue(this._root, this._settings.basePath); - this._handleQueue(); - return [...this._storage]; - } - _pushToQueue(directory, base) { - this._queue.add({ directory, base }); - } - _handleQueue() { - for (const item of this._queue.values()) { - this._handleDirectory(item.directory, item.base); - } - } - _handleDirectory(directory, base) { - try { - const entries = this._scandir(directory, this._settings.fsScandirSettings); - for (const entry of entries) { - this._handleEntry(entry, base); - } - } - catch (error) { - this._handleError(error); - } - } - _handleError(error) { - if (!common.isFatalError(this._settings, error)) { - return; - } - throw error; - } - _handleEntry(entry, base) { - const fullpath = entry.path; - if (base !== undefined) { - entry.path = common.joinPathSegments(base, entry.name, this._settings.pathSegmentSeparator); - } - if (common.isAppliedFilter(this._settings.entryFilter, entry)) { - this._pushToStorage(entry); - } - if (entry.dirent.isDirectory() && common.isAppliedFilter(this._settings.deepFilter, entry)) { - this._pushToQueue(fullpath, entry.path); - } - } - _pushToStorage(entry) { - this._storage.add(entry); - } -} -exports.default = SyncReader; + Object.defineProperty(this, '_errors', {value: errors}); + } + + * [Symbol.iterator]() { + for (const error of this._errors) { + yield error; + } + } +} + +module.exports = AggregateError; /***/ }), -/* 349 */ +/* 365 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const path = __webpack_require__(4); -const fsScandir = __webpack_require__(333); -class Settings { - constructor(_options = {}) { - this._options = _options; - this.basePath = this._getValue(this._options.basePath, undefined); - this.concurrency = this._getValue(this._options.concurrency, Infinity); - this.deepFilter = this._getValue(this._options.deepFilter, null); - this.entryFilter = this._getValue(this._options.entryFilter, null); - this.errorFilter = this._getValue(this._options.errorFilter, null); - this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path.sep); - this.fsScandirSettings = new fsScandir.Settings({ - followSymbolicLinks: this._options.followSymbolicLinks, - fs: this._options.fs, - pathSegmentSeparator: this._options.pathSegmentSeparator, - stats: this._options.stats, - throwErrorOnBrokenSymbolicLink: this._options.throwErrorOnBrokenSymbolicLink - }); - } - _getValue(option, value) { - return option === undefined ? value : option; - } -} -exports.default = Settings; + + +module.exports = (string, count = 1, options) => { + options = { + indent: ' ', + includeEmptyLines: false, + ...options + }; + + if (typeof string !== 'string') { + throw new TypeError( + `Expected \`input\` to be a \`string\`, got \`${typeof string}\`` + ); + } + + if (typeof count !== 'number') { + throw new TypeError( + `Expected \`count\` to be a \`number\`, got \`${typeof count}\`` + ); + } + + if (typeof options.indent !== 'string') { + throw new TypeError( + `Expected \`options.indent\` to be a \`string\`, got \`${typeof options.indent}\`` + ); + } + + if (count === 0) { + return string; + } + + const regex = options.includeEmptyLines ? /^/gm : /^(?!\s*$)/gm; + + return string.replace(regex, options.indent.repeat(count)); +}; /***/ }), -/* 350 */ +/* 366 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const path = __webpack_require__(4); -const fsStat = __webpack_require__(325); -const utils = __webpack_require__(295); -class Reader { - constructor(_settings) { - this._settings = _settings; - this._fsStatSettings = new fsStat.Settings({ - followSymbolicLink: this._settings.followSymbolicLinks, - fs: this._settings.fs, - throwErrorOnBrokenSymbolicLink: this._settings.followSymbolicLinks - }); - } - _getFullEntryPath(filepath) { - return path.resolve(this._settings.cwd, filepath); - } - _makeEntry(stats, pattern) { - const entry = { - name: pattern, - path: pattern, - dirent: utils.fs.createDirentFromStats(pattern, stats) - }; - if (this._settings.stats) { - entry.stats = stats; - } - return entry; - } - _isFatalError(error) { - return !utils.errno.isEnoentCodeError(error) && !this._settings.suppressErrors; - } -} -exports.default = Reader; +const os = __webpack_require__(121); -/***/ }), -/* 351 */ -/***/ (function(module, exports, __webpack_require__) { +const extractPathRegex = /\s+at.*(?:\(|\s)(.*)\)?/; +const pathRegex = /^(?:(?:(?:node|(?:internal\/[\w/]*|.*node_modules\/(?:babel-polyfill|pirates)\/.*)?\w+)\.js:\d+:\d+)|native)/; +const homeDir = typeof os.homedir === 'undefined' ? '' : os.homedir(); -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const path = __webpack_require__(4); -const deep_1 = __webpack_require__(352); -const entry_1 = __webpack_require__(355); -const error_1 = __webpack_require__(356); -const entry_2 = __webpack_require__(357); -class Provider { - constructor(_settings) { - this._settings = _settings; - this.errorFilter = new error_1.default(this._settings); - this.entryFilter = new entry_1.default(this._settings, this._getMicromatchOptions()); - this.deepFilter = new deep_1.default(this._settings, this._getMicromatchOptions()); - this.entryTransformer = new entry_2.default(this._settings); - } - _getRootDirectory(task) { - return path.resolve(this._settings.cwd, task.base); - } - _getReaderOptions(task) { - const basePath = task.base === '.' ? '' : task.base; - return { - basePath, - pathSegmentSeparator: '/', - concurrency: this._settings.concurrency, - deepFilter: this.deepFilter.getFilter(basePath, task.positive, task.negative), - entryFilter: this.entryFilter.getFilter(task.positive, task.negative), - errorFilter: this.errorFilter.getFilter(), - followSymbolicLinks: this._settings.followSymbolicLinks, - fs: this._settings.fs, - stats: this._settings.stats, - throwErrorOnBrokenSymbolicLink: this._settings.throwErrorOnBrokenSymbolicLink, - transform: this.entryTransformer.getTransformer() - }; - } - _getMicromatchOptions() { - return { - dot: this._settings.dot, - matchBase: this._settings.baseNameMatch, - nobrace: !this._settings.braceExpansion, - nocase: !this._settings.caseSensitiveMatch, - noext: !this._settings.extglob, - noglobstar: !this._settings.globstar, - posix: true, - strictSlashes: false - }; - } -} -exports.default = Provider; +module.exports = (stack, options) => { + options = Object.assign({pretty: false}, options); + return stack.replace(/\\/g, '/') + .split('\n') + .filter(line => { + const pathMatches = line.match(extractPathRegex); + if (pathMatches === null || !pathMatches[1]) { + return true; + } -/***/ }), -/* 352 */ -/***/ (function(module, exports, __webpack_require__) { + const match = pathMatches[1]; -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(295); -const partial_1 = __webpack_require__(353); -class DeepFilter { - constructor(_settings, _micromatchOptions) { - this._settings = _settings; - this._micromatchOptions = _micromatchOptions; - } - getFilter(basePath, positive, negative) { - const matcher = this._getMatcher(positive); - const negativeRe = this._getNegativePatternsRe(negative); - return (entry) => this._filter(basePath, entry, matcher, negativeRe); - } - _getMatcher(patterns) { - return new partial_1.default(patterns, this._settings, this._micromatchOptions); - } - _getNegativePatternsRe(patterns) { - const affectDepthOfReadingPatterns = patterns.filter(utils.pattern.isAffectDepthOfReadingPattern); - return utils.pattern.convertPatternsToRe(affectDepthOfReadingPatterns, this._micromatchOptions); - } - _filter(basePath, entry, matcher, negativeRe) { - const depth = this._getEntryLevel(basePath, entry.path); - if (this._isSkippedByDeep(depth)) { - return false; - } - if (this._isSkippedSymbolicLink(entry)) { - return false; - } - const filepath = utils.path.removeLeadingDotSegment(entry.path); - if (this._isSkippedByPositivePatterns(filepath, matcher)) { - return false; - } - return this._isSkippedByNegativePatterns(filepath, negativeRe); - } - _isSkippedByDeep(entryDepth) { - return entryDepth >= this._settings.deep; - } - _isSkippedSymbolicLink(entry) { - return !this._settings.followSymbolicLinks && entry.dirent.isSymbolicLink(); - } - _getEntryLevel(basePath, entryPath) { - const basePathDepth = basePath.split('/').length; - const entryPathDepth = entryPath.split('/').length; - return entryPathDepth - (basePath === '' ? 0 : basePathDepth); - } - _isSkippedByPositivePatterns(entryPath, matcher) { - return !this._settings.baseNameMatch && !matcher.match(entryPath); - } - _isSkippedByNegativePatterns(entryPath, negativeRe) { - return !utils.pattern.matchAny(entryPath, negativeRe); - } -} -exports.default = DeepFilter; + // Electron + if ( + match.includes('.app/Contents/Resources/electron.asar') || + match.includes('.app/Contents/Resources/default_app.asar') + ) { + return false; + } + + return !pathRegex.test(match); + }) + .filter(line => line.trim() !== '') + .map(line => { + if (options.pretty) { + return line.replace(extractPathRegex, (m, p1) => m.replace(p1, p1.replace(homeDir, '~'))); + } + + return line; + }) + .join('\n'); +}; /***/ }), -/* 353 */ +/* 367 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const matcher_1 = __webpack_require__(354); -class PartialMatcher extends matcher_1.default { - match(filepath) { - const parts = filepath.split('/'); - const levels = parts.length; - const patterns = this._storage.filter((info) => !info.complete || info.segments.length > levels); - for (const pattern of patterns) { - const section = pattern.sections[0]; - /** - * In this case, the pattern has a globstar and we must read all directories unconditionally, - * but only if the level has reached the end of the first group. - * - * fixtures/{a,b}/** - * ^ true/false ^ always true - */ - if (!pattern.complete && levels > section.length) { - return true; - } - const match = parts.every((part, index) => { - const segment = pattern.segments[index]; - if (segment.dynamic && segment.patternRe.test(part)) { - return true; - } - if (!segment.dynamic && segment.pattern === part) { - return true; - } - return false; - }); - if (match) { - return true; - } - } - return false; - } -} -exports.default = PartialMatcher; +const readline = __webpack_require__(368); +const chalk = __webpack_require__(369); +const cliCursor = __webpack_require__(376); +const cliSpinners = __webpack_require__(380); +const logSymbols = __webpack_require__(382); +const stripAnsi = __webpack_require__(391); +const wcwidth = __webpack_require__(393); +const isInteractive = __webpack_require__(397); +const MuteStream = __webpack_require__(398); -/***/ }), -/* 354 */ -/***/ (function(module, exports, __webpack_require__) { +const TEXT = Symbol('text'); +const PREFIX_TEXT = Symbol('prefixText'); -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(295); -class Matcher { - constructor(_patterns, _settings, _micromatchOptions) { - this._patterns = _patterns; - this._settings = _settings; - this._micromatchOptions = _micromatchOptions; - this._storage = []; - this._fillStorage(); - } - _fillStorage() { - /** - * The original pattern may include `{,*,**,a/*}`, which will lead to problems with matching (unresolved level). - * So, before expand patterns with brace expansion into separated patterns. - */ - const patterns = utils.pattern.expandPatternsWithBraceExpansion(this._patterns); - for (const pattern of patterns) { - const segments = this._getPatternSegments(pattern); - const sections = this._splitSegmentsIntoSections(segments); - this._storage.push({ - complete: sections.length <= 1, - pattern, - segments, - sections - }); - } - } - _getPatternSegments(pattern) { - const parts = utils.pattern.getPatternParts(pattern, this._micromatchOptions); - return parts.map((part) => { - const dynamic = utils.pattern.isDynamicPattern(part, this._settings); - if (!dynamic) { - return { - dynamic: false, - pattern: part - }; - } - return { - dynamic: true, - pattern: part, - patternRe: utils.pattern.makeRe(part, this._micromatchOptions) - }; - }); - } - _splitSegmentsIntoSections(segments) { - return utils.array.splitWhen(segments, (segment) => segment.dynamic && utils.pattern.hasGlobStar(segment.pattern)); - } -} -exports.default = Matcher; +const ASCII_ETX_CODE = 0x03; // Ctrl+C emits this code +class StdinDiscarder { + constructor() { + this.requests = 0; + + this.mutedStream = new MuteStream(); + this.mutedStream.pipe(process.stdout); + this.mutedStream.mute(); + + const self = this; + this.ourEmit = function (event, data, ...args) { + const {stdin} = process; + if (self.requests > 0 || stdin.emit === self.ourEmit) { + if (event === 'keypress') { // Fixes readline behavior + return; + } -/***/ }), -/* 355 */ -/***/ (function(module, exports, __webpack_require__) { + if (event === 'data' && data.includes(ASCII_ETX_CODE)) { + process.emit('SIGINT'); + } -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(295); -class EntryFilter { - constructor(_settings, _micromatchOptions) { - this._settings = _settings; - this._micromatchOptions = _micromatchOptions; - this.index = new Map(); - } - getFilter(positive, negative) { - const positiveRe = utils.pattern.convertPatternsToRe(positive, this._micromatchOptions); - const negativeRe = utils.pattern.convertPatternsToRe(negative, this._micromatchOptions); - return (entry) => this._filter(entry, positiveRe, negativeRe); - } - _filter(entry, positiveRe, negativeRe) { - if (this._settings.unique) { - if (this._isDuplicateEntry(entry)) { - return false; - } - this._createIndexRecord(entry); - } - if (this._onlyFileFilter(entry) || this._onlyDirectoryFilter(entry)) { - return false; - } - if (this._isSkippedByAbsoluteNegativePatterns(entry, negativeRe)) { - return false; - } - const filepath = this._settings.baseNameMatch ? entry.name : entry.path; - return this._isMatchToPatterns(filepath, positiveRe) && !this._isMatchToPatterns(entry.path, negativeRe); - } - _isDuplicateEntry(entry) { - return this.index.has(entry.path); - } - _createIndexRecord(entry) { - this.index.set(entry.path, undefined); - } - _onlyFileFilter(entry) { - return this._settings.onlyFiles && !entry.dirent.isFile(); - } - _onlyDirectoryFilter(entry) { - return this._settings.onlyDirectories && !entry.dirent.isDirectory(); - } - _isSkippedByAbsoluteNegativePatterns(entry, negativeRe) { - if (!this._settings.absolute) { - return false; - } - const fullpath = utils.path.makeAbsolute(this._settings.cwd, entry.path); - return this._isMatchToPatterns(fullpath, negativeRe); - } - _isMatchToPatterns(entryPath, patternsRe) { - const filepath = utils.path.removeLeadingDotSegment(entryPath); - return utils.pattern.matchAny(filepath, patternsRe); - } -} -exports.default = EntryFilter; + Reflect.apply(self.oldEmit, this, [event, data, ...args]); + } else { + Reflect.apply(process.stdin.emit, this, [event, data, ...args]); + } + }; + } + start() { + this.requests++; -/***/ }), -/* 356 */ -/***/ (function(module, exports, __webpack_require__) { + if (this.requests === 1) { + this.realStart(); + } + } -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(295); -class ErrorFilter { - constructor(_settings) { - this._settings = _settings; - } - getFilter() { - return (error) => this._isNonFatalError(error); - } - _isNonFatalError(error) { - return utils.errno.isEnoentCodeError(error) || this._settings.suppressErrors; - } -} -exports.default = ErrorFilter; + stop() { + if (this.requests <= 0) { + throw new Error('`stop` called more times than `start`'); + } + this.requests--; -/***/ }), -/* 357 */ -/***/ (function(module, exports, __webpack_require__) { + if (this.requests === 0) { + this.realStop(); + } + } -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(295); -class EntryTransformer { - constructor(_settings) { - this._settings = _settings; - } - getTransformer() { - return (entry) => this._transform(entry); - } - _transform(entry) { - let filepath = entry.path; - if (this._settings.absolute) { - filepath = utils.path.makeAbsolute(this._settings.cwd, filepath); - filepath = utils.path.unixify(filepath); - } - if (this._settings.markDirectories && entry.dirent.isDirectory()) { - filepath += '/'; - } - if (!this._settings.objectMode) { - return filepath; - } - return Object.assign(Object.assign({}, entry), { path: filepath }); - } -} -exports.default = EntryTransformer; + realStart() { + // No known way to make it work reliably on Windows + if (process.platform === 'win32') { + return; + } + this.rl = readline.createInterface({ + input: process.stdin, + output: this.mutedStream + }); -/***/ }), -/* 358 */ -/***/ (function(module, exports, __webpack_require__) { + this.rl.on('SIGINT', () => { + if (process.listenerCount('SIGINT') === 0) { + process.emit('SIGINT'); + } else { + this.rl.close(); + process.kill(process.pid, 'SIGINT'); + } + }); + } -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const stream_1 = __webpack_require__(137); -const stream_2 = __webpack_require__(324); -const provider_1 = __webpack_require__(351); -class ProviderStream extends provider_1.default { - constructor() { - super(...arguments); - this._reader = new stream_2.default(this._settings); - } - read(task) { - const root = this._getRootDirectory(task); - const options = this._getReaderOptions(task); - const source = this.api(root, task, options); - const destination = new stream_1.Readable({ objectMode: true, read: () => { } }); - source - .once('error', (error) => destination.emit('error', error)) - .on('data', (entry) => destination.emit('data', options.transform(entry))) - .once('end', () => destination.emit('end')); - destination - .once('close', () => source.destroy()); - return destination; - } - api(root, task, options) { - if (task.dynamic) { - return this._reader.dynamic(root, options); - } - return this._reader.static(task.patterns, options); - } -} -exports.default = ProviderStream; + realStop() { + if (process.platform === 'win32') { + return; + } + this.rl.close(); + this.rl = undefined; + } +} -/***/ }), -/* 359 */ -/***/ (function(module, exports, __webpack_require__) { +let stdinDiscarder; -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const sync_1 = __webpack_require__(360); -const provider_1 = __webpack_require__(351); -class ProviderSync extends provider_1.default { - constructor() { - super(...arguments); - this._reader = new sync_1.default(this._settings); - } - read(task) { - const root = this._getRootDirectory(task); - const options = this._getReaderOptions(task); - const entries = this.api(root, task, options); - return entries.map(options.transform); - } - api(root, task, options) { - if (task.dynamic) { - return this._reader.dynamic(root, options); - } - return this._reader.static(task.patterns, options); - } -} -exports.default = ProviderSync; +class Ora { + constructor(options) { + if (!stdinDiscarder) { + stdinDiscarder = new StdinDiscarder(); + } + if (typeof options === 'string') { + options = { + text: options + }; + } -/***/ }), -/* 360 */ -/***/ (function(module, exports, __webpack_require__) { + this.options = { + text: '', + color: 'cyan', + stream: process.stderr, + discardStdin: true, + ...options + }; -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const fsStat = __webpack_require__(325); -const fsWalk = __webpack_require__(330); -const reader_1 = __webpack_require__(350); -class ReaderSync extends reader_1.default { - constructor() { - super(...arguments); - this._walkSync = fsWalk.walkSync; - this._statSync = fsStat.statSync; - } - dynamic(root, options) { - return this._walkSync(root, options); - } - static(patterns, options) { - const entries = []; - for (const pattern of patterns) { - const filepath = this._getFullEntryPath(pattern); - const entry = this._getEntry(filepath, pattern, options); - if (entry === null || !options.entryFilter(entry)) { - continue; - } - entries.push(entry); - } - return entries; - } - _getEntry(filepath, pattern, options) { - try { - const stats = this._getStat(filepath); - return this._makeEntry(stats, pattern); - } - catch (error) { - if (options.errorFilter(error)) { - return null; - } - throw error; - } - } - _getStat(filepath) { - return this._statSync(filepath, this._fsStatSettings); - } -} -exports.default = ReaderSync; + this.spinner = this.options.spinner; + this.color = this.options.color; + this.hideCursor = this.options.hideCursor !== false; + this.interval = this.options.interval || this.spinner.interval || 100; + this.stream = this.options.stream; + this.id = undefined; + this.isEnabled = typeof this.options.isEnabled === 'boolean' ? this.options.isEnabled : isInteractive({stream: this.stream}); -/***/ }), -/* 361 */ -/***/ (function(module, exports, __webpack_require__) { + // Set *after* `this.stream` + this.text = this.options.text; + this.prefixText = this.options.prefixText; + this.linesToClear = 0; + this.indent = this.options.indent; + this.discardStdin = this.options.discardStdin; + this.isDiscardingStdin = false; + } -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(133); -const os = __webpack_require__(120); -const CPU_COUNT = os.cpus().length; -exports.DEFAULT_FILE_SYSTEM_ADAPTER = { - lstat: fs.lstat, - lstatSync: fs.lstatSync, - stat: fs.stat, - statSync: fs.statSync, - readdir: fs.readdir, - readdirSync: fs.readdirSync -}; -class Settings { - constructor(_options = {}) { - this._options = _options; - this.absolute = this._getValue(this._options.absolute, false); - this.baseNameMatch = this._getValue(this._options.baseNameMatch, false); - this.braceExpansion = this._getValue(this._options.braceExpansion, true); - this.caseSensitiveMatch = this._getValue(this._options.caseSensitiveMatch, true); - this.concurrency = this._getValue(this._options.concurrency, CPU_COUNT); - this.cwd = this._getValue(this._options.cwd, process.cwd()); - this.deep = this._getValue(this._options.deep, Infinity); - this.dot = this._getValue(this._options.dot, false); - this.extglob = this._getValue(this._options.extglob, true); - this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, true); - this.fs = this._getFileSystemMethods(this._options.fs); - this.globstar = this._getValue(this._options.globstar, true); - this.ignore = this._getValue(this._options.ignore, []); - this.markDirectories = this._getValue(this._options.markDirectories, false); - this.objectMode = this._getValue(this._options.objectMode, false); - this.onlyDirectories = this._getValue(this._options.onlyDirectories, false); - this.onlyFiles = this._getValue(this._options.onlyFiles, true); - this.stats = this._getValue(this._options.stats, false); - this.suppressErrors = this._getValue(this._options.suppressErrors, false); - this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, false); - this.unique = this._getValue(this._options.unique, true); - if (this.onlyDirectories) { - this.onlyFiles = false; - } - if (this.stats) { - this.objectMode = true; - } - } - _getValue(option, value) { - return option === undefined ? value : option; - } - _getFileSystemMethods(methods = {}) { - return Object.assign(Object.assign({}, exports.DEFAULT_FILE_SYSTEM_ADAPTER), methods); - } -} -exports.default = Settings; + get indent() { + return this._indent; + } + set indent(indent = 0) { + if (!(indent >= 0 && Number.isInteger(indent))) { + throw new Error('The `indent` option must be an integer from 0 and up'); + } -/***/ }), -/* 362 */ -/***/ (function(module, exports, __webpack_require__) { + this._indent = indent; + } -"use strict"; + _updateInterval(interval) { + if (interval !== undefined) { + this.interval = interval; + } + } -const path = __webpack_require__(4); -const pathType = __webpack_require__(363); + get spinner() { + return this._spinner; + } -const getExtensions = extensions => extensions.length > 1 ? `{${extensions.join(',')}}` : extensions[0]; + set spinner(spinner) { + this.frameIndex = 0; -const getPath = (filepath, cwd) => { - const pth = filepath[0] === '!' ? filepath.slice(1) : filepath; - return path.isAbsolute(pth) ? pth : path.join(cwd, pth); -}; + if (typeof spinner === 'object') { + if (spinner.frames === undefined) { + throw new Error('The given spinner must have a `frames` property'); + } -const addExtensions = (file, extensions) => { - if (path.extname(file)) { - return `**/${file}`; + this._spinner = spinner; + } else if (process.platform === 'win32') { + this._spinner = cliSpinners.line; + } else if (spinner === undefined) { + // Set default spinner + this._spinner = cliSpinners.dots; + } else if (cliSpinners[spinner]) { + this._spinner = cliSpinners[spinner]; + } else { + throw new Error(`There is no built-in spinner named '${spinner}'. See https://github.com/sindresorhus/cli-spinners/blob/master/spinners.json for a full list.`); + } + + this._updateInterval(this._spinner.interval); } - return `**/${file}.${getExtensions(extensions)}`; -}; + get text() { + return this[TEXT]; + } -const getGlob = (directory, options) => { - if (options.files && !Array.isArray(options.files)) { - throw new TypeError(`Expected \`files\` to be of type \`Array\` but received type \`${typeof options.files}\``); + get prefixText() { + return this[PREFIX_TEXT]; } - if (options.extensions && !Array.isArray(options.extensions)) { - throw new TypeError(`Expected \`extensions\` to be of type \`Array\` but received type \`${typeof options.extensions}\``); + get isSpinning() { + return this.id !== undefined; } - if (options.files && options.extensions) { - return options.files.map(x => path.posix.join(directory, addExtensions(x, options.extensions))); + updateLineCount() { + const columns = this.stream.columns || 80; + const fullPrefixText = (typeof this[PREFIX_TEXT] === 'string') ? this[PREFIX_TEXT] + '-' : ''; + this.lineCount = stripAnsi(fullPrefixText + '--' + this[TEXT]).split('\n').reduce((count, line) => { + return count + Math.max(1, Math.ceil(wcwidth(line) / columns)); + }, 0); } - if (options.files) { - return options.files.map(x => path.posix.join(directory, `**/${x}`)); + set text(value) { + this[TEXT] = value; + this.updateLineCount(); } - if (options.extensions) { - return [path.posix.join(directory, `**/*.${getExtensions(options.extensions)}`)]; + set prefixText(value) { + this[PREFIX_TEXT] = value; + this.updateLineCount(); } - return [path.posix.join(directory, '**')]; -}; + frame() { + const {frames} = this.spinner; + let frame = frames[this.frameIndex]; -module.exports = async (input, options) => { - options = { - cwd: process.cwd(), - ...options - }; + if (this.color) { + frame = chalk[this.color](frame); + } - if (typeof options.cwd !== 'string') { - throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof options.cwd}\``); + this.frameIndex = ++this.frameIndex % frames.length; + const fullPrefixText = (typeof this.prefixText === 'string' && this.prefixText !== '') ? this.prefixText + ' ' : ''; + const fullText = typeof this.text === 'string' ? ' ' + this.text : ''; + + return fullPrefixText + frame + fullText; } - const globs = await Promise.all([].concat(input).map(async x => { - const isDirectory = await pathType.isDirectory(getPath(x, options.cwd)); - return isDirectory ? getGlob(x, options) : x; - })); + clear() { + if (!this.isEnabled || !this.stream.isTTY) { + return this; + } - return [].concat.apply([], globs); // eslint-disable-line prefer-spread -}; + for (let i = 0; i < this.linesToClear; i++) { + if (i > 0) { + this.stream.moveCursor(0, -1); + } -module.exports.sync = (input, options) => { - options = { - cwd: process.cwd(), - ...options - }; + this.stream.clearLine(); + this.stream.cursorTo(this.indent); + } - if (typeof options.cwd !== 'string') { - throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof options.cwd}\``); + this.linesToClear = 0; + + return this; } - const globs = [].concat(input).map(x => pathType.isDirectorySync(getPath(x, options.cwd)) ? getGlob(x, options) : x); + render() { + this.clear(); + this.stream.write(this.frame()); + this.linesToClear = this.lineCount; - return [].concat.apply([], globs); // eslint-disable-line prefer-spread -}; + return this; + } + start(text) { + if (text) { + this.text = text; + } -/***/ }), -/* 363 */ -/***/ (function(module, exports, __webpack_require__) { + if (!this.isEnabled) { + if (this.text) { + this.stream.write(`- ${this.text}\n`); + } -"use strict"; + return this; + } -const {promisify} = __webpack_require__(111); -const fs = __webpack_require__(133); + if (this.isSpinning) { + return this; + } -async function isType(fsStatType, statsMethodName, filePath) { - if (typeof filePath !== 'string') { - throw new TypeError(`Expected a string, got ${typeof filePath}`); + if (this.hideCursor) { + cliCursor.hide(this.stream); + } + + if (this.discardStdin && process.stdin.isTTY) { + this.isDiscardingStdin = true; + stdinDiscarder.start(); + } + + this.render(); + this.id = setInterval(this.render.bind(this), this.interval); + + return this; } - try { - const stats = await promisify(fs[fsStatType])(filePath); - return stats[statsMethodName](); - } catch (error) { - if (error.code === 'ENOENT') { - return false; + stop() { + if (!this.isEnabled) { + return this; } - throw error; + clearInterval(this.id); + this.id = undefined; + this.frameIndex = 0; + this.clear(); + if (this.hideCursor) { + cliCursor.show(this.stream); + } + + if (this.discardStdin && process.stdin.isTTY && this.isDiscardingStdin) { + stdinDiscarder.stop(); + this.isDiscardingStdin = false; + } + + return this; } -} -function isTypeSync(fsStatType, statsMethodName, filePath) { - if (typeof filePath !== 'string') { - throw new TypeError(`Expected a string, got ${typeof filePath}`); + succeed(text) { + return this.stopAndPersist({symbol: logSymbols.success, text}); } - try { - return fs[fsStatType](filePath)[statsMethodName](); - } catch (error) { - if (error.code === 'ENOENT') { - return false; - } + fail(text) { + return this.stopAndPersist({symbol: logSymbols.error, text}); + } - throw error; + warn(text) { + return this.stopAndPersist({symbol: logSymbols.warning, text}); + } + + info(text) { + return this.stopAndPersist({symbol: logSymbols.info, text}); + } + + stopAndPersist(options = {}) { + const prefixText = options.prefixText || this.prefixText; + const fullPrefixText = (typeof prefixText === 'string' && prefixText !== '') ? prefixText + ' ' : ''; + const text = options.text || this.text; + const fullText = (typeof text === 'string') ? ' ' + text : ''; + + this.stop(); + this.stream.write(`${fullPrefixText}${options.symbol || ' '}${fullText}\n`); + + return this; } } -exports.isFile = isType.bind(null, 'stat', 'isFile'); -exports.isDirectory = isType.bind(null, 'stat', 'isDirectory'); -exports.isSymlink = isType.bind(null, 'lstat', 'isSymbolicLink'); -exports.isFileSync = isTypeSync.bind(null, 'statSync', 'isFile'); -exports.isDirectorySync = isTypeSync.bind(null, 'statSync', 'isDirectory'); -exports.isSymlinkSync = isTypeSync.bind(null, 'lstatSync', 'isSymbolicLink'); +const oraFactory = function (options) { + return new Ora(options); +}; + +module.exports = oraFactory; + +module.exports.promise = (action, options) => { + // eslint-disable-next-line promise/prefer-await-to-then + if (typeof action.then !== 'function') { + throw new TypeError('Parameter `action` must be a Promise'); + } + + const spinner = new Ora(options); + spinner.start(); + + (async () => { + try { + await action; + spinner.succeed(); + } catch (_) { + spinner.fail(); + } + })(); + + return spinner; +}; /***/ }), -/* 364 */ +/* 368 */ +/***/ (function(module, exports) { + +module.exports = require("readline"); + +/***/ }), +/* 369 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const {promisify} = __webpack_require__(111); -const fs = __webpack_require__(133); -const path = __webpack_require__(4); -const fastGlob = __webpack_require__(293); -const gitIgnore = __webpack_require__(365); -const slash = __webpack_require__(366); +const ansiStyles = __webpack_require__(370); +const {stdout: stdoutColor, stderr: stderrColor} = __webpack_require__(120); +const { + stringReplaceAll, + stringEncaseCRLFWithFirstIndex +} = __webpack_require__(374); -const DEFAULT_IGNORE = [ - '**/node_modules/**', - '**/flow-typed/**', - '**/coverage/**', - '**/.git' +// `supportsColor.level` → `ansiStyles.color[name]` mapping +const levelMapping = [ + 'ansi', + 'ansi', + 'ansi256', + 'ansi16m' ]; -const readFileP = promisify(fs.readFile); +const styles = Object.create(null); -const mapGitIgnorePatternTo = base => ignore => { - if (ignore.startsWith('!')) { - return '!' + path.posix.join(base, ignore.slice(1)); +const applyOptions = (object, options = {}) => { + if (options.level > 3 || options.level < 0) { + throw new Error('The `level` option should be an integer from 0 to 3'); } - return path.posix.join(base, ignore); + // Detect level if not set manually + const colorLevel = stdoutColor ? stdoutColor.level : 0; + object.level = options.level === undefined ? colorLevel : options.level; }; -const parseGitIgnore = (content, options) => { - const base = slash(path.relative(options.cwd, path.dirname(options.fileName))); +class ChalkClass { + constructor(options) { + return chalkFactory(options); + } +} - return content - .split(/\r?\n/) - .filter(Boolean) - .filter(line => !line.startsWith('#')) - .map(mapGitIgnorePatternTo(base)); -}; +const chalkFactory = options => { + const chalk = {}; + applyOptions(chalk, options); -const reduceIgnore = files => { - return files.reduce((ignores, file) => { - ignores.add(parseGitIgnore(file.content, { - cwd: file.cwd, - fileName: file.filePath - })); - return ignores; - }, gitIgnore()); + chalk.template = (...arguments_) => chalkTag(chalk.template, ...arguments_); + + Object.setPrototypeOf(chalk, Chalk.prototype); + Object.setPrototypeOf(chalk.template, chalk); + + chalk.template.constructor = () => { + throw new Error('`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.'); + }; + + chalk.template.Instance = ChalkClass; + + return chalk.template; }; -const ensureAbsolutePathForCwd = (cwd, p) => { - if (path.isAbsolute(p)) { - if (p.startsWith(cwd)) { - return p; +function Chalk(options) { + return chalkFactory(options); +} + +for (const [styleName, style] of Object.entries(ansiStyles)) { + styles[styleName] = { + get() { + const builder = createBuilder(this, createStyler(style.open, style.close, this._styler), this._isEmpty); + Object.defineProperty(this, styleName, {value: builder}); + return builder; } + }; +} - throw new Error(`Path ${p} is not in cwd ${cwd}`); +styles.visible = { + get() { + const builder = createBuilder(this, this._styler, true); + Object.defineProperty(this, 'visible', {value: builder}); + return builder; } - - return path.join(cwd, p); }; -const getIsIgnoredPredecate = (ignores, cwd) => { - return p => ignores.ignores(slash(path.relative(cwd, ensureAbsolutePathForCwd(cwd, p)))); -}; +const usedModels = ['rgb', 'hex', 'keyword', 'hsl', 'hsv', 'hwb', 'ansi', 'ansi256']; -const getFile = async (file, cwd) => { - const filePath = path.join(cwd, file); - const content = await readFileP(filePath, 'utf8'); +for (const model of usedModels) { + styles[model] = { + get() { + const {level} = this; + return function (...arguments_) { + const styler = createStyler(ansiStyles.color[levelMapping[level]][model](...arguments_), ansiStyles.color.close, this._styler); + return createBuilder(this, styler, this._isEmpty); + }; + } + }; +} - return { - cwd, - filePath, - content +for (const model of usedModels) { + const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); + styles[bgModel] = { + get() { + const {level} = this; + return function (...arguments_) { + const styler = createStyler(ansiStyles.bgColor[levelMapping[level]][model](...arguments_), ansiStyles.bgColor.close, this._styler); + return createBuilder(this, styler, this._isEmpty); + }; + } }; -}; +} -const getFileSync = (file, cwd) => { - const filePath = path.join(cwd, file); - const content = fs.readFileSync(filePath, 'utf8'); +const proto = Object.defineProperties(() => {}, { + ...styles, + level: { + enumerable: true, + get() { + return this._generator.level; + }, + set(level) { + this._generator.level = level; + } + } +}); + +const createStyler = (open, close, parent) => { + let openAll; + let closeAll; + if (parent === undefined) { + openAll = open; + closeAll = close; + } else { + openAll = parent.openAll + open; + closeAll = close + parent.closeAll; + } return { - cwd, - filePath, - content + open, + close, + openAll, + closeAll, + parent }; }; -const normalizeOptions = ({ - ignore = [], - cwd = slash(process.cwd()) -} = {}) => { - return {ignore, cwd}; +const createBuilder = (self, _styler, _isEmpty) => { + const builder = (...arguments_) => { + // Single argument is hot path, implicit coercion is faster than anything + // eslint-disable-next-line no-implicit-coercion + return applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' ')); + }; + + // `__proto__` is used because we must return a function, but there is + // no way to create a function with a different prototype + builder.__proto__ = proto; // eslint-disable-line no-proto + + builder._generator = self; + builder._styler = _styler; + builder._isEmpty = _isEmpty; + + return builder; }; -module.exports = async options => { - options = normalizeOptions(options); +const applyStyle = (self, string) => { + if (self.level <= 0 || !string) { + return self._isEmpty ? '' : string; + } - const paths = await fastGlob('**/.gitignore', { - ignore: DEFAULT_IGNORE.concat(options.ignore), - cwd: options.cwd - }); + let styler = self._styler; - const files = await Promise.all(paths.map(file => getFile(file, options.cwd))); - const ignores = reduceIgnore(files); + if (styler === undefined) { + return string; + } - return getIsIgnoredPredecate(ignores, options.cwd); + const {openAll, closeAll} = styler; + if (string.indexOf('\u001B') !== -1) { + while (styler !== undefined) { + // Replace any instances already present with a re-opening code + // otherwise only the part of the string until said closing code + // will be colored, and the rest will simply be 'plain'. + string = stringReplaceAll(string, styler.close, styler.open); + + styler = styler.parent; + } + } + + // We can move both next actions out of loop, because remaining actions in loop won't have + // any/visible effect on parts we add here. Close the styling before a linebreak and reopen + // after next line to fix a bleed issue on macOS: https://github.com/chalk/chalk/pull/92 + const lfIndex = string.indexOf('\n'); + if (lfIndex !== -1) { + string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex); + } + + return openAll + string + closeAll; }; -module.exports.sync = options => { - options = normalizeOptions(options); +let template; +const chalkTag = (chalk, ...strings) => { + const [firstString] = strings; - const paths = fastGlob.sync('**/.gitignore', { - ignore: DEFAULT_IGNORE.concat(options.ignore), - cwd: options.cwd - }); + if (!Array.isArray(firstString)) { + // If chalk() was called by itself or with a string, + // return the string itself as a string. + return strings.join(' '); + } - const files = paths.map(file => getFileSync(file, options.cwd)); - const ignores = reduceIgnore(files); + const arguments_ = strings.slice(1); + const parts = [firstString.raw[0]]; - return getIsIgnoredPredecate(ignores, options.cwd); + for (let i = 1; i < firstString.length; i++) { + parts.push( + String(arguments_[i - 1]).replace(/[{}\\]/g, '\\$&'), + String(firstString.raw[i]) + ); + } + + if (template === undefined) { + template = __webpack_require__(375); + } + + return template(chalk, parts.join('')); }; +Object.defineProperties(Chalk.prototype, styles); -/***/ }), -/* 365 */ -/***/ (function(module, exports) { +const chalk = Chalk(); // eslint-disable-line new-cap +chalk.supportsColor = stdoutColor; +chalk.stderr = Chalk({level: stderrColor ? stderrColor.level : 0}); // eslint-disable-line new-cap +chalk.stderr.supportsColor = stderrColor; -// A simple implementation of make-array -function makeArray (subject) { - return Array.isArray(subject) - ? subject - : [subject] -} +// For TypeScript +chalk.Level = { + None: 0, + Basic: 1, + Ansi256: 2, + TrueColor: 3, + 0: 'None', + 1: 'Basic', + 2: 'Ansi256', + 3: 'TrueColor' +}; -const EMPTY = '' -const SPACE = ' ' -const ESCAPE = '\\' -const REGEX_TEST_BLANK_LINE = /^\s+$/ -const REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION = /^\\!/ -const REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\#/ -const REGEX_SPLITALL_CRLF = /\r?\n/g -// /foo, -// ./foo, -// ../foo, -// . -// .. -const REGEX_TEST_INVALID_PATH = /^\.*\/|^\.+$/ +module.exports = chalk; -const SLASH = '/' -const KEY_IGNORE = typeof Symbol !== 'undefined' - ? Symbol.for('node-ignore') - /* istanbul ignore next */ - : 'node-ignore' -const define = (object, key, value) => - Object.defineProperty(object, key, {value}) +/***/ }), +/* 370 */ +/***/ (function(module, exports, __webpack_require__) { -const REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g +"use strict"; +/* WEBPACK VAR INJECTION */(function(module) { -// Sanitize the range of a regular expression -// The cases are complicated, see test cases for details -const sanitizeRange = range => range.replace( - REGEX_REGEXP_RANGE, - (match, from, to) => from.charCodeAt(0) <= to.charCodeAt(0) - ? match - // Invalid range (out of order) which is ok for gitignore rules but - // fatal for JavaScript regular expression, so eliminate it. - : EMPTY -) - -// See fixtures #59 -const cleanRangeBackSlash = slashes => { - const {length} = slashes - return slashes.slice(0, length - length % 2) -} +const wrapAnsi16 = (fn, offset) => (...args) => { + const code = fn(...args); + return `\u001B[${code + offset}m`; +}; -// > If the pattern ends with a slash, -// > it is removed for the purpose of the following description, -// > but it would only find a match with a directory. -// > In other words, foo/ will match a directory foo and paths underneath it, -// > but will not match a regular file or a symbolic link foo -// > (this is consistent with the way how pathspec works in general in Git). -// '`foo/`' will not match regular file '`foo`' or symbolic link '`foo`' -// -> ignore-rules will not deal with it, because it costs extra `fs.stat` call -// you could use option `mark: true` with `glob` +const wrapAnsi256 = (fn, offset) => (...args) => { + const code = fn(...args); + return `\u001B[${38 + offset};5;${code}m`; +}; -// '`foo/`' should not continue with the '`..`' -const REPLACERS = [ +const wrapAnsi16m = (fn, offset) => (...args) => { + const rgb = fn(...args); + return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; +}; - // > Trailing spaces are ignored unless they are quoted with backslash ("\") - [ - // (a\ ) -> (a ) - // (a ) -> (a) - // (a \ ) -> (a ) - /\\?\s+$/, - match => match.indexOf('\\') === 0 - ? SPACE - : EMPTY - ], +const ansi2ansi = n => n; +const rgb2rgb = (r, g, b) => [r, g, b]; - // replace (\ ) with ' ' - [ - /\\\s/g, - () => SPACE - ], +const setLazyProperty = (object, property, get) => { + Object.defineProperty(object, property, { + get: () => { + const value = get(); - // Escape metacharacters - // which is written down by users but means special for regular expressions. + Object.defineProperty(object, property, { + value, + enumerable: true, + configurable: true + }); - // > There are 12 characters with special meanings: - // > - the backslash \, - // > - the caret ^, - // > - the dollar sign $, - // > - the period or dot ., - // > - the vertical bar or pipe symbol |, - // > - the question mark ?, - // > - the asterisk or star *, - // > - the plus sign +, - // > - the opening parenthesis (, - // > - the closing parenthesis ), - // > - and the opening square bracket [, - // > - the opening curly brace {, - // > These special characters are often called "metacharacters". - [ - /[\\$.|*+(){^]/g, - match => `\\${match}` - ], + return value; + }, + enumerable: true, + configurable: true + }); +}; - [ - // > a question mark (?) matches a single character - /(?!\\)\?/g, - () => '[^/]' - ], +/** @type {typeof import('color-convert')} */ +let colorConvert; +const makeDynamicStyles = (wrap, targetSpace, identity, isBackground) => { + if (colorConvert === undefined) { + colorConvert = __webpack_require__(371); + } - // leading slash - [ + const offset = isBackground ? 10 : 0; + const styles = {}; - // > A leading slash matches the beginning of the pathname. - // > For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c". - // A leading slash matches the beginning of the pathname - /^\//, - () => '^' - ], + for (const [sourceSpace, suite] of Object.entries(colorConvert)) { + const name = sourceSpace === 'ansi16' ? 'ansi' : sourceSpace; + if (sourceSpace === targetSpace) { + styles[name] = wrap(identity, offset); + } else if (typeof suite === 'object') { + styles[name] = wrap(suite[targetSpace], offset); + } + } - // replace special metacharacter slash after the leading slash - [ - /\//g, - () => '\\/' - ], + return styles; +}; - [ - // > A leading "**" followed by a slash means match in all directories. - // > For example, "**/foo" matches file or directory "foo" anywhere, - // > the same as pattern "foo". - // > "**/foo/bar" matches file or directory "bar" anywhere that is directly - // > under directory "foo". - // Notice that the '*'s have been replaced as '\\*' - /^\^*\\\*\\\*\\\//, +function assembleStyles() { + const codes = new Map(); + const styles = { + modifier: { + reset: [0, 0], + // 21 isn't widely supported and 22 does the same thing + bold: [1, 22], + dim: [2, 22], + italic: [3, 23], + underline: [4, 24], + inverse: [7, 27], + hidden: [8, 28], + strikethrough: [9, 29] + }, + color: { + black: [30, 39], + red: [31, 39], + green: [32, 39], + yellow: [33, 39], + blue: [34, 39], + magenta: [35, 39], + cyan: [36, 39], + white: [37, 39], - // '**/foo' <-> 'foo' - () => '^(?:.*\\/)?' - ], + // Bright color + blackBright: [90, 39], + redBright: [91, 39], + greenBright: [92, 39], + yellowBright: [93, 39], + blueBright: [94, 39], + magentaBright: [95, 39], + cyanBright: [96, 39], + whiteBright: [97, 39] + }, + bgColor: { + bgBlack: [40, 49], + bgRed: [41, 49], + bgGreen: [42, 49], + bgYellow: [43, 49], + bgBlue: [44, 49], + bgMagenta: [45, 49], + bgCyan: [46, 49], + bgWhite: [47, 49], - // starting - [ - // there will be no leading '/' - // (which has been replaced by section "leading slash") - // If starts with '**', adding a '^' to the regular expression also works - /^(?=[^^])/, - function startingReplacer () { - // If has a slash `/` at the beginning or middle - return !/\/(?!$)/.test(this) - // > Prior to 2.22.1 - // > If the pattern does not contain a slash /, - // > Git treats it as a shell glob pattern - // Actually, if there is only a trailing slash, - // git also treats it as a shell glob pattern + // Bright color + bgBlackBright: [100, 49], + bgRedBright: [101, 49], + bgGreenBright: [102, 49], + bgYellowBright: [103, 49], + bgBlueBright: [104, 49], + bgMagentaBright: [105, 49], + bgCyanBright: [106, 49], + bgWhiteBright: [107, 49] + } + }; - // After 2.22.1 (compatible but clearer) - // > If there is a separator at the beginning or middle (or both) - // > of the pattern, then the pattern is relative to the directory - // > level of the particular .gitignore file itself. - // > Otherwise the pattern may also match at any level below - // > the .gitignore level. - ? '(?:^|\\/)' + // Alias bright black as gray (and grey) + styles.color.gray = styles.color.blackBright; + styles.bgColor.bgGray = styles.bgColor.bgBlackBright; + styles.color.grey = styles.color.blackBright; + styles.bgColor.bgGrey = styles.bgColor.bgBlackBright; - // > Otherwise, Git treats the pattern as a shell glob suitable for - // > consumption by fnmatch(3) - : '^' - } - ], + for (const [groupName, group] of Object.entries(styles)) { + for (const [styleName, style] of Object.entries(group)) { + styles[styleName] = { + open: `\u001B[${style[0]}m`, + close: `\u001B[${style[1]}m` + }; - // two globstars - [ - // Use lookahead assertions so that we could match more than one `'/**'` - /\\\/\\\*\\\*(?=\\\/|$)/g, + group[styleName] = styles[styleName]; - // Zero, one or several directories - // should not use '*', or it will be replaced by the next replacer + codes.set(style[0], style[1]); + } - // Check if it is not the last `'/**'` - (_, index, str) => index + 6 < str.length + Object.defineProperty(styles, groupName, { + value: group, + enumerable: false + }); + } - // case: /**/ - // > A slash followed by two consecutive asterisks then a slash matches - // > zero or more directories. - // > For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on. - // '/**/' - ? '(?:\\/[^\\/]+)*' + Object.defineProperty(styles, 'codes', { + value: codes, + enumerable: false + }); - // case: /** - // > A trailing `"/**"` matches everything inside. + styles.color.close = '\u001B[39m'; + styles.bgColor.close = '\u001B[49m'; - // #21: everything inside but it should not include the current folder - : '\\/.+' - ], + setLazyProperty(styles.color, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, false)); + setLazyProperty(styles.color, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, false)); + setLazyProperty(styles.color, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, false)); + setLazyProperty(styles.bgColor, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, true)); + setLazyProperty(styles.bgColor, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, true)); + setLazyProperty(styles.bgColor, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, true)); - // intermediate wildcards - [ - // Never replace escaped '*' - // ignore rule '\*' will match the path '*' + return styles; +} - // 'abc.*/' -> go - // 'abc.*' -> skip this rule - /(^|[^\\]+)\\\*(?=.+)/g, +// Make the export immutable +Object.defineProperty(module, 'exports', { + enumerable: true, + get: assembleStyles +}); - // '*.js' matches '.js' - // '*.js' doesn't match 'abc' - (_, p1) => `${p1}[^\\/]*` - ], +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(115)(module))) - [ - // unescape, revert step 3 except for back slash - // For example, if a user escape a '\\*', - // after step 3, the result will be '\\\\\\*' - /\\\\\\(?=[$.|*+(){^])/g, - () => ESCAPE - ], +/***/ }), +/* 371 */ +/***/ (function(module, exports, __webpack_require__) { - [ - // '\\\\' -> '\\' - /\\\\/g, - () => ESCAPE - ], +const conversions = __webpack_require__(372); +const route = __webpack_require__(373); - [ - // > The range notation, e.g. [a-zA-Z], - // > can be used to match one of the characters in a range. +const convert = {}; - // `\` is escaped by step 3 - /(\\)?\[([^\]/]*?)(\\*)($|\])/g, - (match, leadEscape, range, endEscape, close) => leadEscape === ESCAPE - // '\\[bar]' -> '\\\\[bar\\]' - ? `\\[${range}${cleanRangeBackSlash(endEscape)}${close}` - : close === ']' - ? endEscape.length % 2 === 0 - // A normal case, and it is a range notation - // '[bar]' - // '[bar\\\\]' - ? `[${sanitizeRange(range)}${endEscape}]` - // Invalid range notaton - // '[bar\\]' -> '[bar\\\\]' - : '[]' - : '[]' - ], +const models = Object.keys(conversions); - // ending - [ - // 'js' will not match 'js.' - // 'ab' will not match 'abc' - /(?:[^*])$/, +function wrapRaw(fn) { + const wrappedFn = function (...args) { + const arg0 = args[0]; + if (arg0 === undefined || arg0 === null) { + return arg0; + } - // WTF! - // https://git-scm.com/docs/gitignore - // changes in [2.22.1](https://git-scm.com/docs/gitignore/2.22.1) - // which re-fixes #24, #38 + if (arg0.length > 1) { + args = arg0; + } - // > If there is a separator at the end of the pattern then the pattern - // > will only match directories, otherwise the pattern can match both - // > files and directories. + return fn(args); + }; - // 'js*' will not match 'a.js' - // 'js/' will not match 'a.js' - // 'js' will match 'a.js' and 'a.js/' - match => /\/$/.test(match) - // foo/ will not match 'foo' - ? `${match}$` - // foo matches 'foo' and 'foo/' - : `${match}(?=$|\\/$)` - ], + // Preserve .conversion property if there is one + if ('conversion' in fn) { + wrappedFn.conversion = fn.conversion; + } - // trailing wildcard - [ - /(\^|\\\/)?\\\*$/, - (_, p1) => { - const prefix = p1 - // '\^': - // '/*' does not match EMPTY - // '/*' does not match everything + return wrappedFn; +} - // '\\\/': - // 'abc/*' does not match 'abc/' - ? `${p1}[^/]+` +function wrapRounded(fn) { + const wrappedFn = function (...args) { + const arg0 = args[0]; - // 'a*' matches 'a' - // 'a*' matches 'aa' - : '[^/]*' + if (arg0 === undefined || arg0 === null) { + return arg0; + } - return `${prefix}(?=$|\\/$)` - } - ], -] + if (arg0.length > 1) { + args = arg0; + } -// A simple cache, because an ignore rule only has only one certain meaning -const regexCache = Object.create(null) + const result = fn(args); -// @param {pattern} -const makeRegex = (pattern, negative, ignorecase) => { - const r = regexCache[pattern] - if (r) { - return r - } + // We're assuming the result is an array here. + // see notice in conversions.js; don't use box types + // in conversion functions. + if (typeof result === 'object') { + for (let len = result.length, i = 0; i < len; i++) { + result[i] = Math.round(result[i]); + } + } - // const replacers = negative - // ? NEGATIVE_REPLACERS - // : POSITIVE_REPLACERS + return result; + }; - const source = REPLACERS.reduce( - (prev, current) => prev.replace(current[0], current[1].bind(pattern)), - pattern - ) + // Preserve .conversion property if there is one + if ('conversion' in fn) { + wrappedFn.conversion = fn.conversion; + } - return regexCache[pattern] = ignorecase - ? new RegExp(source, 'i') - : new RegExp(source) + return wrappedFn; } -const isString = subject => typeof subject === 'string' +models.forEach(fromModel => { + convert[fromModel] = {}; -// > A blank line matches no files, so it can serve as a separator for readability. -const checkPattern = pattern => pattern - && isString(pattern) - && !REGEX_TEST_BLANK_LINE.test(pattern) + Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels}); + Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels}); - // > A line starting with # serves as a comment. - && pattern.indexOf('#') !== 0 + const routes = route(fromModel); + const routeModels = Object.keys(routes); -const splitPattern = pattern => pattern.split(REGEX_SPLITALL_CRLF) + routeModels.forEach(toModel => { + const fn = routes[toModel]; -class IgnoreRule { - constructor ( - origin, - pattern, - negative, - regex - ) { - this.origin = origin - this.pattern = pattern - this.negative = negative - this.regex = regex - } -} + convert[fromModel][toModel] = wrapRounded(fn); + convert[fromModel][toModel].raw = wrapRaw(fn); + }); +}); -const createRule = (pattern, ignorecase) => { - const origin = pattern - let negative = false +module.exports = convert; - // > An optional prefix "!" which negates the pattern; - if (pattern.indexOf('!') === 0) { - negative = true - pattern = pattern.substr(1) - } - pattern = pattern - // > Put a backslash ("\") in front of the first "!" for patterns that - // > begin with a literal "!", for example, `"\!important!.txt"`. - .replace(REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION, '!') - // > Put a backslash ("\") in front of the first hash for patterns that - // > begin with a hash. - .replace(REGEX_REPLACE_LEADING_EXCAPED_HASH, '#') +/***/ }), +/* 372 */ +/***/ (function(module, exports, __webpack_require__) { - const regex = makeRegex(pattern, negative, ignorecase) +/* MIT license */ +/* eslint-disable no-mixed-operators */ +const cssKeywords = __webpack_require__(118); - return new IgnoreRule( - origin, - pattern, - negative, - regex - ) -} +// NOTE: conversions should only return primitive values (i.e. arrays, or +// values that give correct `typeof` results). +// do not use box values types (i.e. Number(), String(), etc.) -const throwError = (message, Ctor) => { - throw new Ctor(message) +const reverseKeywords = {}; +for (const key of Object.keys(cssKeywords)) { + reverseKeywords[cssKeywords[key]] = key; } -const checkPath = (path, originalPath, doThrow) => { - if (!isString(path)) { - return doThrow( - `path must be a string, but got \`${originalPath}\``, - TypeError - ) - } +const convert = { + rgb: {channels: 3, labels: 'rgb'}, + hsl: {channels: 3, labels: 'hsl'}, + hsv: {channels: 3, labels: 'hsv'}, + hwb: {channels: 3, labels: 'hwb'}, + cmyk: {channels: 4, labels: 'cmyk'}, + xyz: {channels: 3, labels: 'xyz'}, + lab: {channels: 3, labels: 'lab'}, + lch: {channels: 3, labels: 'lch'}, + hex: {channels: 1, labels: ['hex']}, + keyword: {channels: 1, labels: ['keyword']}, + ansi16: {channels: 1, labels: ['ansi16']}, + ansi256: {channels: 1, labels: ['ansi256']}, + hcg: {channels: 3, labels: ['h', 'c', 'g']}, + apple: {channels: 3, labels: ['r16', 'g16', 'b16']}, + gray: {channels: 1, labels: ['gray']} +}; - // We don't know if we should ignore EMPTY, so throw - if (!path) { - return doThrow(`path must not be empty`, TypeError) - } +module.exports = convert; - // Check if it is a relative path - if (checkPath.isNotRelative(path)) { - const r = '`path.relative()`d' - return doThrow( - `path should be a ${r} string, but got "${originalPath}"`, - RangeError - ) - } +// Hide .channels and .labels properties +for (const model of Object.keys(convert)) { + if (!('channels' in convert[model])) { + throw new Error('missing channels property: ' + model); + } - return true -} + if (!('labels' in convert[model])) { + throw new Error('missing channel labels property: ' + model); + } -const isNotRelative = path => REGEX_TEST_INVALID_PATH.test(path) + if (convert[model].labels.length !== convert[model].channels) { + throw new Error('channel and label counts mismatch: ' + model); + } -checkPath.isNotRelative = isNotRelative -checkPath.convert = p => p + const {channels, labels} = convert[model]; + delete convert[model].channels; + delete convert[model].labels; + Object.defineProperty(convert[model], 'channels', {value: channels}); + Object.defineProperty(convert[model], 'labels', {value: labels}); +} -class Ignore { - constructor ({ - ignorecase = true - } = {}) { - this._rules = [] - this._ignorecase = ignorecase - define(this, KEY_IGNORE, true) - this._initCache() - } +convert.rgb.hsl = function (rgb) { + const r = rgb[0] / 255; + const g = rgb[1] / 255; + const b = rgb[2] / 255; + const min = Math.min(r, g, b); + const max = Math.max(r, g, b); + const delta = max - min; + let h; + let s; - _initCache () { - this._ignoreCache = Object.create(null) - this._testCache = Object.create(null) - } + if (max === min) { + h = 0; + } else if (r === max) { + h = (g - b) / delta; + } else if (g === max) { + h = 2 + (b - r) / delta; + } else if (b === max) { + h = 4 + (r - g) / delta; + } - _addPattern (pattern) { - // #32 - if (pattern && pattern[KEY_IGNORE]) { - this._rules = this._rules.concat(pattern._rules) - this._added = true - return - } + h = Math.min(h * 60, 360); - if (checkPattern(pattern)) { - const rule = createRule(pattern, this._ignorecase) - this._added = true - this._rules.push(rule) - } - } + if (h < 0) { + h += 360; + } - // @param {Array | string | Ignore} pattern - add (pattern) { - this._added = false + const l = (min + max) / 2; - makeArray( - isString(pattern) - ? splitPattern(pattern) - : pattern - ).forEach(this._addPattern, this) + if (max === min) { + s = 0; + } else if (l <= 0.5) { + s = delta / (max + min); + } else { + s = delta / (2 - max - min); + } - // Some rules have just added to the ignore, - // making the behavior changed. - if (this._added) { - this._initCache() - } + return [h, s * 100, l * 100]; +}; - return this - } +convert.rgb.hsv = function (rgb) { + let rdif; + let gdif; + let bdif; + let h; + let s; - // legacy - addPattern (pattern) { - return this.add(pattern) - } + const r = rgb[0] / 255; + const g = rgb[1] / 255; + const b = rgb[2] / 255; + const v = Math.max(r, g, b); + const diff = v - Math.min(r, g, b); + const diffc = function (c) { + return (v - c) / 6 / diff + 1 / 2; + }; - // | ignored : unignored - // negative | 0:0 | 0:1 | 1:0 | 1:1 - // -------- | ------- | ------- | ------- | -------- - // 0 | TEST | TEST | SKIP | X - // 1 | TESTIF | SKIP | TEST | X + if (diff === 0) { + h = 0; + s = 0; + } else { + s = diff / v; + rdif = diffc(r); + gdif = diffc(g); + bdif = diffc(b); - // - SKIP: always skip - // - TEST: always test - // - TESTIF: only test if checkUnignored - // - X: that never happen + if (r === v) { + h = bdif - gdif; + } else if (g === v) { + h = (1 / 3) + rdif - bdif; + } else if (b === v) { + h = (2 / 3) + gdif - rdif; + } - // @param {boolean} whether should check if the path is unignored, - // setting `checkUnignored` to `false` could reduce additional - // path matching. + if (h < 0) { + h += 1; + } else if (h > 1) { + h -= 1; + } + } - // @returns {TestResult} true if a file is ignored - _testOne (path, checkUnignored) { - let ignored = false - let unignored = false + return [ + h * 360, + s * 100, + v * 100 + ]; +}; - this._rules.forEach(rule => { - const {negative} = rule - if ( - unignored === negative && ignored !== unignored - || negative && !ignored && !unignored && !checkUnignored - ) { - return - } +convert.rgb.hwb = function (rgb) { + const r = rgb[0]; + const g = rgb[1]; + let b = rgb[2]; + const h = convert.rgb.hsl(rgb)[0]; + const w = 1 / 255 * Math.min(r, Math.min(g, b)); - const matched = rule.regex.test(path) + b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); - if (matched) { - ignored = !negative - unignored = negative - } - }) + return [h, w * 100, b * 100]; +}; - return { - ignored, - unignored - } - } +convert.rgb.cmyk = function (rgb) { + const r = rgb[0] / 255; + const g = rgb[1] / 255; + const b = rgb[2] / 255; - // @returns {TestResult} - _test (originalPath, cache, checkUnignored, slices) { - const path = originalPath - // Supports nullable path - && checkPath.convert(originalPath) + const k = Math.min(1 - r, 1 - g, 1 - b); + const c = (1 - r - k) / (1 - k) || 0; + const m = (1 - g - k) / (1 - k) || 0; + const y = (1 - b - k) / (1 - k) || 0; - checkPath(path, originalPath, throwError) + return [c * 100, m * 100, y * 100, k * 100]; +}; - return this._t(path, cache, checkUnignored, slices) - } +function comparativeDistance(x, y) { + /* + See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance + */ + return ( + ((x[0] - y[0]) ** 2) + + ((x[1] - y[1]) ** 2) + + ((x[2] - y[2]) ** 2) + ); +} - _t (path, cache, checkUnignored, slices) { - if (path in cache) { - return cache[path] - } +convert.rgb.keyword = function (rgb) { + const reversed = reverseKeywords[rgb]; + if (reversed) { + return reversed; + } - if (!slices) { - // path/to/a.js - // ['path', 'to', 'a.js'] - slices = path.split(SLASH) - } + let currentClosestDistance = Infinity; + let currentClosestKeyword; - slices.pop() + for (const keyword of Object.keys(cssKeywords)) { + const value = cssKeywords[keyword]; - // If the path has no parent directory, just test it - if (!slices.length) { - return cache[path] = this._testOne(path, checkUnignored) - } + // Compute comparative distance + const distance = comparativeDistance(rgb, value); - const parent = this._t( - slices.join(SLASH) + SLASH, - cache, - checkUnignored, - slices - ) + // Check if its less, if so set as closest + if (distance < currentClosestDistance) { + currentClosestDistance = distance; + currentClosestKeyword = keyword; + } + } - // If the path contains a parent directory, check the parent first - return cache[path] = parent.ignored - // > It is not possible to re-include a file if a parent directory of - // > that file is excluded. - ? parent - : this._testOne(path, checkUnignored) - } + return currentClosestKeyword; +}; - ignores (path) { - return this._test(path, this._ignoreCache, false).ignored - } +convert.keyword.rgb = function (keyword) { + return cssKeywords[keyword]; +}; - createFilter () { - return path => !this.ignores(path) - } +convert.rgb.xyz = function (rgb) { + let r = rgb[0] / 255; + let g = rgb[1] / 255; + let b = rgb[2] / 255; - filter (paths) { - return makeArray(paths).filter(this.createFilter()) - } + // Assume sRGB + r = r > 0.04045 ? (((r + 0.055) / 1.055) ** 2.4) : (r / 12.92); + g = g > 0.04045 ? (((g + 0.055) / 1.055) ** 2.4) : (g / 12.92); + b = b > 0.04045 ? (((b + 0.055) / 1.055) ** 2.4) : (b / 12.92); - // @returns {TestResult} - test (path) { - return this._test(path, this._testCache, true) - } -} + const x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); + const y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); + const z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); -const factory = options => new Ignore(options) + return [x * 100, y * 100, z * 100]; +}; -const returnFalse = () => false +convert.rgb.lab = function (rgb) { + const xyz = convert.rgb.xyz(rgb); + let x = xyz[0]; + let y = xyz[1]; + let z = xyz[2]; -const isPathValid = path => - checkPath(path && checkPath.convert(path), path, returnFalse) + x /= 95.047; + y /= 100; + z /= 108.883; -factory.isPathValid = isPathValid + x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116); + y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116); + z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116); -// Fixes typescript -factory.default = factory + const l = (116 * y) - 16; + const a = 500 * (x - y); + const b = 200 * (y - z); -module.exports = factory + return [l, a, b]; +}; -// Windows -// -------------------------------------------------------------- -/* istanbul ignore if */ -if ( - // Detect `process` so that it can run in browsers. - typeof process !== 'undefined' - && ( - process.env && process.env.IGNORE_TEST_WIN32 - || process.platform === 'win32' - ) -) { - /* eslint no-control-regex: "off" */ - const makePosix = str => /^\\\\\?\\/.test(str) - || /["<>|\u0000-\u001F]+/u.test(str) - ? str - : str.replace(/\\/g, '/') +convert.hsl.rgb = function (hsl) { + const h = hsl[0] / 360; + const s = hsl[1] / 100; + const l = hsl[2] / 100; + let t2; + let t3; + let val; - checkPath.convert = makePosix + if (s === 0) { + val = l * 255; + return [val, val, val]; + } - // 'C:\\foo' <- 'C:\\foo' has been converted to 'C:/' - // 'd:\\foo' - const REGIX_IS_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i - checkPath.isNotRelative = path => - REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path) - || isNotRelative(path) -} + if (l < 0.5) { + t2 = l * (1 + s); + } else { + t2 = l + s - l * s; + } + const t1 = 2 * l - t2; -/***/ }), -/* 366 */ -/***/ (function(module, exports, __webpack_require__) { + const rgb = [0, 0, 0]; + for (let i = 0; i < 3; i++) { + t3 = h + 1 / 3 * -(i - 1); + if (t3 < 0) { + t3++; + } -"use strict"; + if (t3 > 1) { + t3--; + } -module.exports = path => { - const isExtendedLengthPath = /^\\\\\?\\/.test(path); - const hasNonAscii = /[^\u0000-\u0080]+/.test(path); // eslint-disable-line no-control-regex + if (6 * t3 < 1) { + val = t1 + (t2 - t1) * 6 * t3; + } else if (2 * t3 < 1) { + val = t2; + } else if (3 * t3 < 2) { + val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; + } else { + val = t1; + } - if (isExtendedLengthPath || hasNonAscii) { - return path; + rgb[i] = val * 255; } - return path.replace(/\\/g, '/'); + return rgb; }; +convert.hsl.hsv = function (hsl) { + const h = hsl[0]; + let s = hsl[1] / 100; + let l = hsl[2] / 100; + let smin = s; + const lmin = Math.max(l, 0.01); -/***/ }), -/* 367 */ -/***/ (function(module, exports, __webpack_require__) { + l *= 2; + s *= (l <= 1) ? l : 2 - l; + smin *= lmin <= 1 ? lmin : 2 - lmin; + const v = (l + s) / 2; + const sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s); -"use strict"; + return [h, sv * 100, v * 100]; +}; -const {Transform} = __webpack_require__(137); +convert.hsv.rgb = function (hsv) { + const h = hsv[0] / 60; + const s = hsv[1] / 100; + let v = hsv[2] / 100; + const hi = Math.floor(h) % 6; -class ObjectTransform extends Transform { - constructor() { - super({ - objectMode: true - }); - } -} + const f = h - Math.floor(h); + const p = 255 * v * (1 - s); + const q = 255 * v * (1 - (s * f)); + const t = 255 * v * (1 - (s * (1 - f))); + v *= 255; -class FilterStream extends ObjectTransform { - constructor(filter) { - super(); - this._filter = filter; + switch (hi) { + case 0: + return [v, t, p]; + case 1: + return [q, v, p]; + case 2: + return [p, v, t]; + case 3: + return [p, q, v]; + case 4: + return [t, p, v]; + case 5: + return [v, p, q]; } +}; - _transform(data, encoding, callback) { - if (this._filter(data)) { - this.push(data); - } +convert.hsv.hsl = function (hsv) { + const h = hsv[0]; + const s = hsv[1] / 100; + const v = hsv[2] / 100; + const vmin = Math.max(v, 0.01); + let sl; + let l; - callback(); - } -} + l = (2 - s) * v; + const lmin = (2 - s) * vmin; + sl = s * vmin; + sl /= (lmin <= 1) ? lmin : 2 - lmin; + sl = sl || 0; + l /= 2; -class UniqueStream extends ObjectTransform { - constructor() { - super(); - this._pushed = new Set(); - } + return [h, sl * 100, l * 100]; +}; - _transform(data, encoding, callback) { - if (!this._pushed.has(data)) { - this.push(data); - this._pushed.add(data); - } +// http://dev.w3.org/csswg/css-color/#hwb-to-rgb +convert.hwb.rgb = function (hwb) { + const h = hwb[0] / 360; + let wh = hwb[1] / 100; + let bl = hwb[2] / 100; + const ratio = wh + bl; + let f; - callback(); + // Wh + bl cant be > 1 + if (ratio > 1) { + wh /= ratio; + bl /= ratio; } -} - -module.exports = { - FilterStream, - UniqueStream -}; + const i = Math.floor(6 * h); + const v = 1 - bl; + f = 6 * h - i; -/***/ }), -/* 368 */ -/***/ (function(module, exports, __webpack_require__) { + if ((i & 0x01) !== 0) { + f = 1 - f; + } -/*! - * is-glob - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ + const n = wh + f * (v - wh); // Linear interpolation -var isExtglob = __webpack_require__(303); -var chars = { '{': '}', '(': ')', '[': ']'}; -var strictRegex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; -var relaxedRegex = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; + let r; + let g; + let b; + /* eslint-disable max-statements-per-line,no-multi-spaces */ + switch (i) { + default: + case 6: + case 0: r = v; g = n; b = wh; break; + case 1: r = n; g = v; b = wh; break; + case 2: r = wh; g = v; b = n; break; + case 3: r = wh; g = n; b = v; break; + case 4: r = n; g = wh; b = v; break; + case 5: r = v; g = wh; b = n; break; + } + /* eslint-enable max-statements-per-line,no-multi-spaces */ -module.exports = function isGlob(str, options) { - if (typeof str !== 'string' || str === '') { - return false; - } + return [r * 255, g * 255, b * 255]; +}; - if (isExtglob(str)) { - return true; - } +convert.cmyk.rgb = function (cmyk) { + const c = cmyk[0] / 100; + const m = cmyk[1] / 100; + const y = cmyk[2] / 100; + const k = cmyk[3] / 100; - var regex = strictRegex; - var match; + const r = 1 - Math.min(1, c * (1 - k) + k); + const g = 1 - Math.min(1, m * (1 - k) + k); + const b = 1 - Math.min(1, y * (1 - k) + k); - // optionally relax regex - if (options && options.strict === false) { - regex = relaxedRegex; - } + return [r * 255, g * 255, b * 255]; +}; - while ((match = regex.exec(str))) { - if (match[2]) return true; - var idx = match.index + match[0].length; +convert.xyz.rgb = function (xyz) { + const x = xyz[0] / 100; + const y = xyz[1] / 100; + const z = xyz[2] / 100; + let r; + let g; + let b; - // if an open bracket/brace/paren is escaped, - // set the index to the next closing character - var open = match[1]; - var close = open ? chars[open] : null; - if (open && close) { - var n = str.indexOf(close, idx); - if (n !== -1) { - idx = n + 1; - } - } + r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); + g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); + b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); - str = str.slice(idx); - } - return false; -}; + // Assume sRGB + r = r > 0.0031308 + ? ((1.055 * (r ** (1.0 / 2.4))) - 0.055) + : r * 12.92; + g = g > 0.0031308 + ? ((1.055 * (g ** (1.0 / 2.4))) - 0.055) + : g * 12.92; -/***/ }), -/* 369 */ -/***/ (function(module, exports, __webpack_require__) { + b = b > 0.0031308 + ? ((1.055 * (b ** (1.0 / 2.4))) - 0.055) + : b * 12.92; -"use strict"; + r = Math.min(Math.max(0, r), 1); + g = Math.min(Math.max(0, g), 1); + b = Math.min(Math.max(0, b), 1); -const path = __webpack_require__(4); + return [r * 255, g * 255, b * 255]; +}; -module.exports = path_ => { - let cwd = process.cwd(); +convert.xyz.lab = function (xyz) { + let x = xyz[0]; + let y = xyz[1]; + let z = xyz[2]; - path_ = path.resolve(path_); + x /= 95.047; + y /= 100; + z /= 108.883; - if (process.platform === 'win32') { - cwd = cwd.toLowerCase(); - path_ = path_.toLowerCase(); - } + x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116); + y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116); + z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116); - return path_ === cwd; + const l = (116 * y) - 16; + const a = 500 * (x - y); + const b = 200 * (y - z); + + return [l, a, b]; }; +convert.lab.xyz = function (lab) { + const l = lab[0]; + const a = lab[1]; + const b = lab[2]; + let x; + let y; + let z; -/***/ }), -/* 370 */ -/***/ (function(module, exports, __webpack_require__) { + y = (l + 16) / 116; + x = a / 500 + y; + z = y - b / 200; -"use strict"; + const y2 = y ** 3; + const x2 = x ** 3; + const z2 = z ** 3; + y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787; + x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787; + z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787; -const path = __webpack_require__(4); + x *= 95.047; + y *= 100; + z *= 108.883; -module.exports = (childPath, parentPath) => { - childPath = path.resolve(childPath); - parentPath = path.resolve(parentPath); + return [x, y, z]; +}; - if (process.platform === 'win32') { - childPath = childPath.toLowerCase(); - parentPath = parentPath.toLowerCase(); - } +convert.lab.lch = function (lab) { + const l = lab[0]; + const a = lab[1]; + const b = lab[2]; + let h; - if (childPath === parentPath) { - return false; + const hr = Math.atan2(b, a); + h = hr * 360 / 2 / Math.PI; + + if (h < 0) { + h += 360; } - childPath += path.sep; - parentPath += path.sep; + const c = Math.sqrt(a * a + b * b); - return childPath.startsWith(parentPath); + return [l, c, h]; }; +convert.lch.lab = function (lch) { + const l = lch[0]; + const c = lch[1]; + const h = lch[2]; -/***/ }), -/* 371 */ -/***/ (function(module, exports, __webpack_require__) { + const hr = h / 360 * 2 * Math.PI; + const a = c * Math.cos(hr); + const b = c * Math.sin(hr); -const assert = __webpack_require__(139) -const path = __webpack_require__(4) -const fs = __webpack_require__(133) -let glob = undefined -try { - glob = __webpack_require__(146) -} catch (_err) { - // treat glob as optional. -} + return [l, a, b]; +}; -const defaultGlobOpts = { - nosort: true, - silent: true -} +convert.rgb.ansi16 = function (args, saturation = null) { + const [r, g, b] = args; + let value = saturation === null ? convert.rgb.hsv(args)[2] : saturation; // Hsv -> ansi16 optimization -// for EMFILE handling -let timeout = 0 + value = Math.round(value / 50); -const isWindows = (process.platform === "win32") + if (value === 0) { + return 30; + } -const defaults = options => { - const methods = [ - 'unlink', - 'chmod', - 'stat', - 'lstat', - 'rmdir', - 'readdir' - ] - methods.forEach(m => { - options[m] = options[m] || fs[m] - m = m + 'Sync' - options[m] = options[m] || fs[m] - }) + let ansi = 30 + + ((Math.round(b / 255) << 2) + | (Math.round(g / 255) << 1) + | Math.round(r / 255)); - options.maxBusyTries = options.maxBusyTries || 3 - options.emfileWait = options.emfileWait || 1000 - if (options.glob === false) { - options.disableGlob = true - } - if (options.disableGlob !== true && glob === undefined) { - throw Error('glob dependency not found, set `options.disableGlob = true` if intentional') - } - options.disableGlob = options.disableGlob || false - options.glob = options.glob || defaultGlobOpts -} + if (value === 2) { + ansi += 60; + } -const rimraf = (p, options, cb) => { - if (typeof options === 'function') { - cb = options - options = {} - } + return ansi; +}; - assert(p, 'rimraf: missing path') - assert.equal(typeof p, 'string', 'rimraf: path should be a string') - assert.equal(typeof cb, 'function', 'rimraf: callback function required') - assert(options, 'rimraf: invalid options argument provided') - assert.equal(typeof options, 'object', 'rimraf: options should be object') +convert.hsv.ansi16 = function (args) { + // Optimization here; we already know the value and don't need to get + // it converted for us. + return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]); +}; - defaults(options) +convert.rgb.ansi256 = function (args) { + const r = args[0]; + const g = args[1]; + const b = args[2]; - let busyTries = 0 - let errState = null - let n = 0 + // We use the extended greyscale palette here, with the exception of + // black and white. normal palette only has 4 greyscale shades. + if (r === g && g === b) { + if (r < 8) { + return 16; + } - const next = (er) => { - errState = errState || er - if (--n === 0) - cb(errState) - } + if (r > 248) { + return 231; + } - const afterGlob = (er, results) => { - if (er) - return cb(er) + return Math.round(((r - 8) / 247) * 24) + 232; + } - n = results.length - if (n === 0) - return cb() + const ansi = 16 + + (36 * Math.round(r / 255 * 5)) + + (6 * Math.round(g / 255 * 5)) + + Math.round(b / 255 * 5); - results.forEach(p => { - const CB = (er) => { - if (er) { - if ((er.code === "EBUSY" || er.code === "ENOTEMPTY" || er.code === "EPERM") && - busyTries < options.maxBusyTries) { - busyTries ++ - // try again, with the same exact callback as this one. - return setTimeout(() => rimraf_(p, options, CB), busyTries * 100) - } + return ansi; +}; - // this one won't happen if graceful-fs is used. - if (er.code === "EMFILE" && timeout < options.emfileWait) { - return setTimeout(() => rimraf_(p, options, CB), timeout ++) - } +convert.ansi16.rgb = function (args) { + let color = args % 10; - // already gone - if (er.code === "ENOENT") er = null - } + // Handle greyscale + if (color === 0 || color === 7) { + if (args > 50) { + color += 3.5; + } - timeout = 0 - next(er) - } - rimraf_(p, options, CB) - }) - } + color = color / 10.5 * 255; - if (options.disableGlob || !glob.hasMagic(p)) - return afterGlob(null, [p]) + return [color, color, color]; + } - options.lstat(p, (er, stat) => { - if (!er) - return afterGlob(null, [p]) + const mult = (~~(args > 50) + 1) * 0.5; + const r = ((color & 1) * mult) * 255; + const g = (((color >> 1) & 1) * mult) * 255; + const b = (((color >> 2) & 1) * mult) * 255; - glob(p, options.glob, afterGlob) - }) + return [r, g, b]; +}; -} +convert.ansi256.rgb = function (args) { + // Handle greyscale + if (args >= 232) { + const c = (args - 232) * 10 + 8; + return [c, c, c]; + } -// Two possible strategies. -// 1. Assume it's a file. unlink it, then do the dir stuff on EPERM or EISDIR -// 2. Assume it's a directory. readdir, then do the file stuff on ENOTDIR -// -// Both result in an extra syscall when you guess wrong. However, there -// are likely far more normal files in the world than directories. This -// is based on the assumption that a the average number of files per -// directory is >= 1. -// -// If anyone ever complains about this, then I guess the strategy could -// be made configurable somehow. But until then, YAGNI. -const rimraf_ = (p, options, cb) => { - assert(p) - assert(options) - assert(typeof cb === 'function') + args -= 16; - // sunos lets the root user unlink directories, which is... weird. - // so we have to lstat here and make sure it's not a dir. - options.lstat(p, (er, st) => { - if (er && er.code === "ENOENT") - return cb(null) + let rem; + const r = Math.floor(args / 36) / 5 * 255; + const g = Math.floor((rem = args % 36) / 6) / 5 * 255; + const b = (rem % 6) / 5 * 255; - // Windows can EPERM on stat. Life is suffering. - if (er && er.code === "EPERM" && isWindows) - fixWinEPERM(p, options, er, cb) + return [r, g, b]; +}; - if (st && st.isDirectory()) - return rmdir(p, options, er, cb) +convert.rgb.hex = function (args) { + const integer = ((Math.round(args[0]) & 0xFF) << 16) + + ((Math.round(args[1]) & 0xFF) << 8) + + (Math.round(args[2]) & 0xFF); - options.unlink(p, er => { - if (er) { - if (er.code === "ENOENT") - return cb(null) - if (er.code === "EPERM") - return (isWindows) - ? fixWinEPERM(p, options, er, cb) - : rmdir(p, options, er, cb) - if (er.code === "EISDIR") - return rmdir(p, options, er, cb) - } - return cb(er) - }) - }) -} + const string = integer.toString(16).toUpperCase(); + return '000000'.substring(string.length) + string; +}; -const fixWinEPERM = (p, options, er, cb) => { - assert(p) - assert(options) - assert(typeof cb === 'function') +convert.hex.rgb = function (args) { + const match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); + if (!match) { + return [0, 0, 0]; + } - options.chmod(p, 0o666, er2 => { - if (er2) - cb(er2.code === "ENOENT" ? null : er) - else - options.stat(p, (er3, stats) => { - if (er3) - cb(er3.code === "ENOENT" ? null : er) - else if (stats.isDirectory()) - rmdir(p, options, er, cb) - else - options.unlink(p, cb) - }) - }) -} + let colorString = match[0]; -const fixWinEPERMSync = (p, options, er) => { - assert(p) - assert(options) + if (match[0].length === 3) { + colorString = colorString.split('').map(char => { + return char + char; + }).join(''); + } - try { - options.chmodSync(p, 0o666) - } catch (er2) { - if (er2.code === "ENOENT") - return - else - throw er - } + const integer = parseInt(colorString, 16); + const r = (integer >> 16) & 0xFF; + const g = (integer >> 8) & 0xFF; + const b = integer & 0xFF; - let stats - try { - stats = options.statSync(p) - } catch (er3) { - if (er3.code === "ENOENT") - return - else - throw er - } + return [r, g, b]; +}; - if (stats.isDirectory()) - rmdirSync(p, options, er) - else - options.unlinkSync(p) -} +convert.rgb.hcg = function (rgb) { + const r = rgb[0] / 255; + const g = rgb[1] / 255; + const b = rgb[2] / 255; + const max = Math.max(Math.max(r, g), b); + const min = Math.min(Math.min(r, g), b); + const chroma = (max - min); + let grayscale; + let hue; -const rmdir = (p, options, originalEr, cb) => { - assert(p) - assert(options) - assert(typeof cb === 'function') + if (chroma < 1) { + grayscale = min / (1 - chroma); + } else { + grayscale = 0; + } - // try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS) - // if we guessed wrong, and it's not a directory, then - // raise the original error. - options.rmdir(p, er => { - if (er && (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM")) - rmkids(p, options, cb) - else if (er && er.code === "ENOTDIR") - cb(originalEr) - else - cb(er) - }) -} + if (chroma <= 0) { + hue = 0; + } else + if (max === r) { + hue = ((g - b) / chroma) % 6; + } else + if (max === g) { + hue = 2 + (b - r) / chroma; + } else { + hue = 4 + (r - g) / chroma; + } -const rmkids = (p, options, cb) => { - assert(p) - assert(options) - assert(typeof cb === 'function') + hue /= 6; + hue %= 1; - options.readdir(p, (er, files) => { - if (er) - return cb(er) - let n = files.length - if (n === 0) - return options.rmdir(p, cb) - let errState - files.forEach(f => { - rimraf(path.join(p, f), options, er => { - if (errState) - return - if (er) - return cb(errState = er) - if (--n === 0) - options.rmdir(p, cb) - }) - }) - }) -} + return [hue * 360, chroma * 100, grayscale * 100]; +}; -// this looks simpler, and is strictly *faster*, but will -// tie up the JavaScript thread and fail on excessively -// deep directory trees. -const rimrafSync = (p, options) => { - options = options || {} - defaults(options) +convert.hsl.hcg = function (hsl) { + const s = hsl[1] / 100; + const l = hsl[2] / 100; - assert(p, 'rimraf: missing path') - assert.equal(typeof p, 'string', 'rimraf: path should be a string') - assert(options, 'rimraf: missing options') - assert.equal(typeof options, 'object', 'rimraf: options should be object') + const c = l < 0.5 ? (2.0 * s * l) : (2.0 * s * (1.0 - l)); - let results + let f = 0; + if (c < 1.0) { + f = (l - 0.5 * c) / (1.0 - c); + } - if (options.disableGlob || !glob.hasMagic(p)) { - results = [p] - } else { - try { - options.lstatSync(p) - results = [p] - } catch (er) { - results = glob.sync(p, options.glob) - } - } + return [hsl[0], c * 100, f * 100]; +}; - if (!results.length) - return +convert.hsv.hcg = function (hsv) { + const s = hsv[1] / 100; + const v = hsv[2] / 100; - for (let i = 0; i < results.length; i++) { - const p = results[i] + const c = s * v; + let f = 0; - let st - try { - st = options.lstatSync(p) - } catch (er) { - if (er.code === "ENOENT") - return + if (c < 1.0) { + f = (v - c) / (1 - c); + } - // Windows can EPERM on stat. Life is suffering. - if (er.code === "EPERM" && isWindows) - fixWinEPERMSync(p, options, er) - } + return [hsv[0], c * 100, f * 100]; +}; - try { - // sunos lets the root user unlink directories, which is... weird. - if (st && st.isDirectory()) - rmdirSync(p, options, null) - else - options.unlinkSync(p) - } catch (er) { - if (er.code === "ENOENT") - return - if (er.code === "EPERM") - return isWindows ? fixWinEPERMSync(p, options, er) : rmdirSync(p, options, er) - if (er.code !== "EISDIR") - throw er +convert.hcg.rgb = function (hcg) { + const h = hcg[0] / 360; + const c = hcg[1] / 100; + const g = hcg[2] / 100; - rmdirSync(p, options, er) - } - } -} + if (c === 0.0) { + return [g * 255, g * 255, g * 255]; + } -const rmdirSync = (p, options, originalEr) => { - assert(p) - assert(options) + const pure = [0, 0, 0]; + const hi = (h % 1) * 6; + const v = hi % 1; + const w = 1 - v; + let mg = 0; - try { - options.rmdirSync(p) - } catch (er) { - if (er.code === "ENOENT") - return - if (er.code === "ENOTDIR") - throw originalEr - if (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM") - rmkidsSync(p, options) - } -} + /* eslint-disable max-statements-per-line */ + switch (Math.floor(hi)) { + case 0: + pure[0] = 1; pure[1] = v; pure[2] = 0; break; + case 1: + pure[0] = w; pure[1] = 1; pure[2] = 0; break; + case 2: + pure[0] = 0; pure[1] = 1; pure[2] = v; break; + case 3: + pure[0] = 0; pure[1] = w; pure[2] = 1; break; + case 4: + pure[0] = v; pure[1] = 0; pure[2] = 1; break; + default: + pure[0] = 1; pure[1] = 0; pure[2] = w; + } + /* eslint-enable max-statements-per-line */ -const rmkidsSync = (p, options) => { - assert(p) - assert(options) - options.readdirSync(p).forEach(f => rimrafSync(path.join(p, f), options)) + mg = (1.0 - c) * g; - // We only end up here once we got ENOTEMPTY at least once, and - // at this point, we are guaranteed to have removed all the kids. - // So, we know that it won't be ENOENT or ENOTDIR or anything else. - // try really hard to delete stuff on windows, because it has a - // PROFOUNDLY annoying habit of not closing handles promptly when - // files are deleted, resulting in spurious ENOTEMPTY errors. - const retries = isWindows ? 100 : 1 - let i = 0 - do { - let threw = true - try { - const ret = options.rmdirSync(p, options) - threw = false - return ret - } finally { - if (++i < retries && threw) - continue - } - } while (true) -} + return [ + (c * pure[0] + mg) * 255, + (c * pure[1] + mg) * 255, + (c * pure[2] + mg) * 255 + ]; +}; -module.exports = rimraf -rimraf.sync = rimrafSync +convert.hcg.hsv = function (hcg) { + const c = hcg[1] / 100; + const g = hcg[2] / 100; + const v = c + g * (1.0 - c); + let f = 0; -/***/ }), -/* 372 */ -/***/ (function(module, exports, __webpack_require__) { + if (v > 0.0) { + f = c / v; + } -"use strict"; + return [hcg[0], f * 100, v * 100]; +}; -const AggregateError = __webpack_require__(373); +convert.hcg.hsl = function (hcg) { + const c = hcg[1] / 100; + const g = hcg[2] / 100; -module.exports = async ( - iterable, - mapper, - { - concurrency = Infinity, - stopOnError = true - } = {} -) => { - return new Promise((resolve, reject) => { - if (typeof mapper !== 'function') { - throw new TypeError('Mapper function is required'); - } + const l = g * (1.0 - c) + 0.5 * c; + let s = 0; - if (!(typeof concurrency === 'number' && concurrency >= 1)) { - throw new TypeError(`Expected \`concurrency\` to be a number from 1 and up, got \`${concurrency}\` (${typeof concurrency})`); - } + if (l > 0.0 && l < 0.5) { + s = c / (2 * l); + } else + if (l >= 0.5 && l < 1.0) { + s = c / (2 * (1 - l)); + } - const ret = []; - const errors = []; - const iterator = iterable[Symbol.iterator](); - let isRejected = false; - let isIterableDone = false; - let resolvingCount = 0; - let currentIndex = 0; + return [hcg[0], s * 100, l * 100]; +}; - const next = () => { - if (isRejected) { - return; - } +convert.hcg.hwb = function (hcg) { + const c = hcg[1] / 100; + const g = hcg[2] / 100; + const v = c + g * (1.0 - c); + return [hcg[0], (v - c) * 100, (1 - v) * 100]; +}; - const nextItem = iterator.next(); - const i = currentIndex; - currentIndex++; +convert.hwb.hcg = function (hwb) { + const w = hwb[1] / 100; + const b = hwb[2] / 100; + const v = 1 - b; + const c = v - w; + let g = 0; - if (nextItem.done) { - isIterableDone = true; + if (c < 1) { + g = (v - c) / (1 - c); + } - if (resolvingCount === 0) { - if (!stopOnError && errors.length !== 0) { - reject(new AggregateError(errors)); - } else { - resolve(ret); - } - } + return [hwb[0], c * 100, g * 100]; +}; - return; - } +convert.apple.rgb = function (apple) { + return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255]; +}; - resolvingCount++; +convert.rgb.apple = function (rgb) { + return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535]; +}; - (async () => { - try { - const element = await nextItem.value; - ret[i] = await mapper(element, i); - resolvingCount--; - next(); - } catch (error) { - if (stopOnError) { - isRejected = true; - reject(error); - } else { - errors.push(error); - resolvingCount--; - next(); - } - } - })(); - }; +convert.gray.rgb = function (args) { + return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; +}; - for (let i = 0; i < concurrency; i++) { - next(); +convert.gray.hsl = function (args) { + return [0, 0, args[0]]; +}; - if (isIterableDone) { - break; - } - } - }); +convert.gray.hsv = convert.gray.hsl; + +convert.gray.hwb = function (gray) { + return [0, 100, gray[0]]; }; +convert.gray.cmyk = function (gray) { + return [0, 0, 0, gray[0]]; +}; -/***/ }), -/* 373 */ -/***/ (function(module, exports, __webpack_require__) { +convert.gray.lab = function (gray) { + return [gray[0], 0, 0]; +}; -"use strict"; +convert.gray.hex = function (gray) { + const val = Math.round(gray[0] / 100 * 255) & 0xFF; + const integer = (val << 16) + (val << 8) + val; -const indentString = __webpack_require__(374); -const cleanStack = __webpack_require__(375); + const string = integer.toString(16).toUpperCase(); + return '000000'.substring(string.length) + string; +}; -const cleanInternalStack = stack => stack.replace(/\s+at .*aggregate-error\/index.js:\d+:\d+\)?/g, ''); +convert.rgb.gray = function (rgb) { + const val = (rgb[0] + rgb[1] + rgb[2]) / 3; + return [val / 255 * 100]; +}; -class AggregateError extends Error { - constructor(errors) { - if (!Array.isArray(errors)) { - throw new TypeError(`Expected input to be an Array, got ${typeof errors}`); - } - errors = [...errors].map(error => { - if (error instanceof Error) { - return error; - } +/***/ }), +/* 373 */ +/***/ (function(module, exports, __webpack_require__) { - if (error !== null && typeof error === 'object') { - // Handle plain error objects with message property and/or possibly other metadata - return Object.assign(new Error(error.message), error); - } +const conversions = __webpack_require__(372); - return new Error(error); - }); +/* + This function routes a model to all other models. - let message = errors - .map(error => { - // The `stack` property is not standardized, so we can't assume it exists - return typeof error.stack === 'string' ? cleanInternalStack(cleanStack(error.stack)) : String(error); - }) - .join('\n'); - message = '\n' + indentString(message, 4); - super(message); + all functions that are routed have a property `.conversion` attached + to the returned synthetic function. This property is an array + of strings, each with the steps in between the 'from' and 'to' + color models (inclusive). - this.name = 'AggregateError'; + conversions that are not possible simply are not included. +*/ - Object.defineProperty(this, '_errors', {value: errors}); - } +function buildGraph() { + const graph = {}; + // https://jsperf.com/object-keys-vs-for-in-with-closure/3 + const models = Object.keys(conversions); - * [Symbol.iterator]() { - for (const error of this._errors) { - yield error; - } + for (let len = models.length, i = 0; i < len; i++) { + graph[models[i]] = { + // http://jsperf.com/1-vs-infinity + // micro-opt, but this is simple. + distance: -1, + parent: null + }; } + + return graph; } -module.exports = AggregateError; +// https://en.wikipedia.org/wiki/Breadth-first_search +function deriveBFS(fromModel) { + const graph = buildGraph(); + const queue = [fromModel]; // Unshift -> queue -> pop + graph[fromModel].distance = 0; -/***/ }), -/* 374 */ -/***/ (function(module, exports, __webpack_require__) { + while (queue.length) { + const current = queue.pop(); + const adjacents = Object.keys(conversions[current]); -"use strict"; + for (let len = adjacents.length, i = 0; i < len; i++) { + const adjacent = adjacents[i]; + const node = graph[adjacent]; + + if (node.distance === -1) { + node.distance = graph[current].distance + 1; + node.parent = current; + queue.unshift(adjacent); + } + } + } + return graph; +} -module.exports = (string, count = 1, options) => { - options = { - indent: ' ', - includeEmptyLines: false, - ...options +function link(from, to) { + return function (args) { + return to(from(args)); }; +} - if (typeof string !== 'string') { - throw new TypeError( - `Expected \`input\` to be a \`string\`, got \`${typeof string}\`` - ); - } +function wrapConversion(toModel, graph) { + const path = [graph[toModel].parent, toModel]; + let fn = conversions[graph[toModel].parent][toModel]; - if (typeof count !== 'number') { - throw new TypeError( - `Expected \`count\` to be a \`number\`, got \`${typeof count}\`` - ); + let cur = graph[toModel].parent; + while (graph[cur].parent) { + path.unshift(graph[cur].parent); + fn = link(conversions[graph[cur].parent][cur], fn); + cur = graph[cur].parent; } - if (typeof options.indent !== 'string') { - throw new TypeError( - `Expected \`options.indent\` to be a \`string\`, got \`${typeof options.indent}\`` - ); - } + fn.conversion = path; + return fn; +} - if (count === 0) { - return string; - } +module.exports = function (fromModel) { + const graph = deriveBFS(fromModel); + const conversion = {}; - const regex = options.includeEmptyLines ? /^/gm : /^(?!\s*$)/gm; + const models = Object.keys(graph); + for (let len = models.length, i = 0; i < len; i++) { + const toModel = models[i]; + const node = graph[toModel]; - return string.replace(regex, options.indent.repeat(count)); + if (node.parent === null) { + // No possible conversion, or this node is the source model. + continue; + } + + conversion[toModel] = wrapConversion(toModel, graph); + } + + return conversion; }; + /***/ }), -/* 375 */ +/* 374 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const os = __webpack_require__(120); -const extractPathRegex = /\s+at.*(?:\(|\s)(.*)\)?/; -const pathRegex = /^(?:(?:(?:node|(?:internal\/[\w/]*|.*node_modules\/(?:babel-polyfill|pirates)\/.*)?\w+)\.js:\d+:\d+)|native)/; -const homeDir = typeof os.homedir === 'undefined' ? '' : os.homedir(); - -module.exports = (stack, options) => { - options = Object.assign({pretty: false}, options); +const stringReplaceAll = (string, substring, replacer) => { + let index = string.indexOf(substring); + if (index === -1) { + return string; + } - return stack.replace(/\\/g, '/') - .split('\n') - .filter(line => { - const pathMatches = line.match(extractPathRegex); - if (pathMatches === null || !pathMatches[1]) { - return true; - } + const substringLength = substring.length; + let endIndex = 0; + let returnValue = ''; + do { + returnValue += string.substr(endIndex, index - endIndex) + substring + replacer; + endIndex = index + substringLength; + index = string.indexOf(substring, endIndex); + } while (index !== -1); - const match = pathMatches[1]; + returnValue += string.substr(endIndex); + return returnValue; +}; - // Electron - if ( - match.includes('.app/Contents/Resources/electron.asar') || - match.includes('.app/Contents/Resources/default_app.asar') - ) { - return false; - } +const stringEncaseCRLFWithFirstIndex = (string, prefix, postfix, index) => { + let endIndex = 0; + let returnValue = ''; + do { + const gotCR = string[index - 1] === '\r'; + returnValue += string.substr(endIndex, (gotCR ? index - 1 : index) - endIndex) + prefix + (gotCR ? '\r\n' : '\n') + postfix; + endIndex = index + 1; + index = string.indexOf('\n', endIndex); + } while (index !== -1); - return !pathRegex.test(match); - }) - .filter(line => line.trim() !== '') - .map(line => { - if (options.pretty) { - return line.replace(extractPathRegex, (m, p1) => m.replace(p1, p1.replace(homeDir, '~'))); - } + returnValue += string.substr(endIndex); + return returnValue; +}; - return line; - }) - .join('\n'); +module.exports = { + stringReplaceAll, + stringEncaseCRLFWithFirstIndex }; /***/ }), -/* 376 */ +/* 375 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const chalk = __webpack_require__(377); -const cliCursor = __webpack_require__(386); -const cliSpinners = __webpack_require__(390); -const logSymbols = __webpack_require__(392); - -class Ora { - constructor(options) { - if (typeof options === 'string') { - options = { - text: options - }; - } - - this.options = Object.assign({ - text: '', - color: 'cyan', - stream: process.stderr - }, options); - - const sp = this.options.spinner; - this.spinner = typeof sp === 'object' ? sp : (process.platform === 'win32' ? cliSpinners.line : (cliSpinners[sp] || cliSpinners.dots)); // eslint-disable-line no-nested-ternary +const TEMPLATE_REGEX = /(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; +const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; +const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; +const ESCAPE_REGEX = /\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.)|([^\\])/gi; - if (this.spinner.frames === undefined) { - throw new Error('Spinner must define `frames`'); - } +const ESCAPES = new Map([ + ['n', '\n'], + ['r', '\r'], + ['t', '\t'], + ['b', '\b'], + ['f', '\f'], + ['v', '\v'], + ['0', '\0'], + ['\\', '\\'], + ['e', '\u001B'], + ['a', '\u0007'] +]); - this.text = this.options.text; - this.color = this.options.color; - this.interval = this.options.interval || this.spinner.interval || 100; - this.stream = this.options.stream; - this.id = null; - this.frameIndex = 0; - this.enabled = typeof this.options.enabled === 'boolean' ? this.options.enabled : ((this.stream && this.stream.isTTY) && !process.env.CI); +function unescape(c) { + const u = c[0] === 'u'; + const bracket = c[1] === '{'; + + if ((u && !bracket && c.length === 5) || (c[0] === 'x' && c.length === 3)) { + return String.fromCharCode(parseInt(c.slice(1), 16)); } - frame() { - const frames = this.spinner.frames; - let frame = frames[this.frameIndex]; - if (this.color) { - frame = chalk[this.color](frame); - } + if (u && bracket) { + return String.fromCodePoint(parseInt(c.slice(2, -1), 16)); + } - this.frameIndex = ++this.frameIndex % frames.length; + return ESCAPES.get(c) || c; +} - return frame + ' ' + this.text; - } - clear() { - if (!this.enabled) { - return this; +function parseArguments(name, arguments_) { + const results = []; + const chunks = arguments_.trim().split(/\s*,\s*/g); + let matches; + + for (const chunk of chunks) { + const number = Number(chunk); + if (!Number.isNaN(number)) { + results.push(number); + } else if ((matches = chunk.match(STRING_REGEX))) { + results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, character) => escape ? unescape(escape) : character)); + } else { + throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); } + } - this.stream.clearLine(); - this.stream.cursorTo(0); + return results; +} - return this; - } - render() { - this.clear(); - this.stream.write(this.frame()); +function parseStyle(style) { + STYLE_REGEX.lastIndex = 0; - return this; + const results = []; + let matches; + + while ((matches = STYLE_REGEX.exec(style)) !== null) { + const name = matches[1]; + + if (matches[2]) { + const args = parseArguments(name, matches[2]); + results.push([name].concat(args)); + } else { + results.push([name]); + } } - start(text) { - if (text) { - this.text = text; + + return results; +} + +function buildStyle(chalk, styles) { + const enabled = {}; + + for (const layer of styles) { + for (const style of layer.styles) { + enabled[style[0]] = layer.inverse ? null : style.slice(1); } + } - if (!this.enabled || this.id) { - return this; + let current = chalk; + for (const [styleName, styles] of Object.entries(enabled)) { + if (!Array.isArray(styles)) { + continue; } - cliCursor.hide(this.stream); - this.render(); - this.id = setInterval(this.render.bind(this), this.interval); + if (!(styleName in current)) { + throw new Error(`Unknown Chalk style: ${styleName}`); + } - return this; + current = styles.length > 0 ? current[styleName](...styles) : current[styleName]; } - stop() { - if (!this.enabled) { - return this; + + return current; +} + +module.exports = (chalk, temporary) => { + const styles = []; + const chunks = []; + let chunk = []; + + // eslint-disable-next-line max-params + temporary.replace(TEMPLATE_REGEX, (m, escapeCharacter, inverse, style, close, character) => { + if (escapeCharacter) { + chunk.push(unescape(escapeCharacter)); + } else if (style) { + const string = chunk.join(''); + chunk = []; + chunks.push(styles.length === 0 ? string : buildStyle(chalk, styles)(string)); + styles.push({inverse, styles: parseStyle(style)}); + } else if (close) { + if (styles.length === 0) { + throw new Error('Found extraneous } in Chalk template literal'); + } + + chunks.push(buildStyle(chalk, styles)(chunk.join(''))); + chunk = []; + styles.pop(); + } else { + chunk.push(character); } + }); - clearInterval(this.id); - this.id = null; - this.frameIndex = 0; - this.clear(); - cliCursor.show(this.stream); + chunks.push(chunk.join('')); - return this; + if (styles.length > 0) { + const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; + throw new Error(errMsg); } - succeed(text) { - return this.stopAndPersist({symbol: logSymbols.success, text}); + + return chunks.join(''); +}; + + +/***/ }), +/* 376 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const restoreCursor = __webpack_require__(377); + +let isHidden = false; + +exports.show = (writableStream = process.stderr) => { + if (!writableStream.isTTY) { + return; } - fail(text) { - return this.stopAndPersist({symbol: logSymbols.error, text}); + + isHidden = false; + writableStream.write('\u001B[?25h'); +}; + +exports.hide = (writableStream = process.stderr) => { + if (!writableStream.isTTY) { + return; } - warn(text) { - return this.stopAndPersist({symbol: logSymbols.warning, text}); + + restoreCursor(); + isHidden = true; + writableStream.write('\u001B[?25l'); +}; + +exports.toggle = (force, writableStream) => { + if (force !== undefined) { + isHidden = force; } - info(text) { - return this.stopAndPersist({symbol: logSymbols.info, text}); + + if (isHidden) { + exports.show(writableStream); + } else { + exports.hide(writableStream); } - stopAndPersist(options) { - if (!this.enabled) { - return this; - } +}; - // Legacy argument - // TODO: Deprecate sometime in the future - if (typeof options === 'string') { - options = { - symbol: options - }; + +/***/ }), +/* 377 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const onetime = __webpack_require__(378); +const signalExit = __webpack_require__(218); + +module.exports = onetime(() => { + signalExit(() => { + process.stderr.write('\u001B[?25h'); + }, {alwaysLast: true}); +}); + + +/***/ }), +/* 378 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const mimicFn = __webpack_require__(379); + +const calledFunctions = new WeakMap(); + +const oneTime = (fn, options = {}) => { + if (typeof fn !== 'function') { + throw new TypeError('Expected a function'); + } + + let ret; + let isCalled = false; + let callCount = 0; + const functionName = fn.displayName || fn.name || ''; + + const onetime = function (...args) { + calledFunctions.set(onetime, ++callCount); + + if (isCalled) { + if (options.throw === true) { + throw new Error(`Function \`${functionName}\` can only be called once`); + } + + return ret; } - options = options || {}; + isCalled = true; + ret = fn.apply(this, args); + fn = null; - this.stop(); - this.stream.write(`${options.symbol || ' '} ${options.text || this.text}\n`); + return ret; + }; - return this; + mimicFn(onetime, fn); + calledFunctions.set(onetime, callCount); + + return onetime; +}; + +module.exports = oneTime; +// TODO: Remove this for the next major release +module.exports.default = oneTime; + +module.exports.callCount = fn => { + if (!calledFunctions.has(fn)) { + throw new Error(`The given function \`${fn.name}\` is not wrapped by the \`onetime\` package`); } -} -module.exports = function (opts) { - return new Ora(opts); + return calledFunctions.get(fn); }; -module.exports.promise = (action, options) => { - if (typeof action.then !== 'function') { - throw new TypeError('Parameter `action` must be a Promise'); + +/***/ }), +/* 379 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const mimicFn = (to, from) => { + for (const prop of Reflect.ownKeys(from)) { + Object.defineProperty(to, prop, Object.getOwnPropertyDescriptor(from, prop)); } - const spinner = new Ora(options); - spinner.start(); + return to; +}; - action.then( - () => { - spinner.succeed(); - }, - () => { - spinner.fail(); - } - ); +module.exports = mimicFn; +// TODO: Remove this for the next major release +module.exports.default = mimicFn; - return spinner; + +/***/ }), +/* 380 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const spinners = Object.assign({}, __webpack_require__(381)); + +const spinnersList = Object.keys(spinners); + +Object.defineProperty(spinners, 'random', { + get() { + const randomIndex = Math.floor(Math.random() * spinnersList.length); + const spinnerName = spinnersList[randomIndex]; + return spinners[spinnerName]; + } +}); + +module.exports = spinners; +// TODO: Remove this for the next major release +module.exports.default = spinners; + + +/***/ }), +/* 381 */ +/***/ (function(module) { + +module.exports = JSON.parse("{\"dots\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠹\",\"⠸\",\"⠼\",\"⠴\",\"⠦\",\"⠧\",\"⠇\",\"⠏\"]},\"dots2\":{\"interval\":80,\"frames\":[\"⣾\",\"⣽\",\"⣻\",\"⢿\",\"⡿\",\"⣟\",\"⣯\",\"⣷\"]},\"dots3\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠚\",\"⠞\",\"⠖\",\"⠦\",\"⠴\",\"⠲\",\"⠳\",\"⠓\"]},\"dots4\":{\"interval\":80,\"frames\":[\"⠄\",\"⠆\",\"⠇\",\"⠋\",\"⠙\",\"⠸\",\"⠰\",\"⠠\",\"⠰\",\"⠸\",\"⠙\",\"⠋\",\"⠇\",\"⠆\"]},\"dots5\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\"]},\"dots6\":{\"interval\":80,\"frames\":[\"⠁\",\"⠉\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠤\",\"⠄\",\"⠄\",\"⠤\",\"⠴\",\"⠲\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠚\",\"⠙\",\"⠉\",\"⠁\"]},\"dots7\":{\"interval\":80,\"frames\":[\"⠈\",\"⠉\",\"⠋\",\"⠓\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠖\",\"⠦\",\"⠤\",\"⠠\",\"⠠\",\"⠤\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\",\"⠉\",\"⠈\"]},\"dots8\":{\"interval\":80,\"frames\":[\"⠁\",\"⠁\",\"⠉\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠤\",\"⠄\",\"⠄\",\"⠤\",\"⠠\",\"⠠\",\"⠤\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\",\"⠉\",\"⠈\",\"⠈\"]},\"dots9\":{\"interval\":80,\"frames\":[\"⢹\",\"⢺\",\"⢼\",\"⣸\",\"⣇\",\"⡧\",\"⡗\",\"⡏\"]},\"dots10\":{\"interval\":80,\"frames\":[\"⢄\",\"⢂\",\"⢁\",\"⡁\",\"⡈\",\"⡐\",\"⡠\"]},\"dots11\":{\"interval\":100,\"frames\":[\"⠁\",\"⠂\",\"⠄\",\"⡀\",\"⢀\",\"⠠\",\"⠐\",\"⠈\"]},\"dots12\":{\"interval\":80,\"frames\":[\"⢀⠀\",\"⡀⠀\",\"⠄⠀\",\"⢂⠀\",\"⡂⠀\",\"⠅⠀\",\"⢃⠀\",\"⡃⠀\",\"⠍⠀\",\"⢋⠀\",\"⡋⠀\",\"⠍⠁\",\"⢋⠁\",\"⡋⠁\",\"⠍⠉\",\"⠋⠉\",\"⠋⠉\",\"⠉⠙\",\"⠉⠙\",\"⠉⠩\",\"⠈⢙\",\"⠈⡙\",\"⢈⠩\",\"⡀⢙\",\"⠄⡙\",\"⢂⠩\",\"⡂⢘\",\"⠅⡘\",\"⢃⠨\",\"⡃⢐\",\"⠍⡐\",\"⢋⠠\",\"⡋⢀\",\"⠍⡁\",\"⢋⠁\",\"⡋⠁\",\"⠍⠉\",\"⠋⠉\",\"⠋⠉\",\"⠉⠙\",\"⠉⠙\",\"⠉⠩\",\"⠈⢙\",\"⠈⡙\",\"⠈⠩\",\"⠀⢙\",\"⠀⡙\",\"⠀⠩\",\"⠀⢘\",\"⠀⡘\",\"⠀⠨\",\"⠀⢐\",\"⠀⡐\",\"⠀⠠\",\"⠀⢀\",\"⠀⡀\"]},\"dots8Bit\":{\"interval\":80,\"frames\":[\"⠀\",\"⠁\",\"⠂\",\"⠃\",\"⠄\",\"⠅\",\"⠆\",\"⠇\",\"⡀\",\"⡁\",\"⡂\",\"⡃\",\"⡄\",\"⡅\",\"⡆\",\"⡇\",\"⠈\",\"⠉\",\"⠊\",\"⠋\",\"⠌\",\"⠍\",\"⠎\",\"⠏\",\"⡈\",\"⡉\",\"⡊\",\"⡋\",\"⡌\",\"⡍\",\"⡎\",\"⡏\",\"⠐\",\"⠑\",\"⠒\",\"⠓\",\"⠔\",\"⠕\",\"⠖\",\"⠗\",\"⡐\",\"⡑\",\"⡒\",\"⡓\",\"⡔\",\"⡕\",\"⡖\",\"⡗\",\"⠘\",\"⠙\",\"⠚\",\"⠛\",\"⠜\",\"⠝\",\"⠞\",\"⠟\",\"⡘\",\"⡙\",\"⡚\",\"⡛\",\"⡜\",\"⡝\",\"⡞\",\"⡟\",\"⠠\",\"⠡\",\"⠢\",\"⠣\",\"⠤\",\"⠥\",\"⠦\",\"⠧\",\"⡠\",\"⡡\",\"⡢\",\"⡣\",\"⡤\",\"⡥\",\"⡦\",\"⡧\",\"⠨\",\"⠩\",\"⠪\",\"⠫\",\"⠬\",\"⠭\",\"⠮\",\"⠯\",\"⡨\",\"⡩\",\"⡪\",\"⡫\",\"⡬\",\"⡭\",\"⡮\",\"⡯\",\"⠰\",\"⠱\",\"⠲\",\"⠳\",\"⠴\",\"⠵\",\"⠶\",\"⠷\",\"⡰\",\"⡱\",\"⡲\",\"⡳\",\"⡴\",\"⡵\",\"⡶\",\"⡷\",\"⠸\",\"⠹\",\"⠺\",\"⠻\",\"⠼\",\"⠽\",\"⠾\",\"⠿\",\"⡸\",\"⡹\",\"⡺\",\"⡻\",\"⡼\",\"⡽\",\"⡾\",\"⡿\",\"⢀\",\"⢁\",\"⢂\",\"⢃\",\"⢄\",\"⢅\",\"⢆\",\"⢇\",\"⣀\",\"⣁\",\"⣂\",\"⣃\",\"⣄\",\"⣅\",\"⣆\",\"⣇\",\"⢈\",\"⢉\",\"⢊\",\"⢋\",\"⢌\",\"⢍\",\"⢎\",\"⢏\",\"⣈\",\"⣉\",\"⣊\",\"⣋\",\"⣌\",\"⣍\",\"⣎\",\"⣏\",\"⢐\",\"⢑\",\"⢒\",\"⢓\",\"⢔\",\"⢕\",\"⢖\",\"⢗\",\"⣐\",\"⣑\",\"⣒\",\"⣓\",\"⣔\",\"⣕\",\"⣖\",\"⣗\",\"⢘\",\"⢙\",\"⢚\",\"⢛\",\"⢜\",\"⢝\",\"⢞\",\"⢟\",\"⣘\",\"⣙\",\"⣚\",\"⣛\",\"⣜\",\"⣝\",\"⣞\",\"⣟\",\"⢠\",\"⢡\",\"⢢\",\"⢣\",\"⢤\",\"⢥\",\"⢦\",\"⢧\",\"⣠\",\"⣡\",\"⣢\",\"⣣\",\"⣤\",\"⣥\",\"⣦\",\"⣧\",\"⢨\",\"⢩\",\"⢪\",\"⢫\",\"⢬\",\"⢭\",\"⢮\",\"⢯\",\"⣨\",\"⣩\",\"⣪\",\"⣫\",\"⣬\",\"⣭\",\"⣮\",\"⣯\",\"⢰\",\"⢱\",\"⢲\",\"⢳\",\"⢴\",\"⢵\",\"⢶\",\"⢷\",\"⣰\",\"⣱\",\"⣲\",\"⣳\",\"⣴\",\"⣵\",\"⣶\",\"⣷\",\"⢸\",\"⢹\",\"⢺\",\"⢻\",\"⢼\",\"⢽\",\"⢾\",\"⢿\",\"⣸\",\"⣹\",\"⣺\",\"⣻\",\"⣼\",\"⣽\",\"⣾\",\"⣿\"]},\"line\":{\"interval\":130,\"frames\":[\"-\",\"\\\\\",\"|\",\"/\"]},\"line2\":{\"interval\":100,\"frames\":[\"⠂\",\"-\",\"–\",\"—\",\"–\",\"-\"]},\"pipe\":{\"interval\":100,\"frames\":[\"┤\",\"┘\",\"┴\",\"└\",\"├\",\"┌\",\"┬\",\"┐\"]},\"simpleDots\":{\"interval\":400,\"frames\":[\". \",\".. \",\"...\",\" \"]},\"simpleDotsScrolling\":{\"interval\":200,\"frames\":[\". \",\".. \",\"...\",\" ..\",\" .\",\" \"]},\"star\":{\"interval\":70,\"frames\":[\"✶\",\"✸\",\"✹\",\"✺\",\"✹\",\"✷\"]},\"star2\":{\"interval\":80,\"frames\":[\"+\",\"x\",\"*\"]},\"flip\":{\"interval\":70,\"frames\":[\"_\",\"_\",\"_\",\"-\",\"`\",\"`\",\"'\",\"´\",\"-\",\"_\",\"_\",\"_\"]},\"hamburger\":{\"interval\":100,\"frames\":[\"☱\",\"☲\",\"☴\"]},\"growVertical\":{\"interval\":120,\"frames\":[\"▁\",\"▃\",\"▄\",\"▅\",\"▆\",\"▇\",\"▆\",\"▅\",\"▄\",\"▃\"]},\"growHorizontal\":{\"interval\":120,\"frames\":[\"▏\",\"▎\",\"▍\",\"▌\",\"▋\",\"▊\",\"▉\",\"▊\",\"▋\",\"▌\",\"▍\",\"▎\"]},\"balloon\":{\"interval\":140,\"frames\":[\" \",\".\",\"o\",\"O\",\"@\",\"*\",\" \"]},\"balloon2\":{\"interval\":120,\"frames\":[\".\",\"o\",\"O\",\"°\",\"O\",\"o\",\".\"]},\"noise\":{\"interval\":100,\"frames\":[\"▓\",\"▒\",\"░\"]},\"bounce\":{\"interval\":120,\"frames\":[\"⠁\",\"⠂\",\"⠄\",\"⠂\"]},\"boxBounce\":{\"interval\":120,\"frames\":[\"▖\",\"▘\",\"▝\",\"▗\"]},\"boxBounce2\":{\"interval\":100,\"frames\":[\"▌\",\"▀\",\"▐\",\"▄\"]},\"triangle\":{\"interval\":50,\"frames\":[\"◢\",\"◣\",\"◤\",\"◥\"]},\"arc\":{\"interval\":100,\"frames\":[\"◜\",\"◠\",\"◝\",\"◞\",\"◡\",\"◟\"]},\"circle\":{\"interval\":120,\"frames\":[\"◡\",\"⊙\",\"◠\"]},\"squareCorners\":{\"interval\":180,\"frames\":[\"◰\",\"◳\",\"◲\",\"◱\"]},\"circleQuarters\":{\"interval\":120,\"frames\":[\"◴\",\"◷\",\"◶\",\"◵\"]},\"circleHalves\":{\"interval\":50,\"frames\":[\"◐\",\"◓\",\"◑\",\"◒\"]},\"squish\":{\"interval\":100,\"frames\":[\"╫\",\"╪\"]},\"toggle\":{\"interval\":250,\"frames\":[\"⊶\",\"⊷\"]},\"toggle2\":{\"interval\":80,\"frames\":[\"▫\",\"▪\"]},\"toggle3\":{\"interval\":120,\"frames\":[\"□\",\"■\"]},\"toggle4\":{\"interval\":100,\"frames\":[\"■\",\"□\",\"▪\",\"▫\"]},\"toggle5\":{\"interval\":100,\"frames\":[\"▮\",\"▯\"]},\"toggle6\":{\"interval\":300,\"frames\":[\"ဝ\",\"၀\"]},\"toggle7\":{\"interval\":80,\"frames\":[\"⦾\",\"⦿\"]},\"toggle8\":{\"interval\":100,\"frames\":[\"◍\",\"◌\"]},\"toggle9\":{\"interval\":100,\"frames\":[\"◉\",\"◎\"]},\"toggle10\":{\"interval\":100,\"frames\":[\"㊂\",\"㊀\",\"㊁\"]},\"toggle11\":{\"interval\":50,\"frames\":[\"⧇\",\"⧆\"]},\"toggle12\":{\"interval\":120,\"frames\":[\"☗\",\"☖\"]},\"toggle13\":{\"interval\":80,\"frames\":[\"=\",\"*\",\"-\"]},\"arrow\":{\"interval\":100,\"frames\":[\"←\",\"↖\",\"↑\",\"↗\",\"→\",\"↘\",\"↓\",\"↙\"]},\"arrow2\":{\"interval\":80,\"frames\":[\"⬆️ \",\"↗️ \",\"➡️ \",\"↘️ \",\"⬇️ \",\"↙️ \",\"⬅️ \",\"↖️ \"]},\"arrow3\":{\"interval\":120,\"frames\":[\"▹▹▹▹▹\",\"▸▹▹▹▹\",\"▹▸▹▹▹\",\"▹▹▸▹▹\",\"▹▹▹▸▹\",\"▹▹▹▹▸\"]},\"bouncingBar\":{\"interval\":80,\"frames\":[\"[ ]\",\"[= ]\",\"[== ]\",\"[=== ]\",\"[ ===]\",\"[ ==]\",\"[ =]\",\"[ ]\",\"[ =]\",\"[ ==]\",\"[ ===]\",\"[====]\",\"[=== ]\",\"[== ]\",\"[= ]\"]},\"bouncingBall\":{\"interval\":80,\"frames\":[\"( ● )\",\"( ● )\",\"( ● )\",\"( ● )\",\"( ●)\",\"( ● )\",\"( ● )\",\"( ● )\",\"( ● )\",\"(● )\"]},\"smiley\":{\"interval\":200,\"frames\":[\"😄 \",\"😝 \"]},\"monkey\":{\"interval\":300,\"frames\":[\"🙈 \",\"🙈 \",\"🙉 \",\"🙊 \"]},\"hearts\":{\"interval\":100,\"frames\":[\"💛 \",\"💙 \",\"💜 \",\"💚 \",\"❤️ \"]},\"clock\":{\"interval\":100,\"frames\":[\"🕛 \",\"🕐 \",\"🕑 \",\"🕒 \",\"🕓 \",\"🕔 \",\"🕕 \",\"🕖 \",\"🕗 \",\"🕘 \",\"🕙 \",\"🕚 \"]},\"earth\":{\"interval\":180,\"frames\":[\"🌍 \",\"🌎 \",\"🌏 \"]},\"material\":{\"interval\":17,\"frames\":[\"█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁\",\"██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁\",\"███▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁\",\"████▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁\",\"██████▁▁▁▁▁▁▁▁▁▁▁▁▁▁\",\"██████▁▁▁▁▁▁▁▁▁▁▁▁▁▁\",\"███████▁▁▁▁▁▁▁▁▁▁▁▁▁\",\"████████▁▁▁▁▁▁▁▁▁▁▁▁\",\"█████████▁▁▁▁▁▁▁▁▁▁▁\",\"█████████▁▁▁▁▁▁▁▁▁▁▁\",\"██████████▁▁▁▁▁▁▁▁▁▁\",\"███████████▁▁▁▁▁▁▁▁▁\",\"█████████████▁▁▁▁▁▁▁\",\"██████████████▁▁▁▁▁▁\",\"██████████████▁▁▁▁▁▁\",\"▁██████████████▁▁▁▁▁\",\"▁██████████████▁▁▁▁▁\",\"▁██████████████▁▁▁▁▁\",\"▁▁██████████████▁▁▁▁\",\"▁▁▁██████████████▁▁▁\",\"▁▁▁▁█████████████▁▁▁\",\"▁▁▁▁██████████████▁▁\",\"▁▁▁▁██████████████▁▁\",\"▁▁▁▁▁██████████████▁\",\"▁▁▁▁▁██████████████▁\",\"▁▁▁▁▁██████████████▁\",\"▁▁▁▁▁▁██████████████\",\"▁▁▁▁▁▁██████████████\",\"▁▁▁▁▁▁▁█████████████\",\"▁▁▁▁▁▁▁█████████████\",\"▁▁▁▁▁▁▁▁████████████\",\"▁▁▁▁▁▁▁▁████████████\",\"▁▁▁▁▁▁▁▁▁███████████\",\"▁▁▁▁▁▁▁▁▁███████████\",\"▁▁▁▁▁▁▁▁▁▁██████████\",\"▁▁▁▁▁▁▁▁▁▁██████████\",\"▁▁▁▁▁▁▁▁▁▁▁▁████████\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁███████\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁██████\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█████\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█████\",\"█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████\",\"██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███\",\"██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███\",\"███▁▁▁▁▁▁▁▁▁▁▁▁▁▁███\",\"████▁▁▁▁▁▁▁▁▁▁▁▁▁▁██\",\"█████▁▁▁▁▁▁▁▁▁▁▁▁▁▁█\",\"█████▁▁▁▁▁▁▁▁▁▁▁▁▁▁█\",\"██████▁▁▁▁▁▁▁▁▁▁▁▁▁█\",\"████████▁▁▁▁▁▁▁▁▁▁▁▁\",\"█████████▁▁▁▁▁▁▁▁▁▁▁\",\"█████████▁▁▁▁▁▁▁▁▁▁▁\",\"█████████▁▁▁▁▁▁▁▁▁▁▁\",\"█████████▁▁▁▁▁▁▁▁▁▁▁\",\"███████████▁▁▁▁▁▁▁▁▁\",\"████████████▁▁▁▁▁▁▁▁\",\"████████████▁▁▁▁▁▁▁▁\",\"██████████████▁▁▁▁▁▁\",\"██████████████▁▁▁▁▁▁\",\"▁██████████████▁▁▁▁▁\",\"▁██████████████▁▁▁▁▁\",\"▁▁▁█████████████▁▁▁▁\",\"▁▁▁▁▁████████████▁▁▁\",\"▁▁▁▁▁████████████▁▁▁\",\"▁▁▁▁▁▁███████████▁▁▁\",\"▁▁▁▁▁▁▁▁█████████▁▁▁\",\"▁▁▁▁▁▁▁▁█████████▁▁▁\",\"▁▁▁▁▁▁▁▁▁█████████▁▁\",\"▁▁▁▁▁▁▁▁▁█████████▁▁\",\"▁▁▁▁▁▁▁▁▁▁█████████▁\",\"▁▁▁▁▁▁▁▁▁▁▁████████▁\",\"▁▁▁▁▁▁▁▁▁▁▁████████▁\",\"▁▁▁▁▁▁▁▁▁▁▁▁███████▁\",\"▁▁▁▁▁▁▁▁▁▁▁▁███████▁\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁███████\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁███████\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█████\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁██\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁██\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁██\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁\",\"▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁\"]},\"moon\":{\"interval\":80,\"frames\":[\"🌑 \",\"🌒 \",\"🌓 \",\"🌔 \",\"🌕 \",\"🌖 \",\"🌗 \",\"🌘 \"]},\"runner\":{\"interval\":140,\"frames\":[\"🚶 \",\"🏃 \"]},\"pong\":{\"interval\":80,\"frames\":[\"▐⠂ ▌\",\"▐⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂▌\",\"▐ ⠠▌\",\"▐ ⡀▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐⠠ ▌\"]},\"shark\":{\"interval\":120,\"frames\":[\"▐|\\\\____________▌\",\"▐_|\\\\___________▌\",\"▐__|\\\\__________▌\",\"▐___|\\\\_________▌\",\"▐____|\\\\________▌\",\"▐_____|\\\\_______▌\",\"▐______|\\\\______▌\",\"▐_______|\\\\_____▌\",\"▐________|\\\\____▌\",\"▐_________|\\\\___▌\",\"▐__________|\\\\__▌\",\"▐___________|\\\\_▌\",\"▐____________|\\\\▌\",\"▐____________/|▌\",\"▐___________/|_▌\",\"▐__________/|__▌\",\"▐_________/|___▌\",\"▐________/|____▌\",\"▐_______/|_____▌\",\"▐______/|______▌\",\"▐_____/|_______▌\",\"▐____/|________▌\",\"▐___/|_________▌\",\"▐__/|__________▌\",\"▐_/|___________▌\",\"▐/|____________▌\"]},\"dqpb\":{\"interval\":100,\"frames\":[\"d\",\"q\",\"p\",\"b\"]},\"weather\":{\"interval\":100,\"frames\":[\"☀️ \",\"☀️ \",\"☀️ \",\"🌤 \",\"⛅️ \",\"🌥 \",\"☁️ \",\"🌧 \",\"🌨 \",\"🌧 \",\"🌨 \",\"🌧 \",\"🌨 \",\"⛈ \",\"🌨 \",\"🌧 \",\"🌨 \",\"☁️ \",\"🌥 \",\"⛅️ \",\"🌤 \",\"☀️ \",\"☀️ \"]},\"christmas\":{\"interval\":400,\"frames\":[\"🌲\",\"🎄\"]},\"grenade\":{\"interval\":80,\"frames\":[\"، \",\"′ \",\" ´ \",\" ‾ \",\" ⸌\",\" ⸊\",\" |\",\" ⁎\",\" ⁕\",\" ෴ \",\" ⁓\",\" \",\" \",\" \"]},\"point\":{\"interval\":125,\"frames\":[\"∙∙∙\",\"●∙∙\",\"∙●∙\",\"∙∙●\",\"∙∙∙\"]},\"layer\":{\"interval\":150,\"frames\":[\"-\",\"=\",\"≡\"]},\"betaWave\":{\"interval\":80,\"frames\":[\"ρββββββ\",\"βρβββββ\",\"ββρββββ\",\"βββρβββ\",\"ββββρββ\",\"βββββρβ\",\"ββββββρ\"]}}"); + +/***/ }), +/* 382 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const chalk = __webpack_require__(383); + +const isSupported = process.platform !== 'win32' || process.env.CI || process.env.TERM === 'xterm-256color'; + +const main = { + info: chalk.blue('ℹ'), + success: chalk.green('✔'), + warning: chalk.yellow('⚠'), + error: chalk.red('✖') +}; + +const fallbacks = { + info: chalk.blue('i'), + success: chalk.green('√'), + warning: chalk.yellow('‼'), + error: chalk.red('×') }; +module.exports = isSupported ? main : fallbacks; + /***/ }), -/* 377 */ +/* 383 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const escapeStringRegexp = __webpack_require__(178); -const ansiStyles = __webpack_require__(378); -const stdoutColor = __webpack_require__(383).stdout; +const escapeStringRegexp = __webpack_require__(179); +const ansiStyles = __webpack_require__(384); +const stdoutColor = __webpack_require__(389).stdout; -const template = __webpack_require__(385); +const template = __webpack_require__(390); const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); @@ -48676,12 +49064,12 @@ module.exports.default = module.exports; // For TypeScript /***/ }), -/* 378 */ +/* 384 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* WEBPACK VAR INJECTION */(function(module) { -const colorConvert = __webpack_require__(379); +const colorConvert = __webpack_require__(385); const wrapAnsi16 = (fn, offset) => function () { const code = fn.apply(colorConvert, arguments); @@ -48846,14 +49234,14 @@ Object.defineProperty(module, 'exports', { get: assembleStyles }); -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(114)(module))) +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(115)(module))) /***/ }), -/* 379 */ +/* 385 */ /***/ (function(module, exports, __webpack_require__) { -var conversions = __webpack_require__(380); -var route = __webpack_require__(382); +var conversions = __webpack_require__(386); +var route = __webpack_require__(388); var convert = {}; @@ -48933,11 +49321,11 @@ module.exports = convert; /***/ }), -/* 380 */ +/* 386 */ /***/ (function(module, exports, __webpack_require__) { /* MIT license */ -var cssKeywords = __webpack_require__(381); +var cssKeywords = __webpack_require__(387); // NOTE: conversions should only return primitive values (i.e. arrays, or // values that give correct `typeof` results). @@ -49807,7 +50195,7 @@ convert.rgb.gray = function (rgb) { /***/ }), -/* 381 */ +/* 387 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -49966,10 +50354,10 @@ module.exports = { /***/ }), -/* 382 */ +/* 388 */ /***/ (function(module, exports, __webpack_require__) { -var conversions = __webpack_require__(380); +var conversions = __webpack_require__(386); /* this function routes a model to all other models. @@ -50069,13 +50457,13 @@ module.exports = function (fromModel) { /***/ }), -/* 383 */ +/* 389 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const os = __webpack_require__(120); -const hasFlag = __webpack_require__(384); +const os = __webpack_require__(121); +const hasFlag = __webpack_require__(186); const env = process.env; @@ -50207,22 +50595,7 @@ module.exports = { /***/ }), -/* 384 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -module.exports = (flag, argv) => { - argv = argv || process.argv; - const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); - const pos = argv.indexOf(prefix + flag); - const terminatorPos = argv.indexOf('--'); - return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos); -}; - - -/***/ }), -/* 385 */ +/* 390 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -50357,879 +50730,717 @@ module.exports = (chalk, tmp) => { /***/ }), -/* 386 */ +/* 391 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const restoreCursor = __webpack_require__(387); - -let hidden = false; +const ansiRegex = __webpack_require__(392); -exports.show = stream => { - const s = stream || process.stderr; - - if (!s.isTTY) { - return; - } +module.exports = string => typeof string === 'string' ? string.replace(ansiRegex(), '') : string; - hidden = false; - s.write('\u001b[?25h'); -}; -exports.hide = stream => { - const s = stream || process.stderr; +/***/ }), +/* 392 */ +/***/ (function(module, exports, __webpack_require__) { - if (!s.isTTY) { - return; - } +"use strict"; - restoreCursor(); - hidden = true; - s.write('\u001b[?25l'); -}; -exports.toggle = (force, stream) => { - if (force !== undefined) { - hidden = force; - } +module.exports = ({onlyFirst = false} = {}) => { + const pattern = [ + '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', + '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))' + ].join('|'); - if (hidden) { - exports.show(stream); - } else { - exports.hide(stream); - } + return new RegExp(pattern, onlyFirst ? undefined : 'g'); }; /***/ }), -/* 387 */ +/* 393 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const onetime = __webpack_require__(388); -const signalExit = __webpack_require__(217); -module.exports = onetime(() => { - signalExit(() => { - process.stderr.write('\u001b[?25h'); - }, {alwaysLast: true}); -}); +var defaults = __webpack_require__(394) +var combining = __webpack_require__(396) +var DEFAULTS = { + nul: 0, + control: 0 +} -/***/ }), -/* 388 */ -/***/ (function(module, exports, __webpack_require__) { +module.exports = function wcwidth(str) { + return wcswidth(str, DEFAULTS) +} -"use strict"; +module.exports.config = function(opts) { + opts = defaults(opts || {}, DEFAULTS) + return function wcwidth(str) { + return wcswidth(str, opts) + } +} -const mimicFn = __webpack_require__(389); +/* + * The following functions define the column width of an ISO 10646 + * character as follows: + * - The null character (U+0000) has a column width of 0. + * - Other C0/C1 control characters and DEL will lead to a return value + * of -1. + * - Non-spacing and enclosing combining characters (general category + * code Mn or Me in the + * Unicode database) have a column width of 0. + * - SOFT HYPHEN (U+00AD) has a column width of 1. + * - Other format characters (general category code Cf in the Unicode + * database) and ZERO WIDTH + * SPACE (U+200B) have a column width of 0. + * - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF) + * have a column width of 0. + * - Spacing characters in the East Asian Wide (W) or East Asian + * Full-width (F) category as + * defined in Unicode Technical Report #11 have a column width of 2. + * - All remaining characters (including all printable ISO 8859-1 and + * WGL4 characters, Unicode control characters, etc.) have a column + * width of 1. + * This implementation assumes that characters are encoded in ISO 10646. +*/ -module.exports = (fn, opts) => { - // TODO: Remove this in v3 - if (opts === true) { - throw new TypeError('The second argument is now an options object'); - } +function wcswidth(str, opts) { + if (typeof str !== 'string') return wcwidth(str, opts) - if (typeof fn !== 'function') { - throw new TypeError('Expected a function'); - } + var s = 0 + for (var i = 0; i < str.length; i++) { + var n = wcwidth(str.charCodeAt(i), opts) + if (n < 0) return -1 + s += n + } - opts = opts || {}; + return s +} - let ret; - let called = false; - const fnName = fn.displayName || fn.name || ''; +function wcwidth(ucs, opts) { + // test for 8-bit control characters + if (ucs === 0) return opts.nul + if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) return opts.control - const onetime = function () { - if (called) { - if (opts.throw === true) { - throw new Error(`Function \`${fnName}\` can only be called once`); - } + // binary search in table of non-spacing characters + if (bisearch(ucs)) return 0 - return ret; - } + // if we arrive here, ucs is not a combining or C0/C1 control character + return 1 + + (ucs >= 0x1100 && + (ucs <= 0x115f || // Hangul Jamo init. consonants + ucs == 0x2329 || ucs == 0x232a || + (ucs >= 0x2e80 && ucs <= 0xa4cf && + ucs != 0x303f) || // CJK ... Yi + (ucs >= 0xac00 && ucs <= 0xd7a3) || // Hangul Syllables + (ucs >= 0xf900 && ucs <= 0xfaff) || // CJK Compatibility Ideographs + (ucs >= 0xfe10 && ucs <= 0xfe19) || // Vertical forms + (ucs >= 0xfe30 && ucs <= 0xfe6f) || // CJK Compatibility Forms + (ucs >= 0xff00 && ucs <= 0xff60) || // Fullwidth Forms + (ucs >= 0xffe0 && ucs <= 0xffe6) || + (ucs >= 0x20000 && ucs <= 0x2fffd) || + (ucs >= 0x30000 && ucs <= 0x3fffd))); +} - called = true; - ret = fn.apply(this, arguments); - fn = null; +function bisearch(ucs) { + var min = 0 + var max = combining.length - 1 + var mid - return ret; - }; + if (ucs < combining[0][0] || ucs > combining[max][1]) return false - mimicFn(onetime, fn); + while (max >= min) { + mid = Math.floor((min + max) / 2) + if (ucs > combining[mid][1]) min = mid + 1 + else if (ucs < combining[mid][0]) max = mid - 1 + else return true + } - return onetime; -}; + return false +} /***/ }), -/* 389 */ +/* 394 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +var clone = __webpack_require__(395); -module.exports = (to, from) => { - // TODO: use `Reflect.ownKeys()` when targeting Node.js 6 - for (const prop of Object.getOwnPropertyNames(from).concat(Object.getOwnPropertySymbols(from))) { - Object.defineProperty(to, prop, Object.getOwnPropertyDescriptor(from, prop)); - } +module.exports = function(options, defaults) { + options = options || {}; - return to; -}; + Object.keys(defaults).forEach(function(key) { + if (typeof options[key] === 'undefined') { + options[key] = clone(defaults[key]); + } + }); + return options; +}; /***/ }), -/* 390 */ +/* 395 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +var clone = (function() { +'use strict'; -module.exports = __webpack_require__(391); +/** + * Clones (copies) an Object using deep copying. + * + * This function supports circular references by default, but if you are certain + * there are no circular references in your object, you can save some CPU time + * by calling clone(obj, false). + * + * Caution: if `circular` is false and `parent` contains circular references, + * your program may enter an infinite loop and crash. + * + * @param `parent` - the object to be cloned + * @param `circular` - set to true if the object to be cloned may contain + * circular references. (optional - true by default) + * @param `depth` - set to a number if the object is only to be cloned to + * a particular depth. (optional - defaults to Infinity) + * @param `prototype` - sets the prototype to be used when cloning an object. + * (optional - defaults to parent prototype). +*/ +function clone(parent, circular, depth, prototype) { + var filter; + if (typeof circular === 'object') { + depth = circular.depth; + prototype = circular.prototype; + filter = circular.filter; + circular = circular.circular + } + // maintain two arrays for circular references, where corresponding parents + // and children have the same index + var allParents = []; + var allChildren = []; + + var useBuffer = typeof Buffer != 'undefined'; + + if (typeof circular == 'undefined') + circular = true; + + if (typeof depth == 'undefined') + depth = Infinity; + + // recurse this function so we don't reset allParents and allChildren + function _clone(parent, depth) { + // cloning null always returns null + if (parent === null) + return null; + if (depth == 0) + return parent; + + var child; + var proto; + if (typeof parent != 'object') { + return parent; + } + + if (clone.__isArray(parent)) { + child = []; + } else if (clone.__isRegExp(parent)) { + child = new RegExp(parent.source, __getRegExpFlags(parent)); + if (parent.lastIndex) child.lastIndex = parent.lastIndex; + } else if (clone.__isDate(parent)) { + child = new Date(parent.getTime()); + } else if (useBuffer && Buffer.isBuffer(parent)) { + if (Buffer.allocUnsafe) { + // Node.js >= 4.5.0 + child = Buffer.allocUnsafe(parent.length); + } else { + // Older Node.js versions + child = new Buffer(parent.length); + } + parent.copy(child); + return child; + } else { + if (typeof prototype == 'undefined') { + proto = Object.getPrototypeOf(parent); + child = Object.create(proto); + } + else { + child = Object.create(prototype); + proto = prototype; + } + } -/***/ }), -/* 391 */ -/***/ (function(module) { + if (circular) { + var index = allParents.indexOf(parent); -module.exports = JSON.parse("{\"dots\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠹\",\"⠸\",\"⠼\",\"⠴\",\"⠦\",\"⠧\",\"⠇\",\"⠏\"]},\"dots2\":{\"interval\":80,\"frames\":[\"⣾\",\"⣽\",\"⣻\",\"⢿\",\"⡿\",\"⣟\",\"⣯\",\"⣷\"]},\"dots3\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠚\",\"⠞\",\"⠖\",\"⠦\",\"⠴\",\"⠲\",\"⠳\",\"⠓\"]},\"dots4\":{\"interval\":80,\"frames\":[\"⠄\",\"⠆\",\"⠇\",\"⠋\",\"⠙\",\"⠸\",\"⠰\",\"⠠\",\"⠰\",\"⠸\",\"⠙\",\"⠋\",\"⠇\",\"⠆\"]},\"dots5\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\"]},\"dots6\":{\"interval\":80,\"frames\":[\"⠁\",\"⠉\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠤\",\"⠄\",\"⠄\",\"⠤\",\"⠴\",\"⠲\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠚\",\"⠙\",\"⠉\",\"⠁\"]},\"dots7\":{\"interval\":80,\"frames\":[\"⠈\",\"⠉\",\"⠋\",\"⠓\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠖\",\"⠦\",\"⠤\",\"⠠\",\"⠠\",\"⠤\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\",\"⠉\",\"⠈\"]},\"dots8\":{\"interval\":80,\"frames\":[\"⠁\",\"⠁\",\"⠉\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠤\",\"⠄\",\"⠄\",\"⠤\",\"⠠\",\"⠠\",\"⠤\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\",\"⠉\",\"⠈\",\"⠈\"]},\"dots9\":{\"interval\":80,\"frames\":[\"⢹\",\"⢺\",\"⢼\",\"⣸\",\"⣇\",\"⡧\",\"⡗\",\"⡏\"]},\"dots10\":{\"interval\":80,\"frames\":[\"⢄\",\"⢂\",\"⢁\",\"⡁\",\"⡈\",\"⡐\",\"⡠\"]},\"dots11\":{\"interval\":100,\"frames\":[\"⠁\",\"⠂\",\"⠄\",\"⡀\",\"⢀\",\"⠠\",\"⠐\",\"⠈\"]},\"dots12\":{\"interval\":80,\"frames\":[\"⢀⠀\",\"⡀⠀\",\"⠄⠀\",\"⢂⠀\",\"⡂⠀\",\"⠅⠀\",\"⢃⠀\",\"⡃⠀\",\"⠍⠀\",\"⢋⠀\",\"⡋⠀\",\"⠍⠁\",\"⢋⠁\",\"⡋⠁\",\"⠍⠉\",\"⠋⠉\",\"⠋⠉\",\"⠉⠙\",\"⠉⠙\",\"⠉⠩\",\"⠈⢙\",\"⠈⡙\",\"⢈⠩\",\"⡀⢙\",\"⠄⡙\",\"⢂⠩\",\"⡂⢘\",\"⠅⡘\",\"⢃⠨\",\"⡃⢐\",\"⠍⡐\",\"⢋⠠\",\"⡋⢀\",\"⠍⡁\",\"⢋⠁\",\"⡋⠁\",\"⠍⠉\",\"⠋⠉\",\"⠋⠉\",\"⠉⠙\",\"⠉⠙\",\"⠉⠩\",\"⠈⢙\",\"⠈⡙\",\"⠈⠩\",\"⠀⢙\",\"⠀⡙\",\"⠀⠩\",\"⠀⢘\",\"⠀⡘\",\"⠀⠨\",\"⠀⢐\",\"⠀⡐\",\"⠀⠠\",\"⠀⢀\",\"⠀⡀\"]},\"line\":{\"interval\":130,\"frames\":[\"-\",\"\\\\\",\"|\",\"/\"]},\"line2\":{\"interval\":100,\"frames\":[\"⠂\",\"-\",\"–\",\"—\",\"–\",\"-\"]},\"pipe\":{\"interval\":100,\"frames\":[\"┤\",\"┘\",\"┴\",\"└\",\"├\",\"┌\",\"┬\",\"┐\"]},\"simpleDots\":{\"interval\":400,\"frames\":[\". \",\".. \",\"...\",\" \"]},\"simpleDotsScrolling\":{\"interval\":200,\"frames\":[\". \",\".. \",\"...\",\" ..\",\" .\",\" \"]},\"star\":{\"interval\":70,\"frames\":[\"✶\",\"✸\",\"✹\",\"✺\",\"✹\",\"✷\"]},\"star2\":{\"interval\":80,\"frames\":[\"+\",\"x\",\"*\"]},\"flip\":{\"interval\":70,\"frames\":[\"_\",\"_\",\"_\",\"-\",\"`\",\"`\",\"'\",\"´\",\"-\",\"_\",\"_\",\"_\"]},\"hamburger\":{\"interval\":100,\"frames\":[\"☱\",\"☲\",\"☴\"]},\"growVertical\":{\"interval\":120,\"frames\":[\"▁\",\"▃\",\"▄\",\"▅\",\"▆\",\"▇\",\"▆\",\"▅\",\"▄\",\"▃\"]},\"growHorizontal\":{\"interval\":120,\"frames\":[\"▏\",\"▎\",\"▍\",\"▌\",\"▋\",\"▊\",\"▉\",\"▊\",\"▋\",\"▌\",\"▍\",\"▎\"]},\"balloon\":{\"interval\":140,\"frames\":[\" \",\".\",\"o\",\"O\",\"@\",\"*\",\" \"]},\"balloon2\":{\"interval\":120,\"frames\":[\".\",\"o\",\"O\",\"°\",\"O\",\"o\",\".\"]},\"noise\":{\"interval\":100,\"frames\":[\"▓\",\"▒\",\"░\"]},\"bounce\":{\"interval\":120,\"frames\":[\"⠁\",\"⠂\",\"⠄\",\"⠂\"]},\"boxBounce\":{\"interval\":120,\"frames\":[\"▖\",\"▘\",\"▝\",\"▗\"]},\"boxBounce2\":{\"interval\":100,\"frames\":[\"▌\",\"▀\",\"▐\",\"▄\"]},\"triangle\":{\"interval\":50,\"frames\":[\"◢\",\"◣\",\"◤\",\"◥\"]},\"arc\":{\"interval\":100,\"frames\":[\"◜\",\"◠\",\"◝\",\"◞\",\"◡\",\"◟\"]},\"circle\":{\"interval\":120,\"frames\":[\"◡\",\"⊙\",\"◠\"]},\"squareCorners\":{\"interval\":180,\"frames\":[\"◰\",\"◳\",\"◲\",\"◱\"]},\"circleQuarters\":{\"interval\":120,\"frames\":[\"◴\",\"◷\",\"◶\",\"◵\"]},\"circleHalves\":{\"interval\":50,\"frames\":[\"◐\",\"◓\",\"◑\",\"◒\"]},\"squish\":{\"interval\":100,\"frames\":[\"╫\",\"╪\"]},\"toggle\":{\"interval\":250,\"frames\":[\"⊶\",\"⊷\"]},\"toggle2\":{\"interval\":80,\"frames\":[\"▫\",\"▪\"]},\"toggle3\":{\"interval\":120,\"frames\":[\"□\",\"■\"]},\"toggle4\":{\"interval\":100,\"frames\":[\"■\",\"□\",\"▪\",\"▫\"]},\"toggle5\":{\"interval\":100,\"frames\":[\"▮\",\"▯\"]},\"toggle6\":{\"interval\":300,\"frames\":[\"ဝ\",\"၀\"]},\"toggle7\":{\"interval\":80,\"frames\":[\"⦾\",\"⦿\"]},\"toggle8\":{\"interval\":100,\"frames\":[\"◍\",\"◌\"]},\"toggle9\":{\"interval\":100,\"frames\":[\"◉\",\"◎\"]},\"toggle10\":{\"interval\":100,\"frames\":[\"㊂\",\"㊀\",\"㊁\"]},\"toggle11\":{\"interval\":50,\"frames\":[\"⧇\",\"⧆\"]},\"toggle12\":{\"interval\":120,\"frames\":[\"☗\",\"☖\"]},\"toggle13\":{\"interval\":80,\"frames\":[\"=\",\"*\",\"-\"]},\"arrow\":{\"interval\":100,\"frames\":[\"←\",\"↖\",\"↑\",\"↗\",\"→\",\"↘\",\"↓\",\"↙\"]},\"arrow2\":{\"interval\":80,\"frames\":[\"⬆️ \",\"↗️ \",\"➡️ \",\"↘️ \",\"⬇️ \",\"↙️ \",\"⬅️ \",\"↖️ \"]},\"arrow3\":{\"interval\":120,\"frames\":[\"▹▹▹▹▹\",\"▸▹▹▹▹\",\"▹▸▹▹▹\",\"▹▹▸▹▹\",\"▹▹▹▸▹\",\"▹▹▹▹▸\"]},\"bouncingBar\":{\"interval\":80,\"frames\":[\"[ ]\",\"[= ]\",\"[== ]\",\"[=== ]\",\"[ ===]\",\"[ ==]\",\"[ =]\",\"[ ]\",\"[ =]\",\"[ ==]\",\"[ ===]\",\"[====]\",\"[=== ]\",\"[== ]\",\"[= ]\"]},\"bouncingBall\":{\"interval\":80,\"frames\":[\"( ● )\",\"( ● )\",\"( ● )\",\"( ● )\",\"( ●)\",\"( ● )\",\"( ● )\",\"( ● )\",\"( ● )\",\"(● )\"]},\"smiley\":{\"interval\":200,\"frames\":[\"😄 \",\"😝 \"]},\"monkey\":{\"interval\":300,\"frames\":[\"🙈 \",\"🙈 \",\"🙉 \",\"🙊 \"]},\"hearts\":{\"interval\":100,\"frames\":[\"💛 \",\"💙 \",\"💜 \",\"💚 \",\"❤️ \"]},\"clock\":{\"interval\":100,\"frames\":[\"🕐 \",\"🕑 \",\"🕒 \",\"🕓 \",\"🕔 \",\"🕕 \",\"🕖 \",\"🕗 \",\"🕘 \",\"🕙 \",\"🕚 \"]},\"earth\":{\"interval\":180,\"frames\":[\"🌍 \",\"🌎 \",\"🌏 \"]},\"moon\":{\"interval\":80,\"frames\":[\"🌑 \",\"🌒 \",\"🌓 \",\"🌔 \",\"🌕 \",\"🌖 \",\"🌗 \",\"🌘 \"]},\"runner\":{\"interval\":140,\"frames\":[\"🚶 \",\"🏃 \"]},\"pong\":{\"interval\":80,\"frames\":[\"▐⠂ ▌\",\"▐⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂▌\",\"▐ ⠠▌\",\"▐ ⡀▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐⠠ ▌\"]},\"shark\":{\"interval\":120,\"frames\":[\"▐|\\\\____________▌\",\"▐_|\\\\___________▌\",\"▐__|\\\\__________▌\",\"▐___|\\\\_________▌\",\"▐____|\\\\________▌\",\"▐_____|\\\\_______▌\",\"▐______|\\\\______▌\",\"▐_______|\\\\_____▌\",\"▐________|\\\\____▌\",\"▐_________|\\\\___▌\",\"▐__________|\\\\__▌\",\"▐___________|\\\\_▌\",\"▐____________|\\\\▌\",\"▐____________/|▌\",\"▐___________/|_▌\",\"▐__________/|__▌\",\"▐_________/|___▌\",\"▐________/|____▌\",\"▐_______/|_____▌\",\"▐______/|______▌\",\"▐_____/|_______▌\",\"▐____/|________▌\",\"▐___/|_________▌\",\"▐__/|__________▌\",\"▐_/|___________▌\",\"▐/|____________▌\"]},\"dqpb\":{\"interval\":100,\"frames\":[\"d\",\"q\",\"p\",\"b\"]},\"weather\":{\"interval\":100,\"frames\":[\"☀️ \",\"☀️ \",\"☀️ \",\"🌤 \",\"⛅️ \",\"🌥 \",\"☁️ \",\"🌧 \",\"🌨 \",\"🌧 \",\"🌨 \",\"🌧 \",\"🌨 \",\"⛈ \",\"🌨 \",\"🌧 \",\"🌨 \",\"☁️ \",\"🌥 \",\"⛅️ \",\"🌤 \",\"☀️ \",\"☀️ \"]},\"christmas\":{\"interval\":400,\"frames\":[\"🌲\",\"🎄\"]}}"); + if (index != -1) { + return allChildren[index]; + } + allParents.push(parent); + allChildren.push(child); + } -/***/ }), -/* 392 */ -/***/ (function(module, exports, __webpack_require__) { + for (var i in parent) { + var attrs; + if (proto) { + attrs = Object.getOwnPropertyDescriptor(proto, i); + } -"use strict"; + if (attrs && attrs.set == null) { + continue; + } + child[i] = _clone(parent[i], depth - 1); + } -const chalk = __webpack_require__(393); + return child; + } -const isSupported = process.platform !== 'win32' || process.env.CI || process.env.TERM === 'xterm-256color'; + return _clone(parent, depth); +} -const main = { - info: chalk.blue('ℹ'), - success: chalk.green('✔'), - warning: chalk.yellow('⚠'), - error: chalk.red('✖') +/** + * Simple flat clone using prototype, accepts only objects, usefull for property + * override on FLAT configuration object (no nested props). + * + * USE WITH CAUTION! This may not behave as you wish if you do not know how this + * works. + */ +clone.clonePrototype = function clonePrototype(parent) { + if (parent === null) + return null; + + var c = function () {}; + c.prototype = parent; + return new c(); }; -const fallbacks = { - info: chalk.blue('i'), - success: chalk.green('√'), - warning: chalk.yellow('‼'), - error: chalk.red('×') +// private utility functions + +function __objToStr(o) { + return Object.prototype.toString.call(o); }; +clone.__objToStr = __objToStr; -module.exports = isSupported ? main : fallbacks; +function __isDate(o) { + return typeof o === 'object' && __objToStr(o) === '[object Date]'; +}; +clone.__isDate = __isDate; + +function __isArray(o) { + return typeof o === 'object' && __objToStr(o) === '[object Array]'; +}; +clone.__isArray = __isArray; + +function __isRegExp(o) { + return typeof o === 'object' && __objToStr(o) === '[object RegExp]'; +}; +clone.__isRegExp = __isRegExp; + +function __getRegExpFlags(re) { + var flags = ''; + if (re.global) flags += 'g'; + if (re.ignoreCase) flags += 'i'; + if (re.multiline) flags += 'm'; + return flags; +}; +clone.__getRegExpFlags = __getRegExpFlags; + +return clone; +})(); + +if ( true && module.exports) { + module.exports = clone; +} /***/ }), -/* 393 */ +/* 396 */ +/***/ (function(module, exports) { + +module.exports = [ + [ 0x0300, 0x036F ], [ 0x0483, 0x0486 ], [ 0x0488, 0x0489 ], + [ 0x0591, 0x05BD ], [ 0x05BF, 0x05BF ], [ 0x05C1, 0x05C2 ], + [ 0x05C4, 0x05C5 ], [ 0x05C7, 0x05C7 ], [ 0x0600, 0x0603 ], + [ 0x0610, 0x0615 ], [ 0x064B, 0x065E ], [ 0x0670, 0x0670 ], + [ 0x06D6, 0x06E4 ], [ 0x06E7, 0x06E8 ], [ 0x06EA, 0x06ED ], + [ 0x070F, 0x070F ], [ 0x0711, 0x0711 ], [ 0x0730, 0x074A ], + [ 0x07A6, 0x07B0 ], [ 0x07EB, 0x07F3 ], [ 0x0901, 0x0902 ], + [ 0x093C, 0x093C ], [ 0x0941, 0x0948 ], [ 0x094D, 0x094D ], + [ 0x0951, 0x0954 ], [ 0x0962, 0x0963 ], [ 0x0981, 0x0981 ], + [ 0x09BC, 0x09BC ], [ 0x09C1, 0x09C4 ], [ 0x09CD, 0x09CD ], + [ 0x09E2, 0x09E3 ], [ 0x0A01, 0x0A02 ], [ 0x0A3C, 0x0A3C ], + [ 0x0A41, 0x0A42 ], [ 0x0A47, 0x0A48 ], [ 0x0A4B, 0x0A4D ], + [ 0x0A70, 0x0A71 ], [ 0x0A81, 0x0A82 ], [ 0x0ABC, 0x0ABC ], + [ 0x0AC1, 0x0AC5 ], [ 0x0AC7, 0x0AC8 ], [ 0x0ACD, 0x0ACD ], + [ 0x0AE2, 0x0AE3 ], [ 0x0B01, 0x0B01 ], [ 0x0B3C, 0x0B3C ], + [ 0x0B3F, 0x0B3F ], [ 0x0B41, 0x0B43 ], [ 0x0B4D, 0x0B4D ], + [ 0x0B56, 0x0B56 ], [ 0x0B82, 0x0B82 ], [ 0x0BC0, 0x0BC0 ], + [ 0x0BCD, 0x0BCD ], [ 0x0C3E, 0x0C40 ], [ 0x0C46, 0x0C48 ], + [ 0x0C4A, 0x0C4D ], [ 0x0C55, 0x0C56 ], [ 0x0CBC, 0x0CBC ], + [ 0x0CBF, 0x0CBF ], [ 0x0CC6, 0x0CC6 ], [ 0x0CCC, 0x0CCD ], + [ 0x0CE2, 0x0CE3 ], [ 0x0D41, 0x0D43 ], [ 0x0D4D, 0x0D4D ], + [ 0x0DCA, 0x0DCA ], [ 0x0DD2, 0x0DD4 ], [ 0x0DD6, 0x0DD6 ], + [ 0x0E31, 0x0E31 ], [ 0x0E34, 0x0E3A ], [ 0x0E47, 0x0E4E ], + [ 0x0EB1, 0x0EB1 ], [ 0x0EB4, 0x0EB9 ], [ 0x0EBB, 0x0EBC ], + [ 0x0EC8, 0x0ECD ], [ 0x0F18, 0x0F19 ], [ 0x0F35, 0x0F35 ], + [ 0x0F37, 0x0F37 ], [ 0x0F39, 0x0F39 ], [ 0x0F71, 0x0F7E ], + [ 0x0F80, 0x0F84 ], [ 0x0F86, 0x0F87 ], [ 0x0F90, 0x0F97 ], + [ 0x0F99, 0x0FBC ], [ 0x0FC6, 0x0FC6 ], [ 0x102D, 0x1030 ], + [ 0x1032, 0x1032 ], [ 0x1036, 0x1037 ], [ 0x1039, 0x1039 ], + [ 0x1058, 0x1059 ], [ 0x1160, 0x11FF ], [ 0x135F, 0x135F ], + [ 0x1712, 0x1714 ], [ 0x1732, 0x1734 ], [ 0x1752, 0x1753 ], + [ 0x1772, 0x1773 ], [ 0x17B4, 0x17B5 ], [ 0x17B7, 0x17BD ], + [ 0x17C6, 0x17C6 ], [ 0x17C9, 0x17D3 ], [ 0x17DD, 0x17DD ], + [ 0x180B, 0x180D ], [ 0x18A9, 0x18A9 ], [ 0x1920, 0x1922 ], + [ 0x1927, 0x1928 ], [ 0x1932, 0x1932 ], [ 0x1939, 0x193B ], + [ 0x1A17, 0x1A18 ], [ 0x1B00, 0x1B03 ], [ 0x1B34, 0x1B34 ], + [ 0x1B36, 0x1B3A ], [ 0x1B3C, 0x1B3C ], [ 0x1B42, 0x1B42 ], + [ 0x1B6B, 0x1B73 ], [ 0x1DC0, 0x1DCA ], [ 0x1DFE, 0x1DFF ], + [ 0x200B, 0x200F ], [ 0x202A, 0x202E ], [ 0x2060, 0x2063 ], + [ 0x206A, 0x206F ], [ 0x20D0, 0x20EF ], [ 0x302A, 0x302F ], + [ 0x3099, 0x309A ], [ 0xA806, 0xA806 ], [ 0xA80B, 0xA80B ], + [ 0xA825, 0xA826 ], [ 0xFB1E, 0xFB1E ], [ 0xFE00, 0xFE0F ], + [ 0xFE20, 0xFE23 ], [ 0xFEFF, 0xFEFF ], [ 0xFFF9, 0xFFFB ], + [ 0x10A01, 0x10A03 ], [ 0x10A05, 0x10A06 ], [ 0x10A0C, 0x10A0F ], + [ 0x10A38, 0x10A3A ], [ 0x10A3F, 0x10A3F ], [ 0x1D167, 0x1D169 ], + [ 0x1D173, 0x1D182 ], [ 0x1D185, 0x1D18B ], [ 0x1D1AA, 0x1D1AD ], + [ 0x1D242, 0x1D244 ], [ 0xE0001, 0xE0001 ], [ 0xE0020, 0xE007F ], + [ 0xE0100, 0xE01EF ] +] + + +/***/ }), +/* 397 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const escapeStringRegexp = __webpack_require__(178); -const ansiStyles = __webpack_require__(394); -const stdoutColor = __webpack_require__(184).stdout; -const template = __webpack_require__(395); +module.exports = ({stream = process.stdout} = {}) => { + return Boolean( + stream && stream.isTTY && + process.env.TERM !== 'dumb' && + !('CI' in process.env) + ); +}; -const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); -// `supportsColor.level` → `ansiStyles.color[name]` mapping -const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m']; +/***/ }), +/* 398 */ +/***/ (function(module, exports, __webpack_require__) { -// `color-convert` models to exclude from the Chalk API due to conflicts and such -const skipModels = new Set(['gray']); +var Stream = __webpack_require__(138) -const styles = Object.create(null); +module.exports = MuteStream -function applyOptions(obj, options) { - options = options || {}; +// var out = new MuteStream(process.stdout) +// argument auto-pipes +function MuteStream (opts) { + Stream.apply(this) + opts = opts || {} + this.writable = this.readable = true + this.muted = false + this.on('pipe', this._onpipe) + this.replace = opts.replace - // Detect level if not set manually - const scLevel = stdoutColor ? stdoutColor.level : 0; - obj.level = options.level === undefined ? scLevel : options.level; - obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0; + // For readline-type situations + // This much at the start of a line being redrawn after a ctrl char + // is seen (such as backspace) won't be redrawn as the replacement + this._prompt = opts.prompt || null + this._hadControl = false } -function Chalk(options) { - // We check for this.template here since calling `chalk.constructor()` - // by itself will have a `this` of a previously constructed chalk object - if (!this || !(this instanceof Chalk) || this.template) { - const chalk = {}; - applyOptions(chalk, options); +MuteStream.prototype = Object.create(Stream.prototype) - chalk.template = function () { - const args = [].slice.call(arguments); - return chalkTag.apply(null, [chalk.template].concat(args)); - }; +Object.defineProperty(MuteStream.prototype, 'constructor', { + value: MuteStream, + enumerable: false +}) - Object.setPrototypeOf(chalk, Chalk.prototype); - Object.setPrototypeOf(chalk.template, chalk); +MuteStream.prototype.mute = function () { + this.muted = true +} - chalk.template.constructor = Chalk; +MuteStream.prototype.unmute = function () { + this.muted = false +} - return chalk.template; - } +Object.defineProperty(MuteStream.prototype, '_onpipe', { + value: onPipe, + enumerable: false, + writable: true, + configurable: true +}) - applyOptions(this, options); +function onPipe (src) { + this._src = src } -// Use bright blue on Windows as the normal blue color is illegible -if (isSimpleWindowsTerm) { - ansiStyles.blue.open = '\u001B[94m'; -} +Object.defineProperty(MuteStream.prototype, 'isTTY', { + get: getIsTTY, + set: setIsTTY, + enumerable: true, + configurable: true +}) -for (const key of Object.keys(ansiStyles)) { - ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); +function getIsTTY () { + return( (this._dest) ? this._dest.isTTY + : (this._src) ? this._src.isTTY + : false + ) +} - styles[key] = { - get() { - const codes = ansiStyles[key]; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key); - } - }; +// basically just get replace the getter/setter with a regular value +function setIsTTY (isTTY) { + Object.defineProperty(this, 'isTTY', { + value: isTTY, + enumerable: true, + writable: true, + configurable: true + }) } -styles.visible = { - get() { - return build.call(this, this._styles || [], true, 'visible'); - } -}; +Object.defineProperty(MuteStream.prototype, 'rows', { + get: function () { + return( this._dest ? this._dest.rows + : this._src ? this._src.rows + : undefined ) + }, enumerable: true, configurable: true }) -ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g'); -for (const model of Object.keys(ansiStyles.color.ansi)) { - if (skipModels.has(model)) { - continue; - } +Object.defineProperty(MuteStream.prototype, 'columns', { + get: function () { + return( this._dest ? this._dest.columns + : this._src ? this._src.columns + : undefined ) + }, enumerable: true, configurable: true }) - styles[model] = { - get() { - const level = this.level; - return function () { - const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments); - const codes = { - open, - close: ansiStyles.color.close, - closeRe: ansiStyles.color.closeRe - }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); - }; - } - }; + +MuteStream.prototype.pipe = function (dest, options) { + this._dest = dest + return Stream.prototype.pipe.call(this, dest, options) } -ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g'); -for (const model of Object.keys(ansiStyles.bgColor.ansi)) { - if (skipModels.has(model)) { - continue; - } +MuteStream.prototype.pause = function () { + if (this._src) return this._src.pause() +} - const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); - styles[bgModel] = { - get() { - const level = this.level; - return function () { - const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments); - const codes = { - open, - close: ansiStyles.bgColor.close, - closeRe: ansiStyles.bgColor.closeRe - }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); - }; - } - }; +MuteStream.prototype.resume = function () { + if (this._src) return this._src.resume() } -const proto = Object.defineProperties(() => {}, styles); +MuteStream.prototype.write = function (c) { + if (this.muted) { + if (!this.replace) return true + if (c.match(/^\u001b/)) { + if(c.indexOf(this._prompt) === 0) { + c = c.substr(this._prompt.length); + c = c.replace(/./g, this.replace); + c = this._prompt + c; + } + this._hadControl = true + return this.emit('data', c) + } else { + if (this._prompt && this._hadControl && + c.indexOf(this._prompt) === 0) { + this._hadControl = false + this.emit('data', this._prompt) + c = c.substr(this._prompt.length) + } + c = c.toString().replace(/./g, this.replace) + } + } + this.emit('data', c) +} -function build(_styles, _empty, key) { - const builder = function () { - return applyStyle.apply(builder, arguments); - }; +MuteStream.prototype.end = function (c) { + if (this.muted) { + if (c && this.replace) { + c = c.toString().replace(/./g, this.replace) + } else { + c = null + } + } + if (c) this.emit('data', c) + this.emit('end') +} - builder._styles = _styles; - builder._empty = _empty; +function proxy (fn) { return function () { + var d = this._dest + var s = this._src + if (d && d[fn]) d[fn].apply(d, arguments) + if (s && s[fn]) s[fn].apply(s, arguments) +}} - const self = this; +MuteStream.prototype.destroy = proxy('destroy') +MuteStream.prototype.destroySoon = proxy('destroySoon') +MuteStream.prototype.close = proxy('close') - Object.defineProperty(builder, 'level', { - enumerable: true, - get() { - return self.level; - }, - set(level) { - self.level = level; - } - }); - Object.defineProperty(builder, 'enabled', { - enumerable: true, - get() { - return self.enabled; - }, - set(enabled) { - self.enabled = enabled; - } - }); +/***/ }), +/* 399 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - // See below for fix regarding invisible grey/dim combination on Windows - builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey'; +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RunCommand", function() { return RunCommand; }); +/* harmony import */ var _utils_errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(163); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(144); +/* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(145); +/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(146); +/* + * 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. + */ - // `__proto__` is used because we must return a function, but there is - // no way to create a function with a different prototype - builder.__proto__ = proto; // eslint-disable-line no-proto - return builder; -} -function applyStyle() { - // Support varags, but simply cast to string in case there's only one arg - const args = arguments; - const argsLen = args.length; - let str = String(arguments[0]); - if (argsLen === 0) { - return ''; - } +const RunCommand = { + description: 'Run script defined in package.json in each package that contains that script.', + name: 'run', - if (argsLen > 1) { - // Don't slice `arguments`, it prevents V8 optimizations - for (let a = 1; a < argsLen; a++) { - str += ' ' + args[a]; - } - } + async run(projects, projectGraph, { + extraArgs + }) { + const batchedProjects = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_3__["topologicallyBatchProjects"])(projects, projectGraph); - if (!this.enabled || this.level <= 0 || !str) { - return this._empty ? '' : str; - } + if (extraArgs.length === 0) { + throw new _utils_errors__WEBPACK_IMPORTED_MODULE_0__["CliError"]('No script specified'); + } - // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, - // see https://github.com/chalk/chalk/issues/58 - // If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop. - const originalDim = ansiStyles.dim.open; - if (isSimpleWindowsTerm && this.hasGrey) { - ansiStyles.dim.open = ''; - } + const scriptName = extraArgs[0]; + const scriptArgs = extraArgs.slice(1); + await Object(_utils_parallelize__WEBPACK_IMPORTED_MODULE_2__["parallelizeBatches"])(batchedProjects, async project => { + if (project.hasScript(scriptName)) { + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].info(`[${project.name}] running "${scriptName}" script`); + await project.runScriptStreaming(scriptName, { + args: scriptArgs + }); + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].success(`[${project.name}] complete`); + } + }); + } - for (const code of this._styles.slice().reverse()) { - // Replace any instances already present with a re-opening code - // otherwise only the part of the string until said closing code - // will be colored, and the rest will simply be 'plain'. - str = code.open + str.replace(code.closeRe, code.open) + code.close; +}; - // Close the styling before a linebreak and reopen - // after next line to fix a bleed issue on macOS - // https://github.com/chalk/chalk/pull/92 - str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`); - } +/***/ }), +/* 400 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { - // Reset the original `dim` if we changed it to work around the Windows dimmed gray issue - ansiStyles.dim.open = originalDim; +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WatchCommand", function() { return WatchCommand; }); +/* harmony import */ var _utils_errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(163); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(144); +/* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(145); +/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(146); +/* harmony import */ var _utils_watch__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(401); +/* + * 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. + */ - return str; -} -function chalkTag(chalk, strings) { - if (!Array.isArray(strings)) { - // If chalk() was called by itself or with a string, - // return the string itself as a string. - return [].slice.call(arguments, 1).join(' '); - } - const args = [].slice.call(arguments, 2); - const parts = [strings.raw[0]]; - for (let i = 1; i < strings.length; i++) { - parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&')); - parts.push(String(strings.raw[i])); - } - return template(chalk, parts.join('')); -} -Object.defineProperties(Chalk.prototype, styles); +/** + * Name of the script in the package/project package.json file to run during `kbn watch`. + */ +const watchScriptName = 'kbn:watch'; +/** + * Name of the Kibana project. + */ -module.exports = Chalk(); // eslint-disable-line new-cap -module.exports.supportsColor = stdoutColor; -module.exports.default = module.exports; // For TypeScript +const kibanaProjectName = 'kibana'; +/** + * Command that traverses through list of available projects/packages that have `kbn:watch` script in their + * package.json files, groups them into topology aware batches and then processes theses batches one by one + * running `kbn:watch` scripts in parallel within the same batch. + * + * Command internally relies on the fact that most of the build systems that are triggered by `kbn:watch` + * will emit special "marker" once build/watch process is ready that we can use as completion condition for + * 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 = { + description: 'Runs `kbn:watch` script for every project.', + name: 'watch', -/***/ }), -/* 394 */ -/***/ (function(module, exports, __webpack_require__) { + async run(projects, projectGraph) { + const projectsToWatch = new Map(); -"use strict"; -/* WEBPACK VAR INJECTION */(function(module) { -const colorConvert = __webpack_require__(180); + 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); + } + } -const wrapAnsi16 = (fn, offset) => function () { - const code = fn.apply(colorConvert, arguments); - return `\u001B[${code + offset}m`; -}; + if (projectsToWatch.size === 0) { + throw new _utils_errors__WEBPACK_IMPORTED_MODULE_0__["CliError"](`There are no projects to watch found. Make sure that projects define 'kbn:watch' script in 'package.json'.`); + } -const wrapAnsi256 = (fn, offset) => function () { - const code = fn.apply(colorConvert, arguments); - return `\u001B[${38 + offset};5;${code}m`; -}; + const projectNames = Array.from(projectsToWatch.keys()); + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].info(`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 = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_3__["topologicallyBatchProjects"])(projectsToWatch, projectGraph); + + if (shouldWatchKibanaProject) { + batchedProjects.push([projects.get(kibanaProjectName)]); + } + + 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, { + debug: false + }).stdout); + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].success(`[${pkg.name}] Initial build completed (${completionHint}).`); + }); + } -const wrapAnsi16m = (fn, offset) => function () { - const rgb = fn.apply(colorConvert, arguments); - return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; }; -function assembleStyles() { - const codes = new Map(); - const styles = { - modifier: { - reset: [0, 0], - // 21 isn't widely supported and 22 does the same thing - bold: [1, 22], - dim: [2, 22], - italic: [3, 23], - underline: [4, 24], - inverse: [7, 27], - hidden: [8, 28], - strikethrough: [9, 29] - }, - color: { - black: [30, 39], - red: [31, 39], - green: [32, 39], - yellow: [33, 39], - blue: [34, 39], - magenta: [35, 39], - cyan: [36, 39], - white: [37, 39], - gray: [90, 39], - - // Bright color - redBright: [91, 39], - greenBright: [92, 39], - yellowBright: [93, 39], - blueBright: [94, 39], - magentaBright: [95, 39], - cyanBright: [96, 39], - whiteBright: [97, 39] - }, - bgColor: { - bgBlack: [40, 49], - bgRed: [41, 49], - bgGreen: [42, 49], - bgYellow: [43, 49], - bgBlue: [44, 49], - bgMagenta: [45, 49], - bgCyan: [46, 49], - bgWhite: [47, 49], - - // Bright color - bgBlackBright: [100, 49], - bgRedBright: [101, 49], - bgGreenBright: [102, 49], - bgYellowBright: [103, 49], - bgBlueBright: [104, 49], - bgMagentaBright: [105, 49], - bgCyanBright: [106, 49], - bgWhiteBright: [107, 49] - } - }; - - // Fix humans - styles.color.grey = styles.color.gray; - - for (const groupName of Object.keys(styles)) { - const group = styles[groupName]; - - for (const styleName of Object.keys(group)) { - const style = group[styleName]; - - styles[styleName] = { - open: `\u001B[${style[0]}m`, - close: `\u001B[${style[1]}m` - }; - - group[styleName] = styles[styleName]; - - codes.set(style[0], style[1]); - } - - Object.defineProperty(styles, groupName, { - value: group, - enumerable: false - }); - - Object.defineProperty(styles, 'codes', { - value: codes, - enumerable: false - }); - } - - const ansi2ansi = n => n; - const rgb2rgb = (r, g, b) => [r, g, b]; - - styles.color.close = '\u001B[39m'; - styles.bgColor.close = '\u001B[49m'; - - styles.color.ansi = { - ansi: wrapAnsi16(ansi2ansi, 0) - }; - styles.color.ansi256 = { - ansi256: wrapAnsi256(ansi2ansi, 0) - }; - styles.color.ansi16m = { - rgb: wrapAnsi16m(rgb2rgb, 0) - }; - - styles.bgColor.ansi = { - ansi: wrapAnsi16(ansi2ansi, 10) - }; - styles.bgColor.ansi256 = { - ansi256: wrapAnsi256(ansi2ansi, 10) - }; - styles.bgColor.ansi16m = { - rgb: wrapAnsi16m(rgb2rgb, 10) - }; - - for (let key of Object.keys(colorConvert)) { - if (typeof colorConvert[key] !== 'object') { - continue; - } - - const suite = colorConvert[key]; - - if (key === 'ansi16') { - key = 'ansi'; - } - - if ('ansi16' in suite) { - styles.color.ansi[key] = wrapAnsi16(suite.ansi16, 0); - styles.bgColor.ansi[key] = wrapAnsi16(suite.ansi16, 10); - } - - if ('ansi256' in suite) { - styles.color.ansi256[key] = wrapAnsi256(suite.ansi256, 0); - styles.bgColor.ansi256[key] = wrapAnsi256(suite.ansi256, 10); - } - - if ('rgb' in suite) { - styles.color.ansi16m[key] = wrapAnsi16m(suite.rgb, 0); - styles.bgColor.ansi16m[key] = wrapAnsi16m(suite.rgb, 10); - } - } - - return styles; -} - -// Make the export immutable -Object.defineProperty(module, 'exports', { - enumerable: true, - get: assembleStyles -}); - -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(114)(module))) - -/***/ }), -/* 395 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; -const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; -const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; -const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi; - -const ESCAPES = new Map([ - ['n', '\n'], - ['r', '\r'], - ['t', '\t'], - ['b', '\b'], - ['f', '\f'], - ['v', '\v'], - ['0', '\0'], - ['\\', '\\'], - ['e', '\u001B'], - ['a', '\u0007'] -]); - -function unescape(c) { - if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) { - return String.fromCharCode(parseInt(c.slice(1), 16)); - } - - return ESCAPES.get(c) || c; -} - -function parseArguments(name, args) { - const results = []; - const chunks = args.trim().split(/\s*,\s*/g); - let matches; - - for (const chunk of chunks) { - if (!isNaN(chunk)) { - results.push(Number(chunk)); - } else if ((matches = chunk.match(STRING_REGEX))) { - results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, chr) => escape ? unescape(escape) : chr)); - } else { - throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); - } - } - - return results; -} - -function parseStyle(style) { - STYLE_REGEX.lastIndex = 0; - - const results = []; - let matches; - - while ((matches = STYLE_REGEX.exec(style)) !== null) { - const name = matches[1]; - - if (matches[2]) { - const args = parseArguments(name, matches[2]); - results.push([name].concat(args)); - } else { - results.push([name]); - } - } - - return results; -} - -function buildStyle(chalk, styles) { - const enabled = {}; - - for (const layer of styles) { - for (const style of layer.styles) { - enabled[style[0]] = layer.inverse ? null : style.slice(1); - } - } - - let current = chalk; - for (const styleName of Object.keys(enabled)) { - if (Array.isArray(enabled[styleName])) { - if (!(styleName in current)) { - throw new Error(`Unknown Chalk style: ${styleName}`); - } - - if (enabled[styleName].length > 0) { - current = current[styleName].apply(current, enabled[styleName]); - } else { - current = current[styleName]; - } - } - } - - return current; -} - -module.exports = (chalk, tmp) => { - const styles = []; - const chunks = []; - let chunk = []; - - // eslint-disable-next-line max-params - tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => { - if (escapeChar) { - chunk.push(unescape(escapeChar)); - } else if (style) { - const str = chunk.join(''); - chunk = []; - chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str)); - styles.push({inverse, styles: parseStyle(style)}); - } else if (close) { - if (styles.length === 0) { - throw new Error('Found extraneous } in Chalk template literal'); - } - - chunks.push(buildStyle(chalk, styles)(chunk.join(''))); - chunk = []; - styles.pop(); - } else { - chunk.push(chr); - } - }); - - chunks.push(chunk.join('')); - - if (styles.length > 0) { - const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; - throw new Error(errMsg); - } - - return chunks.join(''); -}; - - /***/ }), -/* 396 */ -/***/ (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 _utils_errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(162); -/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); -/* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(144); -/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(145); -/* - * 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 = { - 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); - - if (extraArgs.length === 0) { - throw new _utils_errors__WEBPACK_IMPORTED_MODULE_0__["CliError"]('No script specified'); - } - - const scriptName = extraArgs[0]; - const scriptArgs = extraArgs.slice(1); - await Object(_utils_parallelize__WEBPACK_IMPORTED_MODULE_2__["parallelizeBatches"])(batchedProjects, async project => { - if (project.hasScript(scriptName)) { - _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].info(`[${project.name}] running "${scriptName}" script`); - await project.runScriptStreaming(scriptName, { - args: scriptArgs - }); - _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].success(`[${project.name}] complete`); - } - }); - } - -}; - -/***/ }), -/* 397 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "WatchCommand", function() { return WatchCommand; }); -/* harmony import */ var _utils_errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(162); -/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); -/* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(144); -/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(145); -/* harmony import */ var _utils_watch__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(398); -/* - * 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. - */ - - - - - - -/** - * Name of the script in the package/project package.json file to run during `kbn watch`. - */ -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 - * package.json files, groups them into topology aware batches and then processes theses batches one by one - * running `kbn:watch` scripts in parallel within the same batch. - * - * Command internally relies on the fact that most of the build systems that are triggered by `kbn:watch` - * will emit special "marker" once build/watch process is ready that we can use as completion condition for - * 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 = { - description: 'Runs `kbn:watch` script for every project.', - name: 'watch', - - async run(projects, projectGraph) { - 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) { - throw new _utils_errors__WEBPACK_IMPORTED_MODULE_0__["CliError"](`There are no projects to watch found. Make sure that projects define 'kbn:watch' script in 'package.json'.`); - } - - const projectNames = Array.from(projectsToWatch.keys()); - _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].info(`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 = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_3__["topologicallyBatchProjects"])(projectsToWatch, projectGraph); - - if (shouldWatchKibanaProject) { - batchedProjects.push([projects.get(kibanaProjectName)]); - } - - 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, { - debug: false - }).stdout); - _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].success(`[${pkg.name}] Initial build completed (${completionHint}).`); - }); - } - -}; - -/***/ }), -/* 398 */ +/* 401 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "waitUntilWatchIsReady", function() { return waitUntilWatchIsReady; }); /* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8); -/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(399); +/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(402); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -51296,141 +51507,141 @@ function waitUntilWatchIsReady(stream, opts = {}) { } /***/ }), -/* 399 */ +/* 402 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony import */ var _internal_operators_audit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(400); +/* harmony import */ var _internal_operators_audit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(403); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "audit", function() { return _internal_operators_audit__WEBPACK_IMPORTED_MODULE_0__["audit"]; }); -/* harmony import */ var _internal_operators_auditTime__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(401); +/* harmony import */ var _internal_operators_auditTime__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(404); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "auditTime", function() { return _internal_operators_auditTime__WEBPACK_IMPORTED_MODULE_1__["auditTime"]; }); -/* harmony import */ var _internal_operators_buffer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(402); +/* harmony import */ var _internal_operators_buffer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(405); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buffer", function() { return _internal_operators_buffer__WEBPACK_IMPORTED_MODULE_2__["buffer"]; }); -/* harmony import */ var _internal_operators_bufferCount__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(403); +/* harmony import */ var _internal_operators_bufferCount__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(406); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferCount", function() { return _internal_operators_bufferCount__WEBPACK_IMPORTED_MODULE_3__["bufferCount"]; }); -/* harmony import */ var _internal_operators_bufferTime__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(404); +/* harmony import */ var _internal_operators_bufferTime__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(407); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferTime", function() { return _internal_operators_bufferTime__WEBPACK_IMPORTED_MODULE_4__["bufferTime"]; }); -/* harmony import */ var _internal_operators_bufferToggle__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(405); +/* harmony import */ var _internal_operators_bufferToggle__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(408); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferToggle", function() { return _internal_operators_bufferToggle__WEBPACK_IMPORTED_MODULE_5__["bufferToggle"]; }); -/* harmony import */ var _internal_operators_bufferWhen__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(406); +/* harmony import */ var _internal_operators_bufferWhen__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(409); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferWhen", function() { return _internal_operators_bufferWhen__WEBPACK_IMPORTED_MODULE_6__["bufferWhen"]; }); -/* harmony import */ var _internal_operators_catchError__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(407); +/* harmony import */ var _internal_operators_catchError__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(410); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "catchError", function() { return _internal_operators_catchError__WEBPACK_IMPORTED_MODULE_7__["catchError"]; }); -/* harmony import */ var _internal_operators_combineAll__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(408); +/* harmony import */ var _internal_operators_combineAll__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(411); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "combineAll", function() { return _internal_operators_combineAll__WEBPACK_IMPORTED_MODULE_8__["combineAll"]; }); -/* harmony import */ var _internal_operators_combineLatest__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(409); +/* harmony import */ var _internal_operators_combineLatest__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(412); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "combineLatest", function() { return _internal_operators_combineLatest__WEBPACK_IMPORTED_MODULE_9__["combineLatest"]; }); -/* harmony import */ var _internal_operators_concat__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(410); +/* harmony import */ var _internal_operators_concat__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(413); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concat", function() { return _internal_operators_concat__WEBPACK_IMPORTED_MODULE_10__["concat"]; }); /* harmony import */ var _internal_operators_concatAll__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(80); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concatAll", function() { return _internal_operators_concatAll__WEBPACK_IMPORTED_MODULE_11__["concatAll"]; }); -/* harmony import */ var _internal_operators_concatMap__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(411); +/* harmony import */ var _internal_operators_concatMap__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(414); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concatMap", function() { return _internal_operators_concatMap__WEBPACK_IMPORTED_MODULE_12__["concatMap"]; }); -/* harmony import */ var _internal_operators_concatMapTo__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(412); +/* harmony import */ var _internal_operators_concatMapTo__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(415); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concatMapTo", function() { return _internal_operators_concatMapTo__WEBPACK_IMPORTED_MODULE_13__["concatMapTo"]; }); -/* harmony import */ var _internal_operators_count__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(413); +/* harmony import */ var _internal_operators_count__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(416); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "count", function() { return _internal_operators_count__WEBPACK_IMPORTED_MODULE_14__["count"]; }); -/* harmony import */ var _internal_operators_debounce__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(414); +/* harmony import */ var _internal_operators_debounce__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(417); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "debounce", function() { return _internal_operators_debounce__WEBPACK_IMPORTED_MODULE_15__["debounce"]; }); -/* harmony import */ var _internal_operators_debounceTime__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(415); +/* harmony import */ var _internal_operators_debounceTime__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(418); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "debounceTime", function() { return _internal_operators_debounceTime__WEBPACK_IMPORTED_MODULE_16__["debounceTime"]; }); -/* harmony import */ var _internal_operators_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(416); +/* harmony import */ var _internal_operators_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(419); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "defaultIfEmpty", function() { return _internal_operators_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_17__["defaultIfEmpty"]; }); -/* harmony import */ var _internal_operators_delay__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(417); +/* harmony import */ var _internal_operators_delay__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(420); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "delay", function() { return _internal_operators_delay__WEBPACK_IMPORTED_MODULE_18__["delay"]; }); -/* harmony import */ var _internal_operators_delayWhen__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(419); +/* harmony import */ var _internal_operators_delayWhen__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(422); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "delayWhen", function() { return _internal_operators_delayWhen__WEBPACK_IMPORTED_MODULE_19__["delayWhen"]; }); -/* harmony import */ var _internal_operators_dematerialize__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(420); +/* harmony import */ var _internal_operators_dematerialize__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(423); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "dematerialize", function() { return _internal_operators_dematerialize__WEBPACK_IMPORTED_MODULE_20__["dematerialize"]; }); -/* harmony import */ var _internal_operators_distinct__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(421); +/* harmony import */ var _internal_operators_distinct__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(424); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "distinct", function() { return _internal_operators_distinct__WEBPACK_IMPORTED_MODULE_21__["distinct"]; }); -/* harmony import */ var _internal_operators_distinctUntilChanged__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(422); +/* harmony import */ var _internal_operators_distinctUntilChanged__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(425); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "distinctUntilChanged", function() { return _internal_operators_distinctUntilChanged__WEBPACK_IMPORTED_MODULE_22__["distinctUntilChanged"]; }); -/* harmony import */ var _internal_operators_distinctUntilKeyChanged__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(423); +/* harmony import */ var _internal_operators_distinctUntilKeyChanged__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(426); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "distinctUntilKeyChanged", function() { return _internal_operators_distinctUntilKeyChanged__WEBPACK_IMPORTED_MODULE_23__["distinctUntilKeyChanged"]; }); -/* harmony import */ var _internal_operators_elementAt__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(424); +/* harmony import */ var _internal_operators_elementAt__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(427); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "elementAt", function() { return _internal_operators_elementAt__WEBPACK_IMPORTED_MODULE_24__["elementAt"]; }); -/* harmony import */ var _internal_operators_endWith__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(427); +/* harmony import */ var _internal_operators_endWith__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(430); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "endWith", function() { return _internal_operators_endWith__WEBPACK_IMPORTED_MODULE_25__["endWith"]; }); -/* harmony import */ var _internal_operators_every__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(428); +/* harmony import */ var _internal_operators_every__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(431); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "every", function() { return _internal_operators_every__WEBPACK_IMPORTED_MODULE_26__["every"]; }); -/* harmony import */ var _internal_operators_exhaust__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(429); +/* harmony import */ var _internal_operators_exhaust__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(432); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "exhaust", function() { return _internal_operators_exhaust__WEBPACK_IMPORTED_MODULE_27__["exhaust"]; }); -/* harmony import */ var _internal_operators_exhaustMap__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(430); +/* harmony import */ var _internal_operators_exhaustMap__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(433); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "exhaustMap", function() { return _internal_operators_exhaustMap__WEBPACK_IMPORTED_MODULE_28__["exhaustMap"]; }); -/* harmony import */ var _internal_operators_expand__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(431); +/* harmony import */ var _internal_operators_expand__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(434); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "expand", function() { return _internal_operators_expand__WEBPACK_IMPORTED_MODULE_29__["expand"]; }); -/* harmony import */ var _internal_operators_filter__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(104); +/* harmony import */ var _internal_operators_filter__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(105); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "filter", function() { return _internal_operators_filter__WEBPACK_IMPORTED_MODULE_30__["filter"]; }); -/* harmony import */ var _internal_operators_finalize__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(432); +/* harmony import */ var _internal_operators_finalize__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(435); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "finalize", function() { return _internal_operators_finalize__WEBPACK_IMPORTED_MODULE_31__["finalize"]; }); -/* harmony import */ var _internal_operators_find__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(433); +/* harmony import */ var _internal_operators_find__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(436); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "find", function() { return _internal_operators_find__WEBPACK_IMPORTED_MODULE_32__["find"]; }); -/* harmony import */ var _internal_operators_findIndex__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(434); +/* harmony import */ var _internal_operators_findIndex__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(437); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "findIndex", function() { return _internal_operators_findIndex__WEBPACK_IMPORTED_MODULE_33__["findIndex"]; }); -/* harmony import */ var _internal_operators_first__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(435); +/* harmony import */ var _internal_operators_first__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(438); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "first", function() { return _internal_operators_first__WEBPACK_IMPORTED_MODULE_34__["first"]; }); /* harmony import */ var _internal_operators_groupBy__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(31); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "groupBy", function() { return _internal_operators_groupBy__WEBPACK_IMPORTED_MODULE_35__["groupBy"]; }); -/* harmony import */ var _internal_operators_ignoreElements__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(436); +/* harmony import */ var _internal_operators_ignoreElements__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(439); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ignoreElements", function() { return _internal_operators_ignoreElements__WEBPACK_IMPORTED_MODULE_36__["ignoreElements"]; }); -/* harmony import */ var _internal_operators_isEmpty__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(437); +/* harmony import */ var _internal_operators_isEmpty__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(440); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "isEmpty", function() { return _internal_operators_isEmpty__WEBPACK_IMPORTED_MODULE_37__["isEmpty"]; }); -/* harmony import */ var _internal_operators_last__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(438); +/* harmony import */ var _internal_operators_last__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(441); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "last", function() { return _internal_operators_last__WEBPACK_IMPORTED_MODULE_38__["last"]; }); /* harmony import */ var _internal_operators_map__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(66); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "map", function() { return _internal_operators_map__WEBPACK_IMPORTED_MODULE_39__["map"]; }); -/* harmony import */ var _internal_operators_mapTo__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(440); +/* harmony import */ var _internal_operators_mapTo__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(443); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mapTo", function() { return _internal_operators_mapTo__WEBPACK_IMPORTED_MODULE_40__["mapTo"]; }); -/* harmony import */ var _internal_operators_materialize__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(441); +/* harmony import */ var _internal_operators_materialize__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(444); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "materialize", function() { return _internal_operators_materialize__WEBPACK_IMPORTED_MODULE_41__["materialize"]; }); -/* harmony import */ var _internal_operators_max__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(442); +/* harmony import */ var _internal_operators_max__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(445); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "max", function() { return _internal_operators_max__WEBPACK_IMPORTED_MODULE_42__["max"]; }); -/* harmony import */ var _internal_operators_merge__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(445); +/* harmony import */ var _internal_operators_merge__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(448); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "merge", function() { return _internal_operators_merge__WEBPACK_IMPORTED_MODULE_43__["merge"]; }); /* harmony import */ var _internal_operators_mergeAll__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(81); @@ -51439,177 +51650,177 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _internal_operators_mergeMap__WEBPACK_IMPORTED_MODULE_45__ = __webpack_require__(82); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mergeMap", function() { return _internal_operators_mergeMap__WEBPACK_IMPORTED_MODULE_45__["mergeMap"]; }); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "flatMap", function() { return _internal_operators_mergeMap__WEBPACK_IMPORTED_MODULE_45__["mergeMap"]; }); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "flatMap", function() { return _internal_operators_mergeMap__WEBPACK_IMPORTED_MODULE_45__["flatMap"]; }); -/* harmony import */ var _internal_operators_mergeMapTo__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(446); +/* harmony import */ var _internal_operators_mergeMapTo__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(449); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mergeMapTo", function() { return _internal_operators_mergeMapTo__WEBPACK_IMPORTED_MODULE_46__["mergeMapTo"]; }); -/* harmony import */ var _internal_operators_mergeScan__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(447); +/* harmony import */ var _internal_operators_mergeScan__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(450); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mergeScan", function() { return _internal_operators_mergeScan__WEBPACK_IMPORTED_MODULE_47__["mergeScan"]; }); -/* harmony import */ var _internal_operators_min__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(448); +/* harmony import */ var _internal_operators_min__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(451); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "min", function() { return _internal_operators_min__WEBPACK_IMPORTED_MODULE_48__["min"]; }); -/* harmony import */ var _internal_operators_multicast__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(449); +/* harmony import */ var _internal_operators_multicast__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(452); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "multicast", function() { return _internal_operators_multicast__WEBPACK_IMPORTED_MODULE_49__["multicast"]; }); /* harmony import */ var _internal_operators_observeOn__WEBPACK_IMPORTED_MODULE_50__ = __webpack_require__(41); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "observeOn", function() { return _internal_operators_observeOn__WEBPACK_IMPORTED_MODULE_50__["observeOn"]; }); -/* harmony import */ var _internal_operators_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_51__ = __webpack_require__(450); +/* harmony import */ var _internal_operators_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_51__ = __webpack_require__(453); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "onErrorResumeNext", function() { return _internal_operators_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_51__["onErrorResumeNext"]; }); -/* harmony import */ var _internal_operators_pairwise__WEBPACK_IMPORTED_MODULE_52__ = __webpack_require__(451); +/* harmony import */ var _internal_operators_pairwise__WEBPACK_IMPORTED_MODULE_52__ = __webpack_require__(454); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "pairwise", function() { return _internal_operators_pairwise__WEBPACK_IMPORTED_MODULE_52__["pairwise"]; }); -/* harmony import */ var _internal_operators_partition__WEBPACK_IMPORTED_MODULE_53__ = __webpack_require__(452); +/* harmony import */ var _internal_operators_partition__WEBPACK_IMPORTED_MODULE_53__ = __webpack_require__(455); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "partition", function() { return _internal_operators_partition__WEBPACK_IMPORTED_MODULE_53__["partition"]; }); -/* harmony import */ var _internal_operators_pluck__WEBPACK_IMPORTED_MODULE_54__ = __webpack_require__(453); +/* harmony import */ var _internal_operators_pluck__WEBPACK_IMPORTED_MODULE_54__ = __webpack_require__(456); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "pluck", function() { return _internal_operators_pluck__WEBPACK_IMPORTED_MODULE_54__["pluck"]; }); -/* harmony import */ var _internal_operators_publish__WEBPACK_IMPORTED_MODULE_55__ = __webpack_require__(454); +/* harmony import */ var _internal_operators_publish__WEBPACK_IMPORTED_MODULE_55__ = __webpack_require__(457); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publish", function() { return _internal_operators_publish__WEBPACK_IMPORTED_MODULE_55__["publish"]; }); -/* harmony import */ var _internal_operators_publishBehavior__WEBPACK_IMPORTED_MODULE_56__ = __webpack_require__(455); +/* harmony import */ var _internal_operators_publishBehavior__WEBPACK_IMPORTED_MODULE_56__ = __webpack_require__(458); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publishBehavior", function() { return _internal_operators_publishBehavior__WEBPACK_IMPORTED_MODULE_56__["publishBehavior"]; }); -/* harmony import */ var _internal_operators_publishLast__WEBPACK_IMPORTED_MODULE_57__ = __webpack_require__(456); +/* harmony import */ var _internal_operators_publishLast__WEBPACK_IMPORTED_MODULE_57__ = __webpack_require__(459); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publishLast", function() { return _internal_operators_publishLast__WEBPACK_IMPORTED_MODULE_57__["publishLast"]; }); -/* harmony import */ var _internal_operators_publishReplay__WEBPACK_IMPORTED_MODULE_58__ = __webpack_require__(457); +/* harmony import */ var _internal_operators_publishReplay__WEBPACK_IMPORTED_MODULE_58__ = __webpack_require__(460); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publishReplay", function() { return _internal_operators_publishReplay__WEBPACK_IMPORTED_MODULE_58__["publishReplay"]; }); -/* harmony import */ var _internal_operators_race__WEBPACK_IMPORTED_MODULE_59__ = __webpack_require__(458); +/* harmony import */ var _internal_operators_race__WEBPACK_IMPORTED_MODULE_59__ = __webpack_require__(461); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "race", function() { return _internal_operators_race__WEBPACK_IMPORTED_MODULE_59__["race"]; }); -/* harmony import */ var _internal_operators_reduce__WEBPACK_IMPORTED_MODULE_60__ = __webpack_require__(443); +/* harmony import */ var _internal_operators_reduce__WEBPACK_IMPORTED_MODULE_60__ = __webpack_require__(446); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "reduce", function() { return _internal_operators_reduce__WEBPACK_IMPORTED_MODULE_60__["reduce"]; }); -/* harmony import */ var _internal_operators_repeat__WEBPACK_IMPORTED_MODULE_61__ = __webpack_require__(459); +/* harmony import */ var _internal_operators_repeat__WEBPACK_IMPORTED_MODULE_61__ = __webpack_require__(462); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "repeat", function() { return _internal_operators_repeat__WEBPACK_IMPORTED_MODULE_61__["repeat"]; }); -/* harmony import */ var _internal_operators_repeatWhen__WEBPACK_IMPORTED_MODULE_62__ = __webpack_require__(460); +/* harmony import */ var _internal_operators_repeatWhen__WEBPACK_IMPORTED_MODULE_62__ = __webpack_require__(463); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "repeatWhen", function() { return _internal_operators_repeatWhen__WEBPACK_IMPORTED_MODULE_62__["repeatWhen"]; }); -/* harmony import */ var _internal_operators_retry__WEBPACK_IMPORTED_MODULE_63__ = __webpack_require__(461); +/* harmony import */ var _internal_operators_retry__WEBPACK_IMPORTED_MODULE_63__ = __webpack_require__(464); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "retry", function() { return _internal_operators_retry__WEBPACK_IMPORTED_MODULE_63__["retry"]; }); -/* harmony import */ var _internal_operators_retryWhen__WEBPACK_IMPORTED_MODULE_64__ = __webpack_require__(462); +/* harmony import */ var _internal_operators_retryWhen__WEBPACK_IMPORTED_MODULE_64__ = __webpack_require__(465); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "retryWhen", function() { return _internal_operators_retryWhen__WEBPACK_IMPORTED_MODULE_64__["retryWhen"]; }); /* harmony import */ var _internal_operators_refCount__WEBPACK_IMPORTED_MODULE_65__ = __webpack_require__(30); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "refCount", function() { return _internal_operators_refCount__WEBPACK_IMPORTED_MODULE_65__["refCount"]; }); -/* harmony import */ var _internal_operators_sample__WEBPACK_IMPORTED_MODULE_66__ = __webpack_require__(463); +/* harmony import */ var _internal_operators_sample__WEBPACK_IMPORTED_MODULE_66__ = __webpack_require__(466); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "sample", function() { return _internal_operators_sample__WEBPACK_IMPORTED_MODULE_66__["sample"]; }); -/* harmony import */ var _internal_operators_sampleTime__WEBPACK_IMPORTED_MODULE_67__ = __webpack_require__(464); +/* harmony import */ var _internal_operators_sampleTime__WEBPACK_IMPORTED_MODULE_67__ = __webpack_require__(467); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "sampleTime", function() { return _internal_operators_sampleTime__WEBPACK_IMPORTED_MODULE_67__["sampleTime"]; }); -/* harmony import */ var _internal_operators_scan__WEBPACK_IMPORTED_MODULE_68__ = __webpack_require__(444); +/* harmony import */ var _internal_operators_scan__WEBPACK_IMPORTED_MODULE_68__ = __webpack_require__(447); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "scan", function() { return _internal_operators_scan__WEBPACK_IMPORTED_MODULE_68__["scan"]; }); -/* harmony import */ var _internal_operators_sequenceEqual__WEBPACK_IMPORTED_MODULE_69__ = __webpack_require__(465); +/* harmony import */ var _internal_operators_sequenceEqual__WEBPACK_IMPORTED_MODULE_69__ = __webpack_require__(468); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "sequenceEqual", function() { return _internal_operators_sequenceEqual__WEBPACK_IMPORTED_MODULE_69__["sequenceEqual"]; }); -/* harmony import */ var _internal_operators_share__WEBPACK_IMPORTED_MODULE_70__ = __webpack_require__(466); +/* harmony import */ var _internal_operators_share__WEBPACK_IMPORTED_MODULE_70__ = __webpack_require__(469); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "share", function() { return _internal_operators_share__WEBPACK_IMPORTED_MODULE_70__["share"]; }); -/* harmony import */ var _internal_operators_shareReplay__WEBPACK_IMPORTED_MODULE_71__ = __webpack_require__(467); +/* harmony import */ var _internal_operators_shareReplay__WEBPACK_IMPORTED_MODULE_71__ = __webpack_require__(470); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "shareReplay", function() { return _internal_operators_shareReplay__WEBPACK_IMPORTED_MODULE_71__["shareReplay"]; }); -/* harmony import */ var _internal_operators_single__WEBPACK_IMPORTED_MODULE_72__ = __webpack_require__(468); +/* harmony import */ var _internal_operators_single__WEBPACK_IMPORTED_MODULE_72__ = __webpack_require__(471); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "single", function() { return _internal_operators_single__WEBPACK_IMPORTED_MODULE_72__["single"]; }); -/* harmony import */ var _internal_operators_skip__WEBPACK_IMPORTED_MODULE_73__ = __webpack_require__(469); +/* harmony import */ var _internal_operators_skip__WEBPACK_IMPORTED_MODULE_73__ = __webpack_require__(472); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skip", function() { return _internal_operators_skip__WEBPACK_IMPORTED_MODULE_73__["skip"]; }); -/* harmony import */ var _internal_operators_skipLast__WEBPACK_IMPORTED_MODULE_74__ = __webpack_require__(470); +/* harmony import */ var _internal_operators_skipLast__WEBPACK_IMPORTED_MODULE_74__ = __webpack_require__(473); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skipLast", function() { return _internal_operators_skipLast__WEBPACK_IMPORTED_MODULE_74__["skipLast"]; }); -/* harmony import */ var _internal_operators_skipUntil__WEBPACK_IMPORTED_MODULE_75__ = __webpack_require__(471); +/* harmony import */ var _internal_operators_skipUntil__WEBPACK_IMPORTED_MODULE_75__ = __webpack_require__(474); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skipUntil", function() { return _internal_operators_skipUntil__WEBPACK_IMPORTED_MODULE_75__["skipUntil"]; }); -/* harmony import */ var _internal_operators_skipWhile__WEBPACK_IMPORTED_MODULE_76__ = __webpack_require__(472); +/* harmony import */ var _internal_operators_skipWhile__WEBPACK_IMPORTED_MODULE_76__ = __webpack_require__(475); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skipWhile", function() { return _internal_operators_skipWhile__WEBPACK_IMPORTED_MODULE_76__["skipWhile"]; }); -/* harmony import */ var _internal_operators_startWith__WEBPACK_IMPORTED_MODULE_77__ = __webpack_require__(473); +/* harmony import */ var _internal_operators_startWith__WEBPACK_IMPORTED_MODULE_77__ = __webpack_require__(476); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "startWith", function() { return _internal_operators_startWith__WEBPACK_IMPORTED_MODULE_77__["startWith"]; }); -/* harmony import */ var _internal_operators_subscribeOn__WEBPACK_IMPORTED_MODULE_78__ = __webpack_require__(474); +/* harmony import */ var _internal_operators_subscribeOn__WEBPACK_IMPORTED_MODULE_78__ = __webpack_require__(477); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "subscribeOn", function() { return _internal_operators_subscribeOn__WEBPACK_IMPORTED_MODULE_78__["subscribeOn"]; }); -/* harmony import */ var _internal_operators_switchAll__WEBPACK_IMPORTED_MODULE_79__ = __webpack_require__(476); +/* harmony import */ var _internal_operators_switchAll__WEBPACK_IMPORTED_MODULE_79__ = __webpack_require__(479); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "switchAll", function() { return _internal_operators_switchAll__WEBPACK_IMPORTED_MODULE_79__["switchAll"]; }); -/* harmony import */ var _internal_operators_switchMap__WEBPACK_IMPORTED_MODULE_80__ = __webpack_require__(477); +/* harmony import */ var _internal_operators_switchMap__WEBPACK_IMPORTED_MODULE_80__ = __webpack_require__(480); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "switchMap", function() { return _internal_operators_switchMap__WEBPACK_IMPORTED_MODULE_80__["switchMap"]; }); -/* harmony import */ var _internal_operators_switchMapTo__WEBPACK_IMPORTED_MODULE_81__ = __webpack_require__(478); +/* harmony import */ var _internal_operators_switchMapTo__WEBPACK_IMPORTED_MODULE_81__ = __webpack_require__(481); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "switchMapTo", function() { return _internal_operators_switchMapTo__WEBPACK_IMPORTED_MODULE_81__["switchMapTo"]; }); -/* harmony import */ var _internal_operators_take__WEBPACK_IMPORTED_MODULE_82__ = __webpack_require__(426); +/* harmony import */ var _internal_operators_take__WEBPACK_IMPORTED_MODULE_82__ = __webpack_require__(429); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "take", function() { return _internal_operators_take__WEBPACK_IMPORTED_MODULE_82__["take"]; }); -/* harmony import */ var _internal_operators_takeLast__WEBPACK_IMPORTED_MODULE_83__ = __webpack_require__(439); +/* harmony import */ var _internal_operators_takeLast__WEBPACK_IMPORTED_MODULE_83__ = __webpack_require__(442); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "takeLast", function() { return _internal_operators_takeLast__WEBPACK_IMPORTED_MODULE_83__["takeLast"]; }); -/* harmony import */ var _internal_operators_takeUntil__WEBPACK_IMPORTED_MODULE_84__ = __webpack_require__(479); +/* harmony import */ var _internal_operators_takeUntil__WEBPACK_IMPORTED_MODULE_84__ = __webpack_require__(482); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "takeUntil", function() { return _internal_operators_takeUntil__WEBPACK_IMPORTED_MODULE_84__["takeUntil"]; }); -/* harmony import */ var _internal_operators_takeWhile__WEBPACK_IMPORTED_MODULE_85__ = __webpack_require__(480); +/* harmony import */ var _internal_operators_takeWhile__WEBPACK_IMPORTED_MODULE_85__ = __webpack_require__(483); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "takeWhile", function() { return _internal_operators_takeWhile__WEBPACK_IMPORTED_MODULE_85__["takeWhile"]; }); -/* harmony import */ var _internal_operators_tap__WEBPACK_IMPORTED_MODULE_86__ = __webpack_require__(481); +/* harmony import */ var _internal_operators_tap__WEBPACK_IMPORTED_MODULE_86__ = __webpack_require__(484); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "tap", function() { return _internal_operators_tap__WEBPACK_IMPORTED_MODULE_86__["tap"]; }); -/* harmony import */ var _internal_operators_throttle__WEBPACK_IMPORTED_MODULE_87__ = __webpack_require__(482); +/* harmony import */ var _internal_operators_throttle__WEBPACK_IMPORTED_MODULE_87__ = __webpack_require__(485); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throttle", function() { return _internal_operators_throttle__WEBPACK_IMPORTED_MODULE_87__["throttle"]; }); -/* harmony import */ var _internal_operators_throttleTime__WEBPACK_IMPORTED_MODULE_88__ = __webpack_require__(483); +/* harmony import */ var _internal_operators_throttleTime__WEBPACK_IMPORTED_MODULE_88__ = __webpack_require__(486); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throttleTime", function() { return _internal_operators_throttleTime__WEBPACK_IMPORTED_MODULE_88__["throttleTime"]; }); -/* harmony import */ var _internal_operators_throwIfEmpty__WEBPACK_IMPORTED_MODULE_89__ = __webpack_require__(425); +/* harmony import */ var _internal_operators_throwIfEmpty__WEBPACK_IMPORTED_MODULE_89__ = __webpack_require__(428); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throwIfEmpty", function() { return _internal_operators_throwIfEmpty__WEBPACK_IMPORTED_MODULE_89__["throwIfEmpty"]; }); -/* harmony import */ var _internal_operators_timeInterval__WEBPACK_IMPORTED_MODULE_90__ = __webpack_require__(484); +/* harmony import */ var _internal_operators_timeInterval__WEBPACK_IMPORTED_MODULE_90__ = __webpack_require__(487); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timeInterval", function() { return _internal_operators_timeInterval__WEBPACK_IMPORTED_MODULE_90__["timeInterval"]; }); -/* harmony import */ var _internal_operators_timeout__WEBPACK_IMPORTED_MODULE_91__ = __webpack_require__(485); +/* harmony import */ var _internal_operators_timeout__WEBPACK_IMPORTED_MODULE_91__ = __webpack_require__(488); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timeout", function() { return _internal_operators_timeout__WEBPACK_IMPORTED_MODULE_91__["timeout"]; }); -/* harmony import */ var _internal_operators_timeoutWith__WEBPACK_IMPORTED_MODULE_92__ = __webpack_require__(486); +/* harmony import */ var _internal_operators_timeoutWith__WEBPACK_IMPORTED_MODULE_92__ = __webpack_require__(489); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timeoutWith", function() { return _internal_operators_timeoutWith__WEBPACK_IMPORTED_MODULE_92__["timeoutWith"]; }); -/* harmony import */ var _internal_operators_timestamp__WEBPACK_IMPORTED_MODULE_93__ = __webpack_require__(487); +/* harmony import */ var _internal_operators_timestamp__WEBPACK_IMPORTED_MODULE_93__ = __webpack_require__(490); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timestamp", function() { return _internal_operators_timestamp__WEBPACK_IMPORTED_MODULE_93__["timestamp"]; }); -/* harmony import */ var _internal_operators_toArray__WEBPACK_IMPORTED_MODULE_94__ = __webpack_require__(488); +/* harmony import */ var _internal_operators_toArray__WEBPACK_IMPORTED_MODULE_94__ = __webpack_require__(491); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "toArray", function() { return _internal_operators_toArray__WEBPACK_IMPORTED_MODULE_94__["toArray"]; }); -/* harmony import */ var _internal_operators_window__WEBPACK_IMPORTED_MODULE_95__ = __webpack_require__(489); +/* harmony import */ var _internal_operators_window__WEBPACK_IMPORTED_MODULE_95__ = __webpack_require__(492); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "window", function() { return _internal_operators_window__WEBPACK_IMPORTED_MODULE_95__["window"]; }); -/* harmony import */ var _internal_operators_windowCount__WEBPACK_IMPORTED_MODULE_96__ = __webpack_require__(490); +/* harmony import */ var _internal_operators_windowCount__WEBPACK_IMPORTED_MODULE_96__ = __webpack_require__(493); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowCount", function() { return _internal_operators_windowCount__WEBPACK_IMPORTED_MODULE_96__["windowCount"]; }); -/* harmony import */ var _internal_operators_windowTime__WEBPACK_IMPORTED_MODULE_97__ = __webpack_require__(491); +/* harmony import */ var _internal_operators_windowTime__WEBPACK_IMPORTED_MODULE_97__ = __webpack_require__(494); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowTime", function() { return _internal_operators_windowTime__WEBPACK_IMPORTED_MODULE_97__["windowTime"]; }); -/* harmony import */ var _internal_operators_windowToggle__WEBPACK_IMPORTED_MODULE_98__ = __webpack_require__(492); +/* harmony import */ var _internal_operators_windowToggle__WEBPACK_IMPORTED_MODULE_98__ = __webpack_require__(495); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowToggle", function() { return _internal_operators_windowToggle__WEBPACK_IMPORTED_MODULE_98__["windowToggle"]; }); -/* harmony import */ var _internal_operators_windowWhen__WEBPACK_IMPORTED_MODULE_99__ = __webpack_require__(493); +/* harmony import */ var _internal_operators_windowWhen__WEBPACK_IMPORTED_MODULE_99__ = __webpack_require__(496); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowWhen", function() { return _internal_operators_windowWhen__WEBPACK_IMPORTED_MODULE_99__["windowWhen"]; }); -/* harmony import */ var _internal_operators_withLatestFrom__WEBPACK_IMPORTED_MODULE_100__ = __webpack_require__(494); +/* harmony import */ var _internal_operators_withLatestFrom__WEBPACK_IMPORTED_MODULE_100__ = __webpack_require__(497); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "withLatestFrom", function() { return _internal_operators_withLatestFrom__WEBPACK_IMPORTED_MODULE_100__["withLatestFrom"]; }); -/* harmony import */ var _internal_operators_zip__WEBPACK_IMPORTED_MODULE_101__ = __webpack_require__(495); +/* harmony import */ var _internal_operators_zip__WEBPACK_IMPORTED_MODULE_101__ = __webpack_require__(498); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "zip", function() { return _internal_operators_zip__WEBPACK_IMPORTED_MODULE_101__["zip"]; }); -/* harmony import */ var _internal_operators_zipAll__WEBPACK_IMPORTED_MODULE_102__ = __webpack_require__(496); +/* harmony import */ var _internal_operators_zipAll__WEBPACK_IMPORTED_MODULE_102__ = __webpack_require__(499); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "zipAll", function() { return _internal_operators_zipAll__WEBPACK_IMPORTED_MODULE_102__["zipAll"]; }); /** PURE_IMPORTS_START PURE_IMPORTS_END */ @@ -51714,24 +51925,21 @@ __webpack_require__.r(__webpack_exports__); - //# sourceMappingURL=index.js.map /***/ }), -/* 400 */ +/* 403 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "audit", function() { return audit; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(69); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(70); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ - +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ function audit(durationSelector) { @@ -51768,7 +51976,7 @@ var AuditSubscriber = /*@__PURE__*/ (function (_super) { catch (err) { return this.destination.error(err); } - var innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(this, duration); + var innerSubscription = Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["innerSubscribe"])(duration, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleInnerSubscriber"](this)); if (!innerSubscription || innerSubscription.closed) { this.clearThrottle(); } @@ -51781,36 +51989,36 @@ var AuditSubscriber = /*@__PURE__*/ (function (_super) { var _a = this, value = _a.value, hasValue = _a.hasValue, throttled = _a.throttled; if (throttled) { this.remove(throttled); - this.throttled = null; + this.throttled = undefined; throttled.unsubscribe(); } if (hasValue) { - this.value = null; + this.value = undefined; this.hasValue = false; this.destination.next(value); } }; - AuditSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex) { + AuditSubscriber.prototype.notifyNext = function () { this.clearThrottle(); }; AuditSubscriber.prototype.notifyComplete = function () { this.clearThrottle(); }; return AuditSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleOuterSubscriber"])); //# sourceMappingURL=audit.js.map /***/ }), -/* 401 */ +/* 404 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "auditTime", function() { return auditTime; }); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(55); -/* harmony import */ var _audit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(400); -/* harmony import */ var _observable_timer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(107); +/* harmony import */ var _audit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(403); +/* harmony import */ var _observable_timer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(108); /** PURE_IMPORTS_START _scheduler_async,_audit,_observable_timer PURE_IMPORTS_END */ @@ -51825,17 +52033,15 @@ function auditTime(duration, scheduler) { /***/ }), -/* 402 */ +/* 405 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "buffer", function() { return buffer; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(69); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(70); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ - +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ function buffer(closingNotifier) { @@ -51857,24 +52063,24 @@ var BufferSubscriber = /*@__PURE__*/ (function (_super) { function BufferSubscriber(destination, closingNotifier) { var _this = _super.call(this, destination) || this; _this.buffer = []; - _this.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(_this, closingNotifier)); + _this.add(Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["innerSubscribe"])(closingNotifier, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleInnerSubscriber"](_this))); return _this; } BufferSubscriber.prototype._next = function (value) { this.buffer.push(value); }; - BufferSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + BufferSubscriber.prototype.notifyNext = function () { var buffer = this.buffer; this.buffer = []; this.destination.next(buffer); }; return BufferSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleOuterSubscriber"])); //# sourceMappingURL=buffer.js.map /***/ }), -/* 403 */ +/* 406 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51975,7 +52181,7 @@ var BufferSkipCountSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 404 */ +/* 407 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52136,7 +52342,7 @@ function dispatchBufferClose(arg) { /***/ }), -/* 405 */ +/* 408 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52170,7 +52376,6 @@ var BufferToggleSubscriber = /*@__PURE__*/ (function (_super) { tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BufferToggleSubscriber, _super); function BufferToggleSubscriber(destination, openings, closingSelector) { var _this = _super.call(this, destination) || this; - _this.openings = openings; _this.closingSelector = closingSelector; _this.contexts = []; _this.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(_this, openings)); @@ -52206,7 +52411,7 @@ var BufferToggleSubscriber = /*@__PURE__*/ (function (_super) { this.contexts = null; _super.prototype._complete.call(this); }; - BufferToggleSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + BufferToggleSubscriber.prototype.notifyNext = function (outerValue, innerValue) { outerValue ? this.closeBuffer(outerValue) : this.openBuffer(innerValue); }; BufferToggleSubscriber.prototype.notifyComplete = function (innerSub) { @@ -52256,7 +52461,7 @@ var BufferToggleSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 406 */ +/* 409 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52264,10 +52469,8 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bufferWhen", function() { return bufferWhen; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(17); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(69); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(70); -/** PURE_IMPORTS_START tslib,_Subscription,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ - +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_Subscription,_innerSubscribe PURE_IMPORTS_END */ @@ -52305,10 +52508,10 @@ var BufferWhenSubscriber = /*@__PURE__*/ (function (_super) { _super.prototype._complete.call(this); }; BufferWhenSubscriber.prototype._unsubscribe = function () { - this.buffer = null; + this.buffer = undefined; this.subscribing = false; }; - BufferWhenSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + BufferWhenSubscriber.prototype.notifyNext = function () { this.openBuffer(); }; BufferWhenSubscriber.prototype.notifyComplete = function () { @@ -52342,28 +52545,24 @@ var BufferWhenSubscriber = /*@__PURE__*/ (function (_super) { this.closingSubscription = closingSubscription; this.add(closingSubscription); this.subscribing = true; - closingSubscription.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, closingNotifier)); + closingSubscription.add(Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_2__["innerSubscribe"])(closingNotifier, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_2__["SimpleInnerSubscriber"](this))); this.subscribing = false; }; return BufferWhenSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_2__["SimpleOuterSubscriber"])); //# sourceMappingURL=bufferWhen.js.map /***/ }), -/* 407 */ +/* 410 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "catchError", function() { return catchError; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(69); -/* harmony import */ var _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(71); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(70); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_InnerSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ - - +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ function catchError(selector) { @@ -52401,21 +52600,21 @@ var CatchSubscriber = /*@__PURE__*/ (function (_super) { return; } this._unsubscribeAndRecycle(); - var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__["InnerSubscriber"](this, undefined, undefined); + var innerSubscriber = new _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleInnerSubscriber"](this); this.add(innerSubscriber); - var innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, result, undefined, undefined, innerSubscriber); + var innerSubscription = Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["innerSubscribe"])(result, innerSubscriber); if (innerSubscription !== innerSubscriber) { this.add(innerSubscription); } } }; return CatchSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleOuterSubscriber"])); //# sourceMappingURL=catchError.js.map /***/ }), -/* 408 */ +/* 411 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52431,7 +52630,7 @@ function combineAll(project) { /***/ }), -/* 409 */ +/* 412 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52463,7 +52662,7 @@ function combineLatest() { /***/ }), -/* 410 */ +/* 413 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52483,7 +52682,7 @@ function concat() { /***/ }), -/* 411 */ +/* 414 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52499,13 +52698,13 @@ function concatMap(project, resultSelector) { /***/ }), -/* 412 */ +/* 415 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concatMapTo", function() { return concatMapTo; }); -/* harmony import */ var _concatMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(411); +/* harmony import */ var _concatMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(414); /** PURE_IMPORTS_START _concatMap PURE_IMPORTS_END */ function concatMapTo(innerObservable, resultSelector) { @@ -52515,7 +52714,7 @@ function concatMapTo(innerObservable, resultSelector) { /***/ }), -/* 413 */ +/* 416 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52580,17 +52779,15 @@ var CountSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 414 */ +/* 417 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "debounce", function() { return debounce; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(69); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(70); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ - +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ function debounce(durationSelector) { @@ -52611,7 +52808,6 @@ var DebounceSubscriber = /*@__PURE__*/ (function (_super) { var _this = _super.call(this, destination) || this; _this.durationSelector = durationSelector; _this.hasValue = false; - _this.durationSubscription = null; return _this; } DebounceSubscriber.prototype._next = function (value) { @@ -52637,12 +52833,12 @@ var DebounceSubscriber = /*@__PURE__*/ (function (_super) { subscription.unsubscribe(); this.remove(subscription); } - subscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(this, duration); + subscription = Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["innerSubscribe"])(duration, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleInnerSubscriber"](this)); if (subscription && !subscription.closed) { this.add(this.durationSubscription = subscription); } }; - DebounceSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + DebounceSubscriber.prototype.notifyNext = function () { this.emitValue(); }; DebounceSubscriber.prototype.notifyComplete = function () { @@ -52653,22 +52849,22 @@ var DebounceSubscriber = /*@__PURE__*/ (function (_super) { var value = this.value; var subscription = this.durationSubscription; if (subscription) { - this.durationSubscription = null; + this.durationSubscription = undefined; subscription.unsubscribe(); this.remove(subscription); } - this.value = null; + this.value = undefined; this.hasValue = false; _super.prototype._next.call(this, value); } }; return DebounceSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleOuterSubscriber"])); //# sourceMappingURL=debounce.js.map /***/ }), -/* 415 */ +/* 418 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52744,7 +52940,7 @@ function dispatchNext(subscriber) { /***/ }), -/* 416 */ +/* 419 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52794,7 +52990,7 @@ var DefaultIfEmptySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 417 */ +/* 420 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52802,7 +52998,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "delay", function() { return delay; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(55); -/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(418); +/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(421); /* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(11); /* harmony import */ var _Notification__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(42); /** PURE_IMPORTS_START tslib,_scheduler_async,_util_isDate,_Subscriber,_Notification PURE_IMPORTS_END */ @@ -52901,7 +53097,7 @@ var DelayMessage = /*@__PURE__*/ (function () { /***/ }), -/* 418 */ +/* 421 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52915,7 +53111,7 @@ function isDate(value) { /***/ }), -/* 419 */ +/* 422 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52960,7 +53156,7 @@ var DelayWhenSubscriber = /*@__PURE__*/ (function (_super) { _this.index = 0; return _this; } - DelayWhenSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + DelayWhenSubscriber.prototype.notifyNext = function (outerValue, _innerValue, _outerIndex, _innerIndex, innerSub) { this.destination.next(outerValue); this.removeSubscription(innerSub); this.tryComplete(); @@ -53061,7 +53257,7 @@ var SubscriptionDelaySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 420 */ +/* 423 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53099,7 +53295,7 @@ var DeMaterializeSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 421 */ +/* 424 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53107,10 +53303,8 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "distinct", function() { return distinct; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DistinctSubscriber", function() { return DistinctSubscriber; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(69); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(70); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ - +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ function distinct(keySelector, flushes) { @@ -53133,14 +53327,14 @@ var DistinctSubscriber = /*@__PURE__*/ (function (_super) { _this.keySelector = keySelector; _this.values = new Set(); if (flushes) { - _this.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(_this, flushes)); + _this.add(Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["innerSubscribe"])(flushes, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleInnerSubscriber"](_this))); } return _this; } - DistinctSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + DistinctSubscriber.prototype.notifyNext = function () { this.values.clear(); }; - DistinctSubscriber.prototype.notifyError = function (error, innerSub) { + DistinctSubscriber.prototype.notifyError = function (error) { this._error(error); }; DistinctSubscriber.prototype._next = function (value) { @@ -53171,13 +53365,13 @@ var DistinctSubscriber = /*@__PURE__*/ (function (_super) { } }; return DistinctSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleOuterSubscriber"])); //# sourceMappingURL=distinct.js.map /***/ }), -/* 422 */ +/* 425 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53248,13 +53442,13 @@ var DistinctUntilChangedSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 423 */ +/* 426 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "distinctUntilKeyChanged", function() { return distinctUntilKeyChanged; }); -/* harmony import */ var _distinctUntilChanged__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(422); +/* harmony import */ var _distinctUntilChanged__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(425); /** PURE_IMPORTS_START _distinctUntilChanged PURE_IMPORTS_END */ function distinctUntilKeyChanged(key, compare) { @@ -53264,17 +53458,17 @@ function distinctUntilKeyChanged(key, compare) { /***/ }), -/* 424 */ +/* 427 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "elementAt", function() { return elementAt; }); /* harmony import */ var _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(62); -/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(104); -/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(425); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(416); -/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(426); +/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(105); +/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(428); +/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(419); +/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(429); /** PURE_IMPORTS_START _util_ArgumentOutOfRangeError,_filter,_throwIfEmpty,_defaultIfEmpty,_take PURE_IMPORTS_END */ @@ -53296,7 +53490,7 @@ function elementAt(index, defaultValue) { /***/ }), -/* 425 */ +/* 428 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53362,7 +53556,7 @@ function defaultErrorFactory() { /***/ }), -/* 426 */ +/* 429 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53424,7 +53618,7 @@ var TakeSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 427 */ +/* 430 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53446,7 +53640,7 @@ function endWith() { /***/ }), -/* 428 */ +/* 431 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53508,17 +53702,15 @@ var EverySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 429 */ +/* 432 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "exhaust", function() { return exhaust; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(69); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(70); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ - +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ function exhaust() { @@ -53543,7 +53735,7 @@ var SwitchFirstSubscriber = /*@__PURE__*/ (function (_super) { SwitchFirstSubscriber.prototype._next = function (value) { if (!this.hasSubscription) { this.hasSubscription = true; - this.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(this, value)); + this.add(Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["innerSubscribe"])(value, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleInnerSubscriber"](this))); } }; SwitchFirstSubscriber.prototype._complete = function () { @@ -53552,41 +53744,36 @@ var SwitchFirstSubscriber = /*@__PURE__*/ (function (_super) { this.destination.complete(); } }; - SwitchFirstSubscriber.prototype.notifyComplete = function (innerSub) { - this.remove(innerSub); + SwitchFirstSubscriber.prototype.notifyComplete = function () { this.hasSubscription = false; if (this.hasCompleted) { this.destination.complete(); } }; return SwitchFirstSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleOuterSubscriber"])); //# sourceMappingURL=exhaust.js.map /***/ }), -/* 430 */ +/* 433 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "exhaustMap", function() { return exhaustMap; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(69); -/* harmony import */ var _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(71); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(70); -/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(66); -/* harmony import */ var _observable_from__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(83); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_InnerSubscriber,_util_subscribeToResult,_map,_observable_from PURE_IMPORTS_END */ - - +/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(66); +/* harmony import */ var _observable_from__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(83); +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_map,_observable_from,_innerSubscribe PURE_IMPORTS_END */ function exhaustMap(project, resultSelector) { if (resultSelector) { - return function (source) { return source.pipe(exhaustMap(function (a, i) { return Object(_observable_from__WEBPACK_IMPORTED_MODULE_5__["from"])(project(a, i)).pipe(Object(_map__WEBPACK_IMPORTED_MODULE_4__["map"])(function (b, ii) { return resultSelector(a, b, i, ii); })); })); }; + return function (source) { return source.pipe(exhaustMap(function (a, i) { return Object(_observable_from__WEBPACK_IMPORTED_MODULE_2__["from"])(project(a, i)).pipe(Object(_map__WEBPACK_IMPORTED_MODULE_1__["map"])(function (b, ii) { return resultSelector(a, b, i, ii); })); })); }; } return function (source) { return source.lift(new ExhaustMapOperator(project)); @@ -53627,13 +53814,13 @@ var ExhaustMapSubscriber = /*@__PURE__*/ (function (_super) { return; } this.hasSubscription = true; - this._innerSub(result, value, index); + this._innerSub(result); }; - ExhaustMapSubscriber.prototype._innerSub = function (result, value, index) { - var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__["InnerSubscriber"](this, value, index); + ExhaustMapSubscriber.prototype._innerSub = function (result) { + var innerSubscriber = new _innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["SimpleInnerSubscriber"](this); var destination = this.destination; destination.add(innerSubscriber); - var innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, result, undefined, undefined, innerSubscriber); + var innerSubscription = Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["innerSubscribe"])(result, innerSubscriber); if (innerSubscription !== innerSubscriber) { destination.add(innerSubscription); } @@ -53645,27 +53832,25 @@ var ExhaustMapSubscriber = /*@__PURE__*/ (function (_super) { } this.unsubscribe(); }; - ExhaustMapSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + ExhaustMapSubscriber.prototype.notifyNext = function (innerValue) { this.destination.next(innerValue); }; ExhaustMapSubscriber.prototype.notifyError = function (err) { this.destination.error(err); }; - ExhaustMapSubscriber.prototype.notifyComplete = function (innerSub) { - var destination = this.destination; - destination.remove(innerSub); + ExhaustMapSubscriber.prototype.notifyComplete = function () { this.hasSubscription = false; if (this.hasCompleted) { this.destination.complete(); } }; return ExhaustMapSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["SimpleOuterSubscriber"])); //# sourceMappingURL=exhaustMap.js.map /***/ }), -/* 431 */ +/* 434 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53674,19 +53859,14 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ExpandOperator", function() { return ExpandOperator; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ExpandSubscriber", function() { return ExpandSubscriber; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(69); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(70); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ - +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ function expand(project, concurrent, scheduler) { if (concurrent === void 0) { concurrent = Number.POSITIVE_INFINITY; } - if (scheduler === void 0) { - scheduler = undefined; - } concurrent = (concurrent || 0) < 1 ? Number.POSITIVE_INFINITY : concurrent; return function (source) { return source.lift(new ExpandOperator(project, concurrent, scheduler)); }; } @@ -53753,7 +53933,7 @@ var ExpandSubscriber = /*@__PURE__*/ (function (_super) { ExpandSubscriber.prototype.subscribeToProjection = function (result, value, index) { this.active++; var destination = this.destination; - destination.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(this, result, value, index)); + destination.add(Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["innerSubscribe"])(result, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleInnerSubscriber"](this))); }; ExpandSubscriber.prototype._complete = function () { this.hasCompleted = true; @@ -53762,13 +53942,11 @@ var ExpandSubscriber = /*@__PURE__*/ (function (_super) { } this.unsubscribe(); }; - ExpandSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + ExpandSubscriber.prototype.notifyNext = function (innerValue) { this._next(innerValue); }; - ExpandSubscriber.prototype.notifyComplete = function (innerSub) { + ExpandSubscriber.prototype.notifyComplete = function () { var buffer = this.buffer; - var destination = this.destination; - destination.remove(innerSub); this.active--; if (buffer && buffer.length > 0) { this._next(buffer.shift()); @@ -53778,13 +53956,13 @@ var ExpandSubscriber = /*@__PURE__*/ (function (_super) { } }; return ExpandSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleOuterSubscriber"])); //# sourceMappingURL=expand.js.map /***/ }), -/* 432 */ +/* 435 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53822,7 +54000,7 @@ var FinallySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 433 */ +/* 436 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53894,13 +54072,13 @@ var FindValueSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 434 */ +/* 437 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findIndex", function() { return findIndex; }); -/* harmony import */ var _operators_find__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(433); +/* harmony import */ var _operators_find__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(436); /** PURE_IMPORTS_START _operators_find PURE_IMPORTS_END */ function findIndex(predicate, thisArg) { @@ -53910,17 +54088,17 @@ function findIndex(predicate, thisArg) { /***/ }), -/* 435 */ +/* 438 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "first", function() { return first; }); /* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(63); -/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(104); -/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(426); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(416); -/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(425); +/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(105); +/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(429); +/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(419); +/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(428); /* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(25); /** PURE_IMPORTS_START _util_EmptyError,_filter,_take,_defaultIfEmpty,_throwIfEmpty,_util_identity PURE_IMPORTS_END */ @@ -53937,7 +54115,7 @@ function first(predicate, defaultValue) { /***/ }), -/* 436 */ +/* 439 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53974,7 +54152,7 @@ var IgnoreElementsSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 437 */ +/* 440 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54018,17 +54196,17 @@ var IsEmptySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 438 */ +/* 441 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "last", function() { return last; }); /* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(63); -/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(104); -/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(439); -/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(425); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(416); +/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(105); +/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(442); +/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(428); +/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(419); /* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(25); /** PURE_IMPORTS_START _util_EmptyError,_filter,_takeLast,_throwIfEmpty,_defaultIfEmpty,_util_identity PURE_IMPORTS_END */ @@ -54045,7 +54223,7 @@ function last(predicate, defaultValue) { /***/ }), -/* 439 */ +/* 442 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54122,7 +54300,7 @@ var TakeLastSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 440 */ +/* 443 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54161,7 +54339,7 @@ var MapToSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 441 */ +/* 444 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54211,13 +54389,13 @@ var MaterializeSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 442 */ +/* 445 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "max", function() { return max; }); -/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(443); +/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(446); /** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ function max(comparer) { @@ -54230,15 +54408,15 @@ function max(comparer) { /***/ }), -/* 443 */ +/* 446 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "reduce", function() { return reduce; }); -/* harmony import */ var _scan__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(444); -/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(439); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(416); +/* harmony import */ var _scan__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(447); +/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(442); +/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(419); /* harmony import */ var _util_pipe__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(24); /** PURE_IMPORTS_START _scan,_takeLast,_defaultIfEmpty,_util_pipe PURE_IMPORTS_END */ @@ -54259,7 +54437,7 @@ function reduce(accumulator, seed) { /***/ }), -/* 444 */ +/* 447 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54341,13 +54519,13 @@ var ScanSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 445 */ +/* 448 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "merge", function() { return merge; }); -/* harmony import */ var _observable_merge__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(98); +/* harmony import */ var _observable_merge__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(99); /** PURE_IMPORTS_START _observable_merge PURE_IMPORTS_END */ function merge() { @@ -54361,7 +54539,7 @@ function merge() { /***/ }), -/* 446 */ +/* 449 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54386,7 +54564,7 @@ function mergeMapTo(innerObservable, resultSelector, concurrent) { /***/ }), -/* 447 */ +/* 450 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54395,12 +54573,8 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MergeScanOperator", function() { return MergeScanOperator; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MergeScanSubscriber", function() { return MergeScanSubscriber; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(70); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(69); -/* harmony import */ var _InnerSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(71); -/** PURE_IMPORTS_START tslib,_util_subscribeToResult,_OuterSubscriber,_InnerSubscriber PURE_IMPORTS_END */ - - +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ function mergeScan(accumulator, seed, concurrent) { @@ -54448,17 +54622,17 @@ var MergeScanSubscriber = /*@__PURE__*/ (function (_super) { return destination.error(e); } this.active++; - this._innerSub(ish, value, index); + this._innerSub(ish); } else { this.buffer.push(value); } }; - MergeScanSubscriber.prototype._innerSub = function (ish, value, index) { - var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_3__["InnerSubscriber"](this, value, index); + MergeScanSubscriber.prototype._innerSub = function (ish) { + var innerSubscriber = new _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleInnerSubscriber"](this); var destination = this.destination; destination.add(innerSubscriber); - var innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_1__["subscribeToResult"])(this, ish, undefined, undefined, innerSubscriber); + var innerSubscription = Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["innerSubscribe"])(ish, innerSubscriber); if (innerSubscription !== innerSubscriber) { destination.add(innerSubscription); } @@ -54473,16 +54647,14 @@ var MergeScanSubscriber = /*@__PURE__*/ (function (_super) { } this.unsubscribe(); }; - MergeScanSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + MergeScanSubscriber.prototype.notifyNext = function (innerValue) { var destination = this.destination; this.acc = innerValue; this.hasValue = true; destination.next(innerValue); }; - MergeScanSubscriber.prototype.notifyComplete = function (innerSub) { + MergeScanSubscriber.prototype.notifyComplete = function () { var buffer = this.buffer; - var destination = this.destination; - destination.remove(innerSub); this.active--; if (buffer.length > 0) { this._next(buffer.shift()); @@ -54495,19 +54667,19 @@ var MergeScanSubscriber = /*@__PURE__*/ (function (_super) { } }; return MergeScanSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleOuterSubscriber"])); //# sourceMappingURL=mergeScan.js.map /***/ }), -/* 448 */ +/* 451 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "min", function() { return min; }); -/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(443); +/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(446); /** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ function min(comparer) { @@ -54520,7 +54692,7 @@ function min(comparer) { /***/ }), -/* 449 */ +/* 452 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54569,7 +54741,7 @@ var MulticastOperator = /*@__PURE__*/ (function () { /***/ }), -/* 450 */ +/* 453 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54579,12 +54751,8 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _observable_from__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(83); /* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(18); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(69); -/* harmony import */ var _InnerSubscriber__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(71); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(70); -/** PURE_IMPORTS_START tslib,_observable_from,_util_isArray,_OuterSubscriber,_InnerSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ - - +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_observable_from,_util_isArray,_innerSubscribe PURE_IMPORTS_END */ @@ -54604,12 +54772,12 @@ function onErrorResumeNextStatic() { for (var _i = 0; _i < arguments.length; _i++) { nextSources[_i] = arguments[_i]; } - var source = null; + var source = undefined; if (nextSources.length === 1 && Object(_util_isArray__WEBPACK_IMPORTED_MODULE_2__["isArray"])(nextSources[0])) { nextSources = nextSources[0]; } source = nextSources.shift(); - return Object(_observable_from__WEBPACK_IMPORTED_MODULE_1__["from"])(source, null).lift(new OnErrorResumeNextOperator(nextSources)); + return Object(_observable_from__WEBPACK_IMPORTED_MODULE_1__["from"])(source).lift(new OnErrorResumeNextOperator(nextSources)); } var OnErrorResumeNextOperator = /*@__PURE__*/ (function () { function OnErrorResumeNextOperator(nextSources) { @@ -54628,10 +54796,10 @@ var OnErrorResumeNextSubscriber = /*@__PURE__*/ (function (_super) { _this.nextSources = nextSources; return _this; } - OnErrorResumeNextSubscriber.prototype.notifyError = function (error, innerSub) { + OnErrorResumeNextSubscriber.prototype.notifyError = function () { this.subscribeToNextSource(); }; - OnErrorResumeNextSubscriber.prototype.notifyComplete = function (innerSub) { + OnErrorResumeNextSubscriber.prototype.notifyComplete = function () { this.subscribeToNextSource(); }; OnErrorResumeNextSubscriber.prototype._error = function (err) { @@ -54645,10 +54813,10 @@ var OnErrorResumeNextSubscriber = /*@__PURE__*/ (function (_super) { OnErrorResumeNextSubscriber.prototype.subscribeToNextSource = function () { var next = this.nextSources.shift(); if (!!next) { - var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_4__["InnerSubscriber"](this, undefined, undefined); + var innerSubscriber = new _innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["SimpleInnerSubscriber"](this); var destination = this.destination; destination.add(innerSubscriber); - var innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_5__["subscribeToResult"])(this, next, undefined, undefined, innerSubscriber); + var innerSubscription = Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["innerSubscribe"])(next, innerSubscriber); if (innerSubscription !== innerSubscriber) { destination.add(innerSubscription); } @@ -54658,12 +54826,12 @@ var OnErrorResumeNextSubscriber = /*@__PURE__*/ (function (_super) { } }; return OnErrorResumeNextSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__["OuterSubscriber"])); +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["SimpleOuterSubscriber"])); //# sourceMappingURL=onErrorResumeNext.js.map /***/ }), -/* 451 */ +/* 454 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54711,14 +54879,14 @@ var PairwiseSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 452 */ +/* 455 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "partition", function() { return partition; }); -/* harmony import */ var _util_not__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(103); -/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(104); +/* harmony import */ var _util_not__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(104); +/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(105); /** PURE_IMPORTS_START _util_not,_filter PURE_IMPORTS_END */ @@ -54734,7 +54902,7 @@ function partition(predicate, thisArg) { /***/ }), -/* 453 */ +/* 456 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54758,8 +54926,8 @@ function plucker(props, length) { var mapper = function (x) { var currentProp = x; for (var i = 0; i < length; i++) { - var p = currentProp[props[i]]; - if (typeof p !== 'undefined') { + var p = currentProp != null ? currentProp[props[i]] : undefined; + if (p !== void 0) { currentProp = p; } else { @@ -54774,14 +54942,14 @@ function plucker(props, length) { /***/ }), -/* 454 */ +/* 457 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publish", function() { return publish; }); /* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(449); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(452); /** PURE_IMPORTS_START _Subject,_multicast PURE_IMPORTS_END */ @@ -54794,14 +54962,14 @@ function publish(selector) { /***/ }), -/* 455 */ +/* 458 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publishBehavior", function() { return publishBehavior; }); /* harmony import */ var _BehaviorSubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(32); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(449); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(452); /** PURE_IMPORTS_START _BehaviorSubject,_multicast PURE_IMPORTS_END */ @@ -54812,14 +54980,14 @@ function publishBehavior(value) { /***/ }), -/* 456 */ +/* 459 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publishLast", function() { return publishLast; }); /* harmony import */ var _AsyncSubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(449); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(452); /** PURE_IMPORTS_START _AsyncSubject,_multicast PURE_IMPORTS_END */ @@ -54830,14 +54998,14 @@ function publishLast() { /***/ }), -/* 457 */ +/* 460 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publishReplay", function() { return publishReplay; }); /* harmony import */ var _ReplaySubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(33); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(449); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(452); /** PURE_IMPORTS_START _ReplaySubject,_multicast PURE_IMPORTS_END */ @@ -54853,14 +55021,14 @@ function publishReplay(bufferSize, windowTime, selectorOrScheduler, scheduler) { /***/ }), -/* 458 */ +/* 461 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "race", function() { return race; }); /* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(18); -/* harmony import */ var _observable_race__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(105); +/* harmony import */ var _observable_race__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(106); /** PURE_IMPORTS_START _util_isArray,_observable_race PURE_IMPORTS_END */ @@ -54880,7 +55048,7 @@ function race() { /***/ }), -/* 459 */ +/* 462 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54945,7 +55113,7 @@ var RepeatSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 460 */ +/* 463 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54953,10 +55121,8 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "repeatWhen", function() { return repeatWhen; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(69); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(70); -/** PURE_IMPORTS_START tslib,_Subject,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ - +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_Subject,_innerSubscribe PURE_IMPORTS_END */ @@ -54981,11 +55147,11 @@ var RepeatWhenSubscriber = /*@__PURE__*/ (function (_super) { _this.sourceIsBeingSubscribedTo = true; return _this; } - RepeatWhenSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + RepeatWhenSubscriber.prototype.notifyNext = function () { this.sourceIsBeingSubscribedTo = true; this.source.subscribe(this); }; - RepeatWhenSubscriber.prototype.notifyComplete = function (innerSub) { + RepeatWhenSubscriber.prototype.notifyComplete = function () { if (this.sourceIsBeingSubscribedTo === false) { return _super.prototype.complete.call(this); } @@ -55000,20 +55166,20 @@ var RepeatWhenSubscriber = /*@__PURE__*/ (function (_super) { return _super.prototype.complete.call(this); } this._unsubscribeAndRecycle(); - this.notifications.next(); + this.notifications.next(undefined); } }; RepeatWhenSubscriber.prototype._unsubscribe = function () { var _a = this, notifications = _a.notifications, retriesSubscription = _a.retriesSubscription; if (notifications) { notifications.unsubscribe(); - this.notifications = null; + this.notifications = undefined; } if (retriesSubscription) { retriesSubscription.unsubscribe(); - this.retriesSubscription = null; + this.retriesSubscription = undefined; } - this.retries = null; + this.retries = undefined; }; RepeatWhenSubscriber.prototype._unsubscribeAndRecycle = function () { var _unsubscribe = this._unsubscribe; @@ -55033,15 +55199,15 @@ var RepeatWhenSubscriber = /*@__PURE__*/ (function (_super) { return _super.prototype.complete.call(this); } this.retries = retries; - this.retriesSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, retries); + this.retriesSubscription = Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_2__["innerSubscribe"])(retries, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_2__["SimpleInnerSubscriber"](this)); }; return RepeatWhenSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_2__["SimpleOuterSubscriber"])); //# sourceMappingURL=repeatWhen.js.map /***/ }), -/* 461 */ +/* 464 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55094,7 +55260,7 @@ var RetrySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 462 */ +/* 465 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55102,10 +55268,8 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "retryWhen", function() { return retryWhen; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(69); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(70); -/** PURE_IMPORTS_START tslib,_Subject,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ - +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_Subject,_innerSubscribe PURE_IMPORTS_END */ @@ -55144,11 +55308,11 @@ var RetryWhenSubscriber = /*@__PURE__*/ (function (_super) { catch (e) { return _super.prototype.error.call(this, e); } - retriesSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, retries); + retriesSubscription = Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_2__["innerSubscribe"])(retries, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_2__["SimpleInnerSubscriber"](this)); } else { - this.errors = null; - this.retriesSubscription = null; + this.errors = undefined; + this.retriesSubscription = undefined; } this._unsubscribeAndRecycle(); this.errors = errors; @@ -55161,15 +55325,15 @@ var RetryWhenSubscriber = /*@__PURE__*/ (function (_super) { var _a = this, errors = _a.errors, retriesSubscription = _a.retriesSubscription; if (errors) { errors.unsubscribe(); - this.errors = null; + this.errors = undefined; } if (retriesSubscription) { retriesSubscription.unsubscribe(); - this.retriesSubscription = null; + this.retriesSubscription = undefined; } - this.retries = null; + this.retries = undefined; }; - RetryWhenSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + RetryWhenSubscriber.prototype.notifyNext = function () { var _unsubscribe = this._unsubscribe; this._unsubscribe = null; this._unsubscribeAndRecycle(); @@ -55177,22 +55341,20 @@ var RetryWhenSubscriber = /*@__PURE__*/ (function (_super) { this.source.subscribe(this); }; return RetryWhenSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_2__["SimpleOuterSubscriber"])); //# sourceMappingURL=retryWhen.js.map /***/ }), -/* 463 */ +/* 466 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sample", function() { return sample; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(69); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(70); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ - +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ function sample(notifier) { @@ -55205,7 +55367,7 @@ var SampleOperator = /*@__PURE__*/ (function () { SampleOperator.prototype.call = function (subscriber, source) { var sampleSubscriber = new SampleSubscriber(subscriber); var subscription = source.subscribe(sampleSubscriber); - subscription.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(sampleSubscriber, this.notifier)); + subscription.add(Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["innerSubscribe"])(this.notifier, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleInnerSubscriber"](sampleSubscriber))); return subscription; }; return SampleOperator; @@ -55221,7 +55383,7 @@ var SampleSubscriber = /*@__PURE__*/ (function (_super) { this.value = value; this.hasValue = true; }; - SampleSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + SampleSubscriber.prototype.notifyNext = function () { this.emitValue(); }; SampleSubscriber.prototype.notifyComplete = function () { @@ -55234,12 +55396,12 @@ var SampleSubscriber = /*@__PURE__*/ (function (_super) { } }; return SampleSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleOuterSubscriber"])); //# sourceMappingURL=sample.js.map /***/ }), -/* 464 */ +/* 467 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55299,7 +55461,7 @@ function dispatchNotification(state) { /***/ }), -/* 465 */ +/* 468 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55422,13 +55584,13 @@ var SequenceEqualCompareToSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 466 */ +/* 469 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "share", function() { return share; }); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(449); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(452); /* harmony import */ var _refCount__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30); /* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(27); /** PURE_IMPORTS_START _multicast,_refCount,_Subject PURE_IMPORTS_END */ @@ -55445,7 +55607,7 @@ function share() { /***/ }), -/* 467 */ +/* 470 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55478,9 +55640,11 @@ function shareReplayOperator(_a) { var isComplete = false; return function shareReplayOperation(source) { refCount++; + var innerSub; if (!subject || hasError) { hasError = false; subject = new _ReplaySubject__WEBPACK_IMPORTED_MODULE_0__["ReplaySubject"](bufferSize, windowTime, scheduler); + innerSub = subject.subscribe(this); subscription = source.subscribe({ next: function (value) { subject.next(value); }, error: function (err) { @@ -55494,7 +55658,9 @@ function shareReplayOperator(_a) { }, }); } - var innerSub = subject.subscribe(this); + else { + innerSub = subject.subscribe(this); + } this.add(function () { refCount--; innerSub.unsubscribe(); @@ -55510,7 +55676,7 @@ function shareReplayOperator(_a) { /***/ }), -/* 468 */ +/* 471 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55590,7 +55756,7 @@ var SingleSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 469 */ +/* 472 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55632,7 +55798,7 @@ var SkipSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 470 */ +/* 473 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55694,19 +55860,15 @@ var SkipLastSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 471 */ +/* 474 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "skipUntil", function() { return skipUntil; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(69); -/* harmony import */ var _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(71); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(70); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_InnerSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ - - +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ function skipUntil(notifier) { @@ -55726,10 +55888,10 @@ var SkipUntilSubscriber = /*@__PURE__*/ (function (_super) { function SkipUntilSubscriber(destination, notifier) { var _this = _super.call(this, destination) || this; _this.hasValue = false; - var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__["InnerSubscriber"](_this, undefined, undefined); + var innerSubscriber = new _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleInnerSubscriber"](_this); _this.add(innerSubscriber); _this.innerSubscription = innerSubscriber; - var innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(_this, notifier, undefined, undefined, innerSubscriber); + var innerSubscription = Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["innerSubscribe"])(notifier, innerSubscriber); if (innerSubscription !== innerSubscriber) { _this.add(innerSubscription); _this.innerSubscription = innerSubscription; @@ -55741,7 +55903,7 @@ var SkipUntilSubscriber = /*@__PURE__*/ (function (_super) { _super.prototype._next.call(this, value); } }; - SkipUntilSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + SkipUntilSubscriber.prototype.notifyNext = function () { this.hasValue = true; if (this.innerSubscription) { this.innerSubscription.unsubscribe(); @@ -55750,12 +55912,12 @@ var SkipUntilSubscriber = /*@__PURE__*/ (function (_super) { SkipUntilSubscriber.prototype.notifyComplete = function () { }; return SkipUntilSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleOuterSubscriber"])); //# sourceMappingURL=skipUntil.js.map /***/ }), -/* 472 */ +/* 475 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55811,7 +55973,7 @@ var SkipWhileSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 473 */ +/* 476 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55840,13 +56002,13 @@ function startWith() { /***/ }), -/* 474 */ +/* 477 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "subscribeOn", function() { return subscribeOn; }); -/* harmony import */ var _observable_SubscribeOnObservable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(475); +/* harmony import */ var _observable_SubscribeOnObservable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(478); /** PURE_IMPORTS_START _observable_SubscribeOnObservable PURE_IMPORTS_END */ function subscribeOn(scheduler, delay) { @@ -55871,7 +56033,7 @@ var SubscribeOnOperator = /*@__PURE__*/ (function () { /***/ }), -/* 475 */ +/* 478 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55880,7 +56042,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9); /* harmony import */ var _scheduler_asap__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(51); -/* harmony import */ var _util_isNumeric__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(97); +/* harmony import */ var _util_isNumeric__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(98); /** PURE_IMPORTS_START tslib,_Observable,_scheduler_asap,_util_isNumeric PURE_IMPORTS_END */ @@ -55935,13 +56097,13 @@ var SubscribeOnObservable = /*@__PURE__*/ (function (_super) { /***/ }), -/* 476 */ +/* 479 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "switchAll", function() { return switchAll; }); -/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(477); +/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(480); /* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(25); /** PURE_IMPORTS_START _switchMap,_util_identity PURE_IMPORTS_END */ @@ -55953,28 +56115,24 @@ function switchAll() { /***/ }), -/* 477 */ +/* 480 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "switchMap", function() { return switchMap; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(69); -/* harmony import */ var _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(71); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(70); -/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(66); -/* harmony import */ var _observable_from__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(83); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_InnerSubscriber,_util_subscribeToResult,_map,_observable_from PURE_IMPORTS_END */ - - +/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(66); +/* harmony import */ var _observable_from__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(83); +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_map,_observable_from,_innerSubscribe PURE_IMPORTS_END */ function switchMap(project, resultSelector) { if (typeof resultSelector === 'function') { - return function (source) { return source.pipe(switchMap(function (a, i) { return Object(_observable_from__WEBPACK_IMPORTED_MODULE_5__["from"])(project(a, i)).pipe(Object(_map__WEBPACK_IMPORTED_MODULE_4__["map"])(function (b, ii) { return resultSelector(a, b, i, ii); })); })); }; + return function (source) { return source.pipe(switchMap(function (a, i) { return Object(_observable_from__WEBPACK_IMPORTED_MODULE_2__["from"])(project(a, i)).pipe(Object(_map__WEBPACK_IMPORTED_MODULE_1__["map"])(function (b, ii) { return resultSelector(a, b, i, ii); })); })); }; } return function (source) { return source.lift(new SwitchMapOperator(project)); }; } @@ -56005,17 +56163,17 @@ var SwitchMapSubscriber = /*@__PURE__*/ (function (_super) { this.destination.error(error); return; } - this._innerSub(result, value, index); + this._innerSub(result); }; - SwitchMapSubscriber.prototype._innerSub = function (result, value, index) { + SwitchMapSubscriber.prototype._innerSub = function (result) { var innerSubscription = this.innerSubscription; if (innerSubscription) { innerSubscription.unsubscribe(); } - var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__["InnerSubscriber"](this, value, index); + var innerSubscriber = new _innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["SimpleInnerSubscriber"](this); var destination = this.destination; destination.add(innerSubscriber); - this.innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, result, undefined, undefined, innerSubscriber); + this.innerSubscription = Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["innerSubscribe"])(result, innerSubscriber); if (this.innerSubscription !== innerSubscriber) { destination.add(this.innerSubscription); } @@ -56028,32 +56186,30 @@ var SwitchMapSubscriber = /*@__PURE__*/ (function (_super) { this.unsubscribe(); }; SwitchMapSubscriber.prototype._unsubscribe = function () { - this.innerSubscription = null; + this.innerSubscription = undefined; }; - SwitchMapSubscriber.prototype.notifyComplete = function (innerSub) { - var destination = this.destination; - destination.remove(innerSub); - this.innerSubscription = null; + SwitchMapSubscriber.prototype.notifyComplete = function () { + this.innerSubscription = undefined; if (this.isStopped) { _super.prototype._complete.call(this); } }; - SwitchMapSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + SwitchMapSubscriber.prototype.notifyNext = function (innerValue) { this.destination.next(innerValue); }; return SwitchMapSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["SimpleOuterSubscriber"])); //# sourceMappingURL=switchMap.js.map /***/ }), -/* 478 */ +/* 481 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "switchMapTo", function() { return switchMapTo; }); -/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(477); +/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(480); /** PURE_IMPORTS_START _switchMap PURE_IMPORTS_END */ function switchMapTo(innerObservable, resultSelector) { @@ -56063,17 +56219,15 @@ function switchMapTo(innerObservable, resultSelector) { /***/ }), -/* 479 */ +/* 482 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "takeUntil", function() { return takeUntil; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(69); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(70); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ - +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ function takeUntil(notifier) { @@ -56085,7 +56239,7 @@ var TakeUntilOperator = /*@__PURE__*/ (function () { } TakeUntilOperator.prototype.call = function (subscriber, source) { var takeUntilSubscriber = new TakeUntilSubscriber(subscriber); - var notifierSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(takeUntilSubscriber, this.notifier); + var notifierSubscription = Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["innerSubscribe"])(this.notifier, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleInnerSubscriber"](takeUntilSubscriber)); if (notifierSubscription && !takeUntilSubscriber.seenValue) { takeUntilSubscriber.add(notifierSubscription); return source.subscribe(takeUntilSubscriber); @@ -56101,19 +56255,19 @@ var TakeUntilSubscriber = /*@__PURE__*/ (function (_super) { _this.seenValue = false; return _this; } - TakeUntilSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + TakeUntilSubscriber.prototype.notifyNext = function () { this.seenValue = true; this.complete(); }; TakeUntilSubscriber.prototype.notifyComplete = function () { }; return TakeUntilSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleOuterSubscriber"])); //# sourceMappingURL=takeUntil.js.map /***/ }), -/* 480 */ +/* 483 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56181,7 +56335,7 @@ var TakeWhileSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 481 */ +/* 484 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56269,7 +56423,7 @@ var TapSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 482 */ +/* 485 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56277,10 +56431,8 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "defaultThrottleConfig", function() { return defaultThrottleConfig; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "throttle", function() { return throttle; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(69); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(70); -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ - +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ var defaultThrottleConfig = { @@ -56291,7 +56443,7 @@ function throttle(durationSelector, config) { if (config === void 0) { config = defaultThrottleConfig; } - return function (source) { return source.lift(new ThrottleOperator(durationSelector, config.leading, config.trailing)); }; + return function (source) { return source.lift(new ThrottleOperator(durationSelector, !!config.leading, !!config.trailing)); }; } var ThrottleOperator = /*@__PURE__*/ (function () { function ThrottleOperator(durationSelector, leading, trailing) { @@ -56334,12 +56486,12 @@ var ThrottleSubscriber = /*@__PURE__*/ (function (_super) { this.throttle(_sendValue); } this._hasValue = false; - this._sendValue = null; + this._sendValue = undefined; }; ThrottleSubscriber.prototype.throttle = function (value) { var duration = this.tryDurationSelector(value); if (!!duration) { - this.add(this._throttled = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(this, duration)); + this.add(this._throttled = Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["innerSubscribe"])(duration, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleInnerSubscriber"](this))); } }; ThrottleSubscriber.prototype.tryDurationSelector = function (value) { @@ -56356,24 +56508,24 @@ var ThrottleSubscriber = /*@__PURE__*/ (function (_super) { if (_throttled) { _throttled.unsubscribe(); } - this._throttled = null; + this._throttled = undefined; if (_trailing) { this.send(); } }; - ThrottleSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + ThrottleSubscriber.prototype.notifyNext = function () { this.throttlingDone(); }; ThrottleSubscriber.prototype.notifyComplete = function () { this.throttlingDone(); }; return ThrottleSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleOuterSubscriber"])); //# sourceMappingURL=throttle.js.map /***/ }), -/* 483 */ +/* 486 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56382,7 +56534,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(55); -/* harmony import */ var _throttle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(482); +/* harmony import */ var _throttle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(485); /** PURE_IMPORTS_START tslib,_Subscriber,_scheduler_async,_throttle PURE_IMPORTS_END */ @@ -56471,7 +56623,7 @@ function dispatchNext(arg) { /***/ }), -/* 484 */ +/* 487 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56479,8 +56631,8 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timeInterval", function() { return timeInterval; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TimeInterval", function() { return TimeInterval; }); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(55); -/* harmony import */ var _scan__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(444); -/* harmony import */ var _observable_defer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(90); +/* harmony import */ var _scan__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(447); +/* harmony import */ var _observable_defer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(91); /* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(66); /** PURE_IMPORTS_START _scheduler_async,_scan,_observable_defer,_map PURE_IMPORTS_END */ @@ -56515,7 +56667,7 @@ var TimeInterval = /*@__PURE__*/ (function () { /***/ }), -/* 485 */ +/* 488 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56523,7 +56675,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timeout", function() { return timeout; }); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(55); /* harmony import */ var _util_TimeoutError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(64); -/* harmony import */ var _timeoutWith__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(486); +/* harmony import */ var _timeoutWith__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(489); /* harmony import */ var _observable_throwError__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(49); /** PURE_IMPORTS_START _scheduler_async,_util_TimeoutError,_timeoutWith,_observable_throwError PURE_IMPORTS_END */ @@ -56540,7 +56692,7 @@ function timeout(due, scheduler) { /***/ }), -/* 486 */ +/* 489 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56548,11 +56700,9 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timeoutWith", function() { return timeoutWith; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(55); -/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(418); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(69); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(70); -/** PURE_IMPORTS_START tslib,_scheduler_async,_util_isDate,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ - +/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(421); +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_scheduler_async,_util_isDate,_innerSubscribe PURE_IMPORTS_END */ @@ -56587,14 +56737,13 @@ var TimeoutWithSubscriber = /*@__PURE__*/ (function (_super) { _this.waitFor = waitFor; _this.withObservable = withObservable; _this.scheduler = scheduler; - _this.action = null; _this.scheduleTimeout(); return _this; } TimeoutWithSubscriber.dispatchTimeout = function (subscriber) { var withObservable = subscriber.withObservable; subscriber._unsubscribeAndRecycle(); - subscriber.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__["subscribeToResult"])(subscriber, withObservable)); + subscriber.add(Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["innerSubscribe"])(withObservable, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["SimpleInnerSubscriber"](subscriber))); }; TimeoutWithSubscriber.prototype.scheduleTimeout = function () { var action = this.action; @@ -56612,17 +56761,17 @@ var TimeoutWithSubscriber = /*@__PURE__*/ (function (_super) { _super.prototype._next.call(this, value); }; TimeoutWithSubscriber.prototype._unsubscribe = function () { - this.action = null; + this.action = undefined; this.scheduler = null; this.withObservable = null; }; return TimeoutWithSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__["OuterSubscriber"])); +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["SimpleOuterSubscriber"])); //# sourceMappingURL=timeoutWith.js.map /***/ }), -/* 487 */ +/* 490 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56652,13 +56801,13 @@ var Timestamp = /*@__PURE__*/ (function () { /***/ }), -/* 488 */ +/* 491 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "toArray", function() { return toArray; }); -/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(443); +/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(446); /** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ function toArrayReducer(arr, item, index) { @@ -56675,7 +56824,7 @@ function toArray() { /***/ }), -/* 489 */ +/* 492 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56683,10 +56832,8 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "window", function() { return window; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(69); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(70); -/** PURE_IMPORTS_START tslib,_Subject,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ - +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_Subject,_innerSubscribe PURE_IMPORTS_END */ @@ -56703,7 +56850,7 @@ var WindowOperator = /*@__PURE__*/ (function () { var windowSubscriber = new WindowSubscriber(subscriber); var sourceSubscription = source.subscribe(windowSubscriber); if (!sourceSubscription.closed) { - windowSubscriber.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(windowSubscriber, this.windowBoundaries)); + windowSubscriber.add(Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_2__["innerSubscribe"])(this.windowBoundaries, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_2__["SimpleInnerSubscriber"](windowSubscriber))); } return sourceSubscription; }; @@ -56717,13 +56864,13 @@ var WindowSubscriber = /*@__PURE__*/ (function (_super) { destination.next(_this.window); return _this; } - WindowSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + WindowSubscriber.prototype.notifyNext = function () { this.openWindow(); }; - WindowSubscriber.prototype.notifyError = function (error, innerSub) { + WindowSubscriber.prototype.notifyError = function (error) { this._error(error); }; - WindowSubscriber.prototype.notifyComplete = function (innerSub) { + WindowSubscriber.prototype.notifyComplete = function () { this._complete(); }; WindowSubscriber.prototype._next = function (value) { @@ -56750,12 +56897,12 @@ var WindowSubscriber = /*@__PURE__*/ (function (_super) { destination.next(newWindow); }; return WindowSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_2__["SimpleOuterSubscriber"])); //# sourceMappingURL=window.js.map /***/ }), -/* 490 */ +/* 493 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56845,7 +56992,7 @@ var WindowCountSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 491 */ +/* 494 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56855,7 +57002,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(55); /* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(11); -/* harmony import */ var _util_isNumeric__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(97); +/* harmony import */ var _util_isNumeric__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(98); /* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(45); /** PURE_IMPORTS_START tslib,_Subject,_scheduler_async,_Subscriber,_util_isNumeric,_util_isScheduler PURE_IMPORTS_END */ @@ -56875,13 +57022,13 @@ function windowTime(windowTimeSpan) { scheduler = arguments[2]; } else if (Object(_util_isNumeric__WEBPACK_IMPORTED_MODULE_4__["isNumeric"])(arguments[2])) { - maxWindowSize = arguments[2]; + maxWindowSize = Number(arguments[2]); } if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_5__["isScheduler"])(arguments[1])) { scheduler = arguments[1]; } else if (Object(_util_isNumeric__WEBPACK_IMPORTED_MODULE_4__["isNumeric"])(arguments[1])) { - windowCreationInterval = arguments[1]; + windowCreationInterval = Number(arguments[1]); } return function windowTimeOperatorFunction(source) { return source.lift(new WindowTimeOperator(windowTimeSpan, windowCreationInterval, maxWindowSize, scheduler)); @@ -57015,7 +57162,7 @@ function dispatchWindowClose(state) { /***/ }), -/* 492 */ +/* 495 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57158,7 +57305,7 @@ var WindowToggleSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 493 */ +/* 496 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57196,10 +57343,10 @@ var WindowSubscriber = /*@__PURE__*/ (function (_super) { _this.openWindow(); return _this; } - WindowSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + WindowSubscriber.prototype.notifyNext = function (_outerValue, _innerValue, _outerIndex, _innerIndex, innerSub) { this.openWindow(innerSub); }; - WindowSubscriber.prototype.notifyError = function (error, innerSub) { + WindowSubscriber.prototype.notifyError = function (error) { this._error(error); }; WindowSubscriber.prototype.notifyComplete = function (innerSub) { @@ -57255,7 +57402,7 @@ var WindowSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 494 */ +/* 497 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57306,11 +57453,11 @@ var WithLatestFromSubscriber = /*@__PURE__*/ (function (_super) { } for (var i = 0; i < len; i++) { var observable = observables[i]; - _this.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(_this, observable, observable, i)); + _this.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(_this, observable, undefined, i)); } return _this; } - WithLatestFromSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + WithLatestFromSubscriber.prototype.notifyNext = function (_outerValue, innerValue, outerIndex) { this.values[outerIndex] = innerValue; var toRespond = this.toRespond; if (toRespond.length > 0) { @@ -57350,13 +57497,13 @@ var WithLatestFromSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 495 */ +/* 498 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "zip", function() { return zip; }); -/* harmony import */ var _observable_zip__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(109); +/* harmony import */ var _observable_zip__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(110); /** PURE_IMPORTS_START _observable_zip PURE_IMPORTS_END */ function zip() { @@ -57372,13 +57519,13 @@ function zip() { /***/ }), -/* 496 */ +/* 499 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "zipAll", function() { return zipAll; }); -/* harmony import */ var _observable_zip__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(109); +/* harmony import */ var _observable_zip__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(110); /** PURE_IMPORTS_START _observable_zip PURE_IMPORTS_END */ function zipAll(project) { @@ -57388,17 +57535,17 @@ function zipAll(project) { /***/ }), -/* 497 */ +/* 500 */ /***/ (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 _utils_errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(162); -/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); -/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(145); -/* harmony import */ var _utils_projects_tree__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(498); -/* harmony import */ var _utils_kibana__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(499); +/* harmony import */ var _utils_errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(163); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(144); +/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(146); +/* harmony import */ var _utils_projects_tree__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(501); +/* harmony import */ var _utils_kibana__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(502); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } @@ -57480,13 +57627,13 @@ function toArray(value) { } /***/ }), -/* 498 */ +/* 501 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __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__(227); +/* harmony import */ var chalk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(113); /* 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__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__); @@ -57633,7 +57780,7 @@ function addProjectToTree(tree, pathParts, project) { } /***/ }), -/* 499 */ +/* 502 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57641,13 +57788,13 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Kibana", function() { return Kibana; }); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var multimatch__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(500); +/* harmony import */ var multimatch__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(503); /* harmony import */ var multimatch__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(multimatch__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var is_path_inside__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(370); +/* harmony import */ var is_path_inside__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(361); /* harmony import */ var is_path_inside__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(is_path_inside__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _yarn_lock__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(283); -/* harmony import */ var _projects__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(145); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(280); +/* harmony import */ var _yarn_lock__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(275); +/* harmony import */ var _projects__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(146); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(272); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } @@ -57809,15 +57956,15 @@ class Kibana { } /***/ }), -/* 500 */ +/* 503 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const minimatch = __webpack_require__(149); -const arrayUnion = __webpack_require__(501); -const arrayDiffer = __webpack_require__(502); -const arrify = __webpack_require__(503); +const minimatch = __webpack_require__(150); +const arrayUnion = __webpack_require__(504); +const arrayDiffer = __webpack_require__(505); +const arrify = __webpack_require__(506); module.exports = (list, patterns, options = {}) => { list = arrify(list); @@ -57841,7 +57988,7 @@ module.exports = (list, patterns, options = {}) => { /***/ }), -/* 501 */ +/* 504 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57853,7 +58000,7 @@ module.exports = (...arguments_) => { /***/ }), -/* 502 */ +/* 505 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57867,444 +58014,12 @@ const arrayDiffer = (array, ...values) => { module.exports = arrayDiffer; -/***/ }), -/* 503 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -const arrify = value => { - if (value === null || value === undefined) { - return []; - } - - if (Array.isArray(value)) { - return value; - } - - if (typeof value === 'string') { - return [value]; - } - - if (typeof value[Symbol.iterator] === 'function') { - return [...value]; - } - - return [value]; -}; - -module.exports = arrify; - - -/***/ }), -/* 504 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _build_production_projects__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(505); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return _build_production_projects__WEBPACK_IMPORTED_MODULE_0__["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. - */ - - -/***/ }), -/* 505 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return buildProductionProjects; }); -/* harmony import */ var cpy__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(506); -/* harmony import */ var cpy__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(cpy__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(289); -/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(del__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4); -/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(280); -/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(130); -/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(143); -/* harmony import */ var _utils_package_json__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(164); -/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(145); -/* - * 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 buildProductionProjects({ - kibanaRoot, - buildRoot, - onlyOSS -}) { - const projects = await getProductionProjects(kibanaRoot, onlyOSS); - 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"].info(`Preparing production build for [${projectNames.join(', ')}]`); - - for (const batch of batchedProjects) { - for (const project of batch) { - await deleteTarget(project); - await buildProject(project); - 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, - * and let Kibana's build process be responsible for installing dependencies, - * we only include Kibana's transitive _production_ dependencies. If onlyOSS - * is supplied, we omit projects with build.oss in their package.json set to false. - */ - -async function getProductionProjects(rootPath, onlyOSS) { - const projectPaths = Object(_config__WEBPACK_IMPORTED_MODULE_3__["getProjectPaths"])({ - rootPath - }); - const projects = await Object(_utils_projects__WEBPACK_IMPORTED_MODULE_7__["getProjects"])(rootPath, projectPaths); - const projectsSubset = [projects.get('kibana')]; - - if (projects.has('x-pack')) { - projectsSubset.push(projects.get('x-pack')); - } - - const productionProjects = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_7__["includeTransitiveProjects"])(projectsSubset, projects, { - onlyProductionDependencies: true - }); // We remove Kibana, as we're already building Kibana - - productionProjects.delete('kibana'); - - if (onlyOSS) { - productionProjects.forEach(project => { - if (project.getBuildConfig().oss === false) { - productionProjects.delete(project.json.name); - } - }); - } - - return productionProjects; -} - -async function deleteTarget(project) { - const targetDir = project.targetLocation; - - if (await Object(_utils_fs__WEBPACK_IMPORTED_MODULE_4__["isDirectory"])(targetDir)) { - await del__WEBPACK_IMPORTED_MODULE_1___default()(targetDir, { - force: true - }); - } -} - -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 - * project or some other location defined in the project's `package.json`. - * - * When copying all the files into the build, we exclude `node_modules` because - * we want the Kibana build to be responsible for actually installing all - * dependencies. The primary reason for allowing the Kibana build process to - * manage dependencies is that it will "dedupe" them, so we don't include - * unnecessary copies of dependencies. - */ - - -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`. - - 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); -} - /***/ }), /* 506 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const EventEmitter = __webpack_require__(155); -const path = __webpack_require__(4); -const os = __webpack_require__(120); -const pAll = __webpack_require__(507); -const arrify = __webpack_require__(509); -const globby = __webpack_require__(510); -const isGlob = __webpack_require__(720); -const cpFile = __webpack_require__(721); -const junk = __webpack_require__(733); -const CpyError = __webpack_require__(734); - -const defaultOptions = { - ignoreJunk: true -}; - -const preprocessSourcePath = (source, options) => options.cwd ? path.resolve(options.cwd, source) : source; - -const preprocessDestinationPath = (source, destination, options) => { - let basename = path.basename(source); - const dirname = path.dirname(source); - - if (typeof options.rename === 'string') { - basename = options.rename; - } else if (typeof options.rename === 'function') { - basename = options.rename(basename); - } - - if (options.cwd) { - destination = path.resolve(options.cwd, destination); - } - - if (options.parents) { - return path.join(destination, dirname, basename); - } - - return path.join(destination, basename); -}; - -module.exports = (source, destination, { - concurrency = (os.cpus().length || 1) * 2, - ...options -} = {}) => { - const progressEmitter = new EventEmitter(); - - options = { - ...defaultOptions, - ...options - }; - - const promise = (async () => { - source = arrify(source); - - if (source.length === 0 || !destination) { - throw new CpyError('`source` and `destination` required'); - } - - const copyStatus = new Map(); - let completedFiles = 0; - let completedSize = 0; - - let files; - try { - files = await globby(source, options); - - if (options.ignoreJunk) { - files = files.filter(file => junk.not(path.basename(file))); - } - } catch (error) { - throw new CpyError(`Cannot glob \`${source}\`: ${error.message}`, error); - } - - const sourcePaths = source.filter(value => !isGlob(value)); - - if (files.length === 0 || (sourcePaths.length > 0 && !sourcePaths.every(value => files.includes(value)))) { - throw new CpyError(`Cannot copy \`${source}\`: the file doesn't exist`); - } - - const fileProgressHandler = event => { - const fileStatus = copyStatus.get(event.src) || {written: 0, percent: 0}; - - if (fileStatus.written !== event.written || fileStatus.percent !== event.percent) { - completedSize -= fileStatus.written; - completedSize += event.written; - - if (event.percent === 1 && fileStatus.percent !== 1) { - completedFiles++; - } - - copyStatus.set(event.src, { - written: event.written, - percent: event.percent - }); - - progressEmitter.emit('progress', { - totalFiles: files.length, - percent: completedFiles / files.length, - completedFiles, - completedSize - }); - } - }; - - return pAll(files.map(sourcePath => { - return async () => { - const from = preprocessSourcePath(sourcePath, options); - const to = preprocessDestinationPath(sourcePath, destination, options); - - try { - await cpFile(from, to, options).on('progress', fileProgressHandler); - } catch (error) { - throw new CpyError(`Cannot copy from \`${from}\` to \`${to}\`: ${error.message}`, error); - } - - return to; - }; - }), {concurrency}); - })(); - - promise.on = (...arguments_) => { - progressEmitter.on(...arguments_); - return promise; - }; - - return promise; -}; - - -/***/ }), -/* 507 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -const pMap = __webpack_require__(508); - -module.exports = (iterable, options) => pMap(iterable, element => element(), options); -// TODO: Remove this for the next major release -module.exports.default = module.exports; - - -/***/ }), -/* 508 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -const pMap = (iterable, mapper, options) => new Promise((resolve, reject) => { - options = Object.assign({ - concurrency: Infinity - }, options); - - if (typeof mapper !== 'function') { - throw new TypeError('Mapper function is required'); - } - - const {concurrency} = options; - - if (!(typeof concurrency === 'number' && concurrency >= 1)) { - throw new TypeError(`Expected \`concurrency\` to be a number from 1 and up, got \`${concurrency}\` (${typeof concurrency})`); - } - - const ret = []; - const iterator = iterable[Symbol.iterator](); - let isRejected = false; - let isIterableDone = false; - let resolvingCount = 0; - let currentIndex = 0; - - const next = () => { - if (isRejected) { - return; - } - - const nextItem = iterator.next(); - const i = currentIndex; - currentIndex++; - - if (nextItem.done) { - isIterableDone = true; - - if (resolvingCount === 0) { - resolve(ret); - } - - return; - } - - resolvingCount++; - - Promise.resolve(nextItem.value) - .then(element => mapper(element, i)) - .then( - value => { - ret[i] = value; - resolvingCount--; - next(); - }, - error => { - isRejected = true; - reject(error); - } - ); - }; - - for (let i = 0; i < concurrency; i++) { - next(); - - if (isIterableDone) { - break; - } - } -}); - -module.exports = pMap; -// TODO: Remove this for the next major release -module.exports.default = pMap; - - -/***/ }), -/* 509 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - const arrify = value => { if (value === null || value === undefined) { @@ -58329,18 +58044,450 @@ const arrify = value => { module.exports = arrify; +/***/ }), +/* 507 */ +/***/ (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__(508); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return _build_production_projects__WEBPACK_IMPORTED_MODULE_0__["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. + */ + + +/***/ }), +/* 508 */ +/***/ (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__(509); +/* 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__(281); +/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(del__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4); +/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(272); +/* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(131); +/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(144); +/* harmony import */ var _utils_package_json__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(165); +/* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(146); +/* + * 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 buildProductionProjects({ + kibanaRoot, + buildRoot, + onlyOSS +}) { + const projects = await getProductionProjects(kibanaRoot, onlyOSS); + 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"].info(`Preparing production build for [${projectNames.join(', ')}]`); + + for (const batch of batchedProjects) { + for (const project of batch) { + await deleteTarget(project); + await buildProject(project); + 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, + * and let Kibana's build process be responsible for installing dependencies, + * we only include Kibana's transitive _production_ dependencies. If onlyOSS + * is supplied, we omit projects with build.oss in their package.json set to false. + */ + +async function getProductionProjects(rootPath, onlyOSS) { + const projectPaths = Object(_config__WEBPACK_IMPORTED_MODULE_3__["getProjectPaths"])({ + rootPath + }); + const projects = await Object(_utils_projects__WEBPACK_IMPORTED_MODULE_7__["getProjects"])(rootPath, projectPaths); + const projectsSubset = [projects.get('kibana')]; + + if (projects.has('x-pack')) { + projectsSubset.push(projects.get('x-pack')); + } + + const productionProjects = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_7__["includeTransitiveProjects"])(projectsSubset, projects, { + onlyProductionDependencies: true + }); // We remove Kibana, as we're already building Kibana + + productionProjects.delete('kibana'); + + if (onlyOSS) { + productionProjects.forEach(project => { + if (project.getBuildConfig().oss === false) { + productionProjects.delete(project.json.name); + } + }); + } + + return productionProjects; +} + +async function deleteTarget(project) { + const targetDir = project.targetLocation; + + if (await Object(_utils_fs__WEBPACK_IMPORTED_MODULE_4__["isDirectory"])(targetDir)) { + await del__WEBPACK_IMPORTED_MODULE_1___default()(targetDir, { + force: true + }); + } +} + +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 + * project or some other location defined in the project's `package.json`. + * + * When copying all the files into the build, we exclude `node_modules` because + * we want the Kibana build to be responsible for actually installing all + * dependencies. The primary reason for allowing the Kibana build process to + * manage dependencies is that it will "dedupe" them, so we don't include + * unnecessary copies of dependencies. + */ + + +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`. + + 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); +} + +/***/ }), +/* 509 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const EventEmitter = __webpack_require__(156); +const path = __webpack_require__(4); +const os = __webpack_require__(121); +const pAll = __webpack_require__(510); +const arrify = __webpack_require__(512); +const globby = __webpack_require__(513); +const isGlob = __webpack_require__(294); +const cpFile = __webpack_require__(713); +const junk = __webpack_require__(723); +const CpyError = __webpack_require__(724); + +const defaultOptions = { + ignoreJunk: true +}; + +const preprocessSourcePath = (source, options) => options.cwd ? path.resolve(options.cwd, source) : source; + +const preprocessDestinationPath = (source, destination, options) => { + let basename = path.basename(source); + const dirname = path.dirname(source); + + if (typeof options.rename === 'string') { + basename = options.rename; + } else if (typeof options.rename === 'function') { + basename = options.rename(basename); + } + + if (options.cwd) { + destination = path.resolve(options.cwd, destination); + } + + if (options.parents) { + return path.join(destination, dirname, basename); + } + + return path.join(destination, basename); +}; + +module.exports = (source, destination, { + concurrency = (os.cpus().length || 1) * 2, + ...options +} = {}) => { + const progressEmitter = new EventEmitter(); + + options = { + ...defaultOptions, + ...options + }; + + const promise = (async () => { + source = arrify(source); + + if (source.length === 0 || !destination) { + throw new CpyError('`source` and `destination` required'); + } + + const copyStatus = new Map(); + let completedFiles = 0; + let completedSize = 0; + + let files; + try { + files = await globby(source, options); + + if (options.ignoreJunk) { + files = files.filter(file => junk.not(path.basename(file))); + } + } catch (error) { + throw new CpyError(`Cannot glob \`${source}\`: ${error.message}`, error); + } + + const sourcePaths = source.filter(value => !isGlob(value)); + + if (files.length === 0 || (sourcePaths.length > 0 && !sourcePaths.every(value => files.includes(value)))) { + throw new CpyError(`Cannot copy \`${source}\`: the file doesn't exist`); + } + + const fileProgressHandler = event => { + const fileStatus = copyStatus.get(event.src) || {written: 0, percent: 0}; + + if (fileStatus.written !== event.written || fileStatus.percent !== event.percent) { + completedSize -= fileStatus.written; + completedSize += event.written; + + if (event.percent === 1 && fileStatus.percent !== 1) { + completedFiles++; + } + + copyStatus.set(event.src, { + written: event.written, + percent: event.percent + }); + + progressEmitter.emit('progress', { + totalFiles: files.length, + percent: completedFiles / files.length, + completedFiles, + completedSize + }); + } + }; + + return pAll(files.map(sourcePath => { + return async () => { + const from = preprocessSourcePath(sourcePath, options); + const to = preprocessDestinationPath(sourcePath, destination, options); + + try { + await cpFile(from, to, options).on('progress', fileProgressHandler); + } catch (error) { + throw new CpyError(`Cannot copy from \`${from}\` to \`${to}\`: ${error.message}`, error); + } + + return to; + }; + }), {concurrency}); + })(); + + promise.on = (...arguments_) => { + progressEmitter.on(...arguments_); + return promise; + }; + + return promise; +}; + + /***/ }), /* 510 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fs = __webpack_require__(133); -const arrayUnion = __webpack_require__(511); -const glob = __webpack_require__(146); -const fastGlob = __webpack_require__(513); -const dirGlob = __webpack_require__(713); -const gitignore = __webpack_require__(716); +const pMap = __webpack_require__(511); + +module.exports = (iterable, options) => pMap(iterable, element => element(), options); +// TODO: Remove this for the next major release +module.exports.default = module.exports; + + +/***/ }), +/* 511 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const pMap = (iterable, mapper, options) => new Promise((resolve, reject) => { + options = Object.assign({ + concurrency: Infinity + }, options); + + if (typeof mapper !== 'function') { + throw new TypeError('Mapper function is required'); + } + + const {concurrency} = options; + + if (!(typeof concurrency === 'number' && concurrency >= 1)) { + throw new TypeError(`Expected \`concurrency\` to be a number from 1 and up, got \`${concurrency}\` (${typeof concurrency})`); + } + + const ret = []; + const iterator = iterable[Symbol.iterator](); + let isRejected = false; + let isIterableDone = false; + let resolvingCount = 0; + let currentIndex = 0; + + const next = () => { + if (isRejected) { + return; + } + + const nextItem = iterator.next(); + const i = currentIndex; + currentIndex++; + + if (nextItem.done) { + isIterableDone = true; + + if (resolvingCount === 0) { + resolve(ret); + } + + return; + } + + resolvingCount++; + + Promise.resolve(nextItem.value) + .then(element => mapper(element, i)) + .then( + value => { + ret[i] = value; + resolvingCount--; + next(); + }, + error => { + isRejected = true; + reject(error); + } + ); + }; + + for (let i = 0; i < concurrency; i++) { + next(); + + if (isIterableDone) { + break; + } + } +}); + +module.exports = pMap; +// TODO: Remove this for the next major release +module.exports.default = pMap; + + +/***/ }), +/* 512 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const arrify = value => { + if (value === null || value === undefined) { + return []; + } + + if (Array.isArray(value)) { + return value; + } + + if (typeof value === 'string') { + return [value]; + } + + if (typeof value[Symbol.iterator] === 'function') { + return [...value]; + } + + return [value]; +}; + +module.exports = arrify; + + +/***/ }), +/* 513 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const fs = __webpack_require__(134); +const arrayUnion = __webpack_require__(514); +const glob = __webpack_require__(147); +const fastGlob = __webpack_require__(516); +const dirGlob = __webpack_require__(706); +const gitignore = __webpack_require__(709); const DEFAULT_FILTER = () => false; @@ -58485,12 +58632,12 @@ module.exports.gitignore = gitignore; /***/ }), -/* 511 */ +/* 514 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var arrayUniq = __webpack_require__(512); +var arrayUniq = __webpack_require__(515); module.exports = function () { return arrayUniq([].concat.apply([], arguments)); @@ -58498,7 +58645,7 @@ module.exports = function () { /***/ }), -/* 512 */ +/* 515 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -58567,10 +58714,10 @@ if ('Set' in global) { /***/ }), -/* 513 */ +/* 516 */ /***/ (function(module, exports, __webpack_require__) { -const pkg = __webpack_require__(514); +const pkg = __webpack_require__(517); module.exports = pkg.async; module.exports.default = pkg.async; @@ -58583,19 +58730,19 @@ module.exports.generateTasks = pkg.generateTasks; /***/ }), -/* 514 */ +/* 517 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var optionsManager = __webpack_require__(515); -var taskManager = __webpack_require__(516); -var reader_async_1 = __webpack_require__(684); -var reader_stream_1 = __webpack_require__(708); -var reader_sync_1 = __webpack_require__(709); -var arrayUtils = __webpack_require__(711); -var streamUtils = __webpack_require__(712); +var optionsManager = __webpack_require__(518); +var taskManager = __webpack_require__(519); +var reader_async_1 = __webpack_require__(677); +var reader_stream_1 = __webpack_require__(701); +var reader_sync_1 = __webpack_require__(702); +var arrayUtils = __webpack_require__(704); +var streamUtils = __webpack_require__(705); /** * Synchronous API. */ @@ -58661,7 +58808,7 @@ function isString(source) { /***/ }), -/* 515 */ +/* 518 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -58699,13 +58846,13 @@ exports.prepare = prepare; /***/ }), -/* 516 */ +/* 519 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var patternUtils = __webpack_require__(517); +var patternUtils = __webpack_require__(520); /** * Generate tasks based on parent directory of each pattern. */ @@ -58796,16 +58943,16 @@ exports.convertPatternGroupToTask = convertPatternGroupToTask; /***/ }), -/* 517 */ +/* 520 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var path = __webpack_require__(4); -var globParent = __webpack_require__(518); -var isGlob = __webpack_require__(521); -var micromatch = __webpack_require__(522); +var globParent = __webpack_require__(521); +var isGlob = __webpack_require__(294); +var micromatch = __webpack_require__(524); var GLOBSTAR = '**'; /** * Return true for static pattern. @@ -58951,16 +59098,16 @@ exports.matchAny = matchAny; /***/ }), -/* 518 */ +/* 521 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var path = __webpack_require__(4); -var isglob = __webpack_require__(519); -var pathDirname = __webpack_require__(520); -var isWin32 = __webpack_require__(120).platform() === 'win32'; +var isglob = __webpack_require__(522); +var pathDirname = __webpack_require__(523); +var isWin32 = __webpack_require__(121).platform() === 'win32'; module.exports = function globParent(str) { // flip windows path separators @@ -58982,7 +59129,7 @@ module.exports = function globParent(str) { /***/ }), -/* 519 */ +/* 522 */ /***/ (function(module, exports, __webpack_require__) { /*! @@ -58992,7 +59139,7 @@ module.exports = function globParent(str) { * Licensed under the MIT License. */ -var isExtglob = __webpack_require__(303); +var isExtglob = __webpack_require__(295); module.exports = function isGlob(str) { if (typeof str !== 'string' || str === '') { @@ -59013,14 +59160,14 @@ module.exports = function isGlob(str) { /***/ }), -/* 520 */ +/* 523 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var path = __webpack_require__(4); -var inspect = __webpack_require__(111).inspect; +var inspect = __webpack_require__(112).inspect; function assertPath(path) { if (typeof path !== 'string') { @@ -59163,59 +59310,7 @@ module.exports.win32 = win32; /***/ }), -/* 521 */ -/***/ (function(module, exports, __webpack_require__) { - -/*! - * is-glob - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ - -var isExtglob = __webpack_require__(303); -var chars = { '{': '}', '(': ')', '[': ']'}; - -module.exports = function isGlob(str, options) { - if (typeof str !== 'string' || str === '') { - return false; - } - - if (isExtglob(str)) { - return true; - } - - var regex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; - var match; - - // optionally relax regex - if (options && options.strict === false) { - regex = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; - } - - while ((match = regex.exec(str))) { - if (match[2]) return true; - var idx = match.index + match[0].length; - - // if an open bracket/brace/paren is escaped, - // set the index to the next closing character - var open = match[1]; - var close = open ? chars[open] : null; - if (open && close) { - var n = str.indexOf(close, idx); - if (n !== -1) { - idx = n + 1; - } - } - - str = str.slice(idx); - } - return false; -}; - - -/***/ }), -/* 522 */ +/* 524 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -59225,19 +59320,19 @@ module.exports = function isGlob(str, options) { * Module dependencies */ -var util = __webpack_require__(111); -var braces = __webpack_require__(523); -var toRegex = __webpack_require__(636); -var extend = __webpack_require__(644); +var util = __webpack_require__(112); +var braces = __webpack_require__(525); +var toRegex = __webpack_require__(526); +var extend = __webpack_require__(638); /** * Local dependencies */ -var compilers = __webpack_require__(647); -var parsers = __webpack_require__(680); -var cache = __webpack_require__(681); -var utils = __webpack_require__(682); +var compilers = __webpack_require__(640); +var parsers = __webpack_require__(672); +var cache = __webpack_require__(673); +var utils = __webpack_require__(674); var MAX_LENGTH = 1024 * 64; /** @@ -60099,7 +60194,7 @@ module.exports = micromatch; /***/ }), -/* 523 */ +/* 525 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -60109,18 +60204,18 @@ module.exports = micromatch; * Module dependencies */ -var toRegex = __webpack_require__(524); -var unique = __webpack_require__(538); -var extend = __webpack_require__(533); +var toRegex = __webpack_require__(526); +var unique = __webpack_require__(548); +var extend = __webpack_require__(549); /** * Local dependencies */ -var compilers = __webpack_require__(539); -var parsers = __webpack_require__(556); -var Braces = __webpack_require__(566); -var utils = __webpack_require__(540); +var compilers = __webpack_require__(551); +var parsers = __webpack_require__(564); +var Braces = __webpack_require__(568); +var utils = __webpack_require__(552); var MAX_LENGTH = 1024 * 64; var cache = {}; @@ -60424,15 +60519,16 @@ module.exports = braces; /***/ }), -/* 524 */ +/* 526 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var define = __webpack_require__(525); -var extend = __webpack_require__(533); -var not = __webpack_require__(535); +var safe = __webpack_require__(527); +var define = __webpack_require__(533); +var extend = __webpack_require__(541); +var not = __webpack_require__(545); var MAX_LENGTH = 1024 * 64; /** @@ -60516,10 +60612,16 @@ function makeRe(pattern, options) { if (opts.negate || typeof opts.strictNegate === 'boolean') { pattern = not.create(pattern, opts); } + var str = open + '(?:' + pattern + ')' + close; regex = new RegExp(str, flags); + + if (opts.safe === true && safe(regex) === false) { + throw new Error('potentially unsafe regular expression: ' + regex.source); + } + } catch (err) { - if (opts.strictErrors === true) { + if (opts.strictErrors === true || opts.safe === true) { err.key = key; err.pattern = pattern; err.originalOptions = options; @@ -60535,18 +60637,18 @@ function makeRe(pattern, options) { } if (opts.cache !== false) { - cacheRegex(regex, key, pattern, opts); + memoize(regex, key, pattern, opts); } return regex; } /** - * Cache generated regex. This can result in dramatic speed improvements + * Memoize generated regex. This can result in dramatic speed improvements * and simplify debugging by adding options and pattern to the regex. It can be * disabled by passing setting `options.cache` to false. */ -function cacheRegex(regex, key, pattern, options) { +function memoize(regex, key, pattern, options) { define(regex, 'cached', true); define(regex, 'pattern', pattern); define(regex, 'options', options); @@ -60579,804 +60681,811 @@ module.exports.makeRe = makeRe; /***/ }), -/* 525 */ +/* 527 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; -/*! - * define-property - * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. - */ - - - -var isDescriptor = __webpack_require__(526); - -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); - } +var parse = __webpack_require__(528); +var types = parse.types; - return Object.defineProperty(obj, prop, { - configurable: true, - enumerable: false, - writable: true, - value: val - }); +module.exports = function (re, opts) { + if (!opts) opts = {}; + var replimit = opts.limit === undefined ? 25 : opts.limit; + + if (isRegExp(re)) re = re.source; + else if (typeof re !== 'string') re = String(re); + + try { re = parse(re) } + catch (err) { return false } + + var reps = 0; + return (function walk (node, starHeight) { + if (node.type === types.REPETITION) { + starHeight ++; + reps ++; + if (starHeight > 1) return false; + if (reps > replimit) return false; + } + + if (node.options) { + for (var i = 0, len = node.options.length; i < len; i++) { + var ok = walk({ stack: node.options[i] }, starHeight); + if (!ok) return false; + } + } + var stack = node.stack || (node.value && node.value.stack); + if (!stack) return true; + + for (var i = 0; i < stack.length; i++) { + var ok = walk(stack[i], starHeight); + if (!ok) return false; + } + + return true; + })(re, 0); }; +function isRegExp (x) { + return {}.toString.call(x) === '[object RegExp]'; +} + /***/ }), -/* 526 */ +/* 528 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; -/*! - * is-descriptor - * - * Copyright (c) 2015-2017, Jon Schlinkert. - * Released under the MIT License. - */ +var util = __webpack_require__(529); +var types = __webpack_require__(530); +var sets = __webpack_require__(531); +var positions = __webpack_require__(532); +module.exports = function(regexpStr) { + var i = 0, l, c, + start = { type: types.ROOT, stack: []}, -var typeOf = __webpack_require__(527); -var isAccessor = __webpack_require__(528); -var isData = __webpack_require__(531); + // Keep track of last clause/group and stack. + lastGroup = start, + last = start.stack, + groupStack = []; -module.exports = function isDescriptor(obj, key) { - if (typeOf(obj) !== 'object') { - return false; - } - if ('get' in obj) { - return isAccessor(obj, key); - } - return isData(obj, key); -}; + var repeatErr = function(i) { + util.error(regexpStr, 'Nothing to repeat at column ' + (i - 1)); + }; -/***/ }), -/* 527 */ -/***/ (function(module, exports) { + // Decode a few escaped characters. + var str = util.strToChars(regexpStr); + l = str.length; -var toString = Object.prototype.toString; + // Iterate through each character in string. + while (i < l) { + c = str[i++]; -/** - * Get the native `typeof` a value. - * - * @param {*} `val` - * @return {*} Native javascript type - */ + switch (c) { + // Handle escaped characters, inclues a few sets. + case '\\': + c = str[i++]; -module.exports = function kindOf(val) { - var type = typeof val; + switch (c) { + case 'b': + last.push(positions.wordBoundary()); + break; - // 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'; - } + case 'B': + last.push(positions.nonWordBoundary()); + break; - // functions - if (type === 'function' || val instanceof Function) { - if (typeof val.constructor.name !== 'undefined' && val.constructor.name.slice(0, 9) === 'Generator') { - return 'generatorfunction'; - } - return 'function'; - } + case 'w': + last.push(sets.words()); + break; - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; - } + case 'W': + last.push(sets.notWords()); + break; - // check for instances of RegExp and Date before calling `toString` - if (val instanceof RegExp) { - return 'regexp'; - } - if (val instanceof Date) { - return 'date'; - } + case 'd': + last.push(sets.ints()); + break; - // other objects - type = toString.call(val); + case 'D': + last.push(sets.notInts()); + break; - 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'; - } + case 's': + last.push(sets.whitespace()); + break; - // buffer - if (isBuffer(val)) { - return 'buffer'; - } + case 'S': + last.push(sets.notWhitespace()); + break; - // 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'; - } + default: + // Check if c is integer. + // In which case it's a reference. + if (/\d/.test(c)) { + last.push({ type: types.REFERENCE, value: parseInt(c, 10) }); - // must be a plain object - return 'object'; -}; + // Escaped character. + } else { + last.push({ type: types.CHAR, value: c.charCodeAt(0) }); + } + } -/** - * If you need to support Safari 5-7 (8-10 yr-old browser), - * take a look at https://github.com/feross/is-buffer - */ + break; -function isBuffer(val) { - return val.constructor - && typeof val.constructor.isBuffer === 'function' - && val.constructor.isBuffer(val); -} + // Positionals. + case '^': + last.push(positions.begin()); + break; -/***/ }), -/* 528 */ -/***/ (function(module, exports, __webpack_require__) { + case '$': + last.push(positions.end()); + break; -"use strict"; -/*! - * is-accessor-descriptor - * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. - */ + // Handle custom sets. + case '[': + // Check if this class is 'anti' i.e. [^abc]. + var not; + if (str[i] === '^') { + not = true; + i++; + } else { + not = false; + } + // Get all the characters in class. + var classTokens = util.tokenizeClass(str.slice(i), regexpStr); -var typeOf = __webpack_require__(529); + // Increase index by length of class. + i += classTokens[1]; + last.push({ + type: types.SET, + set: classTokens[0], + not: not, + }); -// accessor descriptor properties -var accessor = { - get: 'function', - set: 'function', - configurable: 'boolean', - enumerable: 'boolean' -}; + break; -function isAccessorDescriptor(obj, prop) { - if (typeof prop === 'string') { - var val = Object.getOwnPropertyDescriptor(obj, prop); - return typeof val !== 'undefined'; - } - if (typeOf(obj) !== 'object') { - return false; - } + // Class of any character except \n. + case '.': + last.push(sets.anyChar()); + break; - if (has(obj, 'value') || has(obj, 'writable')) { - return false; - } - if (!has(obj, 'get') || typeof obj.get !== 'function') { - return false; - } + // Push group onto stack. + case '(': + // Create group. + var group = { + type: types.GROUP, + stack: [], + remember: 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; - } + c = str[i]; - for (var key in obj) { - if (!accessor.hasOwnProperty(key)) { - continue; - } + // If if this is a special kind of group. + if (c === '?') { + c = str[i + 1]; + i += 2; - if (typeOf(obj[key]) === accessor[key]) { - continue; - } + // Match if followed by. + if (c === '=') { + group.followedBy = true; - if (typeof obj[key] !== 'undefined') { - return false; - } - } - return true; -} + // Match if not followed by. + } else if (c === '!') { + group.notFollowedBy = true; -function has(obj, key) { - return {}.hasOwnProperty.call(obj, key); -} + } else if (c !== ':') { + util.error(regexpStr, + 'Invalid group, character \'' + c + + '\' after \'?\' at column ' + (i - 1)); + } -/** - * Expose `isAccessorDescriptor` - */ + group.remember = false; + } -module.exports = isAccessorDescriptor; + // Insert subgroup into current group stack. + last.push(group); + // Remember the current group for when the group closes. + groupStack.push(lastGroup); -/***/ }), -/* 529 */ -/***/ (function(module, exports, __webpack_require__) { + // Make this new group the current group. + lastGroup = group; + last = group.stack; + break; -var isBuffer = __webpack_require__(530); -var toString = Object.prototype.toString; -/** - * Get the native `typeof` a value. - * - * @param {*} `val` - * @return {*} Native javascript type - */ + // Pop group out of stack. + case ')': + if (groupStack.length === 0) { + util.error(regexpStr, 'Unmatched ) at column ' + (i - 1)); + } + lastGroup = groupStack.pop(); -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'; - } + // Check if this group has a PIPE. + // To get back the correct last stack. + last = lastGroup.options ? + lastGroup.options[lastGroup.options.length - 1] : lastGroup.stack; + break; - // functions - if (typeof val === 'function' || val instanceof Function) { - return 'function'; - } - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; - } + // Use pipe character to give more choices. + case '|': + // Create array where options are if this is the first PIPE + // in this clause. + if (!lastGroup.options) { + lastGroup.options = [lastGroup.stack]; + delete lastGroup.stack; + } - // check for instances of RegExp and Date before calling `toString` - if (val instanceof RegExp) { - return 'regexp'; - } - if (val instanceof Date) { - return 'date'; - } + // Create a new stack and add to options for rest of clause. + var stack = []; + lastGroup.options.push(stack); + last = stack; + break; - // 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'; - } + // Repetition. + // For every repetition, remove last element from last stack + // then insert back a RANGE object. + // This design is chosen because there could be more than + // one repetition symbols in a regex i.e. `a?+{2,3}`. + case '{': + var rs = /^(\d+)(,(\d+)?)?\}/.exec(str.slice(i)), min, max; + if (rs !== null) { + if (last.length === 0) { + repeatErr(i); + } + min = parseInt(rs[1], 10); + max = rs[2] ? rs[3] ? parseInt(rs[3], 10) : Infinity : min; + i += rs[0].length; - // buffer - if (isBuffer(val)) { - return 'buffer'; - } + last.push({ + type: types.REPETITION, + min: min, + max: max, + value: last.pop(), + }); + } else { + last.push({ + type: types.CHAR, + value: 123, + }); + } + break; - // 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'; - } + case '?': + if (last.length === 0) { + repeatErr(i); + } + last.push({ + type: types.REPETITION, + min: 0, + max: 1, + value: last.pop(), + }); + break; + + case '+': + if (last.length === 0) { + repeatErr(i); + } + last.push({ + type: types.REPETITION, + min: 1, + max: Infinity, + value: last.pop(), + }); + break; + + case '*': + if (last.length === 0) { + repeatErr(i); + } + last.push({ + type: types.REPETITION, + min: 0, + max: Infinity, + value: last.pop(), + }); + break; + + + // Default is a character that is not `\[](){}?+*^$`. + default: + last.push({ + type: types.CHAR, + value: c.charCodeAt(0), + }); + } - // 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'; + + // Check if any groups have not been closed. + if (groupStack.length !== 0) { + util.error(regexpStr, 'Unterminated group'); } - // must be a plain object - return 'object'; + return start; }; +module.exports.types = types; + /***/ }), -/* 530 */ -/***/ (function(module, exports) { +/* 529 */ +/***/ (function(module, exports, __webpack_require__) { -/*! - * Determine if an object is a Buffer +var types = __webpack_require__(530); +var sets = __webpack_require__(531); + + +// All of these are private and only used by randexp. +// It's assumed that they will always be called with the correct input. + +var CTRL = '@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ ?'; +var SLSH = { '0': 0, 't': 9, 'n': 10, 'v': 11, 'f': 12, 'r': 13 }; + +/** + * Finds character representations in str and convert all to + * their respective characters * - * @author Feross Aboukhadijeh - * @license MIT + * @param {String} str + * @return {String} */ +exports.strToChars = function(str) { + /* jshint maxlen: false */ + var chars_regex = /(\[\\b\])|(\\)?\\(?:u([A-F0-9]{4})|x([A-F0-9]{2})|(0?[0-7]{2})|c([@A-Z\[\\\]\^?])|([0tnvfr]))/g; + str = str.replace(chars_regex, function(s, b, lbs, a16, b16, c8, dctrl, eslsh) { + if (lbs) { + return s; + } -// The _isBuffer check is for Safari 5-7 support, because it's missing -// Object.prototype.constructor. Remove this eventually -module.exports = function (obj) { - return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer) -} + var code = b ? 8 : + a16 ? parseInt(a16, 16) : + b16 ? parseInt(b16, 16) : + c8 ? parseInt(c8, 8) : + dctrl ? CTRL.indexOf(dctrl) : + SLSH[eslsh]; -function isBuffer (obj) { - return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) -} + var c = String.fromCharCode(code); -// For Node v0.10 support. Remove this eventually. -function isSlowBuffer (obj) { - return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0)) -} + // Escape special regex characters. + if (/[\[\]{}\^$.|?*+()]/.test(c)) { + c = '\\' + c; + } + return c; + }); -/***/ }), -/* 531 */ -/***/ (function(module, exports, __webpack_require__) { + return str; +}; -"use strict"; -/*! - * is-data-descriptor + +/** + * turns class into tokens + * reads str until it encounters a ] not preceeded by a \ * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. + * @param {String} str + * @param {String} regexpStr + * @return {Array., Number>} */ +exports.tokenizeClass = function(str, regexpStr) { + /* jshint maxlen: false */ + var tokens = []; + var regexp = /\\(?:(w)|(d)|(s)|(W)|(D)|(S))|((?:(?:\\)(.)|([^\]\\]))-(?:\\)?([^\]]))|(\])|(?:\\)?(.)/g; + var rs, c; + while ((rs = regexp.exec(str)) != null) { + if (rs[1]) { + tokens.push(sets.words()); -var typeOf = __webpack_require__(532); - -// data descriptor properties -var data = { - configurable: 'boolean', - enumerable: 'boolean', - writable: 'boolean' -}; + } else if (rs[2]) { + tokens.push(sets.ints()); -function isDataDescriptor(obj, prop) { - if (typeOf(obj) !== 'object') { - return false; - } + } else if (rs[3]) { + tokens.push(sets.whitespace()); - if (typeof prop === 'string') { - var val = Object.getOwnPropertyDescriptor(obj, prop); - return typeof val !== 'undefined'; - } + } else if (rs[4]) { + tokens.push(sets.notWords()); - if (!('value' in obj) && !('writable' in obj)) { - return false; - } + } else if (rs[5]) { + tokens.push(sets.notInts()); - for (var key in obj) { - if (key === 'value') continue; + } else if (rs[6]) { + tokens.push(sets.notWhitespace()); - if (!data.hasOwnProperty(key)) { - continue; - } + } else if (rs[7]) { + tokens.push({ + type: types.RANGE, + from: (rs[8] || rs[9]).charCodeAt(0), + to: rs[10].charCodeAt(0), + }); - if (typeOf(obj[key]) === data[key]) { - continue; - } + } else if (c = rs[12]) { + tokens.push({ + type: types.CHAR, + value: c.charCodeAt(0), + }); - if (typeof obj[key] !== 'undefined') { - return false; + } else { + return [tokens, regexp.lastIndex]; } } - return true; -} + + exports.error(regexpStr, 'Unterminated character class'); +}; + /** - * Expose `isDataDescriptor` + * Shortcut to throw errors. + * + * @param {String} regexp + * @param {String} msg */ +exports.error = function(regexp, msg) { + throw new SyntaxError('Invalid regular expression: /' + regexp + '/: ' + msg); +}; -module.exports = isDataDescriptor; + +/***/ }), +/* 530 */ +/***/ (function(module, exports) { + +module.exports = { + ROOT : 0, + GROUP : 1, + POSITION : 2, + SET : 3, + RANGE : 4, + REPETITION : 5, + REFERENCE : 6, + CHAR : 7, +}; /***/ }), -/* 532 */ +/* 531 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(530); -var toString = Object.prototype.toString; +var types = __webpack_require__(530); -/** - * Get the native `typeof` a value. - * - * @param {*} `val` - * @return {*} Native javascript type - */ +var INTS = function() { + return [{ type: types.RANGE , from: 48, to: 57 }]; +}; -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 WORDS = function() { + return [ + { type: types.CHAR, value: 95 }, + { type: types.RANGE, from: 97, to: 122 }, + { type: types.RANGE, from: 65, to: 90 } + ].concat(INTS()); +}; - // functions - if (typeof val === 'function' || val instanceof Function) { - return 'function'; - } +var WHITESPACE = function() { + return [ + { type: types.CHAR, value: 9 }, + { type: types.CHAR, value: 10 }, + { type: types.CHAR, value: 11 }, + { type: types.CHAR, value: 12 }, + { type: types.CHAR, value: 13 }, + { type: types.CHAR, value: 32 }, + { type: types.CHAR, value: 160 }, + { type: types.CHAR, value: 5760 }, + { type: types.CHAR, value: 6158 }, + { type: types.CHAR, value: 8192 }, + { type: types.CHAR, value: 8193 }, + { type: types.CHAR, value: 8194 }, + { type: types.CHAR, value: 8195 }, + { type: types.CHAR, value: 8196 }, + { type: types.CHAR, value: 8197 }, + { type: types.CHAR, value: 8198 }, + { type: types.CHAR, value: 8199 }, + { type: types.CHAR, value: 8200 }, + { type: types.CHAR, value: 8201 }, + { type: types.CHAR, value: 8202 }, + { type: types.CHAR, value: 8232 }, + { type: types.CHAR, value: 8233 }, + { type: types.CHAR, value: 8239 }, + { type: types.CHAR, value: 8287 }, + { type: types.CHAR, value: 12288 }, + { type: types.CHAR, value: 65279 } + ]; +}; - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; - } +var NOTANYCHAR = function() { + return [ + { type: types.CHAR, value: 10 }, + { type: types.CHAR, value: 13 }, + { type: types.CHAR, value: 8232 }, + { type: types.CHAR, value: 8233 }, + ]; +}; - // check for instances of RegExp and Date before calling `toString` - if (val instanceof RegExp) { - return 'regexp'; - } - if (val instanceof Date) { - return 'date'; - } +// Predefined class objects. +exports.words = function() { + return { type: types.SET, set: WORDS(), not: false }; +}; - // other objects - var type = toString.call(val); +exports.notWords = function() { + return { type: types.SET, set: WORDS(), not: true }; +}; - if (type === '[object RegExp]') { - return 'regexp'; - } - if (type === '[object Date]') { - return 'date'; - } - if (type === '[object Arguments]') { - return 'arguments'; - } - if (type === '[object Error]') { - return 'error'; - } +exports.ints = function() { + return { type: types.SET, set: INTS(), not: false }; +}; - // buffer - if (isBuffer(val)) { - return 'buffer'; - } +exports.notInts = function() { + return { type: types.SET, set: INTS(), not: true }; +}; - // 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.whitespace = function() { + return { type: types.SET, set: WHITESPACE(), not: false }; +}; - // 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'; - } +exports.notWhitespace = function() { + return { type: types.SET, set: WHITESPACE(), not: true }; +}; - // must be a plain object - return 'object'; +exports.anyChar = function() { + return { type: types.SET, set: NOTANYCHAR(), not: true }; }; /***/ }), -/* 533 */ +/* 532 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - - -var isObject = __webpack_require__(534); - -module.exports = function extend(o/*, objects*/) { - if (!isObject(o)) { o = {}; } - - var len = arguments.length; - for (var i = 1; i < len; i++) { - var obj = arguments[i]; +var types = __webpack_require__(530); - if (isObject(obj)) { - assign(o, obj); - } - } - return o; +exports.wordBoundary = function() { + return { type: types.POSITION, value: 'b' }; }; -function assign(a, b) { - for (var key in b) { - if (hasOwn(b, key)) { - a[key] = b[key]; - } - } -} +exports.nonWordBoundary = function() { + return { type: types.POSITION, value: 'B' }; +}; -/** - * Returns true if the given `key` is an own property of `obj`. - */ +exports.begin = function() { + return { type: types.POSITION, value: '^' }; +}; -function hasOwn(obj, key) { - return Object.prototype.hasOwnProperty.call(obj, key); -} +exports.end = function() { + return { type: types.POSITION, value: '$' }; +}; /***/ }), -/* 534 */ +/* 533 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! - * is-extendable + * define-property * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. + * Copyright (c) 2015-2018, Jon Schlinkert. + * Released under the MIT License. */ -module.exports = function isExtendable(val) { - return typeof val !== 'undefined' && val !== null - && (typeof val === 'object' || typeof val === 'function'); -}; +var isobject = __webpack_require__(534); +var isDescriptor = __webpack_require__(535); +var define = (typeof Reflect !== 'undefined' && Reflect.defineProperty) + ? Reflect.defineProperty + : Object.defineProperty; +module.exports = function defineProperty(obj, key, val) { + if (!isobject(obj) && typeof obj !== 'function' && !Array.isArray(obj)) { + throw new TypeError('expected an object, function, or array'); + } -/***/ }), -/* 535 */ -/***/ (function(module, exports, __webpack_require__) { + if (typeof key !== 'string') { + throw new TypeError('expected "key" to be a string'); + } -"use strict"; + if (isDescriptor(val)) { + define(obj, key, val); + return obj; + } + define(obj, key, { + configurable: true, + enumerable: false, + writable: true, + value: val + }); -var extend = __webpack_require__(536); + return obj; +}; -/** - * The main export is a function that takes a `pattern` string and an `options` object. - * - * ```js - & var not = require('regex-not'); - & console.log(not('foo')); - & //=> /^(?:(?!^(?:foo)$).)*$/ - * ``` - * - * @param {String} `pattern` - * @param {Object} `options` - * @return {RegExp} Converts the given `pattern` to a regex using the specified `options`. - * @api public - */ -function toRegex(pattern, options) { - return new RegExp(toRegex.create(pattern, options)); -} +/***/ }), +/* 534 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Create a regex-compatible string from the given `pattern` and `options`. +"use strict"; +/*! + * isobject * - * ```js - & var not = require('regex-not'); - & console.log(not.create('foo')); - & //=> '^(?:(?!^(?:foo)$).)*$' - * ``` - * @param {String} `pattern` - * @param {Object} `options` - * @return {String} - * @api public + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. */ -toRegex.create = function(pattern, options) { - if (typeof pattern !== 'string') { - throw new TypeError('expected a string'); - } - var opts = extend({}, options); - if (opts && opts.contains === true) { - opts.strictNegate = false; - } - var open = opts.strictOpen !== false ? '^' : ''; - var close = opts.strictClose !== false ? '$' : ''; - var endChar = opts.endChar ? opts.endChar : '+'; - var str = pattern; +module.exports = function isObject(val) { + return val != null && typeof val === 'object' && Array.isArray(val) === false; +}; - if (opts && opts.strictNegate === false) { - str = '(?:(?!(?:' + pattern + ')).)' + endChar; - } else { - str = '(?:(?!^(?:' + pattern + ')$).)' + endChar; - } - return open + str + close; -}; +/***/ }), +/* 535 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Expose `toRegex` +"use strict"; +/*! + * is-descriptor + * + * Copyright (c) 2015-2017, Jon Schlinkert. + * Released under the MIT License. */ -module.exports = toRegex; + + +var typeOf = __webpack_require__(536); +var isAccessor = __webpack_require__(537); +var isData = __webpack_require__(539); + +module.exports = function isDescriptor(obj, key) { + if (typeOf(obj) !== 'object') { + return false; + } + if ('get' in obj) { + return isAccessor(obj, key); + } + return isData(obj, key); +}; /***/ }), /* 536 */ -/***/ (function(module, exports, __webpack_require__) { +/***/ (function(module, exports) { -"use strict"; +var toString = Object.prototype.toString; +module.exports = function kindOf(val) { + if (val === void 0) return 'undefined'; + if (val === null) return 'null'; -var isObject = __webpack_require__(537); + 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'; + } -module.exports = function extend(o/*, objects*/) { - if (!isObject(o)) { o = {}; } + 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'; - var len = arguments.length; - for (var i = 1; i < len; i++) { - var obj = arguments[i]; + switch (ctorName(val)) { + case 'Symbol': return 'symbol'; + case 'Promise': return 'promise'; - if (isObject(obj)) { - assign(o, obj); - } + // 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'; } - return o; + + if (isGeneratorObj(val)) { + return 'generator'; + } + + // 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'; + } + + // other + return type.slice(8, -1).toLowerCase().replace(/\s/g, ''); }; -function assign(a, b) { - for (var key in b) { - if (hasOwn(b, key)) { - a[key] = b[key]; +function ctorName(val) { + return typeof val.constructor === 'function' ? val.constructor.name : null; +} + +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'); +} + +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 the given `key` is an own property of `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 hasOwn(obj, key) { - return Object.prototype.hasOwnProperty.call(obj, key); +function isBuffer(val) { + if (val.constructor && typeof val.constructor.isBuffer === 'function') { + return val.constructor.isBuffer(val); + } + return false; } @@ -61386,896 +61495,669 @@ function hasOwn(obj, key) { "use strict"; /*! - * is-extendable + * is-accessor-descriptor * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. + * Copyright (c) 2015-2017, Jon Schlinkert. + * Released under the MIT License. */ -module.exports = function isExtendable(val) { - return typeof val !== 'undefined' && val !== null - && (typeof val === 'object' || typeof val === 'function'); -}; - +var typeOf = __webpack_require__(538); -/***/ }), -/* 538 */ -/***/ (function(module, exports, __webpack_require__) { +// accessor descriptor properties +var accessor = { + get: 'function', + set: 'function', + configurable: 'boolean', + enumerable: 'boolean' +}; -"use strict"; -/*! - * array-unique - * - * Copyright (c) 2014-2015, Jon Schlinkert. - * Licensed under the MIT License. - */ +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; + } -module.exports = function unique(arr) { - if (!Array.isArray(arr)) { - throw new TypeError('array-unique expects an array.'); + if (!has(obj, 'get') || typeof obj.get !== 'function') { + return false; } - var len = arr.length; - var i = -1; + // 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 j = i + 1; + for (var key in obj) { + if (!accessor.hasOwnProperty(key)) { + continue; + } - for (; j < arr.length; ++j) { - if (arr[i] === arr[j]) { - arr.splice(j--, 1); - } + if (typeOf(obj[key]) === accessor[key]) { + continue; } - } - return arr; -}; -module.exports.immutable = function uniqueImmutable(arr) { - if (!Array.isArray(arr)) { - throw new TypeError('array-unique expects an array.'); + if (typeof obj[key] !== 'undefined') { + return false; + } } + return true; +} - var arrLen = arr.length; - var newArr = new Array(arrLen); +function has(obj, key) { + return {}.hasOwnProperty.call(obj, key); +} - for (var i = 0; i < arrLen; i++) { - newArr[i] = arr[i]; - } +/** + * Expose `isAccessorDescriptor` + */ - return module.exports(newArr); -}; +module.exports = isAccessorDescriptor; /***/ }), -/* 539 */ -/***/ (function(module, exports, __webpack_require__) { +/* 538 */ +/***/ (function(module, exports) { -"use strict"; +var toString = Object.prototype.toString; +module.exports = function kindOf(val) { + if (val === void 0) return 'undefined'; + if (val === null) return 'null'; -var utils = __webpack_require__(540); + 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'; + } -module.exports = function(braces, options) { - braces.compiler + 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'; - /** - * bos - */ + switch (ctorName(val)) { + case 'Symbol': return 'symbol'; + case 'Promise': return 'promise'; - .set('bos', function() { - if (this.output) return; - this.ast.queue = isEscaped(this.ast) ? [this.ast.val] : []; - this.ast.count = 1; - }) + // Set, Map, WeakSet, WeakMap + case 'WeakMap': return 'weakmap'; + case 'WeakSet': return 'weakset'; + case 'Map': return 'map'; + case 'Set': return 'set'; - /** - * Square brackets - */ + // 8-bit typed arrays + case 'Int8Array': return 'int8array'; + case 'Uint8Array': return 'uint8array'; + case 'Uint8ClampedArray': return 'uint8clampedarray'; - .set('bracket', function(node) { - var close = node.close; - var open = !node.escaped ? '[' : '\\['; - var negated = node.negated; - var inner = node.inner; + // 16-bit typed arrays + case 'Int16Array': return 'int16array'; + case 'Uint16Array': return 'uint16array'; - inner = inner.replace(/\\(?=[\\\w]|$)/g, '\\\\'); - if (inner === ']-') { - inner = '\\]\\-'; - } + // 32-bit typed arrays + case 'Int32Array': return 'int32array'; + case 'Uint32Array': return 'uint32array'; + case 'Float32Array': return 'float32array'; + case 'Float64Array': return 'float64array'; + } - if (negated && inner.indexOf('.') === -1) { - inner += '.'; - } - if (negated && inner.indexOf('/') === -1) { - inner += '/'; - } + if (isGeneratorObj(val)) { + return 'generator'; + } - var val = open + negated + inner + close; - var queue = node.parent.queue; - var last = utils.arrayify(queue.pop()); + // 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'; + } - queue.push(utils.join(last, val)); - queue.push.apply(queue, []); - }) + // other + return type.slice(8, -1).toLowerCase().replace(/\s/g, ''); +}; - /** - * Brace - */ +function ctorName(val) { + return typeof val.constructor === 'function' ? val.constructor.name : null; +} - .set('brace', function(node) { - node.queue = isEscaped(node) ? [node.val] : []; - node.count = 1; - return this.mapVisit(node.nodes); - }) +function isArray(val) { + if (Array.isArray) return Array.isArray(val); + return val instanceof Array; +} - /** - * Open - */ +function isError(val) { + return val instanceof Error || (typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number'); +} - .set('brace.open', function(node) { - node.parent.open = node.val; - }) +function isDate(val) { + if (val instanceof Date) return true; + return typeof val.toDateString === 'function' + && typeof val.getDate === 'function' + && typeof val.setDate === 'function'; +} - /** - * Inner - */ +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'; +} - .set('text', function(node) { - var queue = node.parent.queue; - var escaped = node.escaped; - var segs = [node.val]; +function isGeneratorFn(name, val) { + return ctorName(name) === 'GeneratorFunction'; +} - if (node.optimize === false) { - options = utils.extend({}, options, {optimize: false}); - } +function isGeneratorObj(val) { + return typeof val.throw === 'function' + && typeof val.return === 'function' + && typeof val.next === 'function'; +} - if (node.multiplier > 1) { - node.parent.count *= node.multiplier; - } +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 (options.quantifiers === true && utils.isQuantifier(node.val)) { - escaped = true; +/** + * If you need to support Safari 5-7 (8-10 yr-old browser), + * take a look at https://github.com/feross/is-buffer + */ - } else if (node.val.length > 1) { - if (isType(node.parent, 'brace') && !isEscaped(node)) { - var expanded = utils.expand(node.val, options); - segs = expanded.segs; +function isBuffer(val) { + if (val.constructor && typeof val.constructor.isBuffer === 'function') { + return val.constructor.isBuffer(val); + } + return false; +} - if (expanded.isOptimized) { - node.parent.isOptimized = true; - } - // 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, ''); - } +/***/ }), +/* 539 */ +/***/ (function(module, exports, __webpack_require__) { - segs = [val]; - escaped = true; - } - } +"use strict"; +/*! + * is-data-descriptor + * + * Copyright (c) 2015-2017, Jon Schlinkert. + * Released under the MIT License. + */ - } else if (node.val === ',') { - if (options.expand) { - node.parent.queue.push(['']); - segs = ['']; - } else { - segs = ['|']; - } - } 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; - } - } - if (!hasQueue(node.parent)) { - node.parent.queue = segs; - return; - } +var typeOf = __webpack_require__(540); - var last = utils.arrayify(queue.pop()); - if (node.parent.count > 1 && options.expand) { - last = multiply(last, node.parent.count); - node.parent.count = 1; - } +module.exports = function isDataDescriptor(obj, prop) { + // data descriptor properties + var data = { + configurable: 'boolean', + enumerable: 'boolean', + writable: 'boolean' + }; - queue.push(utils.join(utils.flatten(last), segs.shift())); - queue.push.apply(queue, segs); - }) + if (typeOf(obj) !== 'object') { + return false; + } - /** - * Close - */ + if (typeof prop === 'string') { + var val = Object.getOwnPropertyDescriptor(obj, prop); + return typeof val !== 'undefined'; + } - .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 (!('value' in obj) && !('writable' in obj)) { + return false; + } - if (open && close && isOptimized(node, options)) { - open = '('; - close = ')'; - } + for (var key in obj) { + if (key === 'value') continue; - // 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); - } + if (!data.hasOwnProperty(key)) { + continue; + } - if (close && typeof ele === 'string' && ele.length === 1) { - open = ''; - close = ''; - } + if (typeOf(obj[key]) === data[key]) { + continue; + } - if ((isLiteralBrace(node, options) || noInner(node)) && !node.parent.hasEmpty) { - queue.push(utils.join(open, queue.pop() || '')); - queue = utils.flatten(utils.join(queue, close)); - } + if (typeof obj[key] !== 'undefined') { + return false; + } + } + return true; +}; - if (typeof last === 'undefined') { - prev.queue = [queue]; - } else { - prev.queue.push(utils.flatten(utils.join(last, queue))); - } - }) - /** - * eos - */ +/***/ }), +/* 540 */ +/***/ (function(module, exports) { - .set('eos', function(node) { - if (this.input) return; +var toString = Object.prototype.toString; - 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); - } +module.exports = function kindOf(val) { + if (val === void 0) return 'undefined'; + if (val === null) return 'null'; - if (node.parent.count > 1 && options.expand) { - this.output = multiply(this.output, node.parent.count); - } + 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'; + } - this.output = utils.arrayify(this.output); - this.ast.queue = []; - }); + 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'; -}; + switch (ctorName(val)) { + case 'Symbol': return 'symbol'; + case 'Promise': return 'promise'; -/** - * Multiply the segments in the current brace level - */ + // Set, Map, WeakSet, WeakMap + case 'WeakMap': return 'weakmap'; + case 'WeakSet': return 'weakset'; + case 'Map': return 'map'; + case 'Set': return 'set'; -function multiply(queue, n, options) { - return utils.flatten(utils.repeat(utils.arrayify(queue), n)); -} + // 8-bit typed arrays + case 'Int8Array': return 'int8array'; + case 'Uint8Array': return 'uint8array'; + case 'Uint8ClampedArray': return 'uint8clampedarray'; -/** - * Return true if `node` is escaped - */ + // 16-bit typed arrays + case 'Int16Array': return 'int16array'; + case 'Uint16Array': return 'uint16array'; -function isEscaped(node) { - return node.escaped === true; -} + // 32-bit typed arrays + case 'Int32Array': return 'int32array'; + case 'Uint32Array': return 'uint32array'; + case 'Float32Array': return 'float32array'; + case 'Float64Array': return 'float64array'; + } -/** - * 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 (isGeneratorObj(val)) { + return 'generator'; + } -function isOptimized(node, options) { - if (node.parent.isOptimized) return true; - return isType(node.parent, 'brace') - && !isEscaped(node.parent) - && options.expand !== 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'; + } + + // other + return type.slice(8, -1).toLowerCase().replace(/\s/g, ''); +}; + +function ctorName(val) { + return typeof val.constructor === 'function' ? val.constructor.name : null; } -/** - * Returns true if the value in `node` should be wrapped in a literal brace. - * @return {Boolean} - */ +function isArray(val) { + if (Array.isArray) return Array.isArray(val); + return val instanceof Array; +} -function isLiteralBrace(node, options) { - return isEscaped(node.parent) || options.optimize !== false; +function isError(val) { + return val instanceof Error || (typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number'); } -/** - * Returns true if the given `node` does not have an inner value. - * @return {Boolean} - */ +function isDate(val) { + if (val instanceof Date) return true; + return typeof val.toDateString === 'function' + && typeof val.getDate === 'function' + && typeof val.setDate === 'function'; +} -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 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 `node` is the given `type` - * @return {Boolean} - */ +function isGeneratorFn(name, val) { + return ctorName(name) === 'GeneratorFunction'; +} -function isType(node, type) { - return typeof node !== 'undefined' && node.type === type; +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 the given `node` has a non-empty queue. - * @return {Boolean} + * If you need to support Safari 5-7 (8-10 yr-old browser), + * take a look at https://github.com/feross/is-buffer */ -function hasQueue(node) { - return Array.isArray(node.queue) && node.queue.length; +function isBuffer(val) { + if (val.constructor && typeof val.constructor.isBuffer === 'function') { + return val.constructor.isBuffer(val); + } + return false; } /***/ }), -/* 540 */ +/* 541 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var splitString = __webpack_require__(541); -var utils = module.exports; +var isExtendable = __webpack_require__(542); +var assignSymbols = __webpack_require__(544); -/** - * Module dependencies - */ +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; +}; -utils.extend = __webpack_require__(533); -utils.flatten = __webpack_require__(547); -utils.isObject = __webpack_require__(545); -utils.fillRange = __webpack_require__(548); -utils.repeat = __webpack_require__(555); -utils.unique = __webpack_require__(538); +function assign(a, b) { + for (var key in b) { + if (hasOwn(b, key)) { + a[key] = b[key]; + } + } +} -utils.define = function(obj, key, val) { - Object.defineProperty(obj, key, { - writable: true, - configurable: true, - enumerable: false, - value: val - }); -}; +function isString(val) { + return (val && typeof val === 'string'); +} -/** - * Returns true if the given string contains only empty brace sets. - */ +function toObject(str) { + var obj = {}; + for (var i in str) { + obj[i] = str[i]; + } + return obj; +} -utils.isEmptySets = function(str) { - return /^(?:\{,\})+$/.test(str); -}; +function isObject(val) { + return (val && typeof val === 'object') || isExtendable(val); +} /** - * Returns true if the given string contains only empty brace sets. + * Returns true if the given `key` is an own property of `obj`. */ -utils.isQuotedString = function(str) { - var open = str.charAt(0); - if (open === '\'' || open === '"' || open === '`') { - return str.slice(-1) === open; - } - return false; -}; +function hasOwn(obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key); +} -/** - * 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. - */ +function isEnum(obj, key) { + return Object.prototype.propertyIsEnumerable.call(obj, key); +} -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; -}; -/** - * Normalize options +/***/ }), +/* 542 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/*! + * is-extendable + * + * Copyright (c) 2015-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; + + +var isPlainObject = __webpack_require__(543); + +module.exports = function isExtendable(val) { + return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); }; -/** - * Join patterns in `a` to patterns in `b` + +/***/ }), +/* 543 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/*! + * is-plain-object + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. */ -utils.join = function(a, b, options) { - options = options || {}; - a = utils.arrayify(a); - b = utils.arrayify(b); - if (!a.length) return b; - if (!b.length) return a; - var len = a.length; - var idx = -1; - var arr = []; +var isObject = __webpack_require__(534); - 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; - } +function isObjectObject(o) { + return isObject(o) === true + && Object.prototype.toString.call(o) === '[object Object]'; +} - for (var j = 0; j < b.length; j++) { - var bval = b[j]; +module.exports = function isPlainObject(o) { + var ctor,prot; - if (Array.isArray(bval)) { - arr.push(utils.join(val, bval, options)); - } else { - arr.push(val + bval); - } - } - } - return arr; -}; + if (isObjectObject(o) === false) return false; -/** - * Split the given string on `,` if not escaped. - */ + // If has modified constructor + ctor = o.constructor; + if (typeof ctor !== 'function') return false; -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; + // 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 splitString(str, opts, utils.escapeBrackets(opts)); + + // Most likely a plain Object + return true; }; -/** - * Expand ranges or sets in the given `pattern`. + +/***/ }), +/* 544 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/*! + * assign-symbols * - * @param {String} `str` - * @param {Object} `options` - * @return {Object} + * Copyright (c) 2015, Jon Schlinkert. + * Licensed 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; + +module.exports = function(receiver, objects) { + if (receiver === null || typeof receiver === 'undefined') { + throw new TypeError('expected first argument to be an object.'); } - if (opts.rangeLimit === true) { - opts.rangeLimit = 10000; + if (typeof objects === 'undefined' || typeof Symbol === 'undefined') { + return receiver; } - if (segs.length > 1) { - if (opts.optimize === false) { - tok.val = segs[0]; - return tok; - } + if (typeof Object.getOwnPropertySymbols !== 'function') { + return receiver; + } - 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; - } - - 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.'); - } - } - - arr.push(opts); - tok.segs = utils.fillRange.apply(null, arr); + var isEnumerable = Object.prototype.propertyIsEnumerable; + var target = Object(receiver); + var len = arguments.length, i = 0; - if (!tok.segs.length) { - tok.escaped = true; - tok.val = str; - return tok; - } + while (++i < len) { + var provider = Object(arguments[i]); + var names = Object.getOwnPropertySymbols(provider); - if (opts.optimize === true) { - tok.segs = utils.stringifyArray(tok.segs); - } + for (var j = 0; j < names.length; j++) { + var key = names[j]; - if (tok.segs === '') { - tok.val = str; - } else { - tok.val = tok.segs[0]; + if (isEnumerable.call(provider, key)) { + target[key] = provider[key]; } - return tok; } - } else { - tok.val = str; } - 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 (ch === '\\') { - val += (opts.keepEscaping === false ? '' : ch) + str[++i]; - continue; - } - - if (ch === '(') { - parens.push(ch); - stack.push(ch); - } - - if (ch === '[') { - brackets.push(ch); - stack.push(ch); - } - - if (ch === ')') { - parens.pop(); - stack.pop(); - if (!stack.length) { - val += ch; - break; - } - } - - if (ch === ']') { - brackets.pop(); - stack.pop(); - if (!stack.length) { - val += ch; - break; - } - } - val += ch; - } - - tok.split = false; - tok.val = val.slice(1); - tok.idx = i; - }; + return target; }; -/** - * 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` - */ +/***/ }), +/* 545 */ +/***/ (function(module, exports, __webpack_require__) { -utils.stringifyArray = function(arr) { - return [utils.arrayify(arr).join('|')]; -}; +"use strict"; -/** - * Cast `val` to an array. - * @param {*} `val` - */ -utils.arrayify = function(arr) { - if (typeof arr === 'undefined') { - return []; - } - if (typeof arr === 'string') { - return [arr]; - } - return arr; -}; +var extend = __webpack_require__(546); +var safe = __webpack_require__(527); /** - * Returns true if the given `str` is a non-empty string - * @return {Boolean} + * The main export is a function that takes a `pattern` string and an `options` object. + * + * ```js + & var not = require('regex-not'); + & console.log(not('foo')); + & //=> /^(?:(?!^(?:foo)$).)*$/ + * ``` + * + * @param {String} `pattern` + * @param {Object} `options` + * @return {RegExp} Converts the given `pattern` to a regex using the specified `options`. + * @api public */ -utils.isString = function(str) { - return str != null && typeof str === 'string'; -}; +function toRegex(pattern, options) { + return new RegExp(toRegex.create(pattern, options)); +} /** - * Get the last element from `array` - * @param {Array} `array` - * @return {*} - */ - -utils.last = function(arr, n) { - return arr[arr.length - (n || 1)]; -}; - -utils.escapeRegex = function(str) { - return str.replace(/\\?([!^*?()[\]{}+?/])/g, '\\$1'); -}; - - -/***/ }), -/* 541 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * split-string + * Create a regex-compatible string from the given `pattern` and `options`. * - * Copyright (c) 2015-2017, Jon Schlinkert. - * Released under the MIT License. + * ```js + & var not = require('regex-not'); + & console.log(not.create('foo')); + & //=> '^(?:(?!^(?:foo)$).)*$' + * ``` + * @param {String} `pattern` + * @param {Object} `options` + * @return {String} + * @api public */ - - -var extend = __webpack_require__(542); - -module.exports = function(str, options, fn) { - if (typeof str !== 'string') { +toRegex.create = function(pattern, options) { + if (typeof pattern !== 'string') { throw new TypeError('expected a string'); } - if (typeof options === 'function') { - fn = options; - options = null; - } - - // allow separator to be defined as a string - if (typeof options === 'string') { - options = { sep: options }; - } - - var opts = extend({sep: '.'}, options); - var quotes = opts.quotes || ['"', "'", '`']; - var brackets; - - if (opts.brackets === true) { - brackets = { - '<': '>', - '(': ')', - '[': ']', - '{': '}' - }; - } else if (opts.brackets) { - brackets = opts.brackets; + var opts = extend({}, options); + if (opts.contains === true) { + opts.strictNegate = false; } - var tokens = []; - var stack = []; - var arr = ['']; - var sep = opts.sep; - var len = str.length; - var idx = -1; - var closeIdx; + var open = opts.strictOpen !== false ? '^' : ''; + var close = opts.strictClose !== false ? '$' : ''; + var endChar = opts.endChar ? opts.endChar : '+'; + var str = pattern; - function expected() { - if (brackets && stack.length) { - return brackets[stack[stack.length - 1]]; - } + if (opts.strictNegate === false) { + str = '(?:(?!(?:' + pattern + ')).)' + endChar; + } else { + str = '(?:(?!^(?:' + pattern + ')$).)' + endChar; } - 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; - } - - if (brackets && brackets[ch]) { - stack.push(ch); - var e = expected(); - var i = idx + 1; - - if (str.indexOf(e, i + 1) !== -1) { - while (stack.length && i < len) { - var s = str[++i]; - if (s === '\\') { - s++; - continue; - } - - if (quotes.indexOf(s) !== -1) { - i = getClosingQuote(str, s, i + 1); - continue; - } - - e = expected(); - if (stack.length && str.indexOf(e, i + 1) === -1) { - break; - } - - if (brackets[s]) { - stack.push(s); - continue; - } - - 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; + var res = open + str + close; + if (opts.safe === true && safe(res) === false) { + throw new Error('potentially unsafe regular expression: ' + res); } - return arr; + return res; }; -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; -} +/** + * Expose `toRegex` + */ -function keepEscaping(opts, str, idx) { - if (typeof opts.keepEscaping === 'function') { - return opts.keepEscaping(str, idx); - } - return opts.keepEscaping === true || str[idx + 1] === '\\'; -} +module.exports = toRegex; /***/ }), -/* 542 */ +/* 546 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(543); -var assignSymbols = __webpack_require__(546); +var isExtendable = __webpack_require__(547); +var assignSymbols = __webpack_require__(544); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -62335,7 +62217,7 @@ function isEnum(obj, key) { /***/ }), -/* 543 */ +/* 547 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62348,7 +62230,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(544); +var isPlainObject = __webpack_require__(543); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -62356,75 +62238,102 @@ module.exports = function isExtendable(val) { /***/ }), -/* 544 */ +/* 548 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! - * is-plain-object + * array-unique * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. + * Copyright (c) 2014-2015, Jon Schlinkert. + * Licensed under the MIT License. */ -var isObject = __webpack_require__(545); +module.exports = function unique(arr) { + if (!Array.isArray(arr)) { + throw new TypeError('array-unique expects an array.'); + } -function isObjectObject(o) { - return isObject(o) === true - && Object.prototype.toString.call(o) === '[object Object]'; -} + var len = arr.length; + var i = -1; -module.exports = function isPlainObject(o) { - var ctor,prot; + while (i++ < len) { + var j = i + 1; - if (isObjectObject(o) === false) return false; + for (; j < arr.length; ++j) { + if (arr[i] === arr[j]) { + arr.splice(j--, 1); + } + } + } + return arr; +}; - // If has modified constructor - ctor = o.constructor; - if (typeof ctor !== 'function') return false; +module.exports.immutable = function uniqueImmutable(arr) { + if (!Array.isArray(arr)) { + throw new TypeError('array-unique expects an array.'); + } - // If has modified prototype - prot = ctor.prototype; - if (isObjectObject(prot) === false) return false; + var arrLen = arr.length; + var newArr = new Array(arrLen); - // If constructor does not have an Object-specific method - if (prot.hasOwnProperty('isPrototypeOf') === false) { - return false; + for (var i = 0; i < arrLen; i++) { + newArr[i] = arr[i]; } - // Most likely a plain Object - return true; + return module.exports(newArr); }; /***/ }), -/* 545 */ +/* 549 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/*! - * isobject - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ +var isObject = __webpack_require__(550); -module.exports = function isObject(val) { - return val != null && typeof val === 'object' && Array.isArray(val) === false; +module.exports = function extend(o/*, objects*/) { + if (!isObject(o)) { o = {}; } + + var len = arguments.length; + for (var i = 1; i < len; i++) { + var obj = arguments[i]; + + if (isObject(obj)) { + assign(o, obj); + } + } + return o; }; +function assign(a, b) { + for (var key in b) { + if (hasOwn(b, key)) { + a[key] = b[key]; + } + } +} + +/** + * Returns true if the given `key` is an own property of `obj`. + */ + +function hasOwn(obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key); +} + /***/ }), -/* 546 */ +/* 550 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! - * assign-symbols + * is-extendable * * Copyright (c) 2015, Jon Schlinkert. * Licensed under the MIT License. @@ -62432,4129 +62341,2610 @@ module.exports = function isObject(val) { -module.exports = function(receiver, objects) { - if (receiver === null || typeof receiver === 'undefined') { - throw new TypeError('expected first argument to be an object.'); - } +module.exports = function isExtendable(val) { + return typeof val !== 'undefined' && val !== null + && (typeof val === 'object' || typeof val === 'function'); +}; - if (typeof objects === 'undefined' || typeof Symbol === 'undefined') { - return receiver; - } - if (typeof Object.getOwnPropertySymbols !== 'function') { - return receiver; - } +/***/ }), +/* 551 */ +/***/ (function(module, exports, __webpack_require__) { - var isEnumerable = Object.prototype.propertyIsEnumerable; - var target = Object(receiver); - var len = arguments.length, i = 0; +"use strict"; - 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]; +var utils = __webpack_require__(552); - if (isEnumerable.call(provider, key)) { - target[key] = provider[key]; - } - } - } - return target; -}; +module.exports = function(braces, options) { + braces.compiler + /** + * bos + */ -/***/ }), -/* 547 */ -/***/ (function(module, exports, __webpack_require__) { + .set('bos', function() { + if (this.output) return; + this.ast.queue = isEscaped(this.ast) ? [this.ast.val] : []; + this.ast.count = 1; + }) -"use strict"; -/*! - * arr-flatten - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ + /** + * Square brackets + */ + .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 = '\\]\\-'; + } -module.exports = function (arr) { - return flat(arr, []); -}; + if (negated && inner.indexOf('.') === -1) { + inner += '.'; + } + if (negated && inner.indexOf('/') === -1) { + inner += '/'; + } -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; -} + 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, []); + }) -/***/ }), -/* 548 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Brace + */ -"use strict"; -/*! - * fill-range - * - * Copyright (c) 2014-2015, 2017, Jon Schlinkert. - * Released under the MIT License. - */ + .set('brace', function(node) { + node.queue = isEscaped(node) ? [node.val] : []; + node.count = 1; + return this.mapVisit(node.nodes); + }) + /** + * Open + */ + .set('brace.open', function(node) { + node.parent.open = node.val; + }) -var util = __webpack_require__(111); -var isNumber = __webpack_require__(549); -var extend = __webpack_require__(551); -var repeat = __webpack_require__(553); -var toRegex = __webpack_require__(554); + /** + * Inner + */ -/** - * 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} - */ + .set('text', function(node) { + var queue = node.parent.queue; + var escaped = node.escaped; + var segs = [node.val]; -function fillRange(start, stop, step, options) { - if (typeof start === 'undefined') { - return []; - } + if (node.optimize === false) { + options = utils.extend({}, options, {optimize: false}); + } - 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 (node.multiplier > 1) { + node.parent.count *= node.multiplier; + } - if (typeof step !== 'number' && typeof step !== 'string') { - options = step; - step = undefined; - } + if (options.quantifiers === true && utils.isQuantifier(node.val)) { + escaped = true; - if (typeof options === 'function') { - options = { transform: options }; - } + } else if (node.val.length > 1) { + if (isType(node.parent, 'brace') && !isEscaped(node)) { + var expanded = utils.expand(node.val, options); + segs = expanded.segs; - 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 []; - } + if (expanded.isOptimized) { + node.parent.isOptimized = true; + } - 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 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, ''); + } - opts.isPadded = isPadded(start) || isPadded(stop); - opts.toString = opts.stringify - || typeof opts.step === 'string' - || typeof start === 'string' - || typeof stop === 'string' - || !opts.isNumber; + segs = [val]; + escaped = true; + } + } - if (opts.isPadded) { - opts.maxLength = Math.max(String(start).length, String(stop).length); - } + } else if (node.val === ',') { + if (options.expand) { + node.parent.queue.push(['']); + segs = ['']; + } else { + segs = ['|']; + } + } else { + escaped = true; + } - // 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); -} + 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; + } + } -function expand(start, stop, options) { - var a = options.isNumber ? toNumber(start) : start.charCodeAt(0); - var b = options.isNumber ? toNumber(stop) : stop.charCodeAt(0); + if (!hasQueue(node.parent)) { + node.parent.queue = segs; + return; + } - var step = Math.abs(toNumber(options.step)) || 1; - if (options.toRegex && step === 1) { - return toRange(a, b, start, stop, options); - } + var last = utils.arrayify(queue.pop()); + if (node.parent.count > 1 && options.expand) { + last = multiply(last, node.parent.count); + node.parent.count = 1; + } - var zero = {greater: [], lesser: []}; - var asc = a < b; - var arr = new Array(Math.round((asc ? b - a : a - b) / step)); - var idx = 0; + queue.push(utils.join(utils.flatten(last), segs.shift())); + queue.push.apply(queue, segs); + }) - while (asc ? a <= b : a >= b) { - var val = options.isNumber ? a : String.fromCharCode(a); - if (options.toRegex && (val >= 0 || !options.isNumber)) { - zero.greater.push(val); - } else { - zero.lesser.push(Math.abs(val)); - } + /** + * Close + */ - if (options.isPadded) { - val = zeros(val, options); - } + .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 (options.toString) { - val = String(val); - } + if (open && close && isOptimized(node, options)) { + open = '('; + close = ')'; + } - if (typeof options.transform === 'function') { - arr[idx++] = options.transform(val, a, b, step, idx, arr, options); - } else { - arr[idx++] = 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); + } - if (asc) { - a += step; - } else { - a -= step; - } - } + if (close && typeof ele === 'string' && ele.length === 1) { + open = ''; + close = ''; + } - if (options.toRegex === true) { - return toSequence(arr, zero, options); - } - return arr; -} + if ((isLiteralBrace(node, options) || noInner(node)) && !node.parent.hasEmpty) { + queue.push(utils.join(open, queue.pop() || '')); + queue = utils.flatten(utils.join(queue, close)); + } -function toRange(a, b, start, stop, options) { - if (options.isPadded) { - return toRegex(start, stop, options); - } + if (typeof last === 'undefined') { + prev.queue = [queue]; + } else { + prev.queue.push(utils.flatten(utils.join(last, queue))); + } + }) - if (options.isNumber) { - return toRegex(Math.min(a, b), Math.max(a, b), options); - } + /** + * eos + */ - var start = String.fromCharCode(Math.min(a, b)); - var stop = String.fromCharCode(Math.max(a, b)); - return '[' + start + '-' + stop + ']'; -} + .set('eos', function(node) { + if (this.input) return; -function toSequence(arr, zeros, options) { - var greater = '', lesser = ''; - if (zeros.greater.length) { - greater = zeros.greater.join('|'); - } - if (zeros.lesser.length) { - lesser = '-(' + zeros.lesser.join('|') + ')'; - } - var res = greater && lesser - ? greater + '|' + lesser - : greater || lesser; + 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); + } - if (options.capture) { - return '(' + res + ')'; - } - return res; -} + if (node.parent.count > 1 && options.expand) { + this.output = multiply(this.output, node.parent.count); + } -function zeros(val, options) { - if (options.isPadded) { - var str = String(val); - var len = str.length; - var dash = ''; - if (str.charAt(0) === '-') { - dash = '-'; - str = str.slice(1); - } - var diff = options.maxLength - len; - var pad = repeat('0', diff); - val = (dash + pad + str); - } - if (options.stringify) { - return String(val); - } - return val; + this.output = utils.arrayify(this.output); + this.ast.queue = []; + }); + +}; + +/** + * Multiply the segments in the current brace level + */ + +function multiply(queue, n, options) { + return utils.flatten(utils.repeat(utils.arrayify(queue), n)); } -function toNumber(val) { - return Number(val) || 0; +/** + * Return true if `node` is escaped + */ + +function isEscaped(node) { + return node.escaped === true; } -function isPadded(str) { - return /^-?0\d/.test(str); +/** + * 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 isValid(min, max) { - return (isValidNumber(min) || isValidLetter(min)) - && (isValidNumber(max) || isValidLetter(max)); +/** + * 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 isValidLetter(ch) { - return typeof ch === 'string' && ch.length === 1 && /^\w+$/.test(ch); +/** + * 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 isValidNumber(n) { - return isNumber(n) && !/\./.test(n); +/** + * Returns true if the given `node` is the given `type` + * @return {Boolean} + */ + +function isType(node, type) { + return typeof node !== 'undefined' && node.type === type; } /** - * Expose `fillRange` - * @type {Function} + * Returns true if the given `node` has a non-empty queue. + * @return {Boolean} */ -module.exports = fillRange; +function hasQueue(node) { + return Array.isArray(node.queue) && node.queue.length; +} /***/ }), -/* 549 */ +/* 552 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/*! - * is-number - * - * Copyright (c) 2014-2015, Jon Schlinkert. - * Licensed under the MIT License. - */ +var splitString = __webpack_require__(553); +var utils = module.exports; -var typeOf = __webpack_require__(550); - -module.exports = function isNumber(num) { - var type = typeOf(num); +/** + * Module dependencies + */ - if (type === 'string') { - if (!num.trim()) return false; - } else if (type !== 'number') { - return false; - } +utils.extend = __webpack_require__(549); +utils.flatten = __webpack_require__(556); +utils.isObject = __webpack_require__(534); +utils.fillRange = __webpack_require__(557); +utils.repeat = __webpack_require__(563); +utils.unique = __webpack_require__(548); - return (num - num + 1) >= 0; +utils.define = function(obj, key, val) { + Object.defineProperty(obj, key, { + writable: true, + configurable: true, + enumerable: false, + value: val + }); }; +/** + * Returns true if the given string contains only empty brace sets. + */ -/***/ }), -/* 550 */ -/***/ (function(module, exports, __webpack_require__) { +utils.isEmptySets = function(str) { + return /^(?:\{,\})+$/.test(str); +}; -var isBuffer = __webpack_require__(530); -var toString = Object.prototype.toString; +/** + * Returns true if the given string contains only empty brace sets. + */ + +utils.isQuotedString = function(str) { + var open = str.charAt(0); + if (open === '\'' || open === '"' || open === '`') { + return str.slice(-1) === open; + } + return false; +}; /** - * Get the native `typeof` a value. - * - * @param {*} `val` - * @return {*} Native javascript type + * 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. */ -module.exports = function kindOf(val) { - // primitivies - if (typeof val === 'undefined') { - return 'undefined'; +utils.createKey = function(pattern, options) { + var id = pattern; + if (typeof options === 'undefined') { + return id; } - if (val === null) { - return 'null'; + var keys = Object.keys(options); + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + id += ';' + key + '=' + String(options[key]); } - if (val === true || val === false || val instanceof Boolean) { - return 'boolean'; + return id; +}; + +/** + * Normalize options + */ + +utils.createOptions = function(options) { + var opts = utils.extend.apply(null, arguments); + if (typeof opts.expand === 'boolean') { + opts.optimize = !opts.expand; } - if (typeof val === 'string' || val instanceof String) { - return 'string'; + if (typeof opts.optimize === 'boolean') { + opts.expand = !opts.optimize; } - if (typeof val === 'number' || val instanceof Number) { - return 'number'; + if (opts.optimize === true) { + opts.makeRe = true; } + return opts; +}; - // functions - if (typeof val === 'function' || val instanceof Function) { - return 'function'; - } +/** + * Join patterns in `a` to patterns in `b` + */ - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; - } +utils.join = function(a, b, options) { + options = options || {}; + a = utils.arrayify(a); + b = utils.arrayify(b); - // check for instances of RegExp and Date before calling `toString` - if (val instanceof RegExp) { - return 'regexp'; - } - if (val instanceof Date) { - return 'date'; - } + if (!a.length) return b; + if (!b.length) return a; - // other objects - var type = toString.call(val); + var len = a.length; + var idx = -1; + var arr = []; - if (type === '[object RegExp]') { - return 'regexp'; - } - if (type === '[object Date]') { - return 'date'; - } - if (type === '[object Arguments]') { - return 'arguments'; - } - if (type === '[object Error]') { - return 'error'; - } + 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; + } - // buffer - if (isBuffer(val)) { - return 'buffer'; - } + for (var j = 0; j < b.length; j++) { + var bval = b[j]; - // 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 (Array.isArray(bval)) { + arr.push(utils.join(val, bval, options)); + } else { + arr.push(val + bval); + } + } } + return arr; +}; - // 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'; +/** + * 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 (type === '[object Uint32Array]') { - return 'uint32array'; + if (opts.unescape === false) { + opts.keepEscaping = true; } - if (type === '[object Float32Array]') { - return 'float32array'; + return splitString(str, opts, utils.escapeBrackets(opts)); +}; + +/** + * Expand ranges or sets in the given `pattern`. + * + * @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 }; + + if (utils.isQuotedString(str)) { + return tok; } - if (type === '[object Float64Array]') { - return 'float64array'; + + if (opts.rangeLimit === true) { + opts.rangeLimit = 10000; } - // must be a plain object - return 'object'; -}; + 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('..'); -/***/ }), -/* 551 */ -/***/ (function(module, exports, __webpack_require__) { + if (arr.length === 1) { + tok.val = tok.segs[tok.segs.length - 1] || tok.val || str; + tok.segs = []; + return tok; + } -"use strict"; + 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; + } + 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 isObject = __webpack_require__(552); + 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 extend(o/*, objects*/) { - if (!isObject(o)) { o = {}; } + arr.push(opts); + tok.segs = utils.fillRange.apply(null, arr); - var len = arguments.length; - for (var i = 1; i < len; i++) { - var obj = arguments[i]; + if (!tok.segs.length) { + tok.escaped = true; + tok.val = str; + return tok; + } - if (isObject(obj)) { - assign(o, obj); - } - } - return o; -}; + if (opts.optimize === true) { + tok.segs = utils.stringifyArray(tok.segs); + } -function assign(a, b) { - for (var key in b) { - if (hasOwn(b, key)) { - a[key] = b[key]; + if (tok.segs === '') { + tok.val = str; + } else { + tok.val = tok.segs[0]; + } + return tok; } + } else { + tok.val = str; } -} + return tok; +}; /** - * Returns true if the given `key` is an own property of `obj`. + * Ensure commas inside brackets and parens are not split. + * @param {Object} `tok` Token from the `split-string` module + * @return {undefined} */ -function hasOwn(obj, key) { - return Object.prototype.hasOwnProperty.call(obj, key); -} - - -/***/ }), -/* 552 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * is-extendable - * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. - */ +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]; -module.exports = function isExtendable(val) { - return typeof val !== 'undefined' && val !== null - && (typeof val === 'object' || typeof val === 'function'); -}; + if (ch === '\\') { + val += (opts.keepEscaping === false ? '' : ch) + str[++i]; + continue; + } + if (ch === '(') { + parens.push(ch); + stack.push(ch); + } -/***/ }), -/* 553 */ -/***/ (function(module, exports, __webpack_require__) { + if (ch === '[') { + brackets.push(ch); + stack.push(ch); + } -"use strict"; -/*! - * repeat-string - * - * Copyright (c) 2014-2015, Jon Schlinkert. - * Licensed under the MIT License. - */ + if (ch === ')') { + parens.pop(); + stack.pop(); + if (!stack.length) { + val += ch; + break; + } + } + if (ch === ']') { + brackets.pop(); + stack.pop(); + if (!stack.length) { + val += ch; + break; + } + } + val += ch; + } + tok.split = false; + tok.val = val.slice(1); + tok.idx = i; + }; +}; /** - * Results cache + * Returns true if the given string looks like a regex quantifier + * @return {Boolean} */ -var res = ''; -var cache; +utils.isQuantifier = function(str) { + return /^(?:[0-9]?,[0-9]|[0-9],)$/.test(str); +}; /** - * Expose `repeat` + * Cast `val` to an array. + * @param {*} `val` */ -module.exports = repeat; +utils.stringifyArray = function(arr) { + return [utils.arrayify(arr).join('|')]; +}; /** - * Repeat the given `string` the specified `number` - * of times. - * - * **Example:** - * - * ```js - * var repeat = require('repeat-string'); - * repeat('A', 5); - * //=> AAAAA - * ``` - * - * @param {String} `string` The string to repeat - * @param {Number} `number` The number of times to repeat the string - * @return {String} Repeated string - * @api public + * Cast `val` to an array. + * @param {*} `val` */ -function repeat(str, num) { - if (typeof str !== 'string') { - throw new TypeError('expected a string'); +utils.arrayify = function(arr) { + if (typeof arr === 'undefined') { + return []; + } + if (typeof arr === 'string') { + return [arr]; } + return arr; +}; - // cover common, quick use cases - if (num === 1) return str; - if (num === 2) return str + str; +/** + * Returns true if the given `str` is a non-empty string + * @return {Boolean} + */ - var max = str.length * num; - if (cache !== str || typeof cache === 'undefined') { - cache = str; - res = ''; - } else if (res.length >= max) { - return res.substr(0, max); - } +utils.isString = function(str) { + return str != null && typeof str === 'string'; +}; - while (max > res.length && num > 1) { - if (num & 1) { - res += str; - } +/** + * Get the last element from `array` + * @param {Array} `array` + * @return {*} + */ - num >>= 1; - str += str; - } +utils.last = function(arr, n) { + return arr[arr.length - (n || 1)]; +}; - res += str; - res = res.substr(0, max); - return res; -} +utils.escapeRegex = function(str) { + return str.replace(/\\?([!^*?()[\]{}+?/])/g, '\\$1'); +}; /***/ }), -/* 554 */ +/* 553 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! - * to-regex-range + * split-string * - * Copyright (c) 2015, 2017, Jon Schlinkert. + * Copyright (c) 2015-2017, Jon Schlinkert. * Released under the MIT License. */ -var repeat = __webpack_require__(553); -var isNumber = __webpack_require__(549); -var cache = {}; +var extend = __webpack_require__(554); -function toRegexRange(min, max, options) { - if (isNumber(min) === false) { - throw new RangeError('toRegexRange: first argument is invalid.'); +module.exports = function(str, options, fn) { + if (typeof str !== 'string') { + throw new TypeError('expected a string'); } - if (typeof max === 'undefined' || min === max) { - return String(min); + if (typeof options === 'function') { + fn = options; + options = null; } - if (isNumber(max) === false) { - throw new RangeError('toRegexRange: second argument is invalid.'); + // allow separator to be defined as a string + if (typeof options === 'string') { + options = { sep: options }; } - options = options || {}; - var relax = String(options.relaxZeros); - var shorthand = String(options.shorthand); - var capture = String(options.capture); - var key = min + ':' + max + '=' + relax + shorthand + capture; - if (cache.hasOwnProperty(key)) { - return cache[key].result; + var opts = extend({sep: '.'}, options); + var quotes = opts.quotes || ['"', "'", '`']; + var brackets; + + if (opts.brackets === true) { + brackets = { + '<': '>', + '(': ')', + '[': ']', + '{': '}' + }; + } else if (opts.brackets) { + brackets = opts.brackets; } - var a = Math.min(min, max); - var b = Math.max(min, max); + var tokens = []; + var stack = []; + var arr = ['']; + var sep = opts.sep; + var len = str.length; + var idx = -1; + var closeIdx; - if (Math.abs(a - b) === 1) { - var result = min + '|' + max; - if (options.capture) { - return '(' + result + ')'; + function expected() { + if (brackets && stack.length) { + return brackets[stack[stack.length - 1]]; } - return result; } - var isPadded = padding(min) || padding(max); - var positives = []; - var negatives = []; - - var tok = {min: min, max: max, a: a, b: b}; - if (isPadded) { - tok.isPadded = isPadded; - tok.maxLen = String(tok.max).length; - } + 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 (a < 0) { - var newMin = b < 0 ? Math.abs(b) : 1; - var newMax = Math.abs(a); - negatives = splitToPatterns(newMin, newMax, tok, options); - a = tok.a = 0; - } + 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 (b >= 0) { - positives = splitToPatterns(a, b, tok, options); - } + if (brackets && brackets[ch]) { + stack.push(ch); + var e = expected(); + var i = idx + 1; - tok.negatives = negatives; - tok.positives = positives; - tok.result = siftPatterns(negatives, positives, options); + if (str.indexOf(e, i + 1) !== -1) { + while (stack.length && i < len) { + var s = str[++i]; + if (s === '\\') { + s++; + continue; + } - if (options.capture && (positives.length + negatives.length) > 1) { - tok.result = '(' + tok.result + ')'; - } + if (quotes.indexOf(s) !== -1) { + i = getClosingQuote(str, s, i + 1); + continue; + } - cache[key] = tok; - return tok.result; -} + e = expected(); + if (stack.length && str.indexOf(e, i + 1) === -1) { + break; + } -function siftPatterns(neg, pos, options) { - var onlyNegative = filterPatterns(neg, pos, '-', false, options) || []; - var onlyPositive = filterPatterns(pos, neg, '', false, options) || []; - var intersected = filterPatterns(neg, pos, '-?', true, options) || []; - var subpatterns = onlyNegative.concat(intersected).concat(onlyPositive); - return subpatterns.join('|'); -} + if (brackets[s]) { + stack.push(s); + continue; + } -function splitToRanges(min, max) { - min = Number(min); - max = Number(max); + if (e === s) { + stack.pop(); + } + } + } - var nines = 1; - var stops = [max]; - var stop = +countNines(min, nines); + closeIdx = i; + if (closeIdx === -1) { + arr[arr.length - 1] += ch; + continue; + } - while (min <= stop && stop <= max) { - stops = push(stops, stop); - nines += 1; - stop = +countNines(min, nines); - } + ch = str.slice(idx, closeIdx + 1); + tok.val = ch; + tok.idx = idx = closeIdx; + } - var zeros = 1; - stop = countZeros(max + 1, zeros) - 1; + if (quotes.indexOf(ch) !== -1) { + closeIdx = getClosingQuote(str, ch, idx + 1); + if (closeIdx === -1) { + arr[arr.length - 1] += ch; + continue; + } - while (min < stop && stop <= max) { - stops = push(stops, stop); - zeros += 1; - stop = countZeros(max + 1, zeros) - 1; + 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; } - stops.sort(compare); - return stops; + 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; } -/** - * Convert a range to a regex pattern - * @param {Number} `start` - * @param {Number} `stop` - * @return {String} - */ +function keepQuotes(ch, opts) { + if (opts.keepDoubleQuotes === true && ch === '"') return true; + if (opts.keepSingleQuotes === true && ch === "'") return true; + return opts.keepQuotes; +} -function rangeToPattern(start, stop, options) { - if (start === stop) { - return {pattern: String(start), digits: []}; +function keepEscaping(opts, str, idx) { + if (typeof opts.keepEscaping === 'function') { + return opts.keepEscaping(str, idx); } + return opts.keepEscaping === true || str[idx + 1] === '\\'; +} - var zipped = zip(String(start), String(stop)); - var len = zipped.length, i = -1; - var pattern = ''; - var digits = 0; +/***/ }), +/* 554 */ +/***/ (function(module, exports, __webpack_require__) { - while (++i < len) { - var numbers = zipped[i]; - var startDigit = numbers[0]; - var stopDigit = numbers[1]; +"use strict"; - if (startDigit === stopDigit) { - pattern += startDigit; - } else if (startDigit !== '0' || stopDigit !== '9') { - pattern += toCharacterClass(startDigit, stopDigit); +var isExtendable = __webpack_require__(555); +var assignSymbols = __webpack_require__(544); - } else { - digits += 1; +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; +}; - if (digits) { - pattern += options.shorthand ? '\\d' : '[0-9]'; +function assign(a, b) { + for (var key in b) { + if (hasOwn(b, key)) { + a[key] = b[key]; + } } +} - return { pattern: pattern, digits: [digits] }; +function isString(val) { + return (val && typeof val === 'string'); } -function splitToPatterns(min, max, tok, options) { - var ranges = splitToRanges(min, max); - var len = ranges.length; - var idx = -1; +function toObject(str) { + var obj = {}; + for (var i in str) { + obj[i] = str[i]; + } + return obj; +} - var tokens = []; - var start = min; - var prev; +function isObject(val) { + return (val && typeof val === 'object') || isExtendable(val); +} - while (++idx < len) { - var range = ranges[idx]; - var obj = rangeToPattern(start, range, options); - var zeros = ''; +/** + * Returns true if the given `key` is an own property of `obj`. + */ - if (!tok.isPadded && prev && prev.pattern === obj.pattern) { - if (prev.digits.length > 1) { - prev.digits.pop(); - } - prev.digits.push(obj.digits[0]); - prev.string = prev.pattern + toQuantifier(prev.digits); - start = range + 1; - continue; +function hasOwn(obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key); +} + +function isEnum(obj, key) { + return Object.prototype.propertyIsEnumerable.call(obj, key); +} + + +/***/ }), +/* 555 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/*! + * is-extendable + * + * Copyright (c) 2015-2017, Jon Schlinkert. + * Released under the MIT License. + */ + + + +var isPlainObject = __webpack_require__(543); + +module.exports = function isExtendable(val) { + return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); +}; + + +/***/ }), +/* 556 */ +/***/ (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; +} + + +/***/ }), +/* 557 */ +/***/ (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__(112); +var isNumber = __webpack_require__(558); +var extend = __webpack_require__(549); +var repeat = __webpack_require__(561); +var toRegex = __webpack_require__(562); + +/** + * 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 (tok.isPadded) { - zeros = padZeros(range, tok); + 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 []; + } - obj.string = zeros + obj.pattern + toQuantifier(obj.digits); - tokens.push(obj); - start = range + 1; - prev = obj; + 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 []; } - return tokens; + 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 filterPatterns(arr, comparison, prefix, intersection, options) { - var res = []; +function expand(start, stop, options) { + var a = options.isNumber ? toNumber(start) : start.charCodeAt(0); + var b = options.isNumber ? toNumber(stop) : stop.charCodeAt(0); - for (var i = 0; i < arr.length; i++) { - var tok = arr[i]; - var ele = tok.string; + var step = Math.abs(toNumber(options.step)) || 1; + if (options.toRegex && step === 1) { + return toRange(a, b, start, stop, options); + } - if (options.relaxZeros !== false) { - if (prefix === '-' && ele.charAt(0) === '0') { - if (ele.charAt(1) === '{') { - ele = '0*' + ele.replace(/^0\{\d+\}/, ''); - } else { - ele = '0*' + ele.slice(1); - } - } + 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); + if (options.toRegex && (val >= 0 || !options.isNumber)) { + zero.greater.push(val); + } else { + zero.lesser.push(Math.abs(val)); } - if (!intersection && !contains(comparison, 'string', ele)) { - res.push(prefix + ele); + if (options.isPadded) { + val = zeros(val, options); } - if (intersection && contains(comparison, 'string', ele)) { - res.push(prefix + ele); + if (options.toString) { + val = String(val); } - } - return res; -} -/** - * Zip strings (`for in` can be used on string characters) - */ + if (typeof options.transform === 'function') { + arr[idx++] = options.transform(val, a, b, step, idx, arr, options); + } else { + arr[idx++] = val; + } -function zip(a, b) { - var arr = []; - for (var ch in a) arr.push([a[ch], b[ch]]); + if (asc) { + a += step; + } else { + a -= step; + } + } + + if (options.toRegex === true) { + return toSequence(arr, zero, options); + } return arr; } -function compare(a, b) { - return a > b ? 1 : b > a ? -1 : 0; -} +function toRange(a, b, start, stop, options) { + if (options.isPadded) { + return toRegex(start, stop, options); + } -function push(arr, ele) { - if (arr.indexOf(ele) === -1) arr.push(ele); - return arr; + if (options.isNumber) { + return toRegex(Math.min(a, b), Math.max(a, b), options); + } + + var start = String.fromCharCode(Math.min(a, b)); + var stop = String.fromCharCode(Math.max(a, b)); + return '[' + start + '-' + stop + ']'; } -function contains(arr, key, val) { - for (var i = 0; i < arr.length; i++) { - if (arr[i][key] === val) { - return true; - } +function toSequence(arr, zeros, options) { + var greater = '', lesser = ''; + if (zeros.greater.length) { + greater = zeros.greater.join('|'); } - return false; + if (zeros.lesser.length) { + lesser = '-(' + zeros.lesser.join('|') + ')'; + } + var res = greater && lesser + ? greater + '|' + lesser + : greater || lesser; + + if (options.capture) { + return '(' + res + ')'; + } + return res; } -function countNines(min, len) { - return String(min).slice(0, -len) + repeat('9', len); +function zeros(val, options) { + if (options.isPadded) { + var str = String(val); + var len = str.length; + var dash = ''; + if (str.charAt(0) === '-') { + dash = '-'; + str = str.slice(1); + } + var diff = options.maxLength - len; + var pad = repeat('0', diff); + val = (dash + pad + str); + } + if (options.stringify) { + return String(val); + } + return val; } -function countZeros(integer, zeros) { - return integer - (integer % Math.pow(10, zeros)); +function toNumber(val) { + return Number(val) || 0; } -function toQuantifier(digits) { - var start = digits[0]; - var stop = digits[1] ? (',' + digits[1]) : ''; - if (!stop && (!start || start === 1)) { - return ''; - } - return '{' + start + stop + '}'; +function isPadded(str) { + return /^-?0\d/.test(str); } -function toCharacterClass(a, b) { - return '[' + a + ((b - a === 1) ? '' : '-') + b + ']'; +function isValid(min, max) { + return (isValidNumber(min) || isValidLetter(min)) + && (isValidNumber(max) || isValidLetter(max)); } -function padding(str) { - return /^-?(0+)\d/.exec(str); +function isValidLetter(ch) { + return typeof ch === 'string' && ch.length === 1 && /^\w+$/.test(ch); } -function padZeros(val, tok) { - if (tok.isPadded) { - var diff = Math.abs(tok.maxLen - String(val).length); - switch (diff) { - case 0: - return ''; - case 1: - return '0'; - default: { - return '0{' + diff + '}'; - } - } - } - return val; +function isValidNumber(n) { + return isNumber(n) && !/\./.test(n); } /** - * Expose `toRegexRange` + * Expose `fillRange` + * @type {Function} */ -module.exports = toRegexRange; +module.exports = fillRange; /***/ }), -/* 555 */ +/* 558 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! - * repeat-element + * is-number * - * Copyright (c) 2015 Jon Schlinkert. - * Licensed under the MIT license. + * Copyright (c) 2014-2015, Jon Schlinkert. + * Licensed under the MIT License. */ -module.exports = function repeat(ele, num) { - var arr = new Array(num); +var typeOf = __webpack_require__(559); - for (var i = 0; i < num; i++) { - arr[i] = ele; +module.exports = function isNumber(num) { + var type = typeOf(num); + + if (type === 'string') { + if (!num.trim()) return false; + } else if (type !== 'number') { + return false; } - return arr; + return (num - num + 1) >= 0; }; /***/ }), -/* 556 */ +/* 559 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - - -var Node = __webpack_require__(557); -var utils = __webpack_require__(540); +var isBuffer = __webpack_require__(560); +var toString = Object.prototype.toString; /** - * Braces parsers + * Get the native `typeof` a value. + * + * @param {*} `val` + * @return {*} Native javascript type */ -module.exports = function(braces, options) { - braces.parser - .set('bos', function() { - if (!this.parsed) { - this.ast = this.nodes[0] = new Node(this.ast); - } - }) - - /** - * Character parsers - */ - - .set('escape', function() { - var pos = this.position(); - var m = this.match(/^(?:\\(.)|\$\{)/); - if (!m) return; - - var prev = this.prev(); - var last = utils.last(prev.nodes); - - var node = pos(new Node({ - type: 'text', - multiplier: 1, - val: m[0] - })); +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'; + } - if (node.val === '\\\\') { - return node; - } + // functions + if (typeof val === 'function' || val instanceof Function) { + return 'function'; + } - if (node.val === '${') { - var str = this.input; - var idx = -1; - var ch; + // array + if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { + return 'array'; + } - while ((ch = str[++idx])) { - this.consume(1); - node.val += ch; - if (ch === '\\') { - node.val += str[++idx]; - continue; - } - if (ch === '}') { - break; - } - } - } + // check for instances of RegExp and Date before calling `toString` + if (val instanceof RegExp) { + return 'regexp'; + } + if (val instanceof Date) { + return 'date'; + } - if (this.options.unescape !== false) { - node.val = node.val.replace(/\\([{}])/g, '$1'); - } + // other objects + var type = toString.call(val); - if (last.val === '"' && this.input.charAt(0) === '"') { - last.val = node.val; - this.consume(1); - return; - } + if (type === '[object RegExp]') { + return 'regexp'; + } + if (type === '[object Date]') { + return 'date'; + } + if (type === '[object Arguments]') { + return 'arguments'; + } + if (type === '[object Error]') { + return 'error'; + } - return concatNodes.call(this, pos, node, prev, options); - }) + // buffer + if (isBuffer(val)) { + return 'buffer'; + } - /** - * Brackets: "[...]" (basic, this is overridden by - * other parsers in more advanced implementations) - */ + // 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'; + } - .set('bracket', function() { - var isInside = this.isInside('brace'); - var pos = this.position(); - var m = this.match(/^(?:\[([!^]?)([^\]]{2,}|\]-)(\]|[^*+?]+)|\[)/); - if (!m) 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 prev = this.prev(); - var val = m[0]; - var negated = m[1] ? '^' : ''; - var inner = m[2] || ''; - var close = m[3] || ''; + // must be a plain object + return 'object'; +}; - if (isInside && prev.type === 'brace') { - prev.text = prev.text || ''; - prev.text += val; - } - var esc = this.input.slice(0, 2); - if (inner === '' && esc === '\\]') { - inner += esc; - this.consume(2); +/***/ }), +/* 560 */ +/***/ (function(module, exports) { - var str = this.input; - var idx = -1; - var ch; +/*! + * Determine if an object is a Buffer + * + * @author Feross Aboukhadijeh + * @license MIT + */ - while ((ch = str[++idx])) { - this.consume(1); - if (ch === ']') { - close = ch; - break; - } - inner += ch; - } - } +// The _isBuffer check is for Safari 5-7 support, because it's missing +// Object.prototype.constructor. Remove this eventually +module.exports = function (obj) { + return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer) +} - return pos(new Node({ - type: 'bracket', - val: val, - escaped: close !== ']', - negated: negated, - inner: inner, - close: close - })); - }) +function isBuffer (obj) { + return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) +} - /** - * Empty braces (we capture these early to - * speed up processing in the compiler) - */ +// For Node v0.10 support. Remove this eventually. +function isSlowBuffer (obj) { + return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0)) +} - .set('multiplier', function() { - var isInside = this.isInside('brace'); - var pos = this.position(); - var m = this.match(/^\{((?:,|\{,+\})+)\}/); - if (!m) return; - this.multiplier = true; - var prev = this.prev(); - var val = m[0]; +/***/ }), +/* 561 */ +/***/ (function(module, exports, __webpack_require__) { - if (isInside && prev.type === 'brace') { - prev.text = prev.text || ''; - prev.text += val; - } +"use strict"; +/*! + * repeat-string + * + * Copyright (c) 2014-2015, Jon Schlinkert. + * Licensed under the MIT License. + */ - var node = pos(new Node({ - type: 'text', - multiplier: 1, - match: m, - val: val - })); - return concatNodes.call(this, pos, node, prev, options); - }) - /** - * Open - */ +/** + * Results cache + */ - .set('brace.open', function() { - var pos = this.position(); - var m = this.match(/^\{(?!(?:[^\\}]?|,+)\})/); - if (!m) return; +var res = ''; +var cache; - var prev = this.prev(); - var last = utils.last(prev.nodes); +/** + * Expose `repeat` + */ - // if the last parsed character was an extglob character - // we need to _not optimize_ the brace pattern because - // it might be mistaken for an extglob by a downstream parser - if (last && last.val && isExtglobChar(last.val.slice(-1))) { - last.optimize = false; - } +module.exports = repeat; - var open = pos(new Node({ - type: 'brace.open', - val: m[0] - })); +/** + * Repeat the given `string` the specified `number` + * of times. + * + * **Example:** + * + * ```js + * var repeat = require('repeat-string'); + * repeat('A', 5); + * //=> AAAAA + * ``` + * + * @param {String} `string` The string to repeat + * @param {Number} `number` The number of times to repeat the string + * @return {String} Repeated string + * @api public + */ - var node = pos(new Node({ - type: 'brace', - nodes: [] - })); +function repeat(str, num) { + if (typeof str !== 'string') { + throw new TypeError('expected a string'); + } - node.push(open); - prev.push(node); - this.push('brace', node); - }) + // cover common, quick use cases + if (num === 1) return str; + if (num === 2) return str + str; - /** - * Close - */ + var max = str.length * num; + if (cache !== str || typeof cache === 'undefined') { + cache = str; + res = ''; + } else if (res.length >= max) { + return res.substr(0, max); + } - .set('brace.close', function() { - var pos = this.position(); - var m = this.match(/^\}/); - if (!m || !m[0]) return; + while (max > res.length && num > 1) { + if (num & 1) { + res += str; + } - var brace = this.pop('brace'); - var node = pos(new Node({ - type: 'brace.close', - val: m[0] - })); + num >>= 1; + str += str; + } - if (!this.isType(brace, 'brace')) { - if (this.options.strict) { - throw new Error('missing opening "{"'); - } - node.type = 'text'; - node.multiplier = 0; - node.escaped = true; - return node; - } + res += str; + res = res.substr(0, max); + return res; +} - var prev = this.prev(); - var last = utils.last(prev.nodes); - if (last.text) { - var lastNode = utils.last(last.nodes); - if (lastNode.val === ')' && /[!@*?+]\(/.test(last.text)) { - var open = last.nodes[0]; - var text = last.nodes[1]; - if (open.type === 'brace.open' && text && text.type === 'text') { - text.optimize = false; - } - } - } - if (brace.nodes.length > 2) { - var first = brace.nodes[1]; - if (first.type === 'text' && first.val === ',') { - brace.nodes.splice(1, 1); - brace.nodes.push(first); - } - } +/***/ }), +/* 562 */ +/***/ (function(module, exports, __webpack_require__) { - brace.push(node); - }) +"use strict"; +/*! + * to-regex-range + * + * Copyright (c) 2015, 2017, Jon Schlinkert. + * Released under the MIT License. + */ - /** - * Capture boundary characters - */ - .set('boundary', function() { - var pos = this.position(); - var m = this.match(/^[$^](?!\{)/); - if (!m) return; - return pos(new Node({ - type: 'text', - val: m[0] - })); - }) - /** - * One or zero, non-comma characters wrapped in braces - */ +var repeat = __webpack_require__(561); +var isNumber = __webpack_require__(558); +var cache = {}; - .set('nobrace', function() { - var isInside = this.isInside('brace'); - var pos = this.position(); - var m = this.match(/^\{[^,]?\}/); - if (!m) return; +function toRegexRange(min, max, options) { + if (isNumber(min) === false) { + throw new RangeError('toRegexRange: first argument is invalid.'); + } - var prev = this.prev(); - var val = m[0]; + if (typeof max === 'undefined' || min === max) { + return String(min); + } - if (isInside && prev.type === 'brace') { - prev.text = prev.text || ''; - prev.text += val; - } + if (isNumber(max) === false) { + throw new RangeError('toRegexRange: second argument is invalid.'); + } - return pos(new Node({ - type: 'text', - multiplier: 0, - val: val - })); - }) + options = options || {}; + var relax = String(options.relaxZeros); + var shorthand = String(options.shorthand); + var capture = String(options.capture); + var key = min + ':' + max + '=' + relax + shorthand + capture; + if (cache.hasOwnProperty(key)) { + return cache[key].result; + } - /** - * Text - */ + var a = Math.min(min, max); + var b = Math.max(min, max); - .set('text', function() { - var isInside = this.isInside('brace'); - var pos = this.position(); - var m = this.match(/^((?!\\)[^${}[\]])+/); - if (!m) return; + if (Math.abs(a - b) === 1) { + var result = min + '|' + max; + if (options.capture) { + return '(' + result + ')'; + } + return result; + } - var prev = this.prev(); - var val = m[0]; + var isPadded = padding(min) || padding(max); + var positives = []; + var negatives = []; - if (isInside && prev.type === 'brace') { - prev.text = prev.text || ''; - prev.text += val; - } + var tok = {min: min, max: max, a: a, b: b}; + if (isPadded) { + tok.isPadded = isPadded; + tok.maxLen = String(tok.max).length; + } - var node = pos(new Node({ - type: 'text', - multiplier: 1, - val: val - })); + if (a < 0) { + var newMin = b < 0 ? Math.abs(b) : 1; + var newMax = Math.abs(a); + negatives = splitToPatterns(newMin, newMax, tok, options); + a = tok.a = 0; + } - return concatNodes.call(this, pos, node, prev, options); - }); -}; + if (b >= 0) { + positives = splitToPatterns(a, b, tok, options); + } -/** - * Returns true if the character is an extglob character. - */ + tok.negatives = negatives; + tok.positives = positives; + tok.result = siftPatterns(negatives, positives, options); -function isExtglobChar(ch) { - return ch === '!' || ch === '@' || ch === '*' || ch === '?' || ch === '+'; + if (options.capture && (positives.length + negatives.length) > 1) { + tok.result = '(' + tok.result + ')'; + } + + cache[key] = tok; + return tok.result; } -/** - * Combine text nodes, and calculate empty sets (`{,,}`) - * @param {Function} `pos` Function to calculate node position - * @param {Object} `node` AST node - * @return {Object} - */ +function siftPatterns(neg, pos, options) { + var onlyNegative = filterPatterns(neg, pos, '-', false, options) || []; + var onlyPositive = filterPatterns(pos, neg, '', false, options) || []; + var intersected = filterPatterns(neg, pos, '-?', true, options) || []; + var subpatterns = onlyNegative.concat(intersected).concat(onlyPositive); + return subpatterns.join('|'); +} -function concatNodes(pos, node, parent, options) { - node.orig = node.val; - var prev = this.prev(); - var last = utils.last(prev.nodes); - var isEscaped = false; +function splitToRanges(min, max) { + min = Number(min); + max = Number(max); - if (node.val.length > 1) { - var a = node.val.charAt(0); - var b = node.val.slice(-1); + var nines = 1; + var stops = [max]; + var stop = +countNines(min, nines); - isEscaped = (a === '"' && b === '"') - || (a === "'" && b === "'") - || (a === '`' && b === '`'); + while (min <= stop && stop <= max) { + stops = push(stops, stop); + nines += 1; + stop = +countNines(min, nines); } - if (isEscaped && options.unescape !== false) { - node.val = node.val.slice(1, node.val.length - 1); - node.escaped = true; - } + var zeros = 1; + stop = countZeros(max + 1, zeros) - 1; - if (node.match) { - var match = node.match[1]; - if (!match || match.indexOf('}') === -1) { - match = node.match[0]; - } - - // replace each set with a single "," - var val = match.replace(/\{/g, ',').replace(/\}/g, ''); - node.multiplier *= val.length; - node.val = ''; + while (min < stop && stop <= max) { + stops = push(stops, stop); + zeros += 1; + stop = countZeros(max + 1, zeros) - 1; } - var simpleText = last.type === 'text' - && last.multiplier === 1 - && node.multiplier === 1 - && node.val; + stops.sort(compare); + return stops; +} - if (simpleText) { - last.val += node.val; - return; - } +/** + * Convert a range to a regex pattern + * @param {Number} `start` + * @param {Number} `stop` + * @return {String} + */ - prev.push(node); -} +function rangeToPattern(start, stop, options) { + if (start === stop) { + return {pattern: String(start), digits: []}; + } + var zipped = zip(String(start), String(stop)); + var len = zipped.length, i = -1; -/***/ }), -/* 557 */ -/***/ (function(module, exports, __webpack_require__) { + var pattern = ''; + var digits = 0; -"use strict"; + while (++i < len) { + var numbers = zipped[i]; + var startDigit = numbers[0]; + var stopDigit = numbers[1]; + if (startDigit === stopDigit) { + pattern += startDigit; -var isObject = __webpack_require__(545); -var define = __webpack_require__(558); -var utils = __webpack_require__(565); -var ownNames; + } else if (startDigit !== '0' || stopDigit !== '9') { + pattern += toCharacterClass(startDigit, stopDigit); -/** - * Create a new AST `Node` with the given `val` and `type`. - * - * ```js - * var node = new Node('*', 'Star'); - * var node = new Node({type: 'star', val: '*'}); - * ``` - * @name Node - * @param {String|Object} `val` Pass a matched substring, or an object to merge onto the node. - * @param {String} `type` The node type to use when `val` is a string. - * @return {Object} node instance - * @api public - */ + } else { + digits += 1; + } + } -function Node(val, type, parent) { - if (typeof type !== 'string') { - parent = type; - type = null; + if (digits) { + pattern += options.shorthand ? '\\d' : '[0-9]'; } - define(this, 'parent', parent); - define(this, 'isNode', true); - define(this, 'expect', null); + return { pattern: pattern, digits: [digits] }; +} - if (typeof type !== 'string' && isObject(val)) { - lazyKeys(); - var keys = Object.keys(val); - for (var i = 0; i < keys.length; i++) { - var key = keys[i]; - if (ownNames.indexOf(key) === -1) { - this[key] = val[key]; +function splitToPatterns(min, max, tok, options) { + var ranges = splitToRanges(min, max); + var len = ranges.length; + var idx = -1; + + var tokens = []; + var start = min; + var prev; + + while (++idx < len) { + var range = ranges[idx]; + var obj = rangeToPattern(start, range, options); + var zeros = ''; + + if (!tok.isPadded && prev && prev.pattern === obj.pattern) { + if (prev.digits.length > 1) { + prev.digits.pop(); } + prev.digits.push(obj.digits[0]); + prev.string = prev.pattern + toQuantifier(prev.digits); + start = range + 1; + continue; } - } else { - this.type = type; - this.val = val; + + if (tok.isPadded) { + zeros = padZeros(range, tok); + } + + obj.string = zeros + obj.pattern + toQuantifier(obj.digits); + tokens.push(obj); + start = range + 1; + prev = obj; } + + return tokens; } -/** - * Returns true if the given value is a node. - * - * ```js - * var Node = require('snapdragon-node'); - * var node = new Node({type: 'foo'}); - * console.log(Node.isNode(node)); //=> true - * console.log(Node.isNode({})); //=> false - * ``` - * @param {Object} `node` - * @returns {Boolean} - * @api public - */ +function filterPatterns(arr, comparison, prefix, intersection, options) { + var res = []; -Node.isNode = function(node) { - return utils.isNode(node); -}; + for (var i = 0; i < arr.length; i++) { + var tok = arr[i]; + var ele = tok.string; -/** - * Define a non-enumberable property on the node instance. - * Useful for adding properties that shouldn't be extended - * or visible during debugging. - * - * ```js - * var node = new Node(); - * node.define('foo', 'something non-enumerable'); - * ``` - * @param {String} `name` - * @param {any} `val` - * @return {Object} returns the node instance - * @api public - */ + if (options.relaxZeros !== false) { + if (prefix === '-' && ele.charAt(0) === '0') { + if (ele.charAt(1) === '{') { + ele = '0*' + ele.replace(/^0\{\d+\}/, ''); + } else { + ele = '0*' + ele.slice(1); + } + } + } -Node.prototype.define = function(name, val) { - define(this, name, val); - return this; -}; + if (!intersection && !contains(comparison, 'string', ele)) { + res.push(prefix + ele); + } + + if (intersection && contains(comparison, 'string', ele)) { + res.push(prefix + ele); + } + } + return res; +} /** - * 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'}); - * node.isEmpty(); //=> true - * node.val = 'foo'; - * node.isEmpty(); //=> false - * ``` - * @param {Function} `fn` (optional) Filter function that is called on `node` and/or child nodes. `isEmpty` will return false immediately when the filter function returns false on any nodes. - * @return {Boolean} - * @api public + * Zip strings (`for in` can be used on string characters) */ -Node.prototype.isEmpty = function(fn) { - return utils.isEmpty(this, fn); -}; +function zip(a, b) { + var arr = []; + for (var ch in a) arr.push([a[ch], b[ch]]); + return arr; +} -/** - * Given node `foo` and node `bar`, push node `bar` onto `foo.nodes`, and - * set `foo` as `bar.parent`. - * - * ```js - * var foo = new Node({type: 'foo'}); - * var bar = new Node({type: 'bar'}); - * foo.push(bar); - * ``` - * @param {Object} `node` - * @return {Number} Returns the length of `node.nodes` - * @api public - */ +function compare(a, b) { + return a > b ? 1 : b > a ? -1 : 0; +} -Node.prototype.push = function(node) { - assert(Node.isNode(node), 'expected node to be an instance of Node'); - define(node, 'parent', this); +function push(arr, ele) { + if (arr.indexOf(ele) === -1) arr.push(ele); + return arr; +} - this.nodes = this.nodes || []; - return this.nodes.push(node); -}; +function contains(arr, key, val) { + for (var i = 0; i < arr.length; i++) { + if (arr[i][key] === val) { + return true; + } + } + return false; +} -/** - * Given node `foo` and node `bar`, unshift node `bar` onto `foo.nodes`, and - * set `foo` as `bar.parent`. - * - * ```js - * var foo = new Node({type: 'foo'}); - * var bar = new Node({type: 'bar'}); - * foo.unshift(bar); - * ``` - * @param {Object} `node` - * @return {Number} Returns the length of `node.nodes` - * @api public - */ +function countNines(min, len) { + return String(min).slice(0, -len) + repeat('9', len); +} -Node.prototype.unshift = function(node) { - assert(Node.isNode(node), 'expected node to be an instance of Node'); - define(node, 'parent', this); +function countZeros(integer, zeros) { + return integer - (integer % Math.pow(10, zeros)); +} - this.nodes = this.nodes || []; - return this.nodes.unshift(node); -}; +function toQuantifier(digits) { + var start = digits[0]; + var stop = digits[1] ? (',' + digits[1]) : ''; + if (!stop && (!start || start === 1)) { + return ''; + } + return '{' + start + stop + '}'; +} -/** - * Pop a node from `node.nodes`. - * - * ```js - * var node = new Node({type: 'foo'}); - * node.push(new Node({type: 'a'})); - * node.push(new Node({type: 'b'})); - * node.push(new Node({type: 'c'})); - * node.push(new Node({type: 'd'})); - * console.log(node.nodes.length); - * //=> 4 - * node.pop(); - * console.log(node.nodes.length); - * //=> 3 - * ``` - * @return {Number} Returns the popped `node` - * @api public - */ +function toCharacterClass(a, b) { + return '[' + a + ((b - a === 1) ? '' : '-') + b + ']'; +} -Node.prototype.pop = function() { - return this.nodes && this.nodes.pop(); -}; +function padding(str) { + return /^-?(0+)\d/.exec(str); +} + +function padZeros(val, tok) { + if (tok.isPadded) { + var diff = Math.abs(tok.maxLen - String(val).length); + switch (diff) { + case 0: + return ''; + case 1: + return '0'; + default: { + return '0{' + diff + '}'; + } + } + } + return val; +} /** - * Shift a node from `node.nodes`. - * - * ```js - * var node = new Node({type: 'foo'}); - * node.push(new Node({type: 'a'})); - * node.push(new Node({type: 'b'})); - * node.push(new Node({type: 'c'})); - * node.push(new Node({type: 'd'})); - * console.log(node.nodes.length); - * //=> 4 - * node.shift(); - * console.log(node.nodes.length); - * //=> 3 - * ``` - * @return {Object} Returns the shifted `node` - * @api public + * Expose `toRegexRange` */ -Node.prototype.shift = function() { - return this.nodes && this.nodes.shift(); -}; +module.exports = toRegexRange; -/** - * Remove `node` from `node.nodes`. - * - * ```js - * node.remove(childNode); - * ``` - * @param {Object} `node` - * @return {Object} Returns the removed node. - * @api public - */ -Node.prototype.remove = function(node) { - assert(Node.isNode(node), 'expected node to be an instance of Node'); - this.nodes = this.nodes || []; - var idx = node.index; - if (idx !== -1) { - node.index = -1; - return this.nodes.splice(idx, 1); - } - return null; -}; +/***/ }), +/* 563 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Get the first child node from `node.nodes` that matches the given `type`. - * If `type` is a number, the child node at that index is returned. +"use strict"; +/*! + * repeat-element * - * ```js - * var child = node.find(1); //<= index of the node to get - * var child = node.find('foo'); //<= node.type of a child node - * var child = node.find(/^(foo|bar)$/); //<= regex to match node.type - * var child = node.find(['foo', 'bar']); //<= array of node.type(s) - * ``` - * @param {String} `type` - * @return {Object} Returns a child node or undefined. - * @api public + * Copyright (c) 2015 Jon Schlinkert. + * Licensed under the MIT license. */ -Node.prototype.find = function(type) { - return utils.findNode(this.nodes, type); -}; -/** - * Return true if the node is the given `type`. - * - * ```js - * var node = new Node({type: 'bar'}); - * cosole.log(node.isType('foo')); // false - * cosole.log(node.isType(/^(foo|bar)$/)); // true - * cosole.log(node.isType(['foo', 'bar'])); // true - * ``` - * @param {String} `type` - * @return {Boolean} - * @api public - */ -Node.prototype.isType = function(type) { - return utils.isType(this, type); -}; +module.exports = function repeat(ele, num) { + var arr = new Array(num); -/** - * Return true if the `node.nodes` has the given `type`. - * - * ```js - * var foo = new Node({type: 'foo'}); - * var bar = new Node({type: 'bar'}); - * foo.push(bar); - * - * cosole.log(foo.hasType('qux')); // false - * cosole.log(foo.hasType(/^(qux|bar)$/)); // true - * cosole.log(foo.hasType(['qux', 'bar'])); // true - * ``` - * @param {String} `type` - * @return {Boolean} - * @api public - */ + for (var i = 0; i < num; i++) { + arr[i] = ele; + } -Node.prototype.hasType = function(type) { - return utils.hasType(this, type); + return arr; }; -/** - * Get the siblings array, or `null` if it doesn't exist. - * - * ```js - * var foo = new Node({type: 'foo'}); - * var bar = new Node({type: 'bar'}); - * var baz = new Node({type: 'baz'}); - * foo.push(bar); - * foo.push(baz); - * - * console.log(bar.siblings.length) // 2 - * console.log(baz.siblings.length) // 2 - * ``` - * @return {Array} - * @api public - */ -Object.defineProperty(Node.prototype, 'siblings', { - set: function() { - throw new Error('node.siblings is a getter and cannot be defined'); - }, - get: function() { - return this.parent ? this.parent.nodes : null; - } -}); +/***/ }), +/* 564 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Get the node's current index from `node.parent.nodes`. - * This should always be correct, even when the parent adds nodes. - * - * ```js - * var foo = new Node({type: 'foo'}); - * var bar = new Node({type: 'bar'}); - * var baz = new Node({type: 'baz'}); - * var qux = new Node({type: 'qux'}); - * foo.push(bar); - * foo.push(baz); - * foo.unshift(qux); - * - * console.log(bar.index) // 1 - * console.log(baz.index) // 2 - * console.log(qux.index) // 0 - * ``` - * @return {Number} - * @api public - */ +"use strict"; -Object.defineProperty(Node.prototype, 'index', { - set: function(index) { - define(this, 'idx', index); - }, - get: function() { - if (!Array.isArray(this.siblings)) { - return -1; - } - var tok = this.idx !== -1 ? this.siblings[this.idx] : null; - if (tok !== this) { - this.idx = this.siblings.indexOf(this); - } - return this.idx; - } -}); + +var Node = __webpack_require__(565); +var utils = __webpack_require__(552); /** - * Get the previous node from the siblings array or `null`. - * - * ```js - * var foo = new Node({type: 'foo'}); - * var bar = new Node({type: 'bar'}); - * var baz = new Node({type: 'baz'}); - * foo.push(bar); - * foo.push(baz); - * - * console.log(baz.prev.type) // 'bar' - * ``` - * @return {Object} - * @api public + * Braces parsers */ -Object.defineProperty(Node.prototype, 'prev', { - set: function() { - throw new Error('node.prev is a getter and cannot be defined'); - }, - get: function() { - if (Array.isArray(this.siblings)) { - return this.siblings[this.index - 1] || this.parent.prev; - } - return null; - } -}); +module.exports = function(braces, options) { + braces.parser + .set('bos', function() { + if (!this.parsed) { + this.ast = this.nodes[0] = new Node(this.ast); + } + }) -/** - * Get the siblings array, or `null` if it doesn't exist. - * - * ```js - * var foo = new Node({type: 'foo'}); - * var bar = new Node({type: 'bar'}); - * var baz = new Node({type: 'baz'}); - * foo.push(bar); - * foo.push(baz); - * - * console.log(bar.siblings.length) // 2 - * console.log(baz.siblings.length) // 2 - * ``` - * @return {Object} - * @api public - */ - -Object.defineProperty(Node.prototype, 'next', { - set: function() { - throw new Error('node.next is a getter and cannot be defined'); - }, - get: function() { - if (Array.isArray(this.siblings)) { - return this.siblings[this.index + 1] || this.parent.next; - } - return null; - } -}); - -/** - * Get the first node from `node.nodes`. - * - * ```js - * var foo = new Node({type: 'foo'}); - * var bar = new Node({type: 'bar'}); - * var baz = new Node({type: 'baz'}); - * var qux = new Node({type: 'qux'}); - * foo.push(bar); - * foo.push(baz); - * foo.push(qux); - * - * console.log(foo.first.type) // 'bar' - * ``` - * @return {Object} The first node, or undefiend - * @api public - */ + /** + * Character parsers + */ -Object.defineProperty(Node.prototype, 'first', { - get: function() { - return this.nodes ? this.nodes[0] : null; - } -}); + .set('escape', function() { + var pos = this.position(); + var m = this.match(/^(?:\\(.)|\$\{)/); + if (!m) return; -/** - * Get the last node from `node.nodes`. - * - * ```js - * var foo = new Node({type: 'foo'}); - * var bar = new Node({type: 'bar'}); - * var baz = new Node({type: 'baz'}); - * var qux = new Node({type: 'qux'}); - * foo.push(bar); - * foo.push(baz); - * foo.push(qux); - * - * console.log(foo.last.type) // 'qux' - * ``` - * @return {Object} The last node, or undefiend - * @api public - */ + var prev = this.prev(); + var last = utils.last(prev.nodes); -Object.defineProperty(Node.prototype, 'last', { - get: function() { - return this.nodes ? utils.last(this.nodes) : null; - } -}); + var node = pos(new Node({ + type: 'text', + multiplier: 1, + val: m[0] + })); -/** - * Get the last node from `node.nodes`. - * - * ```js - * var foo = new Node({type: 'foo'}); - * var bar = new Node({type: 'bar'}); - * var baz = new Node({type: 'baz'}); - * var qux = new Node({type: 'qux'}); - * foo.push(bar); - * foo.push(baz); - * foo.push(qux); - * - * console.log(foo.last.type) // 'qux' - * ``` - * @return {Object} The last node, or undefiend - * @api public - */ + if (node.val === '\\\\') { + return node; + } -Object.defineProperty(Node.prototype, 'scope', { - get: function() { - if (this.isScope !== true) { - return this.parent ? this.parent.scope : this; - } - return this; - } -}); + if (node.val === '${') { + var str = this.input; + var idx = -1; + var ch; -/** - * Get own property names from Node prototype, but only the - * first time `Node` is instantiated - */ + while ((ch = str[++idx])) { + this.consume(1); + node.val += ch; + if (ch === '\\') { + node.val += str[++idx]; + continue; + } + if (ch === '}') { + break; + } + } + } -function lazyKeys() { - if (!ownNames) { - ownNames = Object.getOwnPropertyNames(Node.prototype); - } -} + if (this.options.unescape !== false) { + node.val = node.val.replace(/\\([{}])/g, '$1'); + } -/** - * Simplified assertion. Throws an error is `val` is falsey. - */ + if (last.val === '"' && this.input.charAt(0) === '"') { + last.val = node.val; + this.consume(1); + return; + } -function assert(val, message) { - if (!val) throw new Error(message); -} + return concatNodes.call(this, pos, node, prev, options); + }) -/** - * Expose `Node` - */ + /** + * Brackets: "[...]" (basic, this is overridden by + * other parsers in more advanced implementations) + */ -exports = module.exports = Node; + .set('bracket', function() { + var isInside = this.isInside('brace'); + var pos = this.position(); + var m = this.match(/^(?:\[([!^]?)([^\]]{2,}|\]-)(\]|[^*+?]+)|\[)/); + if (!m) return; + var prev = this.prev(); + var val = m[0]; + var negated = m[1] ? '^' : ''; + var inner = m[2] || ''; + var close = m[3] || ''; -/***/ }), -/* 558 */ -/***/ (function(module, exports, __webpack_require__) { + if (isInside && prev.type === 'brace') { + prev.text = prev.text || ''; + prev.text += val; + } -"use strict"; -/*! - * define-property - * - * Copyright (c) 2015, 2017, Jon Schlinkert. - * Released under the MIT License. - */ + var esc = this.input.slice(0, 2); + if (inner === '' && esc === '\\]') { + inner += esc; + this.consume(2); + var str = this.input; + var idx = -1; + var ch; + while ((ch = str[++idx])) { + this.consume(1); + if (ch === ']') { + close = ch; + break; + } + inner += ch; + } + } -var isDescriptor = __webpack_require__(559); + return pos(new Node({ + type: 'bracket', + val: val, + escaped: close !== ']', + negated: negated, + inner: inner, + close: close + })); + }) -module.exports = function defineProperty(obj, prop, val) { - if (typeof obj !== 'object' && typeof obj !== 'function') { - throw new TypeError('expected an object or function.'); - } + /** + * Empty braces (we capture these early to + * speed up processing in the compiler) + */ - if (typeof prop !== 'string') { - throw new TypeError('expected `prop` to be a string.'); - } + .set('multiplier', function() { + var isInside = this.isInside('brace'); + var pos = this.position(); + var m = this.match(/^\{((?:,|\{,+\})+)\}/); + if (!m) return; - if (isDescriptor(val) && ('set' in val || 'get' in val)) { - return Object.defineProperty(obj, prop, val); - } + this.multiplier = true; + var prev = this.prev(); + var val = m[0]; - return Object.defineProperty(obj, prop, { - configurable: true, - enumerable: false, - writable: true, - value: val - }); -}; + if (isInside && prev.type === 'brace') { + prev.text = prev.text || ''; + prev.text += val; + } + var node = pos(new Node({ + type: 'text', + multiplier: 1, + match: m, + val: val + })); -/***/ }), -/* 559 */ -/***/ (function(module, exports, __webpack_require__) { + return concatNodes.call(this, pos, node, prev, options); + }) -"use strict"; -/*! - * is-descriptor - * - * Copyright (c) 2015-2017, Jon Schlinkert. - * Released under the MIT License. - */ + /** + * Open + */ + .set('brace.open', function() { + var pos = this.position(); + var m = this.match(/^\{(?!(?:[^\\}]?|,+)\})/); + if (!m) return; + var prev = this.prev(); + var last = utils.last(prev.nodes); -var typeOf = __webpack_require__(560); -var isAccessor = __webpack_require__(561); -var isData = __webpack_require__(563); + // if the last parsed character was an extglob character + // we need to _not optimize_ the brace pattern because + // it might be mistaken for an extglob by a downstream parser + if (last && last.val && isExtglobChar(last.val.slice(-1))) { + last.optimize = false; + } -module.exports = function isDescriptor(obj, key) { - if (typeOf(obj) !== 'object') { - return false; - } - if ('get' in obj) { - return isAccessor(obj, key); - } - return isData(obj, key); -}; + var open = pos(new Node({ + type: 'brace.open', + val: m[0] + })); + var node = pos(new Node({ + type: 'brace', + nodes: [] + })); -/***/ }), -/* 560 */ -/***/ (function(module, exports) { + node.push(open); + prev.push(node); + this.push('brace', node); + }) -var toString = Object.prototype.toString; + /** + * Close + */ -module.exports = function kindOf(val) { - if (val === void 0) return 'undefined'; - if (val === null) return 'null'; + .set('brace.close', function() { + var pos = this.position(); + var m = this.match(/^\}/); + if (!m || !m[0]) return; - 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 brace = this.pop('brace'); + var node = pos(new Node({ + type: 'brace.close', + val: m[0] + })); - 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 (!this.isType(brace, 'brace')) { + if (this.options.strict) { + throw new Error('missing opening "{"'); + } + node.type = 'text'; + node.multiplier = 0; + node.escaped = true; + return node; + } - switch (ctorName(val)) { - case 'Symbol': return 'symbol'; - case 'Promise': return 'promise'; + var prev = this.prev(); + var last = utils.last(prev.nodes); + if (last.text) { + var lastNode = utils.last(last.nodes); + if (lastNode.val === ')' && /[!@*?+]\(/.test(last.text)) { + var open = last.nodes[0]; + var text = last.nodes[1]; + if (open.type === 'brace.open' && text && text.type === 'text') { + text.optimize = false; + } + } + } - // Set, Map, WeakSet, WeakMap - case 'WeakMap': return 'weakmap'; - case 'WeakSet': return 'weakset'; - case 'Map': return 'map'; - case 'Set': return 'set'; + if (brace.nodes.length > 2) { + var first = brace.nodes[1]; + if (first.type === 'text' && first.val === ',') { + brace.nodes.splice(1, 1); + brace.nodes.push(first); + } + } - // 8-bit typed arrays - case 'Int8Array': return 'int8array'; - case 'Uint8Array': return 'uint8array'; - case 'Uint8ClampedArray': return 'uint8clampedarray'; + brace.push(node); + }) - // 16-bit typed arrays - case 'Int16Array': return 'int16array'; - case 'Uint16Array': return 'uint16array'; + /** + * Capture boundary characters + */ - // 32-bit typed arrays - case 'Int32Array': return 'int32array'; - case 'Uint32Array': return 'uint32array'; - case 'Float32Array': return 'float32array'; - case 'Float64Array': return 'float64array'; - } + .set('boundary', function() { + var pos = this.position(); + var m = this.match(/^[$^](?!\{)/); + if (!m) return; + return pos(new Node({ + type: 'text', + val: m[0] + })); + }) - if (isGeneratorObj(val)) { - return 'generator'; - } + /** + * One or zero, non-comma characters wrapped in braces + */ - // 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'; - } + .set('nobrace', function() { + var isInside = this.isInside('brace'); + var pos = this.position(); + var m = this.match(/^\{[^,]?\}/); + if (!m) return; - // other - return type.slice(8, -1).toLowerCase().replace(/\s/g, ''); -}; + var prev = this.prev(); + var val = m[0]; -function ctorName(val) { - return typeof val.constructor === 'function' ? val.constructor.name : null; -} + if (isInside && prev.type === 'brace') { + prev.text = prev.text || ''; + prev.text += val; + } -function isArray(val) { - if (Array.isArray) return Array.isArray(val); - return val instanceof Array; -} + return pos(new Node({ + type: 'text', + multiplier: 0, + val: val + })); + }) -function isError(val) { - return val instanceof Error || (typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number'); -} + /** + * Text + */ -function isDate(val) { - if (val instanceof Date) return true; - return typeof val.toDateString === 'function' - && typeof val.getDate === 'function' - && typeof val.setDate === 'function'; -} + .set('text', function() { + var isInside = this.isInside('brace'); + var pos = this.position(); + var m = this.match(/^((?!\\)[^${}[\]])+/); + if (!m) return; -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'; -} + var prev = this.prev(); + var val = m[0]; -function isGeneratorFn(name, val) { - return ctorName(name) === 'GeneratorFunction'; -} + if (isInside && prev.type === 'brace') { + prev.text = prev.text || ''; + prev.text += val; + } -function isGeneratorObj(val) { - return typeof val.throw === 'function' - && typeof val.return === 'function' - && typeof val.next === 'function'; -} + var node = pos(new Node({ + type: 'text', + multiplier: 1, + val: 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; -} + return concatNodes.call(this, pos, node, prev, options); + }); +}; /** - * If you need to support Safari 5-7 (8-10 yr-old browser), - * take a look at https://github.com/feross/is-buffer + * Returns true if the character is an extglob character. */ -function isBuffer(val) { - if (val.constructor && typeof val.constructor.isBuffer === 'function') { - return val.constructor.isBuffer(val); - } - return false; +function isExtglobChar(ch) { + return ch === '!' || ch === '@' || ch === '*' || ch === '?' || ch === '+'; } +/** + * Combine text nodes, and calculate empty sets (`{,,}`) + * @param {Function} `pos` Function to calculate node position + * @param {Object} `node` AST node + * @return {Object} + */ -/***/ }), -/* 561 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * is-accessor-descriptor - * - * Copyright (c) 2015-2017, Jon Schlinkert. - * Released under the MIT License. - */ - - - -var typeOf = __webpack_require__(562); - -// 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; - } +function concatNodes(pos, node, parent, options) { + node.orig = node.val; + var prev = this.prev(); + var last = utils.last(prev.nodes); + var isEscaped = false; - if (has(obj, 'value') || has(obj, 'writable')) { - return false; - } + if (node.val.length > 1) { + var a = node.val.charAt(0); + var b = node.val.slice(-1); - if (!has(obj, 'get') || typeof obj.get !== 'function') { - return false; + isEscaped = (a === '"' && b === '"') + || (a === "'" && b === "'") + || (a === '`' && b === '`'); } - // 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; + if (isEscaped && options.unescape !== false) { + node.val = node.val.slice(1, node.val.length - 1); + node.escaped = true; } - for (var key in obj) { - if (!accessor.hasOwnProperty(key)) { - continue; - } - - if (typeOf(obj[key]) === accessor[key]) { - continue; - } - - if (typeof obj[key] !== 'undefined') { - return false; + if (node.match) { + var match = node.match[1]; + if (!match || match.indexOf('}') === -1) { + match = node.match[0]; } - } - return true; -} - -function has(obj, key) { - return {}.hasOwnProperty.call(obj, key); -} - -/** - * Expose `isAccessorDescriptor` - */ - -module.exports = isAccessorDescriptor; - - -/***/ }), -/* 562 */ -/***/ (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'; - } - - 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'; - - 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 (isGeneratorObj(val)) { - return 'generator'; - } - // 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'; + // replace each set with a single "," + var val = match.replace(/\{/g, ',').replace(/\}/g, ''); + node.multiplier *= val.length; + node.val = ''; } - // other - return type.slice(8, -1).toLowerCase().replace(/\s/g, ''); -}; - -function ctorName(val) { - return typeof val.constructor === 'function' ? val.constructor.name : null; -} - -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'); -} - -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'; -} + var simpleText = last.type === 'text' + && last.multiplier === 1 + && node.multiplier === 1 + && node.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; - } + if (simpleText) { + last.val += node.val; + return; } - return false; -} - -/** - * 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) { - if (val.constructor && typeof val.constructor.isBuffer === 'function') { - return val.constructor.isBuffer(val); - } - return false; + prev.push(node); } /***/ }), -/* 563 */ +/* 565 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/*! - * is-data-descriptor - * - * Copyright (c) 2015-2017, Jon Schlinkert. - * Released under the MIT License. - */ - - - -var typeOf = __webpack_require__(564); - -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 (!('value' in obj) && !('writable' in obj)) { - return false; - } - for (var key in obj) { - if (key === 'value') continue; - - if (!data.hasOwnProperty(key)) { - continue; - } - - if (typeOf(obj[key]) === data[key]) { - continue; - } - - if (typeof obj[key] !== 'undefined') { - return false; - } - } - return true; -}; - - -/***/ }), -/* 564 */ -/***/ (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'; - } - - 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'; - - 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'; - } +var isObject = __webpack_require__(534); +var define = __webpack_require__(566); +var utils = __webpack_require__(567); +var ownNames; - if (isGeneratorObj(val)) { - return 'generator'; - } +/** + * Create a new AST `Node` with the given `val` and `type`. + * + * ```js + * var node = new Node('*', 'Star'); + * var node = new Node({type: 'star', val: '*'}); + * ``` + * @name Node + * @param {String|Object} `val` Pass a matched substring, or an object to merge onto the node. + * @param {String} `type` The node type to use when `val` is a string. + * @return {Object} node instance + * @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'; +function Node(val, type, parent) { + if (typeof type !== 'string') { + parent = type; + type = null; } - // other - return type.slice(8, -1).toLowerCase().replace(/\s/g, ''); -}; - -function ctorName(val) { - return typeof val.constructor === 'function' ? val.constructor.name : null; -} - -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'); -} - -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'; -} + define(this, 'parent', parent); + define(this, 'isNode', true); + define(this, 'expect', null); -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; + if (typeof type !== 'string' && isObject(val)) { + lazyKeys(); + var keys = Object.keys(val); + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + if (ownNames.indexOf(key) === -1) { + this[key] = val[key]; + } } + } else { + this.type = type; + this.val = val; } - return false; -} - -/** - * 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) { - if (val.constructor && typeof val.constructor.isBuffer === 'function') { - return val.constructor.isBuffer(val); - } - return false; } - -/***/ }), -/* 565 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var typeOf = __webpack_require__(550); -var utils = module.exports; - /** * 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 + * console.log(Node.isNode(node)); //=> true + * console.log(Node.isNode({})); //=> false * ``` - * @param {Object} `node` Instance of [snapdragon-node][] + * @param {Object} `node` * @returns {Boolean} * @api public */ -utils.isNode = function(node) { - return typeOf(node) === 'object' && node.isNode === true; +Node.isNode = function(node) { + return utils.isNode(node); }; /** - * Emit an empty string for the given `node`. + * Define a non-enumberable property on the node instance. + * Useful for adding properties that shouldn't be extended + * or visible during debugging. * * ```js - * // do nothing for beginning-of-string - * snapdragon.compiler.set('bos', utils.noop); + * var node = new Node(); + * node.define('foo', 'something non-enumerable'); * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @returns {undefined} + * @param {String} `name` + * @param {any} `val` + * @return {Object} returns the node instance * @api public */ -utils.noop = function(node) { - append(this, '', node); +Node.prototype.define = function(name, val) { + define(this, name, val); + return this; }; /** - * Appdend `node.val` to `compiler.output`, exactly as it was created - * by the parser. + * Returns true if `node.val` is an empty string, or `node.nodes` does + * not contain any non-empty text nodes. * * ```js - * snapdragon.compiler.set('text', utils.identity); + * var node = new Node({type: 'text'}); + * node.isEmpty(); //=> true + * node.val = 'foo'; + * node.isEmpty(); //=> false * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @returns {undefined} + * @param {Function} `fn` (optional) Filter function that is called on `node` and/or child nodes. `isEmpty` will return false immediately when the filter function returns false on any nodes. + * @return {Boolean} * @api public */ -utils.identity = function(node) { - append(this, node.val, node); +Node.prototype.isEmpty = function(fn) { + return utils.isEmpty(this, fn); }; /** - * 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`. + * Given node `foo` and node `bar`, push node `bar` onto `foo.nodes`, and + * set `foo` as `bar.parent`. * * ```js - * snapdragon.compiler - * .set('i', function(node) { - * this.mapVisit(node); - * }) - * .set('i.open', utils.append('')) - * .set('i.close', utils.append('')) + * var foo = new Node({type: 'foo'}); + * var bar = new Node({type: 'bar'}); + * foo.push(bar); * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @returns {Function} Returns a compiler middleware function. + * @param {Object} `node` + * @return {Number} Returns the length of `node.nodes` * @api public */ -utils.append = function(val) { - return function(node) { - append(this, val, node); - }; -}; - -/** - * 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 - */ +Node.prototype.push = function(node) { + assert(Node.isNode(node), 'expected node to be an instance of Node'); + define(node, 'parent', this); -utils.toNoop = function(node, nodes) { - if (nodes) { - node.nodes = nodes; - } else { - delete node.nodes; - node.type = 'text'; - node.val = ''; - } + this.nodes = this.nodes || []; + return this.nodes.push(node); }; /** - * 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. + * Given node `foo` and node `bar`, unshift node `bar` onto `foo.nodes`, and + * set `foo` as `bar.parent`. * * ```js - * snapdragon.compiler.set('i', function(node) { - * utils.visit(node, function(childNode) { - * // do stuff with "childNode" - * return childNode; - * }); - * }); + * var foo = new Node({type: 'foo'}); + * var bar = new Node({type: 'bar'}); + * foo.unshift(bar); * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @param {Function} `fn` - * @return {Object} returns the node after recursively visiting all child nodes. + * @param {Object} `node` + * @return {Number} Returns the length of `node.nodes` * @api public */ -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; +Node.prototype.unshift = function(node) { + assert(Node.isNode(node), 'expected node to be an instance of Node'); + define(node, 'parent', this); + + this.nodes = this.nodes || []; + return this.nodes.unshift(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. + * Pop a node from `node.nodes`. * * ```js - * snapdragon.compiler.set('i', function(node) { - * utils.mapVisit(node, function(childNode) { - * // do stuff with "childNode" - * return childNode; - * }); - * }); + * var node = new Node({type: 'foo'}); + * node.push(new Node({type: 'a'})); + * node.push(new Node({type: 'b'})); + * node.push(new Node({type: 'c'})); + * node.push(new Node({type: 'd'})); + * console.log(node.nodes.length); + * //=> 4 + * node.pop(); + * console.log(node.nodes.length); + * //=> 3 * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @param {Object} `options` - * @param {Function} `fn` - * @return {Object} returns the node + * @return {Number} Returns the popped `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'); - - for (var i = 0; i < node.nodes.length; i++) { - utils.visit(node.nodes[i], fn); - } - return node; +Node.prototype.pop = function() { + return this.nodes && this.nodes.pop(); }; /** - * Unshift an `*.open` node onto `node.nodes`. + * Shift a node from `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; - * } - * }); + * var node = new Node({type: 'foo'}); + * node.push(new Node({type: 'a'})); + * node.push(new Node({type: 'b'})); + * node.push(new Node({type: 'c'})); + * node.push(new Node({type: 'd'})); + * console.log(node.nodes.length); + * //=> 4 + * node.shift(); + * console.log(node.nodes.length); + * //=> 3 * ``` - * @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. + * @return {Object} Returns the shifted `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'); - - 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; +Node.prototype.shift = function() { + return this.nodes && this.nodes.shift(); }; /** - * Push a `*.close` node onto `node.nodes`. + * Remove `node` from `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; - * } - * }); + * node.remove(childNode); * ``` - * @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. + * @param {Object} `node` + * @return {Object} Returns the removed node. * @api public */ -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); +Node.prototype.remove = function(node) { + assert(Node.isNode(node), 'expected node to be an instance of Node'); + this.nodes = this.nodes || []; + var idx = node.index; + if (idx !== -1) { + node.index = -1; + return this.nodes.splice(idx, 1); } - return close; + return null; }; /** - * Wraps the given `node` with `*.open` and `*.close` nodes. + * Get the first child node from `node.nodes` that matches the given `type`. + * If `type` is a number, the child node at that index is returned. * - * @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 + * ```js + * var child = node.find(1); //<= index of the node to get + * var child = node.find('foo'); //<= node.type of a child node + * var child = node.find(/^(foo|bar)$/); //<= regex to match node.type + * var child = node.find(['foo', 'bar']); //<= array of node.type(s) + * ``` + * @param {String} `type` + * @return {Object} Returns a child node or undefined. * @api public */ -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; +Node.prototype.find = function(type) { + return utils.findNode(this.nodes, type); }; /** - * Push the given `node` onto `parent.nodes`, and set `parent` as `node.parent. + * Return true if the node is the given `type`. * * ```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' + * cosole.log(node.isType('foo')); // false + * cosole.log(node.isType(/^(foo|bar)$/)); // true + * cosole.log(node.isType(['foo', 'bar'])); // true * ``` - * @param {Object} `parent` - * @param {Object} `node` Instance of [snapdragon-node][] - * @return {Object} Returns the child node + * @param {String} `type` + * @return {Boolean} * @api public */ -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'); - - node.define('parent', parent); - parent.nodes = parent.nodes || []; - parent.nodes.push(node); - return node; +Node.prototype.isType = function(type) { + return utils.isType(this, type); }; /** - * Unshift `node` onto `parent.nodes`, and set `parent` as `node.parent. + * Return true if the `node.nodes` has the given `type`. * * ```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' + * var foo = new Node({type: 'foo'}); + * var bar = new Node({type: 'bar'}); + * foo.push(bar); + * + * cosole.log(foo.hasType('qux')); // false + * cosole.log(foo.hasType(/^(qux|bar)$/)); // true + * cosole.log(foo.hasType(['qux', 'bar'])); // true * ``` - * @param {Object} `parent` - * @param {Object} `node` Instance of [snapdragon-node][] - * @return {undefined} + * @param {String} `type` + * @return {Boolean} * @api public */ -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'); - - node.define('parent', parent); - parent.nodes = parent.nodes || []; - parent.nodes.unshift(node); +Node.prototype.hasType = function(type) { + return utils.hasType(this, type); }; /** - * 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`. + * Get the siblings array, or `null` if it doesn't exist. * * ```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 + * var foo = new Node({type: 'foo'}); + * var bar = new Node({type: 'bar'}); + * var baz = new Node({type: 'baz'}); + * foo.push(bar); + * foo.push(baz); + * + * console.log(bar.siblings.length) // 2 + * console.log(baz.siblings.length) // 2 * ``` - * @param {Object} `parent` - * @param {Object} `node` Instance of [snapdragon-node][] - * @return {Number|Undefined} Returns the length of `node.nodes` or undefined. + * @return {Array} * @api public */ -utils.popNode = function(node) { - assert(utils.isNode(node), 'expected node to be an instance of Node'); - if (typeof node.pop === 'function') { - return node.pop(); +Object.defineProperty(Node.prototype, 'siblings', { + set: function() { + throw new Error('node.siblings is a getter and cannot be defined'); + }, + get: function() { + return this.parent ? this.parent.nodes : null; } - return node.nodes && node.nodes.pop(); -}; +}); /** - * 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`. + * Get the node's current index from `node.parent.nodes`. + * This should always be correct, even when the parent adds nodes. * * ```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 + * var foo = new Node({type: 'foo'}); + * var bar = new Node({type: 'bar'}); + * var baz = new Node({type: 'baz'}); + * var qux = new Node({type: 'qux'}); + * foo.push(bar); + * foo.push(baz); + * foo.unshift(qux); + * + * console.log(bar.index) // 1 + * console.log(baz.index) // 2 + * console.log(qux.index) // 0 * ``` - * @param {Object} `parent` - * @param {Object} `node` Instance of [snapdragon-node][] - * @return {Number|Undefined} Returns the length of `node.nodes` or undefined. + * @return {Number} * @api public */ -utils.shiftNode = function(node) { - assert(utils.isNode(node), 'expected node to be an instance of Node'); - if (typeof node.shift === 'function') { - return node.shift(); +Object.defineProperty(Node.prototype, 'index', { + set: function(index) { + define(this, 'idx', index); + }, + get: function() { + if (!Array.isArray(this.siblings)) { + return -1; + } + var tok = this.idx !== -1 ? this.siblings[this.idx] : null; + if (tok !== this) { + this.idx = this.siblings.indexOf(this); + } + return this.idx; } - return node.nodes && node.nodes.shift(); -}; +}); /** - * Remove the specified `node` from `parent.nodes`. + * Get the previous node from the siblings array or `null`. * * ```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 + * var bar = new Node({type: 'bar'}); + * var baz = new Node({type: 'baz'}); + * foo.push(bar); + * foo.push(baz); + * + * console.log(baz.prev.type) // 'bar' * ``` - * @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`. + * @return {Object} * @api public */ -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) { +Object.defineProperty(Node.prototype, 'prev', { + set: function() { + throw new Error('node.prev is a getter and cannot be defined'); + }, + get: function() { + if (Array.isArray(this.siblings)) { + return this.siblings[this.index - 1] || this.parent.prev; + } return null; } - - if (typeof parent.remove === 'function') { - return parent.remove(node); - } - - var idx = parent.nodes.indexOf(node); - if (idx !== -1) { - return parent.nodes.splice(idx, 1); - } -}; +}); /** - * Returns true if `node.type` matches the given `type`. Throws a - * `TypeError` if `node` is not an instance of `Node`. + * Get the siblings array, or `null` if it doesn't exist. * * ```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 + * var foo = new Node({type: 'foo'}); + * var bar = new Node({type: 'bar'}); + * var baz = new Node({type: 'baz'}); + * foo.push(bar); + * foo.push(baz); + * + * console.log(bar.siblings.length) // 2 + * console.log(baz.siblings.length) // 2 * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @param {String} `type` - * @return {Boolean} + * @return {Object} * @api public */ -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'); +Object.defineProperty(Node.prototype, 'next', { + set: function() { + throw new Error('node.next is a getter and cannot be defined'); + }, + get: function() { + if (Array.isArray(this.siblings)) { + return this.siblings[this.index + 1] || this.parent.next; } + return null; } -}; +}); /** - * Returns true if the given `node` has the given `type` in `node.nodes`. - * Throws a `TypeError` if `node` is not an instance of `Node`. + * Get the first node from `node.nodes`. * * ```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 + * var foo = new Node({type: 'foo'}); + * var bar = new Node({type: 'bar'}); + * var baz = new Node({type: 'baz'}); + * var qux = new Node({type: 'qux'}); + * foo.push(bar); + * foo.push(baz); + * foo.push(qux); + * + * console.log(foo.first.type) // 'bar' * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @param {String} `type` - * @return {Boolean} + * @return {Object} The first node, or undefiend * @api public */ -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; - } +Object.defineProperty(Node.prototype, 'first', { + get: function() { + return this.nodes ? this.nodes[0] : null; } - return false; -}; +}); /** - * Returns the first node from `node.nodes` of the given `type` + * Get the last node from `node.nodes`. * * ```js - * var node = new Node({ - * type: 'foo', - * nodes: [ - * new Node({type: 'text', val: 'abc'}), - * new Node({type: 'text', val: 'xyz'}) - * ] - * }); + * var foo = new Node({type: 'foo'}); + * var bar = new Node({type: 'bar'}); + * var baz = new Node({type: 'baz'}); + * var qux = new Node({type: 'qux'}); + * foo.push(bar); + * foo.push(baz); + * foo.push(qux); * - * var textNode = utils.firstOfType(node.nodes, 'text'); - * console.log(textNode.val); - * //=> 'abc' + * console.log(foo.last.type) // 'qux' * ``` - * @param {Array} `nodes` - * @param {String} `type` - * @return {Object|undefined} Returns the first matching node or undefined. + * @return {Object} The last node, or undefiend * @api public */ -utils.firstOfType = function(nodes, type) { - for (var i = 0; i < nodes.length; i++) { - var node = nodes[i]; - if (utils.isType(node, type)) { - return node; - } - } -}; - -/** - * 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 - */ - -utils.findNode = function(nodes, type) { - if (!Array.isArray(nodes)) { - return null; - } - if (typeof type === 'number') { - return nodes[type]; - } - 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 - */ - -utils.isOpen = function(node) { - assert(utils.isNode(node), 'expected node to be an instance of Node'); - return node.type.slice(-5) === '.open'; -}; - -/** - * 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 - */ - -utils.isClose = function(node) { - assert(utils.isNode(node), 'expected node to be an instance of Node'); - return node.type.slice(-6) === '.close'; -}; - -/** - * 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 - */ - -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'; - } - 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 - */ - -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'; - } - 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); -}; - -/** - * 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 - * 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 - */ - -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 = {}; - } - if (!state.inside.hasOwnProperty(type)) { - state.inside[type] = []; - } - - var arr = state.inside[type]; - arr.push(node); - return arr; -}; - -/** - * 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 - */ - -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'); - - var type = node.parent - ? node.parent.type - : node.type.replace(/\.close$/, ''); - - if (state.inside.hasOwnProperty(type)) { - return state.inside[type].pop(); - } -}; - -/** - * 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; -}; - -/** - * 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 - */ - -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 (!state.inside.hasOwnProperty(type)) { - return false; +Object.defineProperty(Node.prototype, 'last', { + get: function() { + return this.nodes ? utils.last(this.nodes) : null; } - - return state.inside[type].length > 0; -}; +}); /** - * Returns true if `node` is either a child or grand-child of the given `type`, - * or `state.inside[type]` is a non-empty array. + * Get the last node from `node.nodes`. * * ```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 - */ - -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; - } - - var parent = node.parent; - if (typeof type === 'string') { - return (parent && parent.type === type) || utils.isInsideType(state, type); - } - - 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; - } - } - } - 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. + * var foo = new Node({type: 'foo'}); + * var bar = new Node({type: 'bar'}); + * var baz = new Node({type: 'baz'}); + * var qux = new Node({type: 'qux'}); + * foo.push(bar); + * foo.push(baz); + * foo.push(qux); * - * ```js - * console.log(utils.arrayify('')); - * //=> [] - * console.log(utils.arrayify('foo')); - * //=> ['foo'] - * console.log(utils.arrayify(['foo'])); - * //=> ['foo'] + * console.log(foo.last.type) // 'qux' * ``` - * @param {any} `val` - * @return {Array} - * @api public - */ - -utils.arrayify = function(val) { - if (typeof val === 'string' && val !== '') { - return [val]; - } - if (!Array.isArray(val)) { - return []; - } - 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} + * @return {Object} The last node, or undefiend * @api public */ -utils.trim = function(str) { - return typeof str === 'string' ? str.trim() : ''; -}; - -/** - * Return true if val is an object - */ - -function isObject(val) { - return typeOf(val) === 'object'; -} - -/** - * 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'; -} - -/** - * Return true if val is an array - */ - -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); -} - -/** - * Simplified assertion. Throws an error is `val` is falsey. - */ - -function assert(val, message) { - if (!val) throw new Error(message); -} - - -/***/ }), -/* 566 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var extend = __webpack_require__(533); -var Snapdragon = __webpack_require__(567); -var compilers = __webpack_require__(539); -var parsers = __webpack_require__(556); -var utils = __webpack_require__(540); - -/** - * Customize Snapdragon parser and renderer - */ - -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); - - /** - * 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; - }); -}; - -/** - * Decorate `.parse` method - */ - -Braces.prototype.parse = function(ast, options) { - if (ast && typeof ast === 'object' && ast.nodes) return ast; - this.init(options); - return this.snapdragon.parse(ast, options); -}; - -/** - * 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}); -}; - -/** - * Optimize - */ - -Braces.prototype.optimize = function(pattern) { - var ast = this.parse(pattern, {optimize: true}); - return this.compile(ast, {optimize: true}); -}; - -/** - * Expose `Braces` - */ - -module.exports = Braces; - - -/***/ }), -/* 567 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var Base = __webpack_require__(568); -var define = __webpack_require__(594); -var Compiler = __webpack_require__(604); -var Parser = __webpack_require__(633); -var utils = __webpack_require__(613); -var regexCache = {}; -var cache = {}; - -/** - * Create a new instance of `Snapdragon` with the given `options`. - * - * ```js - * var snapdragon = new Snapdragon(); - * ``` - * - * @param {Object} `options` - * @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; - } - }); - - Object.defineProperty(this, 'parsers', { - get: function() { - return this.parser.parsers; - } - }); - - Object.defineProperty(this, 'regex', { - get: function() { - return this.parser.regex; - } - }); -} - -/** - * Inherit Base - */ - -Base.extend(Snapdragon); - -/** - * 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 - */ - -Snapdragon.prototype.capture = function() { - return this.parser.capture.apply(this.parser, arguments); -}; - -/** - * 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 - */ - -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); - - // add non-enumerable parser reference - define(parsed, 'parser', this.parser); - return parsed; -}; - -/** - * Compile the given `AST`. - * - * ```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; -}; - -/** - * Expose `Snapdragon` - */ - -module.exports = Snapdragon; - -/** - * Expose `Parser` and `Compiler` - */ - -module.exports.Compiler = Compiler; -module.exports.Parser = Parser; - - -/***/ }), -/* 568 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var util = __webpack_require__(111); -var define = __webpack_require__(569); -var CacheBase = __webpack_require__(570); -var Emitter = __webpack_require__(571); -var isObject = __webpack_require__(545); -var merge = __webpack_require__(588); -var pascal = __webpack_require__(591); -var cu = __webpack_require__(592); - -/** - * Optionally define a custom `cache` namespace to use. - */ - -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); - } - - /** - * Inherit cache-base - */ - - util.inherits(Base, Cache); - - /** - * Add static emitter methods - */ - - Emitter(Base); - - /** - * Initialize `Base` defaults with the given `config` object - */ - - 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; - }); +Object.defineProperty(Node.prototype, 'scope', { + get: function() { + if (this.isScope !== true) { + return this.parent ? this.parent.scope : this; + } + return this; + } +}); - /** - * 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 - */ +/** + * Get own property names from Node prototype, but only the + * first time `Node` is instantiated + */ - define(Base, 'inherit', cu.inherit); - define(Base, 'bubble', cu.bubble); - return Base; +function lazyKeys() { + if (!ownNames) { + ownNames = Object.getOwnPropertyNames(Node.prototype); + } } /** - * Expose `Base` with default settings + * Simplified assertion. Throws an error is `val` is falsey. */ -module.exports = namespace(); +function assert(val, message) { + if (!val) throw new Error(message); +} /** - * Allow users to define a namespace + * Expose `Node` */ -module.exports.namespace = namespace; +exports = module.exports = Node; /***/ }), -/* 569 */ +/* 566 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -66567,7 +64957,7 @@ module.exports.namespace = namespace; -var isDescriptor = __webpack_require__(559); +var isDescriptor = __webpack_require__(535); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -66592,1698 +64982,2368 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 570 */ +/* 567 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(545); -var Emitter = __webpack_require__(571); -var visit = __webpack_require__(572); -var toPath = __webpack_require__(575); -var union = __webpack_require__(576); -var del = __webpack_require__(580); -var get = __webpack_require__(578); -var has = __webpack_require__(585); -var set = __webpack_require__(579); +var typeOf = __webpack_require__(559); +var utils = module.exports; /** - * Create a `Cache` constructor that when instantiated will - * store values on the given `prop`. + * Returns true if the given value is a node. * * ```js - * var Cache = require('cache-base').namespace('data'); - * var cache = new Cache(); + * 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 + */ + +utils.isNode = function(node) { + return typeOf(node) === 'object' && node.isNode === true; +}; + +/** + * Emit an empty string for the given `node`. * - * cache.set('foo', 'bar'); - * //=> {data: {foo: 'bar'}} + * ```js + * // do nothing for beginning-of-string + * snapdragon.compiler.set('bos', utils.noop); * ``` - * @param {String} `prop` The property name to use for storing values. - * @return {Function} Returns a custom `Cache` constructor + * @param {Object} `node` Instance of [snapdragon-node][] + * @returns {undefined} * @api public */ -function namespace(prop) { +utils.noop = function(node) { + append(this, '', node); +}; - /** - * 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 - */ +/** + * 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 + */ - function Cache(cache) { - if (prop) { - this[prop] = {}; - } - if (cache) { - this.set(cache); - } +utils.identity = function(node) { + append(this, node.val, node); +}; + +/** + * 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 + */ + +utils.append = function(val) { + return function(node) { + append(this, val, node); + }; +}; + +/** + * 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 = ''; } +}; - /** - * Inherit Emitter - */ +/** + * 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 + */ - Emitter(Cache.prototype); +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; +}; - /** - * 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 - */ +/** + * 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 + */ - 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; - }; +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'); - /** - * 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 - */ + for (var i = 0; i < node.nodes.length; i++) { + utils.visit(node.nodes[i], fn); + } + return node; +}; - 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; - }; +/** + * 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 + */ - /** - * 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 - */ +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'); - Cache.prototype.get = function(key) { - key = toPath(arguments); + if (typeof val === 'function') { + filter = val; + val = ''; + } - var ctx = prop ? this[prop] : this; - var val = get(ctx, key); + 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; +}; - this.emit('get', key, val); - return val; - }; +/** + * 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 + */ + +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; +}; + +/** + * 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 + */ + +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; +}; + +/** + * 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 + */ + +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'); + + node.define('parent', parent); + parent.nodes = parent.nodes || []; + parent.nodes.push(node); + return node; +}; + +/** + * 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 + */ + +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'); + + node.define('parent', parent); + parent.nodes = parent.nodes || []; + parent.nodes.unshift(node); +}; + +/** + * 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 + */ + +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(); +}; + +/** + * 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 + */ - /** - * 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 - */ +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(); +}; - Cache.prototype.has = function(key) { - key = toPath(arguments); +/** + * 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 + */ - var ctx = prop ? this[prop] : this; - var val = get(ctx, key); +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'); - var has = typeof val !== 'undefined'; - this.emit('has', key, has); - return has; - }; + if (!parent.nodes) { + return null; + } - /** - * 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 - */ + if (typeof parent.remove === 'function') { + return parent.remove(node); + } - 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; - }; + var idx = parent.nodes.indexOf(node); + if (idx !== -1) { + return parent.nodes.splice(idx, 1); + } +}; - /** - * Reset the entire cache to an empty object. - * - * ```js - * app.clear(); - * ``` - * @api public - */ +/** + * 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 + */ - Cache.prototype.clear = function() { - if (prop) { - this[prop] = {}; +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'); } - }; - - /** - * 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; - }; +/** + * 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 + */ - return Cache; -} +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; + } + } + return false; +}; /** - * Cast val to an array + * 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 */ -function arrayify(val) { - return val ? (Array.isArray(val) ? val : [val]) : []; -} +utils.firstOfType = function(nodes, type) { + for (var i = 0; i < nodes.length; i++) { + var node = nodes[i]; + if (utils.isType(node, type)) { + return node; + } + } +}; /** - * Expose `Cache` + * 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 */ -module.exports = namespace(); +utils.findNode = function(nodes, type) { + if (!Array.isArray(nodes)) { + return null; + } + if (typeof type === 'number') { + return nodes[type]; + } + return utils.firstOfType(nodes, type); +}; /** - * Expose `Cache.namespace` + * 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 */ -module.exports.namespace = namespace; - +utils.isOpen = function(node) { + assert(utils.isNode(node), 'expected node to be an instance of Node'); + return node.type.slice(-5) === '.open'; +}; -/***/ }), -/* 571 */ -/***/ (function(module, exports, __webpack_require__) { +/** + * 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 + */ - -/** - * 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; -}; +utils.isClose = function(node) { + assert(utils.isNode(node), 'expected node to be an instance of Node'); + return node.type.slice(-6) === '.close'; +}; +/** + * 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 + */ -/***/ }), -/* 572 */ -/***/ (function(module, exports, __webpack_require__) { +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'; + } + return false; +}; -"use strict"; -/*! - * collection-visit +/** + * Returns true if `node.nodes` **has** a `.close` node * - * Copyright (c) 2015, 2017, Jon Schlinkert. - * Released under the MIT License. + * ```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 */ - - -var visit = __webpack_require__(573); -var mapVisit = __webpack_require__(574); - -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; +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'; } - - return collection; + return false; }; - -/***/ }), -/* 573 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * object-visit +/** + * Returns true if `node.nodes` has both `.open` and `.close` nodes * - * Copyright (c) 2015, 2017, Jon Schlinkert. - * Released under the MIT License. + * ```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); +}; +/** + * 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 + * 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 + */ -var isObject = __webpack_require__(545); +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'); -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.'); - } + var type = node.parent + ? node.parent.type + : node.type.replace(/\.open$/, ''); - if (typeof method !== 'string') { - throw new Error('object-visit expects `method` name to be a string'); + if (!state.hasOwnProperty('inside')) { + state.inside = {}; } - - if (typeof thisArg[method] !== 'function') { - return thisArg; + if (!state.inside.hasOwnProperty(type)) { + state.inside[type] = []; } - 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; + var arr = state.inside[type]; + arr.push(node); + return arr; }; - -/***/ }), -/* 574 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var util = __webpack_require__(111); -var visit = __webpack_require__(573); - /** - * Map `visit` over an array of objects. + * 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`. * - * @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. + * ```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 */ -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)); - } +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'); - var args = [].slice.call(arguments, 3); + var type = node.parent + ? node.parent.type + : node.type.replace(/\.close$/, ''); - 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)); - } + if (state.inside.hasOwnProperty(type)) { + return state.inside[type].pop(); } }; -function isObject(val) { - return val && (typeof val === 'function' || (!Array.isArray(val) && typeof val === 'object')); -} - - -/***/ }), -/* 575 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * to-object-path +/** + * Returns true if `node.val` is an empty string, or `node.nodes` does + * not contain any non-empty text nodes. * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. + * ```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'); - -var typeOf = __webpack_require__(550); - -module.exports = function toPath(args) { - if (typeOf(args) !== 'arguments') { - args = arguments; + 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); } - 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); + 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 res; -} - - -/***/ }), -/* 576 */ -/***/ (function(module, exports, __webpack_require__) { -"use strict"; + return true; +}; +/** + * 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 isObject = __webpack_require__(537); -var union = __webpack_require__(577); -var get = __webpack_require__(578); -var set = __webpack_require__(579); +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 unionValue(obj, prop, value) { - if (!isObject(obj)) { - throw new TypeError('union-value expects the first argument to be an object.'); + if (!state.hasOwnProperty('inside')) { + return false; } - if (typeof prop !== 'string') { - throw new TypeError('union-value expects `prop` to be a string.'); + if (!state.inside.hasOwnProperty(type)) { + return false; } - var arr = arrayify(get(obj, prop)); - set(obj, prop, union(arr, arrayify(value))); - return obj; + return state.inside[type].length > 0; }; -function arrayify(val) { - if (val === null || typeof val === 'undefined') { - return []; - } - if (Array.isArray(val)) { - return val; - } - return [val]; -} - - -/***/ }), -/* 577 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; +/** + * 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 + */ +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'); -module.exports = function union(init) { - if (!Array.isArray(init)) { - throw new TypeError('arr-union expects the first argument to be an array.'); + if (Array.isArray(type)) { + for (var i = 0; i < type.length; i++) { + if (utils.isInside(state, node, type[i])) { + return true; + } + } + return false; } - var len = arguments.length; - var i = 0; - - while (++i < len) { - var arg = arguments[i]; - if (!arg) continue; + var parent = node.parent; + if (typeof type === 'string') { + return (parent && parent.type === type) || utils.isInsideType(state, type); + } - if (!Array.isArray(arg)) { - arg = [arg]; + if (typeOf(type) === 'regexp') { + if (parent && parent.type && type.test(parent.type)) { + return true; } - for (var j = 0; j < arg.length; j++) { - var ele = arg[j]; + 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 (init.indexOf(ele) >= 0) { - continue; + if (Array.isArray(val) && val.length !== 0 && type.test(key)) { + return true; } - init.push(ele); } } - return init; + return false; }; - -/***/ }), -/* 578 */ -/***/ (function(module, exports) { - -/*! - * get-value +/** + * Get the last `n` element from the given `array`. Used for getting + * a node from `node.nodes.` * - * Copyright (c) 2014-2015, Jon Schlinkert. - * Licensed under the MIT License. + * @param {Array} `array` + * @param {Number} `n` + * @return {undefined} + * @api public */ -module.exports = function(obj, prop, a, b, c) { - if (!isObject(obj) || !prop) { - return obj; - } - - prop = toString(prop); +utils.last = function(arr, n) { + return arr[arr.length - (n || 1)]; +}; - // 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); +/** + * 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 + */ - if (prop in obj) { - return obj[prop]; +utils.arrayify = function(val) { + if (typeof val === 'string' && val !== '') { + return [val]; } - - 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]; + if (!Array.isArray(val)) { + return []; } - return obj; + return val; }; -function isObject(val) { - return val !== null && (typeof val === 'object' || typeof val === 'function'); -} +/** + * 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 + */ -function toString(val) { - if (!val) return ''; - if (Array.isArray(val)) { - return val.join('.'); - } - return val; -} +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 + */ -/***/ }), -/* 579 */ -/***/ (function(module, exports, __webpack_require__) { +utils.trim = function(str) { + return typeof str === 'string' ? str.trim() : ''; +}; -"use strict"; -/*! - * set-value - * - * Copyright (c) 2014-2015, 2017, Jon Schlinkert. - * Released under the MIT License. +/** + * Return true if val is an object */ +function isObject(val) { + return typeOf(val) === 'object'; +} +/** + * Return true if val is a string + */ -var split = __webpack_require__(541); -var extend = __webpack_require__(536); -var isPlainObject = __webpack_require__(544); -var isObject = __webpack_require__(537); +function isString(val) { + return typeof val === 'string'; +} -module.exports = function(obj, prop, val) { - if (!isObject(obj)) { - return obj; - } +/** + * Return true if val is a function + */ - if (Array.isArray(prop)) { - prop = [].concat.apply([], prop).join('.'); - } +function isFunction(val) { + return typeof val === 'function'; +} - if (typeof prop !== 'string') { - return obj; - } +/** + * Return true if val is an array + */ - var keys = split(prop, {sep: '.', brackets: true}).filter(isValidKey); - var len = keys.length; - var idx = -1; - var current = obj; +function isArray(val) { + return Array.isArray(val); +} - while (++idx < len) { - var key = keys[idx]; - if (idx !== len - 1) { - if (!isObject(current[key])) { - current[key] = {}; - } - current = current[key]; - continue; - } +/** + * Shim to ensure the `.append` methods work with any version of snapdragon + */ - if (isPlainObject(current[key]) && isPlainObject(val)) { - current[key] = extend({}, current[key], val); - } else { - current[key] = val; - } +function append(compiler, val, node) { + if (typeof compiler.append !== 'function') { + return compiler.emit(val, node); } + return compiler.append(val, node); +} - return obj; -}; +/** + * Simplified assertion. Throws an error is `val` is falsey. + */ -function isValidKey(key) { - return key !== '__proto__' && key !== 'constructor' && key !== 'prototype'; +function assert(val, message) { + if (!val) throw new Error(message); } /***/ }), -/* 580 */ +/* 568 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/*! - * unset-value - * - * Copyright (c) 2015, 2017, Jon Schlinkert. - * Released under the MIT License. + + +var extend = __webpack_require__(549); +var Snapdragon = __webpack_require__(569); +var compilers = __webpack_require__(551); +var parsers = __webpack_require__(564); +var utils = __webpack_require__(552); + +/** + * 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 isObject = __webpack_require__(545); -var has = __webpack_require__(581); + /** + * 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 unset(obj, prop) { - if (!isObject(obj)) { - throw new TypeError('expected an object.'); - } - if (obj.hasOwnProperty(prop)) { - delete obj[prop]; - return true; - } + utils.define(this.snapdragon, 'parse', function(pattern, options) { + var parsed = Snapdragon.prototype.parse.apply(this, arguments); + this.parser.ast.input = pattern; - 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; + var stack = this.parser.stack; + while (stack.length) { + addParent({type: 'brace.close', val: ''}, stack.pop()); } - while (segs.length) obj = obj[prop = segs.shift()]; - return (delete obj[last]); - } - return true; + + 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; + }); }; +/** + * Decorate `.parse` method + */ -/***/ }), -/* 581 */ -/***/ (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"; -/*! - * has-value - * - * Copyright (c) 2014-2016, Jon Schlinkert. - * Licensed 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 + */ -var isObject = __webpack_require__(582); -var hasValues = __webpack_require__(584); -var get = __webpack_require__(578); +Braces.prototype.expand = function(pattern) { + var ast = this.parse(pattern, {expand: true}); + return this.compile(ast, {expand: true}); +}; -module.exports = function(obj, prop, noZero) { - if (isObject(obj)) { - return hasValues(get(obj, prop), noZero); - } - return hasValues(obj, prop); +/** + * Optimize + */ + +Braces.prototype.optimize = function(pattern) { + var ast = this.parse(pattern, {optimize: true}); + return this.compile(ast, {optimize: true}); }; +/** + * Expose `Braces` + */ + +module.exports = Braces; + /***/ }), -/* 582 */ +/* 569 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/*! - * isobject + + +var Base = __webpack_require__(570); +var define = __webpack_require__(596); +var Compiler = __webpack_require__(606); +var Parser = __webpack_require__(635); +var utils = __webpack_require__(615); +var regexCache = {}; +var cache = {}; + +/** + * Create a new instance of `Snapdragon` with the given `options`. * - * Copyright (c) 2014-2015, Jon Schlinkert. - * Licensed under the MIT License. + * ```js + * var snapdragon = new Snapdragon(); + * ``` + * + * @param {Object} `options` + * @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; + } + }); -var isArray = __webpack_require__(583); + Object.defineProperty(this, 'parsers', { + get: function() { + return this.parser.parsers; + } + }); -module.exports = function isObject(val) { - return val != null && typeof val === 'object' && isArray(val) === false; -}; + Object.defineProperty(this, 'regex', { + get: function() { + return this.parser.regex; + } + }); +} +/** + * Inherit Base + */ -/***/ }), -/* 583 */ -/***/ (function(module, exports) { +Base.extend(Snapdragon); -var toString = {}.toString; +/** + * 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 + */ -module.exports = Array.isArray || function (arr) { - return toString.call(arr) == '[object Array]'; +Snapdragon.prototype.capture = function() { + return this.parser.capture.apply(this.parser, arguments); }; +/** + * 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 + */ -/***/ }), -/* 584 */ -/***/ (function(module, exports, __webpack_require__) { +Snapdragon.prototype.use = function(fn) { + fn.call(this, this); + return this; +}; -"use strict"; -/*! - * has-values +/** + * Parse the given `str`. * - * Copyright (c) 2014-2015, Jon Schlinkert. - * Licensed under the MIT License. + * ```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); + + // add non-enumerable parser reference + define(parsed, 'parser', this.parser); + return parsed; +}; + +/** + * Compile the given `AST`. + * + * ```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); -module.exports = function hasValue(o, noZero) { - if (o === null || o === undefined) { - return false; - } + // add non-enumerable compiler reference + define(compiled, 'compiler', this.compiler); + return compiled; +}; - if (typeof o === 'boolean') { - return true; - } +/** + * Expose `Snapdragon` + */ - if (typeof o === 'number') { - if (o === 0 && noZero === true) { - return false; - } - return true; - } +module.exports = Snapdragon; - if (o.length !== undefined) { - return o.length !== 0; - } +/** + * Expose `Parser` and `Compiler` + */ - for (var key in o) { - if (o.hasOwnProperty(key)) { - return true; - } - } - return false; -}; +module.exports.Compiler = Compiler; +module.exports.Parser = Parser; /***/ }), -/* 585 */ +/* 570 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/*! - * has-value - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Licensed under the MIT License. + + +var util = __webpack_require__(112); +var define = __webpack_require__(571); +var CacheBase = __webpack_require__(572); +var Emitter = __webpack_require__(573); +var isObject = __webpack_require__(534); +var merge = __webpack_require__(590); +var pascal = __webpack_require__(593); +var cu = __webpack_require__(594); + +/** + * 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 + */ -var isObject = __webpack_require__(545); -var hasValues = __webpack_require__(586); -var get = __webpack_require__(578); + function Base(config, options) { + if (!(this instanceof Base)) { + return new Base(config, options); + } + Cache.call(this, config); + this.is('base'); + this.initBase(config, options); + } -module.exports = function(val, prop) { - return hasValues(isObject(val) && prop ? get(val, prop) : val); -}; + /** + * Inherit cache-base + */ + util.inherits(Base, Cache); -/***/ }), -/* 586 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Add static emitter methods + */ -"use strict"; -/*! - * has-values - * - * Copyright (c) 2014-2015, 2017, Jon Schlinkert. - * Released under the MIT License. - */ + Emitter(Base); + /** + * Initialize `Base` defaults with the given `config` object + */ + Base.prototype.initBase = function(config, options) { + this.options = merge({}, this.options, options); + this.cache = this.cache || {}; + this.define('registered', {}); + if (name) this[name] = {}; -var typeOf = __webpack_require__(587); -var isNumber = __webpack_require__(549); + // 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 hasValue(val) { - // is-number checks for NaN and other edge cases - if (isNumber(val)) { - return true; - } + /** + * 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 + */ - switch (typeOf(val)) { - case 'null': - case 'boolean': - case '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; + }; + + /** + * 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; - 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; } - } -}; + 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 + */ -/***/ }), -/* 587 */ -/***/ (function(module, exports, __webpack_require__) { + Base.prototype.use = function(fn) { + fn.call(this, this); + return this; + }; -var isBuffer = __webpack_require__(530); -var toString = Object.prototype.toString; + /** + * 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 + */ -/** - * Get the native `typeof` a value. - * - * @param {*} `val` - * @return {*} Native javascript type - */ + Base.prototype.define = function(key, val) { + if (isObject(key)) { + return this.visit('define', key); + } + define(this, key, val); + return this; + }; -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'; - } + /** + * 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 + */ - // functions - if (typeof val === 'function' || val instanceof Function) { - return 'function'; - } + Base.prototype.mixin = function(key, val) { + Base.prototype[key] = val; + return this; + }; - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; - } + /** + * Non-enumberable mixin array, used by the static [Base.mixin]() method. + */ - // check for instances of RegExp and Date before calling `toString` - if (val instanceof RegExp) { - return 'regexp'; - } - if (val instanceof Date) { - return 'date'; - } + Base.prototype.mixins = Base.prototype.mixins || []; - // other objects - var type = toString.call(val); + /** + * 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 + */ - 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'; - } + Object.defineProperty(Base.prototype, 'base', { + configurable: true, + get: function() { + return this.parent ? this.parent.base : this; + } + }); - // buffer - if (isBuffer(val)) { - return 'buffer'; - } + /** + * 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 + */ - // 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'; - } + define(Base, 'use', function(fn) { + fns.push(fn); + return Base; + }); - // 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'; - } + /** + * 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. + */ - // must be a plain object - return 'object'; -}; + 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 + */ -/***/ }), -/* 588 */ -/***/ (function(module, exports, __webpack_require__) { + define(Base, 'extend', cu.extend(Base, function(Ctor, Parent) { + Ctor.prototype.mixins = Ctor.prototype.mixins || []; -"use strict"; + 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; + }); -var isExtendable = __webpack_require__(589); -var forIn = __webpack_require__(590); + Ctor.prototype.mixin = function(key, value) { + Ctor.prototype[key] = value; + return this; + }; + return Base; + })); -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; -} + /** + * 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 + */ -/** - * Copy properties from the source object to the - * target object. - * - * @param {*} `val` - * @param {String} `key` - */ + define(Base, 'mixin', function(fn) { + var mixin = fn(Base.prototype, Base); + if (typeof mixin === 'function') { + Base.prototype.mixins.push(mixin); + } + return Base; + }); -function copy(val, key) { - if (!isValidKey(key)) { - return; - } + /** + * 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 + */ - var obj = this[key]; - if (isObject(val) && isObject(obj)) { - mixinDeep(obj, val); - } else { - this[key] = val; - } -} + define(Base, 'mixins', function(Child) { + Base.run(Child, 'mixin', Base.prototype.mixins); + return Base; + }); -/** - * Returns true if `val` is an object or function. - * - * @param {any} val - * @return {Boolean} - */ + /** + * 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 + */ -function isObject(val) { - return isExtendable(val) && !Array.isArray(val); + define(Base, 'inherit', cu.inherit); + define(Base, 'bubble', cu.bubble); + return Base; } /** - * Returns true if `key` is a valid key to use when extending objects. - * - * @param {String} `key` - * @return {Boolean} + * Expose `Base` with default settings */ -function isValidKey(key) { - return key !== '__proto__' && key !== 'constructor' && key !== 'prototype'; -}; +module.exports = namespace(); /** - * Expose `mixinDeep` + * Allow users to define a namespace */ -module.exports = mixinDeep; +module.exports.namespace = namespace; /***/ }), -/* 589 */ +/* 571 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! - * is-extendable + * define-property * - * Copyright (c) 2015-2017, Jon Schlinkert. + * Copyright (c) 2015, 2017, Jon Schlinkert. * Released under the MIT License. */ -var isPlainObject = __webpack_require__(544); +var isDescriptor = __webpack_require__(535); -module.exports = function isExtendable(val) { - return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); +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 + }); }; /***/ }), -/* 590 */ +/* 572 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/*! - * for-in + + +var isObject = __webpack_require__(534); +var Emitter = __webpack_require__(573); +var visit = __webpack_require__(574); +var toPath = __webpack_require__(577); +var union = __webpack_require__(578); +var del = __webpack_require__(582); +var get = __webpack_require__(580); +var has = __webpack_require__(587); +var set = __webpack_require__(581); + +/** + * Create a `Cache` constructor that when instantiated will + * store values on the given `prop`. * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. + * ```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 + */ -module.exports = function forIn(obj, fn, thisArg) { - for (var key in obj) { - if (fn.call(thisArg, obj[key], key, obj) === false) { - break; + function Cache(cache) { + if (prop) { + this[prop] = {}; + } + if (cache) { + this.set(cache); } } -}; - - -/***/ }), -/* 591 */ -/***/ (function(module, exports) { - -/*! - * 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(); - }); -} + /** + * Inherit Emitter + */ -module.exports = pascalcase; + 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 + */ -/***/ }), -/* 592 */ -/***/ (function(module, exports, __webpack_require__) { + 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; + }; -"use strict"; + /** + * 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; + }; -var util = __webpack_require__(111); -var utils = __webpack_require__(593); + /** + * 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 + */ -/** - * Expose class utils - */ + Cache.prototype.get = function(key) { + key = toPath(arguments); -var cu = module.exports; + var ctx = prop ? this[prop] : this; + var val = get(ctx, key); -/** - * Expose class utils: `cu` - */ + this.emit('get', key, val); + return val; + }; -cu.isObject = function isObject(val) { - return utils.isObj(val) || typeof val === 'function'; -}; + /** + * 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 + */ -/** - * 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 - */ + Cache.prototype.has = function(key) { + key = toPath(arguments); -cu.has = function has(obj, val) { - val = cu.arrayify(val); - var len = val.length; + var ctx = prop ? this[prop] : this; + var val = get(ctx, key); - if (cu.isObject(obj)) { - for (var key in obj) { - if (val.indexOf(key) > -1) { - return true; - } - } + var has = typeof val !== 'undefined'; + this.emit('has', key, has); + return has; + }; - var keys = cu.nativeKeys(obj); - return cu.has(keys, val); - } + /** + * 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 + */ - if (Array.isArray(obj)) { - var arr = obj; - while (len--) { - if (arr.indexOf(val[len]) > -1) { - return true; - } + 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 false; - } - - throw new TypeError('expected an array or object.'); -}; + return this; + }; -/** - * 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 - */ + /** + * Reset the entire cache to an empty object. + * + * ```js + * app.clear(); + * ``` + * @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; + Cache.prototype.clear = function() { + if (prop) { + this[prop] = {}; } - } - return true; -}; + }; -/** - * Cast the given value to an array. - * - * ```js - * cu.arrayify('foo'); - * //=> ['foo'] - * - * cu.arrayify(['foo']); - * //=> ['foo'] - * ``` - * - * @param {String|Array} `val` - * @return {Array} - * @api public - */ + /** + * 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 + */ -cu.arrayify = function arrayify(val) { - return val ? (Array.isArray(val) ? val : [val]) : []; -}; + Cache.prototype.visit = function(method, val) { + visit(this, method, val); + return this; + }; + + return Cache; +} /** - * Noop + * Cast val to an array */ -cu.noop = function noop() { - return; -}; +function arrayify(val) { + return val ? (Array.isArray(val) ? val : [val]) : []; +} /** - * Returns the first argument passed to the function. + * Expose `Cache` */ -cu.identity = function identity(val) { - return val; -}; +module.exports = namespace(); /** - * Returns true if a value has a `contructor` - * - * ```js - * cu.hasConstructor({}); - * //=> true - * - * cu.hasConstructor(Object.create(null)); - * //=> false - * ``` - * @param {Object} `value` - * @return {Boolean} - * @api public + * Expose `Cache.namespace` */ -cu.hasConstructor = function hasConstructor(val) { - return cu.isObject(val) && typeof val.constructor !== 'undefined'; -}; +module.exports.namespace = namespace; -/** - * 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 - */ -cu.nativeKeys = function nativeKeys(val) { - if (!cu.hasConstructor(val)) return []; - return Object.getOwnPropertyNames(val); -}; +/***/ }), +/* 573 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * 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 - */ + +/** + * 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; +}; -cu.getDescriptor = function getDescriptor(obj, key) { - if (!cu.isObject(obj)) { - throw new TypeError('expected an object.'); - } - if (typeof key !== 'string') { - throw new TypeError('expected key to be a string.'); - } - return Object.getOwnPropertyDescriptor(obj, key); -}; -/** - * Copy a descriptor from one object to another. +/***/ }), +/* 574 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/*! + * collection-visit * - * ```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 + * Copyright (c) 2015, 2017, Jon Schlinkert. + * Released under the MIT License. */ -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.'); - } - if (typeof name !== 'string') { - throw new TypeError('expected name to be a string.'); - } - var val = cu.getDescriptor(provider, name); - if (val) Object.defineProperty(receiver, name, val); -}; -/** - * Copy static properties, prototype properties, and descriptors - * from one object to another. - * - * @param {Object} `receiver` - * @param {Object} `provider` - * @param {String|Array} `omit` One or more properties to omit - * @return {Object} - * @api public - */ +var visit = __webpack_require__(575); +var mapVisit = __webpack_require__(576); -cu.copy = function copy(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 props = Object.getOwnPropertyNames(provider); - var keys = Object.keys(provider); - var len = props.length, - key; - omit = cu.arrayify(omit); +module.exports = function(collection, method, val) { + var result; - while (len--) { - key = props[len]; + 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 (cu.has(keys, key)) { - utils.define(receiver, key, provider[key]); - } else if (!(key in receiver) && !cu.has(omit, key)) { - cu.copyDescriptor(receiver, provider, key); - } + if (typeof result !== 'undefined') { + return result; } + + return collection; }; -/** - * Inherit the static properties, prototype properties, and descriptors - * from of an object. + +/***/ }), +/* 575 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/*! + * object-visit * - * @param {Object} `receiver` - * @param {Object} `provider` - * @param {String|Array} `omit` One or more properties to omit - * @return {Object} - * @api public + * Copyright (c) 2015, 2017, Jon Schlinkert. + * Released under the MIT License. */ -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 isObject = __webpack_require__(534); - var a = provider.prototype || provider; - var b = receiver.prototype || receiver; - cu.copy(b, a, keys); -}; +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.'); + } -/** - * Returns a function for extending the static properties, - * prototype properties, and descriptors from the `Parent` - * constructor onto `Child` constructors. - * - * ```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 - */ + if (typeof method !== 'string') { + throw new Error('object-visit expects `method` name to be a string'); + } -cu.extend = function() { - // keep it lazy, instead of assigning to `cu.extend` - return utils.staticExtend.apply(null, arguments); -}; + if (typeof thisArg[method] !== 'function') { + return thisArg; + } -/** - * Bubble up events emitted from static methods on the Parent ctor. - * - * @param {Object} `Parent` - * @param {Array} `events` Event names to bubble up - * @api public - */ + var args = [].slice.call(arguments, 3); + target = target || {}; -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); - }; + for (var key in target) { + var arr = [key, target[key]].concat(args); + thisArg[method].apply(thisArg, arr); + } + return thisArg; }; /***/ }), -/* 593 */ +/* 576 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var utils = {}; - - +var util = __webpack_require__(112); +var visit = __webpack_require__(575); /** - * Lazily required module dependencies + * 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. */ -utils.union = __webpack_require__(577); -utils.define = __webpack_require__(594); -utils.isObj = __webpack_require__(545); -utils.staticExtend = __webpack_require__(601); +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)); + } -/** - * Expose `utils` - */ + var args = [].slice.call(arguments, 3); -module.exports = utils; + 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')); +} /***/ }), -/* 594 */ +/* 577 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! - * define-property + * to-object-path * * Copyright (c) 2015, Jon Schlinkert. * Licensed under the MIT License. @@ -68291,477 +67351,458 @@ module.exports = utils; -var isDescriptor = __webpack_require__(595); +var typeOf = __webpack_require__(559); -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 = []; + + 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; +} + + +/***/ }), +/* 578 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var isObject = __webpack_require__(550); +var union = __webpack_require__(579); +var get = __webpack_require__(580); +var set = __webpack_require__(581); + +module.exports = function unionValue(obj, prop, value) { + if (!isObject(obj)) { + throw new TypeError('union-value expects the first argument to be an object.'); } - if (isDescriptor(val) && ('set' in val || 'get' in val)) { - return Object.defineProperty(obj, prop, val); + if (typeof prop !== 'string') { + throw new TypeError('union-value expects `prop` to be a string.'); } - return Object.defineProperty(obj, prop, { - configurable: true, - enumerable: false, - writable: true, - value: val - }); + 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]; +} + /***/ }), -/* 595 */ +/* 579 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/*! - * is-descriptor - * - * Copyright (c) 2015-2017, Jon Schlinkert. - * Released under the MIT License. - */ +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; -var typeOf = __webpack_require__(596); -var isAccessor = __webpack_require__(597); -var isData = __webpack_require__(599); + while (++i < len) { + var arg = arguments[i]; + if (!arg) continue; -module.exports = function isDescriptor(obj, key) { - if (typeOf(obj) !== 'object') { - return false; - } - if ('get' in obj) { - return isAccessor(obj, key); + 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 isData(obj, key); + return init; }; /***/ }), -/* 596 */ +/* 580 */ /***/ (function(module, exports) { -var toString = Object.prototype.toString; - -/** - * Get the native `typeof` a value. +/*! + * get-value * - * @param {*} `val` - * @return {*} Native javascript type + * Copyright (c) 2014-2015, Jon Schlinkert. + * Licensed under the MIT License. */ -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'; +module.exports = function(obj, prop, a, b, c) { + if (!isObject(obj) || !prop) { + return obj; } - if (type === 'number' || val instanceof Number) { - return 'number'; + + 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]; } - // functions - if (type === 'function' || val instanceof Function) { - if (typeof val.constructor.name !== 'undefined' && val.constructor.name.slice(0, 9) === 'Generator') { - return 'generatorfunction'; + 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]; } - return 'function'; + obj = obj[key]; } + return obj; +}; - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; - } +function isObject(val) { + return val !== null && (typeof val === 'object' || typeof val === 'function'); +} - // check for instances of RegExp and Date before calling `toString` - if (val instanceof RegExp) { - return 'regexp'; - } - if (val instanceof Date) { - return 'date'; +function toString(val) { + if (!val) return ''; + if (Array.isArray(val)) { + return val.join('.'); } + return val; +} - // 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'; - } +/***/ }), +/* 581 */ +/***/ (function(module, exports, __webpack_require__) { - // buffer - if (isBuffer(val)) { - return 'buffer'; - } +"use strict"; +/*! + * set-value + * + * Copyright (c) 2014-2015, 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'; - } - - 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'; + + +var split = __webpack_require__(553); +var extend = __webpack_require__(549); +var isPlainObject = __webpack_require__(543); +var isObject = __webpack_require__(550); + +module.exports = function(obj, prop, val) { + if (!isObject(obj)) { + return obj; } - if (type === '[object Uint32Array]') { - return 'uint32array'; + + if (Array.isArray(prop)) { + prop = [].concat.apply([], prop).join('.'); } - if (type === '[object Float32Array]') { - return 'float32array'; + + if (typeof prop !== 'string') { + return obj; } - if (type === '[object Float64Array]') { - return 'float64array'; + + var keys = split(prop, {sep: '.', brackets: true}).filter(isValidKey); + 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; + } } - // must be a plain object - return 'object'; + 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 isBuffer(val) { - return val.constructor - && typeof val.constructor.isBuffer === 'function' - && val.constructor.isBuffer(val); +function isValidKey(key) { + return key !== '__proto__' && key !== 'constructor' && key !== 'prototype'; } /***/ }), -/* 597 */ +/* 582 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! - * is-accessor-descriptor + * unset-value * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. + * Copyright (c) 2015, 2017, Jon Schlinkert. + * Released under the MIT License. */ -var typeOf = __webpack_require__(598); - -// accessor descriptor properties -var accessor = { - get: 'function', - set: 'function', - configurable: 'boolean', - enumerable: 'boolean' -}; +var isObject = __webpack_require__(534); +var has = __webpack_require__(583); -function isAccessorDescriptor(obj, prop) { - if (typeof prop === 'string') { - var val = Object.getOwnPropertyDescriptor(obj, prop); - return typeof val !== 'undefined'; +module.exports = function unset(obj, prop) { + if (!isObject(obj)) { + throw new TypeError('expected an object.'); } - - if (typeOf(obj) !== 'object') { - return false; + if (obj.hasOwnProperty(prop)) { + delete obj[prop]; + return true; } - if (has(obj, 'value') || has(obj, 'writable')) { - return false; + 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; +}; - 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; - } +/***/ }), +/* 583 */ +/***/ (function(module, exports, __webpack_require__) { - for (var key in obj) { - if (!accessor.hasOwnProperty(key)) { - continue; - } +"use strict"; +/*! + * has-value + * + * Copyright (c) 2014-2016, Jon Schlinkert. + * Licensed under the MIT License. + */ - if (typeOf(obj[key]) === accessor[key]) { - continue; - } - if (typeof obj[key] !== 'undefined') { - return false; - } + +var isObject = __webpack_require__(584); +var hasValues = __webpack_require__(586); +var get = __webpack_require__(580); + +module.exports = function(obj, prop, noZero) { + if (isObject(obj)) { + return hasValues(get(obj, prop), noZero); } - return true; -} + return hasValues(obj, prop); +}; -function has(obj, key) { - return {}.hasOwnProperty.call(obj, key); -} -/** - * Expose `isAccessorDescriptor` +/***/ }), +/* 584 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/*! + * isobject + * + * Copyright (c) 2014-2015, Jon Schlinkert. + * Licensed under the MIT License. */ -module.exports = isAccessorDescriptor; + + +var isArray = __webpack_require__(585); + +module.exports = function isObject(val) { + return val != null && typeof val === 'object' && isArray(val) === false; +}; /***/ }), -/* 598 */ -/***/ (function(module, exports, __webpack_require__) { +/* 585 */ +/***/ (function(module, exports) { -var isBuffer = __webpack_require__(530); -var toString = Object.prototype.toString; +var toString = {}.toString; -/** - * Get the native `typeof` a value. - * - * @param {*} `val` - * @return {*} Native javascript type - */ +module.exports = Array.isArray || function (arr) { + return toString.call(arr) == '[object Array]'; +}; -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'; - } +/***/ }), +/* 586 */ +/***/ (function(module, exports, __webpack_require__) { - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; - } +"use strict"; +/*! + * has-values + * + * Copyright (c) 2014-2015, Jon Schlinkert. + * Licensed under the MIT License. + */ - // 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'; +module.exports = function hasValue(o, noZero) { + if (o === null || o === undefined) { + return false; } - // buffer - if (isBuffer(val)) { - return 'buffer'; + if (typeof o === 'boolean') { + return true; } - // 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 o === 'number') { + if (o === 0 && noZero === true) { + return false; + } + return true; } - // 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 (o.length !== undefined) { + return o.length !== 0; } - // must be a plain object - return 'object'; + for (var key in o) { + if (o.hasOwnProperty(key)) { + return true; + } + } + return false; }; /***/ }), -/* 599 */ +/* 587 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! - * is-data-descriptor + * has-value * - * Copyright (c) 2015, Jon Schlinkert. + * Copyright (c) 2014-2017, Jon Schlinkert. * Licensed under the MIT License. */ -var typeOf = __webpack_require__(600); +var isObject = __webpack_require__(534); +var hasValues = __webpack_require__(588); +var get = __webpack_require__(580); -// data descriptor properties -var data = { - configurable: 'boolean', - enumerable: 'boolean', - writable: 'boolean' +module.exports = function(val, prop) { + return hasValues(isObject(val) && prop ? get(val, prop) : val); }; -function isDataDescriptor(obj, prop) { - if (typeOf(obj) !== 'object') { - return false; - } - if (typeof prop === 'string') { - var val = Object.getOwnPropertyDescriptor(obj, prop); - return typeof val !== 'undefined'; - } +/***/ }), +/* 588 */ +/***/ (function(module, exports, __webpack_require__) { - if (!('value' in obj) && !('writable' in obj)) { - return false; - } +"use strict"; +/*! + * has-values + * + * Copyright (c) 2014-2015, 2017, Jon Schlinkert. + * Released under the MIT License. + */ - for (var key in obj) { - if (key === 'value') continue; - if (!data.hasOwnProperty(key)) { - continue; - } - if (typeOf(obj[key]) === data[key]) { - continue; - } +var typeOf = __webpack_require__(589); +var isNumber = __webpack_require__(558); - if (typeof obj[key] !== 'undefined') { +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; } } - return true; -} - -/** - * Expose `isDataDescriptor` - */ - -module.exports = isDataDescriptor; +}; /***/ }), -/* 600 */ +/* 589 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(530); +var isBuffer = __webpack_require__(560); var toString = Object.prototype.toString; /** @@ -68822,6 +67863,9 @@ module.exports = function kindOf(val) { if (type === '[object Error]') { return 'error'; } + if (type === '[object Promise]') { + return 'promise'; + } // buffer if (isBuffer(val)) { @@ -68880,196 +67924,204 @@ module.exports = function kindOf(val) { /***/ }), -/* 601 */ +/* 590 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/*! - * static-extend - * - * Copyright (c) 2016, Jon Schlinkert. - * Licensed under the MIT License. - */ +var isExtendable = __webpack_require__(591); +var forIn = __webpack_require__(592); -var copy = __webpack_require__(602); -var define = __webpack_require__(594); -var util = __webpack_require__(111); +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; +} /** - * Returns a function for extending the static properties, - * prototype properties, and descriptors from the `Parent` - * constructor onto `Child` constructors. + * Copy properties from the source object to the + * target object. * - * ```js - * var extend = require('static-extend'); - * Parent.extend = extend(Parent); + * @param {*} `val` + * @param {String} `key` + */ + +function copy(val, key) { + if (!isValidKey(key)) { + return; + } + + 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. * - * // 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; - * }; - * }); + * @param {any} val + * @return {Boolean} + */ + +function isObject(val) { + return isExtendable(val) && !Array.isArray(val); +} + +/** + * Returns true if `key` is a valid key to use when extending objects. * - * // extend "child" constructors - * Parent.extend(Child); + * @param {String} `key` + * @return {Boolean} + */ + +function isValidKey(key) { + return key !== '__proto__' && key !== 'constructor' && key !== 'prototype'; +}; + +/** + * Expose `mixinDeep` + */ + +module.exports = mixinDeep; + + +/***/ }), +/* 591 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/*! + * is-extendable * - * // 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 + * Copyright (c) 2015-2017, Jon Schlinkert. + * Released under the MIT License. */ -function extend(Parent, extendFn) { - if (typeof Parent !== 'function') { - throw new TypeError('expected Parent to be a function.'); - } - return function(Ctor, proto) { - if (typeof Ctor !== 'function') { - throw new TypeError('expected Ctor to be a function.'); - } - util.inherits(Ctor, Parent); - copy(Ctor, Parent); +var isPlainObject = __webpack_require__(543); - // proto can be null or a plain object - if (typeof proto === 'object') { - var obj = Object.create(proto); +module.exports = function isExtendable(val) { + return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); +}; + + +/***/ }), +/* 592 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/*! + * for-in + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */ - for (var k in obj) { - Ctor.prototype[k] = obj[k]; - } - } - // keep a reference to the parent prototype - define(Ctor.prototype, '_parent_', { - configurable: true, - set: function() {}, - get: function() { - return Parent.prototype; - } - }); - if (typeof extendFn === 'function') { - extendFn(Ctor, Parent); +module.exports = function forIn(obj, fn, thisArg) { + for (var key in obj) { + if (fn.call(thisArg, obj[key], key, obj) === false) { + break; } - - Ctor.extend = extend(Ctor, extendFn); - }; + } }; -/** - * Expose `extend` + +/***/ }), +/* 593 */ +/***/ (function(module, exports) { + +/*! + * pascalcase + * + * Copyright (c) 2015, Jon Schlinkert. + * Licensed under the MIT License. */ -module.exports = extend; +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; /***/ }), -/* 602 */ +/* 594 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var typeOf = __webpack_require__(550); -var copyDescriptor = __webpack_require__(603); -var define = __webpack_require__(594); +var util = __webpack_require__(112); +var utils = __webpack_require__(595); /** - * 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 class utils */ -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.'); - } - - var props = nativeKeys(provider); - var keys = Object.keys(provider); - var len = props.length; - omit = arrayify(omit); - - while (len--) { - var key = props[len]; - - if (has(keys, key)) { - define(receiver, key, provider[key]); - } else if (!(key in receiver) && !has(omit, key)) { - copyDescriptor(receiver, provider, key); - } - } -}; +var cu = module.exports; /** - * Return true if the given value is an object or function + * Expose class utils: `cu` */ -function isObject(val) { - return typeOf(val) === 'object' || typeof val === 'function'; -} +cu.isObject = function isObject(val) { + return utils.isObj(val) || typeof val === 'function'; +}; /** * 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'); + * cu.has(['a', 'b', 'c'], 'c'); * //=> true * - * has(['a', 'b', 'c'], ['c', 'z']); + * cu.has(['a', 'b', 'c'], ['c', 'z']); * //=> true * - * has({a: 'b', c: 'd'}, ['c', 'z']); + * cu.has({a: 'b', c: 'd'}, ['c', 'z']); * //=> true * ``` * @param {Object} `obj` * @param {String|Array} `val` * @return {Boolean} + * @api public */ -function has(obj, val) { - val = arrayify(val); +cu.has = function has(obj, val) { + val = cu.arrayify(val); var len = val.length; - if (isObject(obj)) { + if (cu.isObject(obj)) { for (var key in obj) { if (val.indexOf(key) > -1) { return true; } } - var keys = nativeKeys(obj); - return has(keys, val); + var keys = cu.nativeKeys(obj); + return cu.has(keys, val); } if (Array.isArray(obj)) { @@ -69083,44 +68135,92 @@ function has(obj, val) { } throw new TypeError('expected an array or object.'); -} +}; + +/** + * 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 + */ + +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; +}; /** * Cast the given value to an array. * * ```js - * arrayify('foo'); + * cu.arrayify('foo'); * //=> ['foo'] * - * arrayify(['foo']); + * cu.arrayify(['foo']); * //=> ['foo'] * ``` * * @param {String|Array} `val` * @return {Array} + * @api public */ -function arrayify(val) { +cu.arrayify = function arrayify(val) { return val ? (Array.isArray(val) ? val : [val]) : []; -} +}; + +/** + * Noop + */ + +cu.noop = function noop() { + return; +}; + +/** + * Returns the first argument passed to the function. + */ + +cu.identity = function identity(val) { + return val; +}; /** * Returns true if a value has a `contructor` * * ```js - * hasConstructor({}); + * cu.hasConstructor({}); * //=> true * - * hasConstructor(Object.create(null)); + * cu.hasConstructor(Object.create(null)); * //=> false * ``` * @param {Object} `value` * @return {Boolean} + * @api public */ -function hasConstructor(val) { - return isObject(val) && typeof val.constructor !== 'undefined'; -} +cu.hasConstructor = function hasConstructor(val) { + return cu.isObject(val) && typeof val.constructor !== 'undefined'; +}; /** * Get the native `ownPropertyNames` from the constructor of the @@ -69128,437 +68228,217 @@ function hasConstructor(val) { * not have a constructor. * * ```js - * nativeKeys({a: 'b', b: 'c', c: 'd'}) + * cu.nativeKeys({a: 'b', b: 'c', c: 'd'}) * //=> ['a', 'b', 'c'] * - * nativeKeys(function(){}) + * cu.nativeKeys(function(){}) * //=> ['length', 'caller'] * ``` * * @param {Object} `obj` Object that has a `constructor`. * @return {Array} Array of keys. + * @api public */ -function nativeKeys(val) { - if (!hasConstructor(val)) return []; +cu.nativeKeys = function nativeKeys(val) { + if (!cu.hasConstructor(val)) return []; return Object.getOwnPropertyNames(val); -} - -/** - * Expose `copy` - */ - -module.exports = copy; +}; /** - * Expose `copy.has` for tests - */ - -module.exports.has = has; - - -/***/ }), -/* 603 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * copy-descriptor + * Returns property descriptor `key` if it's an "own" property + * of the given object. * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. + * ```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 */ - +cu.getDescriptor = function getDescriptor(obj, key) { + if (!cu.isObject(obj)) { + throw new TypeError('expected an object.'); + } + if (typeof key !== 'string') { + throw new TypeError('expected key to be a string.'); + } + return Object.getOwnPropertyDescriptor(obj, key); +}; /** * 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; - * }; + * function App() {} * Object.defineProperty(App.prototype, 'count', { * get: function() { - * return Object.keys(this.cache).length; + * return Object.keys(this).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 + * var obj = {}; + * cu.copyDescriptor(obj, App.prototype, 'count'); * ``` - * @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. + * @param {Object} `receiver` + * @param {Object} `provider` + * @param {String} `name` * @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'); - } - - if (typeof to !== 'string') { - to = from; +cu.copyDescriptor = function copyDescriptor(receiver, provider, name) { + if (!cu.isObject(receiver)) { + throw new TypeError('expected receiving object to be an object.'); } - if (typeof from !== 'string') { - throw new TypeError('expected key to be a string'); + if (!cu.isObject(provider)) { + throw new TypeError('expected providing object to be an object.'); } - - if (!(from in provider)) { - throw new Error('property "' + from + '" does not exist'); + if (typeof name !== 'string') { + throw new TypeError('expected name to be a string.'); } - var val = Object.getOwnPropertyDescriptor(provider, from); - if (val) Object.defineProperty(receiver, to, val); + var val = cu.getDescriptor(provider, name); + if (val) Object.defineProperty(receiver, name, val); }; -function isObject(val) { - return {}.toString.call(val) === '[object Object]'; -} - - - -/***/ }), -/* 604 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var use = __webpack_require__(605); -var define = __webpack_require__(594); -var debug = __webpack_require__(607)('snapdragon:compiler'); -var utils = __webpack_require__(613); - -/** - * Create a new `Compiler` with the given `options`. - * @param {Object} `options` - */ - -function Compiler(options, state) { - debug('initializing', __filename); - this.options = utils.extend({source: 'string'}, options); - this.state = state || {}; - this.compilers = {}; - this.output = ''; - this.set('eos', function(node) { - return this.emit(node.val, node); - }); - this.set('noop', function(node) { - return this.emit(node.val, node); - }); - this.set('bos', function(node) { - return this.emit(node.val, node); - }); - use(this); -} - /** - * Prototype methods + * Copy static properties, prototype properties, and descriptors + * from one object to another. + * + * @param {Object} `receiver` + * @param {Object} `provider` + * @param {String|Array} `omit` One or more properties to omit + * @return {Object} + * @api public */ -Compiler.prototype = { - - /** - * Throw an error message with details including the cursor position. - * @param {String} `msg` Message to use in the Error. - */ - - error: function(msg, node) { - var pos = node.position || {start: {column: 0}}; - var message = this.options.source + ' column:' + pos.start.column + ': ' + msg; - - var err = new Error(message); - err.reason = msg; - err.column = pos.start.column; - err.source = this.pattern; - - if (this.options.silent) { - this.errors.push(err); - } else { - throw err; - } - }, - - /** - * Define a non-enumberable property on the `Compiler` instance. - * - * ```js - * compiler.define('foo', 'bar'); - * ``` - * @name .define - * @param {String} `key` propery name - * @param {any} `val` property value - * @return {Object} Returns the Compiler instance for chaining. - * @api public - */ - - define: function(key, val) { - define(this, key, val); - return this; - }, - - /** - * Emit `node.val` - */ - - emit: function(str, node) { - this.output += str; - return str; - }, - - /** - * Add a compiler `fn` with the given `name` - */ - - set: function(name, fn) { - this.compilers[name] = fn; - return this; - }, - - /** - * Get compiler `name`. - */ - - get: function(name) { - return this.compilers[name]; - }, - - /** - * Get the previous AST node. - */ - - prev: function(n) { - return this.ast.nodes[this.idx - (n || 1)] || { type: 'bos', val: '' }; - }, - - /** - * Get the next AST node. - */ - - next: function(n) { - return this.ast.nodes[this.idx + (n || 1)] || { type: 'eos', val: '' }; - }, - - /** - * Visit `node`. - */ - - visit: function(node, nodes, i) { - var fn = this.compilers[node.type]; - this.idx = i; - - if (typeof fn !== 'function') { - throw this.error('compiler "' + node.type + '" is not registered', node); - } - return fn.call(this, node, nodes, i); - }, - - /** - * Map visit over array of `nodes`. - */ - - mapVisit: function(nodes) { - if (!Array.isArray(nodes)) { - throw new TypeError('expected an array'); - } - var len = nodes.length; - var idx = -1; - while (++idx < len) { - this.visit(nodes[idx], nodes, idx); - } - return this; - }, - - /** - * Compile `ast`. - */ +cu.copy = function copy(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 props = Object.getOwnPropertyNames(provider); + var keys = Object.keys(provider); + var len = props.length, + key; + omit = cu.arrayify(omit); - compile: function(ast, options) { - var opts = utils.extend({}, this.options, options); - this.ast = ast; - this.parsingErrors = this.ast.errors; - this.output = ''; + while (len--) { + key = props[len]; - // source map support - if (opts.sourcemap) { - var sourcemaps = __webpack_require__(632); - sourcemaps(this); - this.mapVisit(this.ast.nodes); - this.applySourceMaps(); - this.map = opts.sourcemap === 'generator' ? this.map : this.map.toJSON(); - return this; + 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); } - - this.mapVisit(this.ast.nodes); - return this; } }; /** - * Expose `Compiler` - */ - -module.exports = Compiler; - - -/***/ }), -/* 605 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * use + * 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 utils = __webpack_require__(606); - -module.exports = function base(app, opts) { - if (!utils.isObject(app) && typeof app !== 'function') { - throw new TypeError('use: expect `app` be an object or function'); +cu.inherit = function inherit(receiver, provider, omit) { + if (!cu.isObject(receiver)) { + throw new TypeError('expected receiving object to be an object.'); } - - if (!utils.isObject(opts)) { - opts = {}; + if (!cu.isObject(provider)) { + throw new TypeError('expected providing object to be an object.'); } - var prop = utils.isString(opts.prop) ? opts.prop : 'fns'; - if (!Array.isArray(app[prop])) { - utils.define(app, prop, []); + var keys = []; + for (var key in provider) { + keys.push(key); + receiver[key] = provider[key]; } - /** - * 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; + keys = keys.concat(cu.arrayify(omit)); - while (++idx < len) { - val.use(fns[idx]); - } - return val; - }); + var a = provider.prototype || provider; + var b = receiver.prototype || receiver; + cu.copy(b, a, keys); +}; - /** - * Call plugin `fn`. If a function is returned push it into the - * `fns` array to be called by the `run` method. - */ +/** + * Returns a function for extending the static properties, + * prototype properties, and descriptors from the `Parent` + * constructor onto `Child` constructors. + * + * ```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 + */ - function use(fn, options) { - if (typeof fn !== 'function') { - throw new TypeError('.use expects `fn` be a function'); - } +cu.extend = function() { + // keep it lazy, instead of assigning to `cu.extend` + return utils.staticExtend.apply(null, arguments); +}; - var self = this || app; - if (typeof opts.fn === 'function') { - opts.fn.call(self, self, options); - } +/** + * Bubble up events emitted from static methods on the Parent ctor. + * + * @param {Object} `Parent` + * @param {Array} `events` Event names to bubble up + * @api public + */ - var plugin = fn.call(self, self); - if (typeof plugin === 'function') { - var fns = self[prop]; - fns.push(plugin); +cu.bubble = function(Parent, events) { + events = events || []; + Parent.bubble = function(Child, arr) { + if (Array.isArray(arr)) { + events = utils.union([], events, arr); } - return self; - } - - /** - * Ensure the `.use` method exists on `val` - */ - - function decorate(val) { - if (!val.use || !val.run) { - base(val); + var len = events.length; + var idx = -1; + while (++idx < len) { + var name = events[idx]; + Parent.on(name, Child.emit.bind(Child, name)); } - } - - return app; + cu.bubble(Child, events); + }; }; /***/ }), -/* 606 */ +/* 595 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -69572,3290 +68452,3298 @@ var utils = {}; * Lazily required module dependencies */ -utils.define = __webpack_require__(594); -utils.isObject = __webpack_require__(545); - +utils.union = __webpack_require__(579); +utils.define = __webpack_require__(596); +utils.isObj = __webpack_require__(534); +utils.staticExtend = __webpack_require__(603); -utils.isString = function(val) { - return val && typeof val === 'string'; -}; /** - * Expose `utils` modules + * Expose `utils` */ module.exports = utils; /***/ }), -/* 607 */ -/***/ (function(module, exports, __webpack_require__) { - -/** - * Detect Electron renderer process, which is node, but we should - * treat as a browser. - */ - -if (typeof process !== 'undefined' && process.type === 'renderer') { - module.exports = __webpack_require__(608); -} else { - module.exports = __webpack_require__(611); -} - - -/***/ }), -/* 608 */ +/* 596 */ /***/ (function(module, exports, __webpack_require__) { -/** - * This is the web browser implementation of `debug()`. +"use strict"; +/*! + * define-property * - * Expose `debug()` as the module. + * Copyright (c) 2015, Jon Schlinkert. + * Licensed under the MIT License. */ -exports = module.exports = __webpack_require__(609); -exports.log = log; -exports.formatArgs = formatArgs; -exports.save = save; -exports.load = load; -exports.useColors = useColors; -exports.storage = 'undefined' != typeof chrome - && 'undefined' != typeof chrome.storage - ? chrome.storage.local - : localstorage(); - -/** - * Colors. - */ -exports.colors = [ - 'lightseagreen', - 'forestgreen', - 'goldenrod', - 'dodgerblue', - 'darkorchid', - 'crimson' -]; -/** - * Currently only WebKit-based Web Inspectors, Firefox >= v31, - * and the Firebug extension (any Firefox version) are known - * to support "%c" CSS customizations. - * - * TODO: add a `localStorage` variable to explicitly enable/disable colors - */ +var isDescriptor = __webpack_require__(597); -function useColors() { - // NB: In an Electron preload script, document will be defined but not fully - // initialized. Since we know we're in Chrome, we'll just detect this case - // explicitly - if (typeof window !== 'undefined' && window.process && window.process.type === 'renderer') { - return true; +module.exports = function defineProperty(obj, prop, val) { + if (typeof obj !== 'object' && typeof obj !== 'function') { + throw new TypeError('expected an object or function.'); } - // is webkit? http://stackoverflow.com/a/16459606/376773 - // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 - return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) || - // is firebug? http://stackoverflow.com/a/398120/376773 - (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) || - // is firefox >= v31? - // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages - (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) || - // double check webkit in userAgent just in case we are in a worker - (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)); -} - -/** - * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. - */ + if (typeof prop !== 'string') { + throw new TypeError('expected `prop` to be a string.'); + } -exports.formatters.j = function(v) { - try { - return JSON.stringify(v); - } catch (err) { - return '[UnexpectedJSONParseError]: ' + err.message; + 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 + }); }; -/** - * Colorize log arguments if enabled. +/***/ }), +/* 597 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/*! + * is-descriptor * - * @api public + * Copyright (c) 2015-2017, Jon Schlinkert. + * Released under the MIT License. */ -function formatArgs(args) { - var useColors = this.useColors; - args[0] = (useColors ? '%c' : '') - + this.namespace - + (useColors ? ' %c' : ' ') - + args[0] - + (useColors ? '%c ' : ' ') - + '+' + exports.humanize(this.diff); - if (!useColors) return; +var typeOf = __webpack_require__(598); +var isAccessor = __webpack_require__(599); +var isData = __webpack_require__(601); - var c = 'color: ' + this.color; - args.splice(1, 0, c, 'color: inherit') +module.exports = function isDescriptor(obj, key) { + if (typeOf(obj) !== 'object') { + return false; + } + if ('get' in obj) { + return isAccessor(obj, key); + } + return isData(obj, key); +}; - // the final "%c" is somewhat tricky, because there could be other - // arguments passed either before or after the %c, so we need to - // figure out the correct index to insert the CSS into - var index = 0; - var lastC = 0; - args[0].replace(/%[a-zA-Z%]/g, function(match) { - if ('%%' === match) return; - index++; - if ('%c' === match) { - // we only are interested in the *last* %c - // (the user may have provided their own) - lastC = index; - } - }); - args.splice(lastC, 0, c); -} +/***/ }), +/* 598 */ +/***/ (function(module, exports) { + +var toString = Object.prototype.toString; /** - * Invokes `console.log()` when available. - * No-op when `console.log` is not a "function". + * Get the native `typeof` a value. * - * @api public + * @param {*} `val` + * @return {*} Native javascript type */ -function log() { - // this hackery is required for IE8/9, where - // the `console.log` function doesn't have 'apply' - return 'object' === typeof console - && console.log - && Function.prototype.apply.call(console.log, console, arguments); -} +module.exports = function kindOf(val) { + var type = typeof val; -/** - * Save `namespaces`. - * - * @param {String} namespaces - * @api private - */ + // 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 save(namespaces) { - try { - if (null == namespaces) { - exports.storage.removeItem('debug'); - } else { - exports.storage.debug = namespaces; + // functions + if (type === 'function' || val instanceof Function) { + if (typeof val.constructor.name !== 'undefined' && val.constructor.name.slice(0, 9) === 'Generator') { + return 'generatorfunction'; } - } catch(e) {} -} + return 'function'; + } -/** - * Load `namespaces`. - * - * @return {String} returns the previously persisted debug modes - * @api private - */ + // array + if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { + return 'array'; + } -function load() { - var r; - try { - r = exports.storage.debug; - } catch(e) {} + // check for instances of RegExp and Date before calling `toString` + if (val instanceof RegExp) { + return 'regexp'; + } + if (val instanceof Date) { + return 'date'; + } - // If debug isn't set in LS, and we're in Electron, try to load $DEBUG - if (!r && typeof process !== 'undefined' && 'env' in process) { - r = process.env.DEBUG; + // 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'; } - return r; -} + // buffer + if (isBuffer(val)) { + return 'buffer'; + } -/** - * Enable namespaces listed in `localStorage.debug` initially. - */ + // 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'; + } -exports.enable(load()); + // must be a plain object + return 'object'; +}; /** - * Localstorage attempts to return the localstorage. - * - * This is necessary because safari throws - * when a user disables cookies/localstorage - * and you attempt to access it. - * - * @return {LocalStorage} - * @api private + * If you need to support Safari 5-7 (8-10 yr-old browser), + * take a look at https://github.com/feross/is-buffer */ -function localstorage() { - try { - return window.localStorage; - } catch (e) {} +function isBuffer(val) { + return val.constructor + && typeof val.constructor.isBuffer === 'function' + && val.constructor.isBuffer(val); } /***/ }), -/* 609 */ -/***/ (function(module, exports, __webpack_require__) { - - -/** - * This is the common logic for both the Node.js and web browser - * implementations of `debug()`. +/* 599 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/*! + * is-accessor-descriptor * - * Expose `debug()` as the module. + * Copyright (c) 2015, Jon Schlinkert. + * Licensed under the MIT License. */ -exports = module.exports = createDebug.debug = createDebug['default'] = createDebug; -exports.coerce = coerce; -exports.disable = disable; -exports.enable = enable; -exports.enabled = enabled; -exports.humanize = __webpack_require__(610); -/** - * The currently active debug mode names, and names to skip. - */ -exports.names = []; -exports.skips = []; +var typeOf = __webpack_require__(600); -/** - * Map of special "%n" handling functions, for the debug "format" argument. - * - * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". - */ +// accessor descriptor properties +var accessor = { + get: 'function', + set: 'function', + configurable: 'boolean', + enumerable: 'boolean' +}; -exports.formatters = {}; +function isAccessorDescriptor(obj, prop) { + if (typeof prop === 'string') { + var val = Object.getOwnPropertyDescriptor(obj, prop); + return typeof val !== 'undefined'; + } -/** - * Previous log timestamp. - */ + if (typeOf(obj) !== 'object') { + return false; + } -var prevTime; + if (has(obj, 'value') || has(obj, 'writable')) { + return false; + } -/** - * Select a color. - * @param {String} namespace - * @return {Number} - * @api private - */ + if (!has(obj, 'get') || typeof obj.get !== 'function') { + return false; + } -function selectColor(namespace) { - var hash = 0, i; + // 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 (i in namespace) { - hash = ((hash << 5) - hash) + namespace.charCodeAt(i); - hash |= 0; // Convert to 32bit integer + 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; +} - return exports.colors[Math.abs(hash) % exports.colors.length]; +function has(obj, key) { + return {}.hasOwnProperty.call(obj, key); } /** - * Create a debugger with the given `namespace`. - * - * @param {String} namespace - * @return {Function} - * @api public + * Expose `isAccessorDescriptor` */ -function createDebug(namespace) { +module.exports = isAccessorDescriptor; - function debug() { - // disabled? - if (!debug.enabled) return; - var self = debug; +/***/ }), +/* 600 */ +/***/ (function(module, exports, __webpack_require__) { - // set `diff` timestamp - var curr = +new Date(); - var ms = curr - (prevTime || curr); - self.diff = ms; - self.prev = prevTime; - self.curr = curr; - prevTime = curr; +var isBuffer = __webpack_require__(560); +var toString = Object.prototype.toString; - // turn the `arguments` into a proper Array - var args = new Array(arguments.length); - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i]; - } +/** + * Get the native `typeof` a value. + * + * @param {*} `val` + * @return {*} Native javascript type + */ - args[0] = exports.coerce(args[0]); +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'; + } - if ('string' !== typeof args[0]) { - // anything else let's inspect with %O - args.unshift('%O'); - } + // functions + if (typeof val === 'function' || val instanceof Function) { + return 'function'; + } - // apply any `formatters` transformations - var index = 0; - args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) { - // if we encounter an escaped % then don't increase the array index - if (match === '%%') return match; - index++; - var formatter = exports.formatters[format]; - if ('function' === typeof formatter) { - var val = args[index]; - match = formatter.call(self, val); + // array + if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { + return 'array'; + } - // now we need to remove `args[index]` since it's inlined in the `format` - args.splice(index, 1); - index--; - } - return match; - }); + // check for instances of RegExp and Date before calling `toString` + if (val instanceof RegExp) { + return 'regexp'; + } + if (val instanceof Date) { + return 'date'; + } - // apply env-specific formatting (colors, etc.) - exports.formatArgs.call(self, args); + // other objects + var type = toString.call(val); - var logFn = debug.log || exports.log || console.log.bind(console); - logFn.apply(self, args); + if (type === '[object RegExp]') { + return 'regexp'; + } + if (type === '[object Date]') { + return 'date'; + } + if (type === '[object Arguments]') { + return 'arguments'; + } + if (type === '[object Error]') { + return 'error'; } - debug.namespace = namespace; - debug.enabled = exports.enabled(namespace); - debug.useColors = exports.useColors(); - debug.color = selectColor(namespace); + // buffer + if (isBuffer(val)) { + return 'buffer'; + } - // env-specific initialization logic for debug instances - if ('function' === typeof exports.init) { - exports.init(debug); + // 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'; } - return debug; -} + // 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'; + } -/** - * Enables a debug mode by namespaces. This can include modes - * separated by a colon and wildcards. + // must be a plain object + return 'object'; +}; + + +/***/ }), +/* 601 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/*! + * is-data-descriptor * - * @param {String} namespaces - * @api public + * Copyright (c) 2015, Jon Schlinkert. + * Licensed under the MIT License. */ -function enable(namespaces) { - exports.save(namespaces); - exports.names = []; - exports.skips = []; - var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); - var len = split.length; +var typeOf = __webpack_require__(602); - for (var i = 0; i < len; i++) { - if (!split[i]) continue; // ignore empty strings - namespaces = split[i].replace(/\*/g, '.*?'); - if (namespaces[0] === '-') { - exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); - } else { - exports.names.push(new RegExp('^' + namespaces + '$')); - } +// data descriptor properties +var data = { + configurable: 'boolean', + enumerable: 'boolean', + writable: 'boolean' +}; + +function isDataDescriptor(obj, prop) { + if (typeOf(obj) !== 'object') { + return false; } -} -/** - * Disable debug output. - * - * @api public - */ + if (typeof prop === 'string') { + var val = Object.getOwnPropertyDescriptor(obj, prop); + return typeof val !== 'undefined'; + } -function disable() { - exports.enable(''); -} + if (!('value' in obj) && !('writable' in obj)) { + return false; + } -/** - * Returns true if the given mode name is enabled, false otherwise. - * - * @param {String} name - * @return {Boolean} - * @api public - */ + for (var key in obj) { + if (key === 'value') continue; -function enabled(name) { - var i, len; - for (i = 0, len = exports.skips.length; i < len; i++) { - if (exports.skips[i].test(name)) { - return false; + if (!data.hasOwnProperty(key)) { + continue; } - } - for (i = 0, len = exports.names.length; i < len; i++) { - if (exports.names[i].test(name)) { - return true; + + if (typeOf(obj[key]) === data[key]) { + continue; + } + + if (typeof obj[key] !== 'undefined') { + return false; } } - return false; + return true; } /** - * Coerce `val`. - * - * @param {Mixed} val - * @return {Mixed} - * @api private + * Expose `isDataDescriptor` */ -function coerce(val) { - if (val instanceof Error) return val.stack || val.message; - return val; -} +module.exports = isDataDescriptor; /***/ }), -/* 610 */ -/***/ (function(module, exports) { - -/** - * Helpers. - */ +/* 602 */ +/***/ (function(module, exports, __webpack_require__) { -var s = 1000; -var m = s * 60; -var h = m * 60; -var d = h * 24; -var y = d * 365.25; +var isBuffer = __webpack_require__(560); +var toString = Object.prototype.toString; /** - * Parse or format the given `val`. - * - * Options: - * - * - `long` verbose formatting [false] + * Get the native `typeof` a value. * - * @param {String|Number} val - * @param {Object} [options] - * @throws {Error} throw an error if val is not a non-empty string or a number - * @return {String|Number} - * @api public + * @param {*} `val` + * @return {*} Native javascript type */ -module.exports = function(val, options) { - options = options || {}; - var type = typeof val; - if (type === 'string' && val.length > 0) { - return parse(val); - } else if (type === 'number' && isNaN(val) === false) { - return options.long ? fmtLong(val) : fmtShort(val); +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'; } - throw new Error( - 'val is not a non-empty string or a valid number. val=' + - JSON.stringify(val) - ); -}; -/** - * Parse the given `str` and return milliseconds. - * - * @param {String} str - * @return {Number} - * @api private - */ + // functions + if (typeof val === 'function' || val instanceof Function) { + return 'function'; + } -function parse(str) { - str = String(str); - if (str.length > 100) { - return; + // array + if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { + return 'array'; } - var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec( - str - ); - if (!match) { - return; + + // check for instances of RegExp and Date before calling `toString` + if (val instanceof RegExp) { + return 'regexp'; } - var n = parseFloat(match[1]); - var type = (match[2] || 'ms').toLowerCase(); - switch (type) { - case 'years': - case 'year': - case 'yrs': - case 'yr': - case 'y': - return n * y; - case 'days': - case 'day': - case 'd': - return n * d; - case 'hours': - case 'hour': - case 'hrs': - case 'hr': - case 'h': - return n * h; - case 'minutes': - case 'minute': - case 'mins': - case 'min': - case 'm': - return n * m; - case 'seconds': - case 'second': - case 'secs': - case 'sec': - case 's': - return n * s; - case 'milliseconds': - case 'millisecond': - case 'msecs': - case 'msec': - case 'ms': - return n; - default: - return undefined; + if (val instanceof Date) { + return 'date'; } -} -/** - * Short format for `ms`. - * - * @param {Number} ms - * @return {String} - * @api private - */ + // other objects + var type = toString.call(val); -function fmtShort(ms) { - if (ms >= d) { - return Math.round(ms / d) + 'd'; + if (type === '[object RegExp]') { + return 'regexp'; + } + if (type === '[object Date]') { + return 'date'; + } + if (type === '[object Arguments]') { + return 'arguments'; + } + if (type === '[object Error]') { + return 'error'; + } + + // 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 (ms >= h) { - return Math.round(ms / h) + 'h'; + + // typed arrays + if (type === '[object Int8Array]') { + return 'int8array'; } - if (ms >= m) { - return Math.round(ms / m) + 'm'; + if (type === '[object Uint8Array]') { + return 'uint8array'; } - if (ms >= s) { - return Math.round(ms / s) + 's'; + if (type === '[object Uint8ClampedArray]') { + return 'uint8clampedarray'; } - return ms + 'ms'; -} - -/** - * Long format for `ms`. - * - * @param {Number} ms - * @return {String} - * @api private - */ - -function fmtLong(ms) { - return plural(ms, d, 'day') || - plural(ms, h, 'hour') || - plural(ms, m, 'minute') || - plural(ms, s, 'second') || - ms + ' ms'; -} - -/** - * Pluralization helper. - */ - -function plural(ms, n, name) { - if (ms < n) { - return; + if (type === '[object Int16Array]') { + return 'int16array'; } - if (ms < n * 1.5) { - return Math.floor(ms / n) + ' ' + name; + if (type === '[object Uint16Array]') { + return 'uint16array'; } - return Math.ceil(ms / n) + ' ' + name + 's'; -} + 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'; +}; /***/ }), -/* 611 */ +/* 603 */ /***/ (function(module, exports, __webpack_require__) { -/** - * Module dependencies. - */ - -var tty = __webpack_require__(121); -var util = __webpack_require__(111); - -/** - * This is the Node.js implementation of `debug()`. +"use strict"; +/*! + * static-extend * - * Expose `debug()` as the module. + * Copyright (c) 2016, Jon Schlinkert. + * Licensed under the MIT License. */ -exports = module.exports = __webpack_require__(609); -exports.init = init; -exports.log = log; -exports.formatArgs = formatArgs; -exports.save = save; -exports.load = load; -exports.useColors = useColors; -/** - * Colors. - */ -exports.colors = [6, 2, 3, 4, 5, 1]; +var copy = __webpack_require__(604); +var define = __webpack_require__(596); +var util = __webpack_require__(112); /** - * Build up the default `inspectOpts` object from the environment variables. + * Returns a function for extending the static properties, + * prototype properties, and descriptors from the `Parent` + * constructor onto `Child` constructors. * - * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js + * ```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 */ -exports.inspectOpts = Object.keys(process.env).filter(function (key) { - return /^debug_/i.test(key); -}).reduce(function (obj, key) { - // camel-case - var prop = key - .substring(6) - .toLowerCase() - .replace(/_([a-z])/g, function (_, k) { return k.toUpperCase() }); +function extend(Parent, extendFn) { + if (typeof Parent !== 'function') { + throw new TypeError('expected Parent to be a function.'); + } - // coerce string value into JS value - var val = process.env[key]; - if (/^(yes|on|true|enabled)$/i.test(val)) val = true; - else if (/^(no|off|false|disabled)$/i.test(val)) val = false; - else if (val === 'null') val = null; - else val = Number(val); + return function(Ctor, proto) { + if (typeof Ctor !== 'function') { + throw new TypeError('expected Ctor to be a function.'); + } - obj[prop] = val; - return obj; -}, {}); + util.inherits(Ctor, Parent); + copy(Ctor, Parent); -/** - * The file descriptor to write the `debug()` calls to. - * Set the `DEBUG_FD` env variable to override with another value. i.e.: - * - * $ DEBUG_FD=3 node script.js 3>debug.log - */ + // proto can be null or a plain object + if (typeof proto === 'object') { + var obj = Object.create(proto); -var fd = parseInt(process.env.DEBUG_FD, 10) || 2; + for (var k in obj) { + Ctor.prototype[k] = obj[k]; + } + } -if (1 !== fd && 2 !== fd) { - util.deprecate(function(){}, 'except for stderr(2) and stdout(1), any other usage of DEBUG_FD is deprecated. Override debug.log if you want to use a different log function (https://git.io/debug_fd)')() -} + // keep a reference to the parent prototype + define(Ctor.prototype, '_parent_', { + configurable: true, + set: function() {}, + get: function() { + return Parent.prototype; + } + }); -var stream = 1 === fd ? process.stdout : - 2 === fd ? process.stderr : - createWritableStdioStream(fd); + if (typeof extendFn === 'function') { + extendFn(Ctor, Parent); + } + + Ctor.extend = extend(Ctor, extendFn); + }; +}; /** - * Is stdout a TTY? Colored output is enabled when `true`. + * Expose `extend` */ -function useColors() { - return 'colors' in exports.inspectOpts - ? Boolean(exports.inspectOpts.colors) - : tty.isatty(fd); -} +module.exports = extend; -/** - * Map %o to `util.inspect()`, all on a single line. - */ -exports.formatters.o = function(v) { - this.inspectOpts.colors = this.useColors; - return util.inspect(v, this.inspectOpts) - .split('\n').map(function(str) { - return str.trim() - }).join(' '); -}; +/***/ }), +/* 604 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Map %o to `util.inspect()`, allowing multiple lines if needed. - */ +"use strict"; -exports.formatters.O = function(v) { - this.inspectOpts.colors = this.useColors; - return util.inspect(v, this.inspectOpts); -}; + +var typeOf = __webpack_require__(559); +var copyDescriptor = __webpack_require__(605); +var define = __webpack_require__(596); /** - * Adds ANSI color escape codes if enabled. + * 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 */ -function formatArgs(args) { - var name = this.namespace; - var useColors = this.useColors; +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.'); + } - if (useColors) { - var c = this.color; - var prefix = ' \u001b[3' + c + ';1m' + name + ' ' + '\u001b[0m'; + var props = nativeKeys(provider); + var keys = Object.keys(provider); + var len = props.length; + omit = arrayify(omit); - args[0] = prefix + args[0].split('\n').join('\n' + prefix); - args.push('\u001b[3' + c + 'm+' + exports.humanize(this.diff) + '\u001b[0m'); - } else { - args[0] = new Date().toUTCString() - + ' ' + name + ' ' + args[0]; + while (len--) { + var key = props[len]; + + if (has(keys, key)) { + define(receiver, key, provider[key]); + } else if (!(key in receiver) && !has(omit, key)) { + copyDescriptor(receiver, provider, key); + } } -} +}; /** - * Invokes `util.format()` with the specified arguments and writes to `stream`. + * Return true if the given value is an object or function */ -function log() { - return stream.write(util.format.apply(util, arguments) + '\n'); +function isObject(val) { + return typeOf(val) === 'object' || typeof val === 'function'; } /** - * Save `namespaces`. + * Returns true if an array has any of the given elements, or an + * object has any of the give keys. * - * @param {String} namespaces - * @api private + * ```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 save(namespaces) { - if (null == namespaces) { - // If you set a process.env field to null or undefined, it gets cast to the - // string 'null' or 'undefined'. Just delete instead. - delete process.env.DEBUG; - } else { - process.env.DEBUG = namespaces; +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); + } + + if (Array.isArray(obj)) { + var arr = obj; + while (len--) { + if (arr.indexOf(val[len]) > -1) { + return true; + } + } + return false; } + + throw new TypeError('expected an array or object.'); } /** - * Load `namespaces`. + * Cast the given value to an array. * - * @return {String} returns the previously persisted debug modes - * @api private + * ```js + * arrayify('foo'); + * //=> ['foo'] + * + * arrayify(['foo']); + * //=> ['foo'] + * ``` + * + * @param {String|Array} `val` + * @return {Array} */ -function load() { - return process.env.DEBUG; +function arrayify(val) { + return val ? (Array.isArray(val) ? val : [val]) : []; } /** - * Copied from `node/src/node.js`. + * Returns true if a value has a `contructor` * - * XXX: It's lame that node doesn't expose this API out-of-the-box. It also - * relies on the undocumented `tty_wrap.guessHandleType()` which is also lame. + * ```js + * hasConstructor({}); + * //=> true + * + * hasConstructor(Object.create(null)); + * //=> false + * ``` + * @param {Object} `value` + * @return {Boolean} */ -function createWritableStdioStream (fd) { - var stream; - var tty_wrap = process.binding('tty_wrap'); +function hasConstructor(val) { + return isObject(val) && typeof val.constructor !== 'undefined'; +} - // Note stream._type is used for test-module-load-list.js +/** + * 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. + */ - switch (tty_wrap.guessHandleType(fd)) { - case 'TTY': - stream = new tty.WriteStream(fd); - stream._type = 'tty'; +function nativeKeys(val) { + if (!hasConstructor(val)) return []; + return Object.getOwnPropertyNames(val); +} - // Hack to have stream not keep the event loop alive. - // See https://github.com/joyent/node/issues/1726 - if (stream._handle && stream._handle.unref) { - stream._handle.unref(); - } - break; +/** + * Expose `copy` + */ - case 'FILE': - var fs = __webpack_require__(133); - stream = new fs.SyncWriteStream(fd, { autoClose: false }); - stream._type = 'fs'; - break; +module.exports = copy; - case 'PIPE': - case 'TCP': - var net = __webpack_require__(612); - stream = new net.Socket({ - fd: fd, - readable: false, - writable: true - }); +/** + * Expose `copy.has` for tests + */ - // FIXME Should probably have an option in net.Socket to create a - // stream from an existing fd which is writable only. But for now - // we'll just add this hack and set the `readable` member to false. - // Test: ./node test/fixtures/echo.js < /etc/passwd - stream.readable = false; - stream.read = null; - stream._type = 'pipe'; +module.exports.has = has; - // FIXME Hack to have stream not keep the event loop alive. - // See https://github.com/joyent/node/issues/1726 - if (stream._handle && stream._handle.unref) { - stream._handle.unref(); - } - break; - default: - // Probably an error on in uv_guess_handle() - throw new Error('Implement me. Unknown stream file type!'); - } +/***/ }), +/* 605 */ +/***/ (function(module, exports, __webpack_require__) { - // For supporting legacy API we put the FD here. - stream.fd = fd; +"use strict"; +/*! + * copy-descriptor + * + * Copyright (c) 2015, Jon Schlinkert. + * Licensed under the MIT License. + */ - stream._isStdio = true; - return stream; -} /** - * Init logic for `debug` instances. + * Copy a descriptor from one object to another. * - * Create a new `inspectOpts` object in case `useColors` is set - * differently for a particular `debug` instance. + * ```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 */ -function init (debug) { - debug.inspectOpts = {}; - - var keys = Object.keys(exports.inspectOpts); - for (var i = 0; i < keys.length; i++) { - debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]]; +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'); } -} -/** - * Enable namespaces listed in `process.env.DEBUG` initially. - */ + if (typeof to !== 'string') { + to = from; + } + if (typeof from !== 'string') { + throw new TypeError('expected key to be a string'); + } -exports.enable(load()); + if (!(from in provider)) { + throw new Error('property "' + from + '" does not exist'); + } + var val = Object.getOwnPropertyDescriptor(provider, from); + if (val) Object.defineProperty(receiver, to, val); +}; + +function isObject(val) { + return {}.toString.call(val) === '[object Object]'; +} -/***/ }), -/* 612 */ -/***/ (function(module, exports) { -module.exports = require("net"); /***/ }), -/* 613 */ +/* 606 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/** - * Module dependencies - */ - -exports.extend = __webpack_require__(536); -exports.SourceMap = __webpack_require__(614); -exports.sourceMapResolve = __webpack_require__(625); +var use = __webpack_require__(607); +var define = __webpack_require__(596); +var debug = __webpack_require__(609)('snapdragon:compiler'); +var utils = __webpack_require__(615); /** - * Convert backslash in the given string to forward slashes + * Create a new `Compiler` with the given `options`. + * @param {Object} `options` */ -exports.unixify = function(fp) { - return fp.split(/\\+/).join('/'); -}; +function Compiler(options, state) { + debug('initializing', __filename); + this.options = utils.extend({source: 'string'}, options); + this.state = state || {}; + this.compilers = {}; + this.output = ''; + this.set('eos', function(node) { + return this.emit(node.val, node); + }); + this.set('noop', function(node) { + return this.emit(node.val, node); + }); + this.set('bos', function(node) { + return this.emit(node.val, node); + }); + use(this); +} /** - * Return true if `val` is a non-empty string - * - * @param {String} `str` - * @return {Boolean} + * Prototype methods */ -exports.isString = function(str) { - return str && typeof str === 'string'; -}; - -/** - * Cast `val` to an array - * @return {Array} - */ +Compiler.prototype = { -exports.arrayify = function(val) { - if (typeof val === 'string') return [val]; - return val ? (Array.isArray(val) ? val : [val]) : []; -}; + /** + * Throw an error message with details including the cursor position. + * @param {String} `msg` Message to use in the Error. + */ -/** - * Get the last `n` element from the given `array` - * @param {Array} `array` - * @return {*} - */ + error: function(msg, node) { + var pos = node.position || {start: {column: 0}}; + var message = this.options.source + ' column:' + pos.start.column + ': ' + msg; -exports.last = function(arr, n) { - return arr[arr.length - (n || 1)]; -}; + var err = new Error(message); + err.reason = msg; + err.column = pos.start.column; + err.source = this.pattern; + if (this.options.silent) { + this.errors.push(err); + } else { + throw err; + } + }, -/***/ }), -/* 614 */ -/***/ (function(module, exports, __webpack_require__) { + /** + * Define a non-enumberable property on the `Compiler` instance. + * + * ```js + * compiler.define('foo', 'bar'); + * ``` + * @name .define + * @param {String} `key` propery name + * @param {any} `val` property value + * @return {Object} Returns the Compiler instance for chaining. + * @api public + */ -/* - * Copyright 2009-2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE.txt or: - * http://opensource.org/licenses/BSD-3-Clause - */ -exports.SourceMapGenerator = __webpack_require__(615).SourceMapGenerator; -exports.SourceMapConsumer = __webpack_require__(621).SourceMapConsumer; -exports.SourceNode = __webpack_require__(624).SourceNode; + define: function(key, val) { + define(this, key, val); + return this; + }, + /** + * Emit `node.val` + */ -/***/ }), -/* 615 */ -/***/ (function(module, exports, __webpack_require__) { + emit: function(str, node) { + this.output += str; + return str; + }, -/* -*- Mode: js; js-indent-level: 2; -*- */ -/* - * Copyright 2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause - */ + /** + * Add a compiler `fn` with the given `name` + */ -var base64VLQ = __webpack_require__(616); -var util = __webpack_require__(618); -var ArraySet = __webpack_require__(619).ArraySet; -var MappingList = __webpack_require__(620).MappingList; + set: function(name, fn) { + this.compilers[name] = fn; + return this; + }, -/** - * An instance of the SourceMapGenerator represents a source map which is - * being built incrementally. You may pass an object with the following - * properties: - * - * - file: The filename of the generated source. - * - sourceRoot: A root for all relative URLs in this source map. - */ -function SourceMapGenerator(aArgs) { - if (!aArgs) { - aArgs = {}; - } - this._file = util.getArg(aArgs, 'file', null); - this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null); - this._skipValidation = util.getArg(aArgs, 'skipValidation', false); - this._sources = new ArraySet(); - this._names = new ArraySet(); - this._mappings = new MappingList(); - this._sourcesContents = null; -} + /** + * Get compiler `name`. + */ -SourceMapGenerator.prototype._version = 3; + get: function(name) { + return this.compilers[name]; + }, -/** - * Creates a new SourceMapGenerator based on a SourceMapConsumer - * - * @param aSourceMapConsumer The SourceMap. - */ -SourceMapGenerator.fromSourceMap = - function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) { - var sourceRoot = aSourceMapConsumer.sourceRoot; - var generator = new SourceMapGenerator({ - file: aSourceMapConsumer.file, - sourceRoot: sourceRoot - }); - aSourceMapConsumer.eachMapping(function (mapping) { - var newMapping = { - generated: { - line: mapping.generatedLine, - column: mapping.generatedColumn - } - }; + /** + * Get the previous AST node. + */ - if (mapping.source != null) { - newMapping.source = mapping.source; - if (sourceRoot != null) { - newMapping.source = util.relative(sourceRoot, newMapping.source); - } + prev: function(n) { + return this.ast.nodes[this.idx - (n || 1)] || { type: 'bos', val: '' }; + }, - newMapping.original = { - line: mapping.originalLine, - column: mapping.originalColumn - }; + /** + * Get the next AST node. + */ - if (mapping.name != null) { - newMapping.name = mapping.name; - } - } + next: function(n) { + return this.ast.nodes[this.idx + (n || 1)] || { type: 'eos', val: '' }; + }, - generator.addMapping(newMapping); - }); - aSourceMapConsumer.sources.forEach(function (sourceFile) { - var content = aSourceMapConsumer.sourceContentFor(sourceFile); - if (content != null) { - generator.setSourceContent(sourceFile, content); - } - }); - return generator; - }; + /** + * Visit `node`. + */ -/** - * Add a single mapping from original source line and column to the generated - * source's line and column for this source map being created. The mapping - * object should have the following properties: - * - * - generated: An object with the generated line and column positions. - * - original: An object with the original line and column positions. - * - source: The original source file (relative to the sourceRoot). - * - name: An optional original token name for this mapping. - */ -SourceMapGenerator.prototype.addMapping = - function SourceMapGenerator_addMapping(aArgs) { - var generated = util.getArg(aArgs, 'generated'); - var original = util.getArg(aArgs, 'original', null); - var source = util.getArg(aArgs, 'source', null); - var name = util.getArg(aArgs, 'name', null); + visit: function(node, nodes, i) { + var fn = this.compilers[node.type]; + this.idx = i; - if (!this._skipValidation) { - this._validateMapping(generated, original, source, name); + if (typeof fn !== 'function') { + throw this.error('compiler "' + node.type + '" is not registered', node); } + return fn.call(this, node, nodes, i); + }, - if (source != null) { - source = String(source); - if (!this._sources.has(source)) { - this._sources.add(source); - } - } + /** + * Map visit over array of `nodes`. + */ - if (name != null) { - name = String(name); - if (!this._names.has(name)) { - this._names.add(name); - } + mapVisit: function(nodes) { + if (!Array.isArray(nodes)) { + throw new TypeError('expected an array'); } + var len = nodes.length; + var idx = -1; + while (++idx < len) { + this.visit(nodes[idx], nodes, idx); + } + return this; + }, - this._mappings.add({ - generatedLine: generated.line, - generatedColumn: generated.column, - originalLine: original != null && original.line, - originalColumn: original != null && original.column, - source: source, - name: name - }); - }; + /** + * Compile `ast`. + */ -/** - * Set the source content for a source file. - */ -SourceMapGenerator.prototype.setSourceContent = - function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) { - var source = aSourceFile; - if (this._sourceRoot != null) { - source = util.relative(this._sourceRoot, source); - } + compile: function(ast, options) { + var opts = utils.extend({}, this.options, options); + this.ast = ast; + this.parsingErrors = this.ast.errors; + this.output = ''; - if (aSourceContent != null) { - // Add the source content to the _sourcesContents map. - // Create a new _sourcesContents map if the property is null. - if (!this._sourcesContents) { - this._sourcesContents = Object.create(null); - } - this._sourcesContents[util.toSetString(source)] = aSourceContent; - } else if (this._sourcesContents) { - // Remove the source file from the _sourcesContents map. - // If the _sourcesContents map is empty, set the property to null. - delete this._sourcesContents[util.toSetString(source)]; - if (Object.keys(this._sourcesContents).length === 0) { - this._sourcesContents = null; - } + // source map support + if (opts.sourcemap) { + var sourcemaps = __webpack_require__(634); + 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; + } +}; /** - * Applies the mappings of a sub-source-map for a specific source file to the - * source map being generated. Each mapping to the supplied source file is - * rewritten using the supplied source map. Note: The resolution for the - * resulting mappings is the minimium of this map and the supplied map. - * - * @param aSourceMapConsumer The source map to be applied. - * @param aSourceFile Optional. The filename of the source file. - * If omitted, SourceMapConsumer's file property will be used. - * @param aSourceMapPath Optional. The dirname of the path to the source map - * to be applied. If relative, it is relative to the SourceMapConsumer. - * This parameter is needed when the two source maps aren't in the same - * directory, and the source map to be applied contains relative source - * paths. If so, those relative source paths need to be rewritten - * relative to the SourceMapGenerator. + * Expose `Compiler` */ -SourceMapGenerator.prototype.applySourceMap = - function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) { - var sourceFile = aSourceFile; - // If aSourceFile is omitted, we will use the file property of the SourceMap - if (aSourceFile == null) { - if (aSourceMapConsumer.file == null) { - throw new Error( - 'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' + - 'or the source map\'s "file" property. Both were omitted.' - ); - } - sourceFile = aSourceMapConsumer.file; - } - var sourceRoot = this._sourceRoot; - // Make "sourceFile" relative if an absolute Url is passed. - if (sourceRoot != null) { - sourceFile = util.relative(sourceRoot, sourceFile); - } - // Applying the SourceMap can add and remove items from the sources and - // the names array. - var newSources = new ArraySet(); - var newNames = new ArraySet(); - - // Find mappings for the "sourceFile" - this._mappings.unsortedForEach(function (mapping) { - if (mapping.source === sourceFile && mapping.originalLine != null) { - // Check if it can be mapped by the source map, then update the mapping. - var original = aSourceMapConsumer.originalPositionFor({ - line: mapping.originalLine, - column: mapping.originalColumn - }); - if (original.source != null) { - // Copy mapping - mapping.source = original.source; - if (aSourceMapPath != null) { - mapping.source = util.join(aSourceMapPath, mapping.source) - } - if (sourceRoot != null) { - mapping.source = util.relative(sourceRoot, mapping.source); - } - mapping.originalLine = original.line; - mapping.originalColumn = original.column; - if (original.name != null) { - mapping.name = original.name; - } - } - } - - var source = mapping.source; - if (source != null && !newSources.has(source)) { - newSources.add(source); - } - var name = mapping.name; - if (name != null && !newNames.has(name)) { - newNames.add(name); - } +module.exports = Compiler; - }, this); - this._sources = newSources; - this._names = newNames; - // Copy sourcesContents of applied map. - aSourceMapConsumer.sources.forEach(function (sourceFile) { - var content = aSourceMapConsumer.sourceContentFor(sourceFile); - if (content != null) { - if (aSourceMapPath != null) { - sourceFile = util.join(aSourceMapPath, sourceFile); - } - if (sourceRoot != null) { - sourceFile = util.relative(sourceRoot, sourceFile); - } - this.setSourceContent(sourceFile, content); - } - }, this); - }; +/***/ }), +/* 607 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * A mapping can have one of the three levels of data: - * - * 1. Just the generated position. - * 2. The Generated position, original position, and original source. - * 3. Generated and original position, original source, as well as a name - * token. +"use strict"; +/*! + * use * - * To maintain consistency, we validate that any new mapping being added falls - * in to one of these categories. + * Copyright (c) 2015, 2017, Jon Schlinkert. + * Released under the MIT License. */ -SourceMapGenerator.prototype._validateMapping = - function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource, - aName) { - // When aOriginal is truthy but has empty values for .line and .column, - // it is most likely a programmer error. In this case we throw a very - // specific error message to try to guide them the right way. - // For example: https://github.com/Polymer/polymer-bundler/pull/519 - if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') { - throw new Error( - 'original.line and original.column are not numbers -- you probably meant to omit ' + - 'the original mapping entirely and only map the generated position. If so, pass ' + - 'null for the original mapping instead of an object with empty or null values.' - ); - } - if (aGenerated && 'line' in aGenerated && 'column' in aGenerated - && aGenerated.line > 0 && aGenerated.column >= 0 - && !aOriginal && !aSource && !aName) { - // Case 1. - return; - } - else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated - && aOriginal && 'line' in aOriginal && 'column' in aOriginal - && aGenerated.line > 0 && aGenerated.column >= 0 - && aOriginal.line > 0 && aOriginal.column >= 0 - && aSource) { - // Cases 2 and 3. - return; - } - else { - throw new Error('Invalid mapping: ' + JSON.stringify({ - generated: aGenerated, - source: aSource, - original: aOriginal, - name: aName - })); - } - }; -/** - * Serialize the accumulated mappings in to the stream of base 64 VLQs - * specified by the source map format. - */ -SourceMapGenerator.prototype._serializeMappings = - function SourceMapGenerator_serializeMappings() { - var previousGeneratedColumn = 0; - var previousGeneratedLine = 1; - var previousOriginalColumn = 0; - var previousOriginalLine = 0; - var previousName = 0; - var previousSource = 0; - var result = ''; - var next; - var mapping; - var nameIdx; - var sourceIdx; - var mappings = this._mappings.toArray(); - for (var i = 0, len = mappings.length; i < len; i++) { - mapping = mappings[i]; - next = '' +var utils = __webpack_require__(608); - if (mapping.generatedLine !== previousGeneratedLine) { - previousGeneratedColumn = 0; - while (mapping.generatedLine !== previousGeneratedLine) { - next += ';'; - previousGeneratedLine++; - } - } - else { - if (i > 0) { - if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) { - continue; - } - next += ','; - } - } +module.exports = function base(app, opts) { + if (!utils.isObject(app) && typeof app !== 'function') { + throw new TypeError('use: expect `app` be an object or function'); + } - next += base64VLQ.encode(mapping.generatedColumn - - previousGeneratedColumn); - previousGeneratedColumn = mapping.generatedColumn; + 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 + */ - if (mapping.source != null) { - sourceIdx = this._sources.indexOf(mapping.source); - next += base64VLQ.encode(sourceIdx - previousSource); - previousSource = sourceIdx; + utils.define(app, 'use', use); - // lines are stored 0-based in SourceMap spec version 3 - next += base64VLQ.encode(mapping.originalLine - 1 - - previousOriginalLine); - previousOriginalLine = mapping.originalLine - 1; + /** + * 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 + */ - next += base64VLQ.encode(mapping.originalColumn - - previousOriginalColumn); - previousOriginalColumn = mapping.originalColumn; + utils.define(app, 'run', function(val) { + if (!utils.isObject(val)) return; + decorate(val); - if (mapping.name != null) { - nameIdx = this._names.indexOf(mapping.name); - next += base64VLQ.encode(nameIdx - previousName); - previousName = nameIdx; - } - } + var self = this || app; + var fns = self[prop]; + var len = fns.length; + var idx = -1; - result += next; + while (++idx < len) { + val.use(fns[idx]); } + return val; + }); - return result; - }; - -SourceMapGenerator.prototype._generateSourcesContent = - function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) { - return aSources.map(function (source) { - if (!this._sourcesContents) { - return null; - } - if (aSourceRoot != null) { - source = util.relative(aSourceRoot, source); - } - var key = util.toSetString(source); - return Object.prototype.hasOwnProperty.call(this._sourcesContents, key) - ? this._sourcesContents[key] - : null; - }, this); - }; + /** + * Call plugin `fn`. If a function is returned push it into the + * `fns` array to be called by the `run` method. + */ -/** - * Externalize the source map. - */ -SourceMapGenerator.prototype.toJSON = - function SourceMapGenerator_toJSON() { - var map = { - version: this._version, - sources: this._sources.toArray(), - names: this._names.toArray(), - mappings: this._serializeMappings() - }; - if (this._file != null) { - map.file = this._file; + function use(fn, options) { + if (typeof fn !== 'function') { + throw new TypeError('.use expects `fn` be a function'); } - if (this._sourceRoot != null) { - map.sourceRoot = this._sourceRoot; + + var self = this || app; + if (typeof opts.fn === 'function') { + opts.fn.call(self, self, options); } - if (this._sourcesContents) { - map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot); + + var plugin = fn.call(self, self); + if (typeof plugin === 'function') { + var fns = self[prop]; + fns.push(plugin); } + return self; + } - return map; - }; + /** + * Ensure the `.use` method exists on `val` + */ -/** - * Render the source map being generated to a string. - */ -SourceMapGenerator.prototype.toString = - function SourceMapGenerator_toString() { - return JSON.stringify(this.toJSON()); - }; + function decorate(val) { + if (!val.use || !val.run) { + base(val); + } + } -exports.SourceMapGenerator = SourceMapGenerator; + return app; +}; /***/ }), -/* 616 */ +/* 608 */ /***/ (function(module, exports, __webpack_require__) { -/* -*- Mode: js; js-indent-level: 2; -*- */ -/* - * Copyright 2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause - * - * Based on the Base 64 VLQ implementation in Closure Compiler: - * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java - * - * Copyright 2011 The Closure Compiler Authors. All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -var base64 = __webpack_require__(617); - -// A single base 64 digit can contain 6 bits of data. For the base 64 variable -// length quantities we use in the source map spec, the first bit is the sign, -// the next four bits are the actual value, and the 6th bit is the -// continuation bit. The continuation bit tells us whether there are more -// digits in this value following this digit. -// -// Continuation -// | Sign -// | | -// V V -// 101011 - -var VLQ_BASE_SHIFT = 5; - -// binary: 100000 -var VLQ_BASE = 1 << VLQ_BASE_SHIFT; +"use strict"; -// binary: 011111 -var VLQ_BASE_MASK = VLQ_BASE - 1; -// binary: 100000 -var VLQ_CONTINUATION_BIT = VLQ_BASE; +var utils = {}; -/** - * Converts from a two-complement value to a value where the sign bit is - * placed in the least significant bit. For example, as decimals: - * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary) - * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary) - */ -function toVLQSigned(aValue) { - return aValue < 0 - ? ((-aValue) << 1) + 1 - : (aValue << 1) + 0; -} -/** - * Converts to a two-complement value from a value where the sign bit is - * placed in the least significant bit. For example, as decimals: - * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1 - * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2 - */ -function fromVLQSigned(aValue) { - var isNegative = (aValue & 1) === 1; - var shifted = aValue >> 1; - return isNegative - ? -shifted - : shifted; -} /** - * Returns the base 64 VLQ encoded value. + * Lazily required module dependencies */ -exports.encode = function base64VLQ_encode(aValue) { - var encoded = ""; - var digit; - var vlq = toVLQSigned(aValue); +utils.define = __webpack_require__(596); +utils.isObject = __webpack_require__(534); - do { - digit = vlq & VLQ_BASE_MASK; - vlq >>>= VLQ_BASE_SHIFT; - if (vlq > 0) { - // There are still more digits in this value, so we must make sure the - // continuation bit is marked. - digit |= VLQ_CONTINUATION_BIT; - } - encoded += base64.encode(digit); - } while (vlq > 0); - return encoded; +utils.isString = function(val) { + return val && typeof val === 'string'; }; /** - * Decodes the next base 64 VLQ value from the given string and returns the - * value and the rest of the string via the out parameter. + * Expose `utils` modules */ -exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) { - var strLen = aStr.length; - var result = 0; - var shift = 0; - var continuation, digit; - do { - if (aIndex >= strLen) { - throw new Error("Expected more digits in base 64 VLQ value."); - } +module.exports = utils; - digit = base64.decode(aStr.charCodeAt(aIndex++)); - if (digit === -1) { - throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1)); - } - continuation = !!(digit & VLQ_CONTINUATION_BIT); - digit &= VLQ_BASE_MASK; - result = result + (digit << shift); - shift += VLQ_BASE_SHIFT; - } while (continuation); +/***/ }), +/* 609 */ +/***/ (function(module, exports, __webpack_require__) { - aOutParam.value = fromVLQSigned(result); - aOutParam.rest = aIndex; -}; +/** + * Detect Electron renderer process, which is node, but we should + * treat as a browser. + */ + +if (typeof process !== 'undefined' && process.type === 'renderer') { + module.exports = __webpack_require__(610); +} else { + module.exports = __webpack_require__(613); +} /***/ }), -/* 617 */ -/***/ (function(module, exports) { +/* 610 */ +/***/ (function(module, exports, __webpack_require__) { -/* -*- Mode: js; js-indent-level: 2; -*- */ -/* - * Copyright 2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause +/** + * This is the web browser implementation of `debug()`. + * + * Expose `debug()` as the module. */ -var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split(''); +exports = module.exports = __webpack_require__(611); +exports.log = log; +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; +exports.storage = 'undefined' != typeof chrome + && 'undefined' != typeof chrome.storage + ? chrome.storage.local + : localstorage(); /** - * Encode an integer in the range of 0 to 63 to a single base 64 digit. + * Colors. */ -exports.encode = function (number) { - if (0 <= number && number < intToCharMap.length) { - return intToCharMap[number]; - } - throw new TypeError("Must be between 0 and 63: " + number); -}; + +exports.colors = [ + 'lightseagreen', + 'forestgreen', + 'goldenrod', + 'dodgerblue', + 'darkorchid', + 'crimson' +]; /** - * Decode a single base 64 character code digit to an integer. Returns -1 on - * failure. + * Currently only WebKit-based Web Inspectors, Firefox >= v31, + * and the Firebug extension (any Firefox version) are known + * to support "%c" CSS customizations. + * + * TODO: add a `localStorage` variable to explicitly enable/disable colors */ -exports.decode = function (charCode) { - var bigA = 65; // 'A' - var bigZ = 90; // 'Z' - - var littleA = 97; // 'a' - var littleZ = 122; // 'z' - var zero = 48; // '0' - var nine = 57; // '9' +function useColors() { + // NB: In an Electron preload script, document will be defined but not fully + // initialized. Since we know we're in Chrome, we'll just detect this case + // explicitly + if (typeof window !== 'undefined' && window.process && window.process.type === 'renderer') { + return true; + } - var plus = 43; // '+' - var slash = 47; // '/' + // is webkit? http://stackoverflow.com/a/16459606/376773 + // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 + return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) || + // is firebug? http://stackoverflow.com/a/398120/376773 + (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) || + // is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) || + // double check webkit in userAgent just in case we are in a worker + (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)); +} - var littleOffset = 26; - var numberOffset = 52; +/** + * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. + */ - // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ - if (bigA <= charCode && charCode <= bigZ) { - return (charCode - bigA); +exports.formatters.j = function(v) { + try { + return JSON.stringify(v); + } catch (err) { + return '[UnexpectedJSONParseError]: ' + err.message; } +}; - // 26 - 51: abcdefghijklmnopqrstuvwxyz - if (littleA <= charCode && charCode <= littleZ) { - return (charCode - littleA + littleOffset); - } - // 52 - 61: 0123456789 - if (zero <= charCode && charCode <= nine) { - return (charCode - zero + numberOffset); - } +/** + * Colorize log arguments if enabled. + * + * @api public + */ - // 62: + - if (charCode == plus) { - return 62; - } +function formatArgs(args) { + var useColors = this.useColors; - // 63: / - if (charCode == slash) { - return 63; - } + args[0] = (useColors ? '%c' : '') + + this.namespace + + (useColors ? ' %c' : ' ') + + args[0] + + (useColors ? '%c ' : ' ') + + '+' + exports.humanize(this.diff); - // Invalid base64 digit. - return -1; -}; + if (!useColors) return; + var c = 'color: ' + this.color; + args.splice(1, 0, c, 'color: inherit') -/***/ }), -/* 618 */ -/***/ (function(module, exports) { + // the final "%c" is somewhat tricky, because there could be other + // arguments passed either before or after the %c, so we need to + // figure out the correct index to insert the CSS into + var index = 0; + var lastC = 0; + args[0].replace(/%[a-zA-Z%]/g, function(match) { + if ('%%' === match) return; + index++; + if ('%c' === match) { + // we only are interested in the *last* %c + // (the user may have provided their own) + lastC = index; + } + }); -/* -*- Mode: js; js-indent-level: 2; -*- */ -/* - * Copyright 2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause - */ + args.splice(lastC, 0, c); +} /** - * This is a helper function for getting values from parameter/options - * objects. + * Invokes `console.log()` when available. + * No-op when `console.log` is not a "function". * - * @param args The object we are extracting values from - * @param name The name of the property we are getting. - * @param defaultValue An optional value to return if the property is missing - * from the object. If this is not specified and the property is missing, an - * error will be thrown. + * @api public */ -function getArg(aArgs, aName, aDefaultValue) { - if (aName in aArgs) { - return aArgs[aName]; - } else if (arguments.length === 3) { - return aDefaultValue; - } else { - throw new Error('"' + aName + '" is a required argument.'); - } + +function log() { + // this hackery is required for IE8/9, where + // the `console.log` function doesn't have 'apply' + return 'object' === typeof console + && console.log + && Function.prototype.apply.call(console.log, console, arguments); } -exports.getArg = getArg; -var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/; -var dataUrlRegexp = /^data:.+\,.+$/; +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ -function urlParse(aUrl) { - var match = aUrl.match(urlRegexp); - if (!match) { - return null; - } - return { - scheme: match[1], - auth: match[2], - host: match[3], - port: match[4], - path: match[5] - }; +function save(namespaces) { + try { + if (null == namespaces) { + exports.storage.removeItem('debug'); + } else { + exports.storage.debug = namespaces; + } + } catch(e) {} } -exports.urlParse = urlParse; -function urlGenerate(aParsedUrl) { - var url = ''; - if (aParsedUrl.scheme) { - url += aParsedUrl.scheme + ':'; - } - url += '//'; - if (aParsedUrl.auth) { - url += aParsedUrl.auth + '@'; - } - if (aParsedUrl.host) { - url += aParsedUrl.host; - } - if (aParsedUrl.port) { - url += ":" + aParsedUrl.port - } - if (aParsedUrl.path) { - url += aParsedUrl.path; +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ + +function load() { + var r; + try { + r = exports.storage.debug; + } catch(e) {} + + // If debug isn't set in LS, and we're in Electron, try to load $DEBUG + if (!r && typeof process !== 'undefined' && 'env' in process) { + r = process.env.DEBUG; } - return url; + + return r; } -exports.urlGenerate = urlGenerate; /** - * Normalizes a path, or the path portion of a URL: - * - * - Replaces consecutive slashes with one slash. - * - Removes unnecessary '.' parts. - * - Removes unnecessary '
/..' parts. + * Enable namespaces listed in `localStorage.debug` initially. + */ + +exports.enable(load()); + +/** + * Localstorage attempts to return the localstorage. * - * Based on code in the Node.js 'path' core module. + * This is necessary because safari throws + * when a user disables cookies/localstorage + * and you attempt to access it. * - * @param aPath The path or url to normalize. + * @return {LocalStorage} + * @api private */ -function normalize(aPath) { - var path = aPath; - var url = urlParse(aPath); - if (url) { - if (!url.path) { - return aPath; - } - path = url.path; - } - var isAbsolute = exports.isAbsolute(path); - var parts = path.split(/\/+/); - for (var part, up = 0, i = parts.length - 1; i >= 0; i--) { - part = parts[i]; - if (part === '.') { - parts.splice(i, 1); - } else if (part === '..') { - up++; - } else if (up > 0) { - if (part === '') { - // The first part is blank if the path is absolute. Trying to go - // above the root is a no-op. Therefore we can remove all '..' parts - // directly after the root. - parts.splice(i + 1, up); - up = 0; - } else { - parts.splice(i, 2); - up--; - } - } - } - path = parts.join('/'); +function localstorage() { + try { + return window.localStorage; + } catch (e) {} +} - if (path === '') { - path = isAbsolute ? '/' : '.'; - } - if (url) { - url.path = path; - return urlGenerate(url); - } - return path; -} -exports.normalize = normalize; +/***/ }), +/* 611 */ +/***/ (function(module, exports, __webpack_require__) { + /** - * Joins two paths/URLs. + * This is the common logic for both the Node.js and web browser + * implementations of `debug()`. * - * @param aRoot The root path or URL. - * @param aPath The path or URL to be joined with the root. + * Expose `debug()` as the module. + */ + +exports = module.exports = createDebug.debug = createDebug['default'] = createDebug; +exports.coerce = coerce; +exports.disable = disable; +exports.enable = enable; +exports.enabled = enabled; +exports.humanize = __webpack_require__(612); + +/** + * The currently active debug mode names, and names to skip. + */ + +exports.names = []; +exports.skips = []; + +/** + * Map of special "%n" handling functions, for the debug "format" argument. * - * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a - * scheme-relative URL: Then the scheme of aRoot, if any, is prepended - * first. - * - Otherwise aPath is a path. If aRoot is a URL, then its path portion - * is updated with the result and aRoot is returned. Otherwise the result - * is returned. - * - If aPath is absolute, the result is aPath. - * - Otherwise the two paths are joined with a slash. - * - Joining for example 'http://' and 'www.example.com' is also supported. + * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". */ -function join(aRoot, aPath) { - if (aRoot === "") { - aRoot = "."; - } - if (aPath === "") { - aPath = "."; - } - var aPathUrl = urlParse(aPath); - var aRootUrl = urlParse(aRoot); - if (aRootUrl) { - aRoot = aRootUrl.path || '/'; - } - // `join(foo, '//www.example.org')` - if (aPathUrl && !aPathUrl.scheme) { - if (aRootUrl) { - aPathUrl.scheme = aRootUrl.scheme; - } - return urlGenerate(aPathUrl); - } +exports.formatters = {}; - if (aPathUrl || aPath.match(dataUrlRegexp)) { - return aPath; - } +/** + * Previous log timestamp. + */ - // `join('http://', 'www.example.com')` - if (aRootUrl && !aRootUrl.host && !aRootUrl.path) { - aRootUrl.host = aPath; - return urlGenerate(aRootUrl); - } +var prevTime; - var joined = aPath.charAt(0) === '/' - ? aPath - : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath); +/** + * Select a color. + * @param {String} namespace + * @return {Number} + * @api private + */ - if (aRootUrl) { - aRootUrl.path = joined; - return urlGenerate(aRootUrl); +function selectColor(namespace) { + var hash = 0, i; + + for (i in namespace) { + hash = ((hash << 5) - hash) + namespace.charCodeAt(i); + hash |= 0; // Convert to 32bit integer } - return joined; -} -exports.join = join; -exports.isAbsolute = function (aPath) { - return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp); -}; + return exports.colors[Math.abs(hash) % exports.colors.length]; +} /** - * Make a path relative to a URL or another path. + * Create a debugger with the given `namespace`. * - * @param aRoot The root path or URL. - * @param aPath The path or URL to be made relative to aRoot. + * @param {String} namespace + * @return {Function} + * @api public */ -function relative(aRoot, aPath) { - if (aRoot === "") { - aRoot = "."; - } - aRoot = aRoot.replace(/\/$/, ''); +function createDebug(namespace) { - // It is possible for the path to be above the root. In this case, simply - // checking whether the root is a prefix of the path won't work. Instead, we - // need to remove components from the root one by one, until either we find - // a prefix that fits, or we run out of components to remove. - var level = 0; - while (aPath.indexOf(aRoot + '/') !== 0) { - var index = aRoot.lastIndexOf("/"); - if (index < 0) { - return aPath; + function debug() { + // disabled? + if (!debug.enabled) return; + + var self = debug; + + // set `diff` timestamp + var curr = +new Date(); + var ms = curr - (prevTime || curr); + self.diff = ms; + self.prev = prevTime; + self.curr = curr; + prevTime = curr; + + // turn the `arguments` into a proper Array + var args = new Array(arguments.length); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i]; } - // If the only part of the root that is left is the scheme (i.e. http://, - // file:///, etc.), one or more slashes (/), or simply nothing at all, we - // have exhausted all components, so the path is not relative to the root. - aRoot = aRoot.slice(0, index); - if (aRoot.match(/^([^\/]+:\/)?\/*$/)) { - return aPath; + args[0] = exports.coerce(args[0]); + + if ('string' !== typeof args[0]) { + // anything else let's inspect with %O + args.unshift('%O'); } - ++level; + // apply any `formatters` transformations + var index = 0; + args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) { + // if we encounter an escaped % then don't increase the array index + if (match === '%%') return match; + index++; + var formatter = exports.formatters[format]; + if ('function' === typeof formatter) { + var val = args[index]; + match = formatter.call(self, val); + + // now we need to remove `args[index]` since it's inlined in the `format` + args.splice(index, 1); + index--; + } + return match; + }); + + // apply env-specific formatting (colors, etc.) + exports.formatArgs.call(self, args); + + var logFn = debug.log || exports.log || console.log.bind(console); + logFn.apply(self, args); } - // Make sure we add a "../" for each component we removed from the root. - return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1); -} -exports.relative = relative; + debug.namespace = namespace; + debug.enabled = exports.enabled(namespace); + debug.useColors = exports.useColors(); + debug.color = selectColor(namespace); -var supportsNullProto = (function () { - var obj = Object.create(null); - return !('__proto__' in obj); -}()); + // env-specific initialization logic for debug instances + if ('function' === typeof exports.init) { + exports.init(debug); + } -function identity (s) { - return s; + return debug; } /** - * Because behavior goes wacky when you set `__proto__` on objects, we - * have to prefix all the strings in our set with an arbitrary character. - * - * See https://github.com/mozilla/source-map/pull/31 and - * https://github.com/mozilla/source-map/issues/30 + * Enables a debug mode by namespaces. This can include modes + * separated by a colon and wildcards. * - * @param String aStr + * @param {String} namespaces + * @api public */ -function toSetString(aStr) { - if (isProtoString(aStr)) { - return '$' + aStr; - } - return aStr; -} -exports.toSetString = supportsNullProto ? identity : toSetString; +function enable(namespaces) { + exports.save(namespaces); -function fromSetString(aStr) { - if (isProtoString(aStr)) { - return aStr.slice(1); - } + exports.names = []; + exports.skips = []; - return aStr; -} -exports.fromSetString = supportsNullProto ? identity : fromSetString; + var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); + var len = split.length; -function isProtoString(s) { - if (!s) { - return false; + for (var i = 0; i < len; i++) { + if (!split[i]) continue; // ignore empty strings + namespaces = split[i].replace(/\*/g, '.*?'); + if (namespaces[0] === '-') { + exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); + } else { + exports.names.push(new RegExp('^' + namespaces + '$')); + } } +} - var length = s.length; +/** + * Disable debug output. + * + * @api public + */ - if (length < 9 /* "__proto__".length */) { - return false; - } +function disable() { + exports.enable(''); +} - if (s.charCodeAt(length - 1) !== 95 /* '_' */ || - s.charCodeAt(length - 2) !== 95 /* '_' */ || - s.charCodeAt(length - 3) !== 111 /* 'o' */ || - s.charCodeAt(length - 4) !== 116 /* 't' */ || - s.charCodeAt(length - 5) !== 111 /* 'o' */ || - s.charCodeAt(length - 6) !== 114 /* 'r' */ || - s.charCodeAt(length - 7) !== 112 /* 'p' */ || - s.charCodeAt(length - 8) !== 95 /* '_' */ || - s.charCodeAt(length - 9) !== 95 /* '_' */) { - return false; - } +/** + * Returns true if the given mode name is enabled, false otherwise. + * + * @param {String} name + * @return {Boolean} + * @api public + */ - for (var i = length - 10; i >= 0; i--) { - if (s.charCodeAt(i) !== 36 /* '$' */) { +function enabled(name) { + var i, len; + for (i = 0, len = exports.skips.length; i < len; i++) { + if (exports.skips[i].test(name)) { return false; } } - - return true; + for (i = 0, len = exports.names.length; i < len; i++) { + if (exports.names[i].test(name)) { + return true; + } + } + return false; } /** - * Comparator between two mappings where the original positions are compared. + * Coerce `val`. * - * Optionally pass in `true` as `onlyCompareGenerated` to consider two - * mappings with the same original source/line/column, but different generated - * line and column the same. Useful when searching for a mapping with a - * stubbed out mapping. + * @param {Mixed} val + * @return {Mixed} + * @api private */ -function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) { - var cmp = mappingA.source - mappingB.source; - if (cmp !== 0) { - return cmp; - } - cmp = mappingA.originalLine - mappingB.originalLine; - if (cmp !== 0) { - return cmp; - } +function coerce(val) { + if (val instanceof Error) return val.stack || val.message; + return val; +} - cmp = mappingA.originalColumn - mappingB.originalColumn; - if (cmp !== 0 || onlyCompareOriginal) { - return cmp; - } - cmp = mappingA.generatedColumn - mappingB.generatedColumn; - if (cmp !== 0) { - return cmp; - } +/***/ }), +/* 612 */ +/***/ (function(module, exports) { - cmp = mappingA.generatedLine - mappingB.generatedLine; - if (cmp !== 0) { - return cmp; - } +/** + * Helpers. + */ - return mappingA.name - mappingB.name; -} -exports.compareByOriginalPositions = compareByOriginalPositions; +var s = 1000; +var m = s * 60; +var h = m * 60; +var d = h * 24; +var y = d * 365.25; /** - * Comparator between two mappings with deflated source and name indices where - * the generated positions are compared. + * Parse or format the given `val`. * - * Optionally pass in `true` as `onlyCompareGenerated` to consider two - * mappings with the same generated line and column, but different - * source/name/original line and column the same. Useful when searching for a - * mapping with a stubbed out mapping. + * Options: + * + * - `long` verbose formatting [false] + * + * @param {String|Number} val + * @param {Object} [options] + * @throws {Error} throw an error if val is not a non-empty string or a number + * @return {String|Number} + * @api public */ -function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) { - var cmp = mappingA.generatedLine - mappingB.generatedLine; - if (cmp !== 0) { - return cmp; - } - cmp = mappingA.generatedColumn - mappingB.generatedColumn; - if (cmp !== 0 || onlyCompareGenerated) { - return cmp; +module.exports = function(val, options) { + options = options || {}; + var type = typeof val; + if (type === 'string' && val.length > 0) { + return parse(val); + } else if (type === 'number' && isNaN(val) === false) { + return options.long ? fmtLong(val) : fmtShort(val); } + throw new Error( + 'val is not a non-empty string or a valid number. val=' + + JSON.stringify(val) + ); +}; - cmp = mappingA.source - mappingB.source; - if (cmp !== 0) { - return cmp; - } +/** + * Parse the given `str` and return milliseconds. + * + * @param {String} str + * @return {Number} + * @api private + */ - cmp = mappingA.originalLine - mappingB.originalLine; - if (cmp !== 0) { - return cmp; +function parse(str) { + str = String(str); + if (str.length > 100) { + return; } + var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec( + str + ); + if (!match) { + return; + } + var n = parseFloat(match[1]); + var type = (match[2] || 'ms').toLowerCase(); + switch (type) { + case 'years': + case 'year': + case 'yrs': + case 'yr': + case 'y': + return n * y; + case 'days': + case 'day': + case 'd': + return n * d; + case 'hours': + case 'hour': + case 'hrs': + case 'hr': + case 'h': + return n * h; + case 'minutes': + case 'minute': + case 'mins': + case 'min': + case 'm': + return n * m; + case 'seconds': + case 'second': + case 'secs': + case 'sec': + case 's': + return n * s; + case 'milliseconds': + case 'millisecond': + case 'msecs': + case 'msec': + case 'ms': + return n; + default: + return undefined; + } +} - cmp = mappingA.originalColumn - mappingB.originalColumn; - if (cmp !== 0) { - return cmp; +/** + * Short format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ + +function fmtShort(ms) { + if (ms >= d) { + return Math.round(ms / d) + 'd'; + } + if (ms >= h) { + return Math.round(ms / h) + 'h'; } - - return mappingA.name - mappingB.name; -} -exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated; - -function strcmp(aStr1, aStr2) { - if (aStr1 === aStr2) { - return 0; + if (ms >= m) { + return Math.round(ms / m) + 'm'; } - - if (aStr1 > aStr2) { - return 1; + if (ms >= s) { + return Math.round(ms / s) + 's'; } - - return -1; + return ms + 'ms'; } /** - * Comparator between two mappings with inflated source and name strings where - * the generated positions are compared. + * Long format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private */ -function compareByGeneratedPositionsInflated(mappingA, mappingB) { - var cmp = mappingA.generatedLine - mappingB.generatedLine; - if (cmp !== 0) { - return cmp; - } - cmp = mappingA.generatedColumn - mappingB.generatedColumn; - if (cmp !== 0) { - return cmp; - } +function fmtLong(ms) { + return plural(ms, d, 'day') || + plural(ms, h, 'hour') || + plural(ms, m, 'minute') || + plural(ms, s, 'second') || + ms + ' ms'; +} - cmp = strcmp(mappingA.source, mappingB.source); - if (cmp !== 0) { - return cmp; - } +/** + * Pluralization helper. + */ - cmp = mappingA.originalLine - mappingB.originalLine; - if (cmp !== 0) { - return cmp; +function plural(ms, n, name) { + if (ms < n) { + return; } - - cmp = mappingA.originalColumn - mappingB.originalColumn; - if (cmp !== 0) { - return cmp; + if (ms < n * 1.5) { + return Math.floor(ms / n) + ' ' + name; } - - return strcmp(mappingA.name, mappingB.name); + return Math.ceil(ms / n) + ' ' + name + 's'; } -exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated; /***/ }), -/* 619 */ +/* 613 */ /***/ (function(module, exports, __webpack_require__) { -/* -*- Mode: js; js-indent-level: 2; -*- */ -/* - * Copyright 2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause +/** + * Module dependencies. */ -var util = __webpack_require__(618); -var has = Object.prototype.hasOwnProperty; -var hasNativeMap = typeof Map !== "undefined"; +var tty = __webpack_require__(122); +var util = __webpack_require__(112); /** - * A data structure which is a combination of an array and a set. Adding a new - * member is O(1), testing for membership is O(1), and finding the index of an - * element is O(1). Removing elements from the set is not supported. Only - * strings are supported for membership. + * This is the Node.js implementation of `debug()`. + * + * Expose `debug()` as the module. */ -function ArraySet() { - this._array = []; - this._set = hasNativeMap ? new Map() : Object.create(null); -} + +exports = module.exports = __webpack_require__(611); +exports.init = init; +exports.log = log; +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; /** - * Static method for creating ArraySet instances from an existing array. + * Colors. */ -ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) { - var set = new ArraySet(); - for (var i = 0, len = aArray.length; i < len; i++) { - set.add(aArray[i], aAllowDuplicates); - } - return set; -}; + +exports.colors = [6, 2, 3, 4, 5, 1]; /** - * Return how many unique items are in this ArraySet. If duplicates have been - * added, than those do not count towards the size. + * Build up the default `inspectOpts` object from the environment variables. * - * @returns Number + * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js */ -ArraySet.prototype.size = function ArraySet_size() { - return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length; -}; + +exports.inspectOpts = Object.keys(process.env).filter(function (key) { + return /^debug_/i.test(key); +}).reduce(function (obj, key) { + // camel-case + var prop = key + .substring(6) + .toLowerCase() + .replace(/_([a-z])/g, function (_, k) { return k.toUpperCase() }); + + // coerce string value into JS value + var val = process.env[key]; + if (/^(yes|on|true|enabled)$/i.test(val)) val = true; + else if (/^(no|off|false|disabled)$/i.test(val)) val = false; + else if (val === 'null') val = null; + else val = Number(val); + + obj[prop] = val; + return obj; +}, {}); /** - * Add the given string to this set. + * The file descriptor to write the `debug()` calls to. + * Set the `DEBUG_FD` env variable to override with another value. i.e.: * - * @param String aStr + * $ DEBUG_FD=3 node script.js 3>debug.log */ -ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) { - var sStr = hasNativeMap ? aStr : util.toSetString(aStr); - var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr); - var idx = this._array.length; - if (!isDuplicate || aAllowDuplicates) { - this._array.push(aStr); - } - if (!isDuplicate) { - if (hasNativeMap) { - this._set.set(aStr, idx); - } else { - this._set[sStr] = idx; - } - } -}; + +var fd = parseInt(process.env.DEBUG_FD, 10) || 2; + +if (1 !== fd && 2 !== fd) { + util.deprecate(function(){}, 'except for stderr(2) and stdout(1), any other usage of DEBUG_FD is deprecated. Override debug.log if you want to use a different log function (https://git.io/debug_fd)')() +} + +var stream = 1 === fd ? process.stdout : + 2 === fd ? process.stderr : + createWritableStdioStream(fd); /** - * Is the given string a member of this set? - * - * @param String aStr + * Is stdout a TTY? Colored output is enabled when `true`. */ -ArraySet.prototype.has = function ArraySet_has(aStr) { - if (hasNativeMap) { - return this._set.has(aStr); - } else { - var sStr = util.toSetString(aStr); - return has.call(this._set, sStr); - } -}; + +function useColors() { + return 'colors' in exports.inspectOpts + ? Boolean(exports.inspectOpts.colors) + : tty.isatty(fd); +} /** - * What is the index of the given string in the array? - * - * @param String aStr + * Map %o to `util.inspect()`, all on a single line. */ -ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) { - if (hasNativeMap) { - var idx = this._set.get(aStr); - if (idx >= 0) { - return idx; - } - } else { - var sStr = util.toSetString(aStr); - if (has.call(this._set, sStr)) { - return this._set[sStr]; - } - } - throw new Error('"' + aStr + '" is not in the set.'); +exports.formatters.o = function(v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts) + .split('\n').map(function(str) { + return str.trim() + }).join(' '); }; /** - * What is the element at the given index? - * - * @param Number aIdx + * Map %o to `util.inspect()`, allowing multiple lines if needed. */ -ArraySet.prototype.at = function ArraySet_at(aIdx) { - if (aIdx >= 0 && aIdx < this._array.length) { - return this._array[aIdx]; - } - throw new Error('No element indexed by ' + aIdx); + +exports.formatters.O = function(v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts); }; /** - * Returns the array representation of this set (which has the proper indices - * indicated by indexOf). Note that this is a copy of the internal array used - * for storing the members so that no one can mess with internal state. + * Adds ANSI color escape codes if enabled. + * + * @api public */ -ArraySet.prototype.toArray = function ArraySet_toArray() { - return this._array.slice(); -}; -exports.ArraySet = ArraySet; +function formatArgs(args) { + var name = this.namespace; + var useColors = this.useColors; + if (useColors) { + var c = this.color; + var prefix = ' \u001b[3' + c + ';1m' + name + ' ' + '\u001b[0m'; -/***/ }), -/* 620 */ -/***/ (function(module, exports, __webpack_require__) { + args[0] = prefix + args[0].split('\n').join('\n' + prefix); + args.push('\u001b[3' + c + 'm+' + exports.humanize(this.diff) + '\u001b[0m'); + } else { + args[0] = new Date().toUTCString() + + ' ' + name + ' ' + args[0]; + } +} -/* -*- Mode: js; js-indent-level: 2; -*- */ -/* - * Copyright 2014 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause +/** + * Invokes `util.format()` with the specified arguments and writes to `stream`. */ -var util = __webpack_require__(618); +function log() { + return stream.write(util.format.apply(util, arguments) + '\n'); +} /** - * Determine whether mappingB is after mappingA with respect to generated - * position. + * Save `namespaces`. + * + * @param {String} namespaces + * @api private */ -function generatedPositionAfter(mappingA, mappingB) { - // Optimized for most common case - var lineA = mappingA.generatedLine; - var lineB = mappingB.generatedLine; - var columnA = mappingA.generatedColumn; - var columnB = mappingB.generatedColumn; - return lineB > lineA || lineB == lineA && columnB >= columnA || - util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0; + +function save(namespaces) { + if (null == namespaces) { + // If you set a process.env field to null or undefined, it gets cast to the + // string 'null' or 'undefined'. Just delete instead. + delete process.env.DEBUG; + } else { + process.env.DEBUG = namespaces; + } } /** - * A data structure to provide a sorted view of accumulated mappings in a - * performance conscious manner. It trades a neglibable overhead in general - * case for a large speedup in case of mappings being added in order. + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private */ -function MappingList() { - this._array = []; - this._sorted = true; - // Serves as infimum - this._last = {generatedLine: -1, generatedColumn: 0}; + +function load() { + return process.env.DEBUG; } /** - * Iterate through internal items. This method takes the same arguments that - * `Array.prototype.forEach` takes. + * Copied from `node/src/node.js`. * - * NOTE: The order of the mappings is NOT guaranteed. + * XXX: It's lame that node doesn't expose this API out-of-the-box. It also + * relies on the undocumented `tty_wrap.guessHandleType()` which is also lame. */ -MappingList.prototype.unsortedForEach = - function MappingList_forEach(aCallback, aThisArg) { - this._array.forEach(aCallback, aThisArg); - }; + +function createWritableStdioStream (fd) { + var stream; + var tty_wrap = process.binding('tty_wrap'); + + // Note stream._type is used for test-module-load-list.js + + switch (tty_wrap.guessHandleType(fd)) { + case 'TTY': + stream = new tty.WriteStream(fd); + stream._type = 'tty'; + + // Hack to have stream not keep the event loop alive. + // See https://github.com/joyent/node/issues/1726 + if (stream._handle && stream._handle.unref) { + stream._handle.unref(); + } + break; + + case 'FILE': + var fs = __webpack_require__(134); + stream = new fs.SyncWriteStream(fd, { autoClose: false }); + stream._type = 'fs'; + break; + + case 'PIPE': + case 'TCP': + var net = __webpack_require__(614); + stream = new net.Socket({ + fd: fd, + readable: false, + writable: true + }); + + // FIXME Should probably have an option in net.Socket to create a + // stream from an existing fd which is writable only. But for now + // we'll just add this hack and set the `readable` member to false. + // Test: ./node test/fixtures/echo.js < /etc/passwd + stream.readable = false; + stream.read = null; + stream._type = 'pipe'; + + // FIXME Hack to have stream not keep the event loop alive. + // See https://github.com/joyent/node/issues/1726 + if (stream._handle && stream._handle.unref) { + stream._handle.unref(); + } + break; + + default: + // Probably an error on in uv_guess_handle() + throw new Error('Implement me. Unknown stream file type!'); + } + + // For supporting legacy API we put the FD here. + stream.fd = fd; + + stream._isStdio = true; + + return stream; +} /** - * Add the given source mapping. + * Init logic for `debug` instances. * - * @param Object aMapping + * Create a new `inspectOpts` object in case `useColors` is set + * differently for a particular `debug` instance. */ -MappingList.prototype.add = function MappingList_add(aMapping) { - if (generatedPositionAfter(this._last, aMapping)) { - this._last = aMapping; - this._array.push(aMapping); - } else { - this._sorted = false; - this._array.push(aMapping); + +function init (debug) { + debug.inspectOpts = {}; + + var keys = Object.keys(exports.inspectOpts); + for (var i = 0; i < keys.length; i++) { + debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]]; } -}; +} /** - * Returns the flat, sorted array of mappings. The mappings are sorted by - * generated position. - * - * WARNING: This method returns internal data without copying, for - * performance. The return value must NOT be mutated, and should be treated as - * an immutable borrow. If you want to take ownership, you must make your own - * copy. + * Enable namespaces listed in `process.env.DEBUG` initially. */ -MappingList.prototype.toArray = function MappingList_toArray() { - if (!this._sorted) { - this._array.sort(util.compareByGeneratedPositionsInflated); - this._sorted = true; - } - return this._array; -}; -exports.MappingList = MappingList; +exports.enable(load()); /***/ }), -/* 621 */ +/* 614 */ +/***/ (function(module, exports) { + +module.exports = require("net"); + +/***/ }), +/* 615 */ /***/ (function(module, exports, __webpack_require__) { -/* -*- Mode: js; js-indent-level: 2; -*- */ -/* - * Copyright 2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause +"use strict"; + + +/** + * Module dependencies */ -var util = __webpack_require__(618); -var binarySearch = __webpack_require__(622); -var ArraySet = __webpack_require__(619).ArraySet; -var base64VLQ = __webpack_require__(616); -var quickSort = __webpack_require__(623).quickSort; +exports.extend = __webpack_require__(549); +exports.SourceMap = __webpack_require__(616); +exports.sourceMapResolve = __webpack_require__(627); -function SourceMapConsumer(aSourceMap) { - var sourceMap = aSourceMap; - if (typeof aSourceMap === 'string') { - sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); - } +/** + * Convert backslash in the given string to forward slashes + */ - return sourceMap.sections != null - ? new IndexedSourceMapConsumer(sourceMap) - : new BasicSourceMapConsumer(sourceMap); -} +exports.unixify = function(fp) { + return fp.split(/\\+/).join('/'); +}; -SourceMapConsumer.fromSourceMap = function(aSourceMap) { - return BasicSourceMapConsumer.fromSourceMap(aSourceMap); -} +/** + * Return true if `val` is a non-empty string + * + * @param {String} `str` + * @return {Boolean} + */ + +exports.isString = function(str) { + return str && typeof str === 'string'; +}; /** - * The version of the source mapping spec that we are consuming. + * Cast `val` to an array + * @return {Array} */ -SourceMapConsumer.prototype._version = 3; -// `__generatedMappings` and `__originalMappings` are arrays that hold the -// parsed mapping coordinates from the source map's "mappings" attribute. They -// are lazily instantiated, accessed via the `_generatedMappings` and -// `_originalMappings` getters respectively, and we only parse the mappings -// and create these arrays once queried for a source location. We jump through -// these hoops because there can be many thousands of mappings, and parsing -// them is expensive, so we only want to do it if we must. -// -// Each object in the arrays is of the form: -// -// { -// generatedLine: The line number in the generated code, -// generatedColumn: The column number in the generated code, -// source: The path to the original source file that generated this -// chunk of code, -// originalLine: The line number in the original source that -// corresponds to this chunk of generated code, -// originalColumn: The column number in the original source that -// corresponds to this chunk of generated code, -// name: The name of the original symbol which generated this chunk of -// code. -// } -// -// All properties except for `generatedLine` and `generatedColumn` can be -// `null`. -// -// `_generatedMappings` is ordered by the generated positions. -// -// `_originalMappings` is ordered by the original positions. +exports.arrayify = function(val) { + if (typeof val === 'string') return [val]; + return val ? (Array.isArray(val) ? val : [val]) : []; +}; -SourceMapConsumer.prototype.__generatedMappings = null; -Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', { - get: function () { - if (!this.__generatedMappings) { - this._parseMappings(this._mappings, this.sourceRoot); - } +/** + * Get the last `n` element from the given `array` + * @param {Array} `array` + * @return {*} + */ - return this.__generatedMappings; - } -}); +exports.last = function(arr, n) { + return arr[arr.length - (n || 1)]; +}; -SourceMapConsumer.prototype.__originalMappings = null; -Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', { - get: function () { - if (!this.__originalMappings) { - this._parseMappings(this._mappings, this.sourceRoot); - } - return this.__originalMappings; - } -}); +/***/ }), +/* 616 */ +/***/ (function(module, exports, __webpack_require__) { + +/* + * Copyright 2009-2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE.txt or: + * http://opensource.org/licenses/BSD-3-Clause + */ +exports.SourceMapGenerator = __webpack_require__(617).SourceMapGenerator; +exports.SourceMapConsumer = __webpack_require__(623).SourceMapConsumer; +exports.SourceNode = __webpack_require__(626).SourceNode; + -SourceMapConsumer.prototype._charIsMappingSeparator = - function SourceMapConsumer_charIsMappingSeparator(aStr, index) { - var c = aStr.charAt(index); - return c === ";" || c === ","; - }; +/***/ }), +/* 617 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Parse the mappings in a string in to a data structure which we can easily - * query (the ordered arrays in the `this.__generatedMappings` and - * `this.__originalMappings` properties). +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause */ -SourceMapConsumer.prototype._parseMappings = - function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { - throw new Error("Subclasses must implement _parseMappings"); - }; - -SourceMapConsumer.GENERATED_ORDER = 1; -SourceMapConsumer.ORIGINAL_ORDER = 2; -SourceMapConsumer.GREATEST_LOWER_BOUND = 1; -SourceMapConsumer.LEAST_UPPER_BOUND = 2; +var base64VLQ = __webpack_require__(618); +var util = __webpack_require__(620); +var ArraySet = __webpack_require__(621).ArraySet; +var MappingList = __webpack_require__(622).MappingList; /** - * Iterate over each mapping between an original source/line/column and a - * generated line/column in this source map. + * An instance of the SourceMapGenerator represents a source map which is + * being built incrementally. You may pass an object with the following + * properties: * - * @param Function aCallback - * The function that is called with each mapping. - * @param Object aContext - * Optional. If specified, this object will be the value of `this` every - * time that `aCallback` is called. - * @param aOrder - * Either `SourceMapConsumer.GENERATED_ORDER` or - * `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to - * iterate over the mappings sorted by the generated file's line/column - * order or the original's source/line/column order, respectively. Defaults to - * `SourceMapConsumer.GENERATED_ORDER`. + * - file: The filename of the generated source. + * - sourceRoot: A root for all relative URLs in this source map. */ -SourceMapConsumer.prototype.eachMapping = - function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) { - var context = aContext || null; - var order = aOrder || SourceMapConsumer.GENERATED_ORDER; - - var mappings; - switch (order) { - case SourceMapConsumer.GENERATED_ORDER: - mappings = this._generatedMappings; - break; - case SourceMapConsumer.ORIGINAL_ORDER: - mappings = this._originalMappings; - break; - default: - throw new Error("Unknown order of iteration."); - } +function SourceMapGenerator(aArgs) { + if (!aArgs) { + aArgs = {}; + } + this._file = util.getArg(aArgs, 'file', null); + this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null); + this._skipValidation = util.getArg(aArgs, 'skipValidation', false); + this._sources = new ArraySet(); + this._names = new ArraySet(); + this._mappings = new MappingList(); + this._sourcesContents = null; +} - var sourceRoot = this.sourceRoot; - mappings.map(function (mapping) { - var source = mapping.source === null ? null : this._sources.at(mapping.source); - if (source != null && sourceRoot != null) { - source = util.join(sourceRoot, source); - } - return { - source: source, - generatedLine: mapping.generatedLine, - generatedColumn: mapping.generatedColumn, - originalLine: mapping.originalLine, - originalColumn: mapping.originalColumn, - name: mapping.name === null ? null : this._names.at(mapping.name) - }; - }, this).forEach(aCallback, context); - }; +SourceMapGenerator.prototype._version = 3; /** - * Returns all generated line and column information for the original source, - * line, and column provided. If no column is provided, returns all mappings - * corresponding to a either the line we are searching for or the next - * closest line that has any mappings. Otherwise, returns all mappings - * corresponding to the given line and either the column we are searching for - * or the next closest column that has any offsets. - * - * The only argument is an object with the following properties: - * - * - source: The filename of the original source. - * - line: The line number in the original source. - * - column: Optional. the column number in the original source. - * - * and an array of objects is returned, each with the following properties: + * Creates a new SourceMapGenerator based on a SourceMapConsumer * - * - line: The line number in the generated source, or null. - * - column: The column number in the generated source, or null. + * @param aSourceMapConsumer The SourceMap. */ -SourceMapConsumer.prototype.allGeneratedPositionsFor = - function SourceMapConsumer_allGeneratedPositionsFor(aArgs) { - var line = util.getArg(aArgs, 'line'); - - // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping - // returns the index of the closest mapping less than the needle. By - // setting needle.originalColumn to 0, we thus find the last mapping for - // the given line, provided such a mapping exists. - var needle = { - source: util.getArg(aArgs, 'source'), - originalLine: line, - originalColumn: util.getArg(aArgs, 'column', 0) - }; - - if (this.sourceRoot != null) { - needle.source = util.relative(this.sourceRoot, needle.source); - } - if (!this._sources.has(needle.source)) { - return []; - } - needle.source = this._sources.indexOf(needle.source); - - var mappings = []; - - var index = this._findMapping(needle, - this._originalMappings, - "originalLine", - "originalColumn", - util.compareByOriginalPositions, - binarySearch.LEAST_UPPER_BOUND); - if (index >= 0) { - var mapping = this._originalMappings[index]; - - if (aArgs.column === undefined) { - var originalLine = mapping.originalLine; - - // Iterate until either we run out of mappings, or we run into - // a mapping for a different line than the one we found. Since - // mappings are sorted, this is guaranteed to find all mappings for - // the line we found. - while (mapping && mapping.originalLine === originalLine) { - mappings.push({ - line: util.getArg(mapping, 'generatedLine', null), - column: util.getArg(mapping, 'generatedColumn', null), - lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) - }); +SourceMapGenerator.fromSourceMap = + function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) { + var sourceRoot = aSourceMapConsumer.sourceRoot; + var generator = new SourceMapGenerator({ + file: aSourceMapConsumer.file, + sourceRoot: sourceRoot + }); + aSourceMapConsumer.eachMapping(function (mapping) { + var newMapping = { + generated: { + line: mapping.generatedLine, + column: mapping.generatedColumn + } + }; - mapping = this._originalMappings[++index]; + if (mapping.source != null) { + newMapping.source = mapping.source; + if (sourceRoot != null) { + newMapping.source = util.relative(sourceRoot, newMapping.source); } - } else { - var originalColumn = mapping.originalColumn; - // Iterate until either we run out of mappings, or we run into - // a mapping for a different line than the one we were searching for. - // Since mappings are sorted, this is guaranteed to find all mappings for - // the line we are searching for. - while (mapping && - mapping.originalLine === line && - mapping.originalColumn == originalColumn) { - mappings.push({ - line: util.getArg(mapping, 'generatedLine', null), - column: util.getArg(mapping, 'generatedColumn', null), - lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) - }); + newMapping.original = { + line: mapping.originalLine, + column: mapping.originalColumn + }; - mapping = this._originalMappings[++index]; + if (mapping.name != null) { + newMapping.name = mapping.name; } } - } - return mappings; + generator.addMapping(newMapping); + }); + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + generator.setSourceContent(sourceFile, content); + } + }); + return generator; }; -exports.SourceMapConsumer = SourceMapConsumer; - /** - * A BasicSourceMapConsumer instance represents a parsed source map which we can - * query for information about the original file positions by giving it a file - * position in the generated source. - * - * The only parameter is the raw source map (either as a JSON string, or - * already parsed to an object). According to the spec, source maps have the - * following attributes: - * - * - version: Which version of the source map spec this map is following. - * - sources: An array of URLs to the original source files. - * - names: An array of identifiers which can be referrenced by individual mappings. - * - sourceRoot: Optional. The URL root from which all sources are relative. - * - sourcesContent: Optional. An array of contents of the original source files. - * - mappings: A string of base64 VLQs which contain the actual mappings. - * - file: Optional. The generated file this source map is associated with. - * - * Here is an example source map, taken from the source map spec[0]: - * - * { - * version : 3, - * file: "out.js", - * sourceRoot : "", - * sources: ["foo.js", "bar.js"], - * names: ["src", "maps", "are", "fun"], - * mappings: "AA,AB;;ABCDE;" - * } + * Add a single mapping from original source line and column to the generated + * source's line and column for this source map being created. The mapping + * object should have the following properties: * - * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1# + * - generated: An object with the generated line and column positions. + * - original: An object with the original line and column positions. + * - source: The original source file (relative to the sourceRoot). + * - name: An optional original token name for this mapping. */ -function BasicSourceMapConsumer(aSourceMap) { - var sourceMap = aSourceMap; - if (typeof aSourceMap === 'string') { - sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); - } +SourceMapGenerator.prototype.addMapping = + function SourceMapGenerator_addMapping(aArgs) { + var generated = util.getArg(aArgs, 'generated'); + var original = util.getArg(aArgs, 'original', null); + var source = util.getArg(aArgs, 'source', null); + var name = util.getArg(aArgs, 'name', null); - var version = util.getArg(sourceMap, 'version'); - var sources = util.getArg(sourceMap, 'sources'); - // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which - // requires the array) to play nice here. - var names = util.getArg(sourceMap, 'names', []); - var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null); - var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null); - var mappings = util.getArg(sourceMap, 'mappings'); - var file = util.getArg(sourceMap, 'file', null); + if (!this._skipValidation) { + this._validateMapping(generated, original, source, name); + } - // Once again, Sass deviates from the spec and supplies the version as a - // string rather than a number, so we use loose equality checking here. - if (version != this._version) { - throw new Error('Unsupported version: ' + version); - } + if (source != null) { + source = String(source); + if (!this._sources.has(source)) { + this._sources.add(source); + } + } - sources = sources - .map(String) - // Some source maps produce relative source paths like "./foo.js" instead of - // "foo.js". Normalize these first so that future comparisons will succeed. - // See bugzil.la/1090768. - .map(util.normalize) - // Always ensure that absolute sources are internally stored relative to - // the source root, if the source root is absolute. Not doing this would - // be particularly problematic when the source root is a prefix of the - // source (valid, but why??). See github issue #199 and bugzil.la/1188982. - .map(function (source) { - return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source) - ? util.relative(sourceRoot, source) - : source; - }); + if (name != null) { + name = String(name); + if (!this._names.has(name)) { + this._names.add(name); + } + } - // Pass `true` below to allow duplicate names and sources. While source maps - // are intended to be compressed and deduplicated, the TypeScript compiler - // sometimes generates source maps with duplicates in them. See Github issue - // #72 and bugzil.la/889492. - this._names = ArraySet.fromArray(names.map(String), true); - this._sources = ArraySet.fromArray(sources, true); + this._mappings.add({ + generatedLine: generated.line, + generatedColumn: generated.column, + originalLine: original != null && original.line, + originalColumn: original != null && original.column, + source: source, + name: name + }); + }; - this.sourceRoot = sourceRoot; - this.sourcesContent = sourcesContent; - this._mappings = mappings; - this.file = file; -} +/** + * Set the source content for a source file. + */ +SourceMapGenerator.prototype.setSourceContent = + function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) { + var source = aSourceFile; + if (this._sourceRoot != null) { + source = util.relative(this._sourceRoot, source); + } -BasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); -BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer; + if (aSourceContent != null) { + // Add the source content to the _sourcesContents map. + // Create a new _sourcesContents map if the property is null. + if (!this._sourcesContents) { + this._sourcesContents = Object.create(null); + } + this._sourcesContents[util.toSetString(source)] = aSourceContent; + } else if (this._sourcesContents) { + // Remove the source file from the _sourcesContents map. + // If the _sourcesContents map is empty, set the property to null. + delete this._sourcesContents[util.toSetString(source)]; + if (Object.keys(this._sourcesContents).length === 0) { + this._sourcesContents = null; + } + } + }; /** - * Create a BasicSourceMapConsumer from a SourceMapGenerator. + * Applies the mappings of a sub-source-map for a specific source file to the + * source map being generated. Each mapping to the supplied source file is + * rewritten using the supplied source map. Note: The resolution for the + * resulting mappings is the minimium of this map and the supplied map. * - * @param SourceMapGenerator aSourceMap - * The source map that will be consumed. - * @returns BasicSourceMapConsumer + * @param aSourceMapConsumer The source map to be applied. + * @param aSourceFile Optional. The filename of the source file. + * If omitted, SourceMapConsumer's file property will be used. + * @param aSourceMapPath Optional. The dirname of the path to the source map + * to be applied. If relative, it is relative to the SourceMapConsumer. + * This parameter is needed when the two source maps aren't in the same + * directory, and the source map to be applied contains relative source + * paths. If so, those relative source paths need to be rewritten + * relative to the SourceMapGenerator. */ -BasicSourceMapConsumer.fromSourceMap = - function SourceMapConsumer_fromSourceMap(aSourceMap) { - var smc = Object.create(BasicSourceMapConsumer.prototype); - - var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true); - var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true); - smc.sourceRoot = aSourceMap._sourceRoot; - smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(), - smc.sourceRoot); - smc.file = aSourceMap._file; +SourceMapGenerator.prototype.applySourceMap = + function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) { + var sourceFile = aSourceFile; + // If aSourceFile is omitted, we will use the file property of the SourceMap + if (aSourceFile == null) { + if (aSourceMapConsumer.file == null) { + throw new Error( + 'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' + + 'or the source map\'s "file" property. Both were omitted.' + ); + } + sourceFile = aSourceMapConsumer.file; + } + var sourceRoot = this._sourceRoot; + // Make "sourceFile" relative if an absolute Url is passed. + if (sourceRoot != null) { + sourceFile = util.relative(sourceRoot, sourceFile); + } + // Applying the SourceMap can add and remove items from the sources and + // the names array. + var newSources = new ArraySet(); + var newNames = new ArraySet(); - // Because we are modifying the entries (by converting string sources and - // names to indices into the sources and names ArraySets), we have to make - // a copy of the entry or else bad things happen. Shared mutable state - // strikes again! See github issue #191. + // Find mappings for the "sourceFile" + this._mappings.unsortedForEach(function (mapping) { + if (mapping.source === sourceFile && mapping.originalLine != null) { + // Check if it can be mapped by the source map, then update the mapping. + var original = aSourceMapConsumer.originalPositionFor({ + line: mapping.originalLine, + column: mapping.originalColumn + }); + if (original.source != null) { + // Copy mapping + mapping.source = original.source; + if (aSourceMapPath != null) { + mapping.source = util.join(aSourceMapPath, mapping.source) + } + if (sourceRoot != null) { + mapping.source = util.relative(sourceRoot, mapping.source); + } + mapping.originalLine = original.line; + mapping.originalColumn = original.column; + if (original.name != null) { + mapping.name = original.name; + } + } + } - var generatedMappings = aSourceMap._mappings.toArray().slice(); - var destGeneratedMappings = smc.__generatedMappings = []; - var destOriginalMappings = smc.__originalMappings = []; + var source = mapping.source; + if (source != null && !newSources.has(source)) { + newSources.add(source); + } - for (var i = 0, length = generatedMappings.length; i < length; i++) { - var srcMapping = generatedMappings[i]; - var destMapping = new Mapping; - destMapping.generatedLine = srcMapping.generatedLine; - destMapping.generatedColumn = srcMapping.generatedColumn; + var name = mapping.name; + if (name != null && !newNames.has(name)) { + newNames.add(name); + } - if (srcMapping.source) { - destMapping.source = sources.indexOf(srcMapping.source); - destMapping.originalLine = srcMapping.originalLine; - destMapping.originalColumn = srcMapping.originalColumn; + }, this); + this._sources = newSources; + this._names = newNames; - if (srcMapping.name) { - destMapping.name = names.indexOf(srcMapping.name); + // Copy sourcesContents of applied map. + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + if (aSourceMapPath != null) { + sourceFile = util.join(aSourceMapPath, sourceFile); } - - destOriginalMappings.push(destMapping); + if (sourceRoot != null) { + sourceFile = util.relative(sourceRoot, sourceFile); + } + this.setSourceContent(sourceFile, content); } + }, this); + }; - destGeneratedMappings.push(destMapping); +/** + * A mapping can have one of the three levels of data: + * + * 1. Just the generated position. + * 2. The Generated position, original position, and original source. + * 3. Generated and original position, original source, as well as a name + * token. + * + * To maintain consistency, we validate that any new mapping being added falls + * in to one of these categories. + */ +SourceMapGenerator.prototype._validateMapping = + function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource, + aName) { + // When aOriginal is truthy but has empty values for .line and .column, + // it is most likely a programmer error. In this case we throw a very + // specific error message to try to guide them the right way. + // For example: https://github.com/Polymer/polymer-bundler/pull/519 + if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') { + throw new Error( + 'original.line and original.column are not numbers -- you probably meant to omit ' + + 'the original mapping entirely and only map the generated position. If so, pass ' + + 'null for the original mapping instead of an object with empty or null values.' + ); } - quickSort(smc.__originalMappings, util.compareByOriginalPositions); - - return smc; + if (aGenerated && 'line' in aGenerated && 'column' in aGenerated + && aGenerated.line > 0 && aGenerated.column >= 0 + && !aOriginal && !aSource && !aName) { + // Case 1. + return; + } + else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated + && aOriginal && 'line' in aOriginal && 'column' in aOriginal + && aGenerated.line > 0 && aGenerated.column >= 0 + && aOriginal.line > 0 && aOriginal.column >= 0 + && aSource) { + // Cases 2 and 3. + return; + } + else { + throw new Error('Invalid mapping: ' + JSON.stringify({ + generated: aGenerated, + source: aSource, + original: aOriginal, + name: aName + })); + } }; /** - * The version of the source mapping spec that we are consuming. - */ -BasicSourceMapConsumer.prototype._version = 3; - -/** - * The list of original sources. - */ -Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', { - get: function () { - return this._sources.toArray().map(function (s) { - return this.sourceRoot != null ? util.join(this.sourceRoot, s) : s; - }, this); - } -}); - -/** - * Provide the JIT with a nice shape / hidden class. - */ -function Mapping() { - this.generatedLine = 0; - this.generatedColumn = 0; - this.source = null; - this.originalLine = null; - this.originalColumn = null; - this.name = null; -} - -/** - * Parse the mappings in a string in to a data structure which we can easily - * query (the ordered arrays in the `this.__generatedMappings` and - * `this.__originalMappings` properties). + * Serialize the accumulated mappings in to the stream of base 64 VLQs + * specified by the source map format. */ -BasicSourceMapConsumer.prototype._parseMappings = - function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { - var generatedLine = 1; +SourceMapGenerator.prototype._serializeMappings = + function SourceMapGenerator_serializeMappings() { var previousGeneratedColumn = 0; - var previousOriginalLine = 0; + var previousGeneratedLine = 1; var previousOriginalColumn = 0; - var previousSource = 0; + var previousOriginalLine = 0; var previousName = 0; - var length = aStr.length; - var index = 0; - var cachedSegments = {}; - var temp = {}; - var originalMappings = []; - var generatedMappings = []; - var mapping, str, segment, end, value; + var previousSource = 0; + var result = ''; + var next; + var mapping; + var nameIdx; + var sourceIdx; - while (index < length) { - if (aStr.charAt(index) === ';') { - generatedLine++; - index++; + var mappings = this._mappings.toArray(); + for (var i = 0, len = mappings.length; i < len; i++) { + mapping = mappings[i]; + next = '' + + if (mapping.generatedLine !== previousGeneratedLine) { previousGeneratedColumn = 0; - } - else if (aStr.charAt(index) === ',') { - index++; + while (mapping.generatedLine !== previousGeneratedLine) { + next += ';'; + previousGeneratedLine++; + } } else { - mapping = new Mapping(); - mapping.generatedLine = generatedLine; - - // Because each offset is encoded relative to the previous one, - // many segments often have the same encoding. We can exploit this - // fact by caching the parsed variable length fields of each segment, - // allowing us to avoid a second parse if we encounter the same - // segment again. - for (end = index; end < length; end++) { - if (this._charIsMappingSeparator(aStr, end)) { - break; - } - } - str = aStr.slice(index, end); - - segment = cachedSegments[str]; - if (segment) { - index += str.length; - } else { - segment = []; - while (index < end) { - base64VLQ.decode(aStr, index, temp); - value = temp.value; - index = temp.rest; - segment.push(value); - } - - if (segment.length === 2) { - throw new Error('Found a source, but no line and column'); - } - - if (segment.length === 3) { - throw new Error('Found a source and line, but no column'); + if (i > 0) { + if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) { + continue; } - - cachedSegments[str] = segment; + next += ','; } + } - // Generated column. - mapping.generatedColumn = previousGeneratedColumn + segment[0]; - previousGeneratedColumn = mapping.generatedColumn; - - if (segment.length > 1) { - // Original source. - mapping.source = previousSource + segment[1]; - previousSource += segment[1]; + next += base64VLQ.encode(mapping.generatedColumn + - previousGeneratedColumn); + previousGeneratedColumn = mapping.generatedColumn; - // Original line. - mapping.originalLine = previousOriginalLine + segment[2]; - previousOriginalLine = mapping.originalLine; - // Lines are stored 0-based - mapping.originalLine += 1; + if (mapping.source != null) { + sourceIdx = this._sources.indexOf(mapping.source); + next += base64VLQ.encode(sourceIdx - previousSource); + previousSource = sourceIdx; - // Original column. - mapping.originalColumn = previousOriginalColumn + segment[3]; - previousOriginalColumn = mapping.originalColumn; + // lines are stored 0-based in SourceMap spec version 3 + next += base64VLQ.encode(mapping.originalLine - 1 + - previousOriginalLine); + previousOriginalLine = mapping.originalLine - 1; - if (segment.length > 4) { - // Original name. - mapping.name = previousName + segment[4]; - previousName += segment[4]; - } - } + next += base64VLQ.encode(mapping.originalColumn + - previousOriginalColumn); + previousOriginalColumn = mapping.originalColumn; - generatedMappings.push(mapping); - if (typeof mapping.originalLine === 'number') { - originalMappings.push(mapping); + if (mapping.name != null) { + nameIdx = this._names.indexOf(mapping.name); + next += base64VLQ.encode(nameIdx - previousName); + previousName = nameIdx; } } + + result += next; } - quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated); - this.__generatedMappings = generatedMappings; + return result; + }; - quickSort(originalMappings, util.compareByOriginalPositions); - this.__originalMappings = originalMappings; +SourceMapGenerator.prototype._generateSourcesContent = + function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) { + return aSources.map(function (source) { + if (!this._sourcesContents) { + return null; + } + if (aSourceRoot != null) { + source = util.relative(aSourceRoot, source); + } + var key = util.toSetString(source); + return Object.prototype.hasOwnProperty.call(this._sourcesContents, key) + ? this._sourcesContents[key] + : null; + }, this); }; /** - * Find the mapping that best matches the hypothetical "needle" mapping that - * we are searching for in the given "haystack" of mappings. + * Externalize the source map. */ -BasicSourceMapConsumer.prototype._findMapping = - function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName, - aColumnName, aComparator, aBias) { - // To return the position we are searching for, we must first find the - // mapping for the given position and then return the opposite position it - // points to. Because the mappings are sorted, we can use binary search to - // find the best mapping. - - if (aNeedle[aLineName] <= 0) { - throw new TypeError('Line must be greater than or equal to 1, got ' - + aNeedle[aLineName]); +SourceMapGenerator.prototype.toJSON = + function SourceMapGenerator_toJSON() { + var map = { + version: this._version, + sources: this._sources.toArray(), + names: this._names.toArray(), + mappings: this._serializeMappings() + }; + if (this._file != null) { + map.file = this._file; } - if (aNeedle[aColumnName] < 0) { - throw new TypeError('Column must be greater than or equal to 0, got ' - + aNeedle[aColumnName]); + if (this._sourceRoot != null) { + map.sourceRoot = this._sourceRoot; + } + if (this._sourcesContents) { + map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot); } - return binarySearch.search(aNeedle, aMappings, aComparator, aBias); + return map; }; /** - * Compute the last column for each generated mapping. The last column is - * inclusive. + * Render the source map being generated to a string. */ -BasicSourceMapConsumer.prototype.computeColumnSpans = - function SourceMapConsumer_computeColumnSpans() { - for (var index = 0; index < this._generatedMappings.length; ++index) { - var mapping = this._generatedMappings[index]; +SourceMapGenerator.prototype.toString = + function SourceMapGenerator_toString() { + return JSON.stringify(this.toJSON()); + }; - // Mappings do not contain a field for the last generated columnt. We - // can come up with an optimistic estimate, however, by assuming that - // mappings are contiguous (i.e. given two consecutive mappings, the - // first mapping ends where the second one starts). - if (index + 1 < this._generatedMappings.length) { - var nextMapping = this._generatedMappings[index + 1]; +exports.SourceMapGenerator = SourceMapGenerator; - if (mapping.generatedLine === nextMapping.generatedLine) { - mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1; - continue; - } - } - // The last mapping for each line spans the entire line. - mapping.lastGeneratedColumn = Infinity; - } - }; +/***/ }), +/* 618 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Returns the original source, line, and column information for the generated - * source's line and column positions provided. The only argument is an object - * with the following properties: +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause * - * - line: The line number in the generated source. - * - column: The column number in the generated source. - * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or - * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the - * closest element that is smaller than or greater than the one we are - * searching for, respectively, if the exact element cannot be found. - * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. + * Based on the Base 64 VLQ implementation in Closure Compiler: + * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java * - * and an object is returned with the following properties: + * Copyright 2011 The Closure Compiler Authors. All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: * - * - source: The original source file, or null. - * - line: The line number in the original source, or null. - * - column: The column number in the original source, or null. - * - name: The original identifier, or null. + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -BasicSourceMapConsumer.prototype.originalPositionFor = - function SourceMapConsumer_originalPositionFor(aArgs) { - var needle = { - generatedLine: util.getArg(aArgs, 'line'), - generatedColumn: util.getArg(aArgs, 'column') - }; - var index = this._findMapping( - needle, - this._generatedMappings, - "generatedLine", - "generatedColumn", - util.compareByGeneratedPositionsDeflated, - util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) - ); +var base64 = __webpack_require__(619); - if (index >= 0) { - var mapping = this._generatedMappings[index]; +// 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, +// the next four bits are the actual value, and the 6th bit is the +// continuation bit. The continuation bit tells us whether there are more +// digits in this value following this digit. +// +// Continuation +// | Sign +// | | +// V V +// 101011 - if (mapping.generatedLine === needle.generatedLine) { - var source = util.getArg(mapping, 'source', null); - if (source !== null) { - source = this._sources.at(source); - if (this.sourceRoot != null) { - source = util.join(this.sourceRoot, source); - } - } - var name = util.getArg(mapping, 'name', null); - if (name !== null) { - name = this._names.at(name); - } - return { - source: source, - line: util.getArg(mapping, 'originalLine', null), - column: util.getArg(mapping, 'originalColumn', null), - name: name - }; - } - } +var VLQ_BASE_SHIFT = 5; - return { - source: null, - line: null, - column: null, - name: null - }; - }; +// binary: 100000 +var VLQ_BASE = 1 << VLQ_BASE_SHIFT; + +// binary: 011111 +var VLQ_BASE_MASK = VLQ_BASE - 1; + +// binary: 100000 +var VLQ_CONTINUATION_BIT = VLQ_BASE; /** - * Return true if we have the source content for every source in the source - * map, false otherwise. + * Converts from a two-complement value to a value where the sign bit is + * placed in the least significant bit. For example, as decimals: + * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary) + * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary) */ -BasicSourceMapConsumer.prototype.hasContentsOfAllSources = - function BasicSourceMapConsumer_hasContentsOfAllSources() { - if (!this.sourcesContent) { - return false; +function toVLQSigned(aValue) { + return aValue < 0 + ? ((-aValue) << 1) + 1 + : (aValue << 1) + 0; +} + +/** + * Converts to a two-complement value from a value where the sign bit is + * placed in the least significant bit. For example, as decimals: + * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1 + * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2 + */ +function fromVLQSigned(aValue) { + var isNegative = (aValue & 1) === 1; + var shifted = aValue >> 1; + return isNegative + ? -shifted + : shifted; +} + +/** + * Returns the base 64 VLQ encoded value. + */ +exports.encode = function base64VLQ_encode(aValue) { + var encoded = ""; + var digit; + + var vlq = toVLQSigned(aValue); + + do { + digit = vlq & VLQ_BASE_MASK; + vlq >>>= VLQ_BASE_SHIFT; + if (vlq > 0) { + // There are still more digits in this value, so we must make sure the + // continuation bit is marked. + digit |= VLQ_CONTINUATION_BIT; } - return this.sourcesContent.length >= this._sources.size() && - !this.sourcesContent.some(function (sc) { return sc == null; }); - }; + encoded += base64.encode(digit); + } while (vlq > 0); + + return encoded; +}; /** - * Returns the original source content. The only argument is the url of the - * original source file. Returns null if no original source content is - * available. + * Decodes the next base 64 VLQ value from the given string and returns the + * value and the rest of the string via the out parameter. */ -BasicSourceMapConsumer.prototype.sourceContentFor = - function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { - if (!this.sourcesContent) { - return null; +exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) { + var strLen = aStr.length; + var result = 0; + var shift = 0; + var continuation, digit; + + do { + if (aIndex >= strLen) { + throw new Error("Expected more digits in base 64 VLQ value."); } - if (this.sourceRoot != null) { - aSource = util.relative(this.sourceRoot, aSource); - } + digit = base64.decode(aStr.charCodeAt(aIndex++)); + if (digit === -1) { + throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1)); + } + + continuation = !!(digit & VLQ_CONTINUATION_BIT); + digit &= VLQ_BASE_MASK; + result = result + (digit << shift); + shift += VLQ_BASE_SHIFT; + } while (continuation); + + aOutParam.value = fromVLQSigned(result); + aOutParam.rest = aIndex; +}; + + +/***/ }), +/* 619 */ +/***/ (function(module, exports) { + +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + +var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split(''); + +/** + * Encode an integer in the range of 0 to 63 to a single base 64 digit. + */ +exports.encode = function (number) { + if (0 <= number && number < intToCharMap.length) { + return intToCharMap[number]; + } + throw new TypeError("Must be between 0 and 63: " + number); +}; + +/** + * Decode a single base 64 character code digit to an integer. Returns -1 on + * failure. + */ +exports.decode = function (charCode) { + var bigA = 65; // 'A' + var bigZ = 90; // 'Z' + + var littleA = 97; // 'a' + var littleZ = 122; // 'z' + + var zero = 48; // '0' + var nine = 57; // '9' + + var plus = 43; // '+' + var slash = 47; // '/' + + var littleOffset = 26; + var numberOffset = 52; + + // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ + if (bigA <= charCode && charCode <= bigZ) { + return (charCode - bigA); + } + + // 26 - 51: abcdefghijklmnopqrstuvwxyz + if (littleA <= charCode && charCode <= littleZ) { + return (charCode - littleA + littleOffset); + } + + // 52 - 61: 0123456789 + if (zero <= charCode && charCode <= nine) { + return (charCode - zero + numberOffset); + } + + // 62: + + if (charCode == plus) { + return 62; + } + + // 63: / + if (charCode == slash) { + return 63; + } + + // Invalid base64 digit. + return -1; +}; + - if (this._sources.has(aSource)) { - return this.sourcesContent[this._sources.indexOf(aSource)]; - } +/***/ }), +/* 620 */ +/***/ (function(module, exports) { - var url; - if (this.sourceRoot != null - && (url = util.urlParse(this.sourceRoot))) { - // XXX: file:// URIs and absolute paths lead to unexpected behavior for - // many users. We can help them out when they expect file:// URIs to - // behave like it would if they were running a local HTTP server. See - // https://bugzilla.mozilla.org/show_bug.cgi?id=885597. - var fileUriAbsPath = aSource.replace(/^file:\/\//, ""); - if (url.scheme == "file" - && this._sources.has(fileUriAbsPath)) { - return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)] - } +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ - if ((!url.path || url.path == "/") - && this._sources.has("/" + aSource)) { - return this.sourcesContent[this._sources.indexOf("/" + aSource)]; - } - } +/** + * This is a helper function for getting values from parameter/options + * objects. + * + * @param args The object we are extracting values from + * @param name The name of the property we are getting. + * @param defaultValue An optional value to return if the property is missing + * from the object. If this is not specified and the property is missing, an + * error will be thrown. + */ +function getArg(aArgs, aName, aDefaultValue) { + if (aName in aArgs) { + return aArgs[aName]; + } else if (arguments.length === 3) { + return aDefaultValue; + } else { + throw new Error('"' + aName + '" is a required argument.'); + } +} +exports.getArg = getArg; - // This function is used recursively from - // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we - // don't want to throw if we can't find the source - we just want to - // return null, so we provide a flag to exit gracefully. - if (nullOnMissing) { - return null; - } - else { - throw new Error('"' + aSource + '" is not in the SourceMap.'); - } +var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/; +var dataUrlRegexp = /^data:.+\,.+$/; + +function urlParse(aUrl) { + var match = aUrl.match(urlRegexp); + if (!match) { + return null; + } + return { + scheme: match[1], + auth: match[2], + host: match[3], + port: match[4], + path: match[5] }; +} +exports.urlParse = urlParse; + +function urlGenerate(aParsedUrl) { + var url = ''; + if (aParsedUrl.scheme) { + url += aParsedUrl.scheme + ':'; + } + url += '//'; + if (aParsedUrl.auth) { + url += aParsedUrl.auth + '@'; + } + if (aParsedUrl.host) { + url += aParsedUrl.host; + } + if (aParsedUrl.port) { + url += ":" + aParsedUrl.port + } + if (aParsedUrl.path) { + url += aParsedUrl.path; + } + return url; +} +exports.urlGenerate = urlGenerate; /** - * Returns the generated line and column information for the original source, - * line, and column positions provided. The only argument is an object with - * the following properties: + * Normalizes a path, or the path portion of a URL: * - * - source: The filename of the original source. - * - line: The line number in the original source. - * - column: The column number in the original source. - * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or - * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the - * closest element that is smaller than or greater than the one we are - * searching for, respectively, if the exact element cannot be found. - * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. + * - Replaces consecutive slashes with one slash. + * - Removes unnecessary '.' parts. + * - Removes unnecessary '/..' parts. * - * and an object is returned with the following properties: + * Based on code in the Node.js 'path' core module. * - * - line: The line number in the generated source, or null. - * - column: The column number in the generated source, or null. + * @param aPath The path or url to normalize. */ -BasicSourceMapConsumer.prototype.generatedPositionFor = - function SourceMapConsumer_generatedPositionFor(aArgs) { - var source = util.getArg(aArgs, 'source'); - if (this.sourceRoot != null) { - source = util.relative(this.sourceRoot, source); - } - if (!this._sources.has(source)) { - return { - line: null, - column: null, - lastColumn: null - }; +function normalize(aPath) { + var path = aPath; + var url = urlParse(aPath); + if (url) { + if (!url.path) { + return aPath; } - source = this._sources.indexOf(source); - - var needle = { - source: source, - originalLine: util.getArg(aArgs, 'line'), - originalColumn: util.getArg(aArgs, 'column') - }; - - var index = this._findMapping( - needle, - this._originalMappings, - "originalLine", - "originalColumn", - util.compareByOriginalPositions, - util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) - ); - - if (index >= 0) { - var mapping = this._originalMappings[index]; + path = url.path; + } + var isAbsolute = exports.isAbsolute(path); - if (mapping.source === needle.source) { - return { - line: util.getArg(mapping, 'generatedLine', null), - column: util.getArg(mapping, 'generatedColumn', null), - lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) - }; + var parts = path.split(/\/+/); + for (var part, up = 0, i = parts.length - 1; i >= 0; i--) { + part = parts[i]; + if (part === '.') { + parts.splice(i, 1); + } else if (part === '..') { + up++; + } else if (up > 0) { + if (part === '') { + // The first part is blank if the path is absolute. Trying to go + // above the root is a no-op. Therefore we can remove all '..' parts + // directly after the root. + parts.splice(i + 1, up); + up = 0; + } else { + parts.splice(i, 2); + up--; } } + } + path = parts.join('/'); - return { - line: null, - column: null, - lastColumn: null - }; - }; + if (path === '') { + path = isAbsolute ? '/' : '.'; + } -exports.BasicSourceMapConsumer = BasicSourceMapConsumer; + if (url) { + url.path = path; + return urlGenerate(url); + } + return path; +} +exports.normalize = normalize; /** - * An IndexedSourceMapConsumer instance represents a parsed source map which - * we can query for information. It differs from BasicSourceMapConsumer in - * that it takes "indexed" source maps (i.e. ones with a "sections" field) as - * input. - * - * The only parameter is a raw source map (either as a JSON string, or already - * parsed to an object). According to the spec for indexed source maps, they - * have the following attributes: - * - * - version: Which version of the source map spec this map is following. - * - file: Optional. The generated file this source map is associated with. - * - sections: A list of section definitions. - * - * Each value under the "sections" field has two fields: - * - offset: The offset into the original specified at which this section - * begins to apply, defined as an object with a "line" and "column" - * field. - * - map: A source map definition. This source map could also be indexed, - * but doesn't have to be. - * - * Instead of the "map" field, it's also possible to have a "url" field - * specifying a URL to retrieve a source map from, but that's currently - * unsupported. - * - * Here's an example source map, taken from the source map spec[0], but - * modified to omit a section which uses the "url" field. + * Joins two paths/URLs. * - * { - * version : 3, - * file: "app.js", - * sections: [{ - * offset: {line:100, column:10}, - * map: { - * version : 3, - * file: "section.js", - * sources: ["foo.js", "bar.js"], - * names: ["src", "maps", "are", "fun"], - * mappings: "AAAA,E;;ABCDE;" - * } - * }], - * } + * @param aRoot The root path or URL. + * @param aPath The path or URL to be joined with the root. * - * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt + * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a + * scheme-relative URL: Then the scheme of aRoot, if any, is prepended + * first. + * - Otherwise aPath is a path. If aRoot is a URL, then its path portion + * is updated with the result and aRoot is returned. Otherwise the result + * is returned. + * - If aPath is absolute, the result is aPath. + * - Otherwise the two paths are joined with a slash. + * - Joining for example 'http://' and 'www.example.com' is also supported. */ -function IndexedSourceMapConsumer(aSourceMap) { - var sourceMap = aSourceMap; - if (typeof aSourceMap === 'string') { - sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); +function join(aRoot, aPath) { + if (aRoot === "") { + aRoot = "."; + } + if (aPath === "") { + aPath = "."; + } + var aPathUrl = urlParse(aPath); + var aRootUrl = urlParse(aRoot); + if (aRootUrl) { + aRoot = aRootUrl.path || '/'; } - var version = util.getArg(sourceMap, 'version'); - var sections = util.getArg(sourceMap, 'sections'); - - if (version != this._version) { - throw new Error('Unsupported version: ' + version); + // `join(foo, '//www.example.org')` + if (aPathUrl && !aPathUrl.scheme) { + if (aRootUrl) { + aPathUrl.scheme = aRootUrl.scheme; + } + return urlGenerate(aPathUrl); } - this._sources = new ArraySet(); - this._names = new ArraySet(); + if (aPathUrl || aPath.match(dataUrlRegexp)) { + return aPath; + } - var lastOffset = { - line: -1, - column: 0 - }; - this._sections = sections.map(function (s) { - if (s.url) { - // The url field will require support for asynchronicity. - // See https://github.com/mozilla/source-map/issues/16 - throw new Error('Support for url field in sections not implemented.'); - } - var offset = util.getArg(s, 'offset'); - var offsetLine = util.getArg(offset, 'line'); - var offsetColumn = util.getArg(offset, 'column'); + // `join('http://', 'www.example.com')` + if (aRootUrl && !aRootUrl.host && !aRootUrl.path) { + aRootUrl.host = aPath; + return urlGenerate(aRootUrl); + } - if (offsetLine < lastOffset.line || - (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) { - throw new Error('Section offsets must be ordered and non-overlapping.'); - } - lastOffset = offset; + var joined = aPath.charAt(0) === '/' + ? aPath + : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath); - return { - generatedOffset: { - // The offset fields are 0-based, but we use 1-based indices when - // encoding/decoding from VLQ. - generatedLine: offsetLine + 1, - generatedColumn: offsetColumn + 1 - }, - consumer: new SourceMapConsumer(util.getArg(s, 'map')) - } - }); + if (aRootUrl) { + aRootUrl.path = joined; + return urlGenerate(aRootUrl); + } + return joined; } +exports.join = join; -IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); -IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer; +exports.isAbsolute = function (aPath) { + return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp); +}; /** - * The version of the source mapping spec that we are consuming. + * Make a path relative to a URL or another path. + * + * @param aRoot The root path or URL. + * @param aPath The path or URL to be made relative to aRoot. */ -IndexedSourceMapConsumer.prototype._version = 3; +function relative(aRoot, aPath) { + if (aRoot === "") { + aRoot = "."; + } -/** - * The list of original sources. - */ -Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', { - get: function () { - var sources = []; - for (var i = 0; i < this._sections.length; i++) { - for (var j = 0; j < this._sections[i].consumer.sources.length; j++) { - sources.push(this._sections[i].consumer.sources[j]); - } + aRoot = aRoot.replace(/\/$/, ''); + + // It is possible for the path to be above the root. In this case, simply + // checking whether the root is a prefix of the path won't work. Instead, we + // need to remove components from the root one by one, until either we find + // a prefix that fits, or we run out of components to remove. + var level = 0; + while (aPath.indexOf(aRoot + '/') !== 0) { + var index = aRoot.lastIndexOf("/"); + if (index < 0) { + return aPath; } - return sources; + + // If the only part of the root that is left is the scheme (i.e. http://, + // file:///, etc.), one or more slashes (/), or simply nothing at all, we + // have exhausted all components, so the path is not relative to the root. + aRoot = aRoot.slice(0, index); + if (aRoot.match(/^([^\/]+:\/)?\/*$/)) { + return aPath; + } + + ++level; } -}); + + // Make sure we add a "../" for each component we removed from the root. + return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1); +} +exports.relative = relative; + +var supportsNullProto = (function () { + var obj = Object.create(null); + return !('__proto__' in obj); +}()); + +function identity (s) { + return s; +} /** - * Returns the original source, line, and column information for the generated - * source's line and column positions provided. The only argument is an object - * with the following properties: - * - * - line: The line number in the generated source. - * - column: The column number in the generated source. + * Because behavior goes wacky when you set `__proto__` on objects, we + * have to prefix all the strings in our set with an arbitrary character. * - * and an object is returned with the following properties: + * See https://github.com/mozilla/source-map/pull/31 and + * https://github.com/mozilla/source-map/issues/30 * - * - source: The original source file, or null. - * - line: The line number in the original source, or null. - * - column: The column number in the original source, or null. - * - name: The original identifier, or null. + * @param String aStr */ -IndexedSourceMapConsumer.prototype.originalPositionFor = - function IndexedSourceMapConsumer_originalPositionFor(aArgs) { - var needle = { - generatedLine: util.getArg(aArgs, 'line'), - generatedColumn: util.getArg(aArgs, 'column') - }; +function toSetString(aStr) { + if (isProtoString(aStr)) { + return '$' + aStr; + } - // Find the section containing the generated position we're trying to map - // to an original position. - var sectionIndex = binarySearch.search(needle, this._sections, - function(needle, section) { - var cmp = needle.generatedLine - section.generatedOffset.generatedLine; - if (cmp) { - return cmp; - } + return aStr; +} +exports.toSetString = supportsNullProto ? identity : toSetString; - return (needle.generatedColumn - - section.generatedOffset.generatedColumn); - }); - var section = this._sections[sectionIndex]; +function fromSetString(aStr) { + if (isProtoString(aStr)) { + return aStr.slice(1); + } - if (!section) { - return { - source: null, - line: null, - column: null, - name: null - }; + return aStr; +} +exports.fromSetString = supportsNullProto ? identity : fromSetString; + +function isProtoString(s) { + if (!s) { + return false; + } + + var length = s.length; + + if (length < 9 /* "__proto__".length */) { + return false; + } + + if (s.charCodeAt(length - 1) !== 95 /* '_' */ || + s.charCodeAt(length - 2) !== 95 /* '_' */ || + s.charCodeAt(length - 3) !== 111 /* 'o' */ || + s.charCodeAt(length - 4) !== 116 /* 't' */ || + s.charCodeAt(length - 5) !== 111 /* 'o' */ || + s.charCodeAt(length - 6) !== 114 /* 'r' */ || + s.charCodeAt(length - 7) !== 112 /* 'p' */ || + s.charCodeAt(length - 8) !== 95 /* '_' */ || + s.charCodeAt(length - 9) !== 95 /* '_' */) { + return false; + } + + for (var i = length - 10; i >= 0; i--) { + if (s.charCodeAt(i) !== 36 /* '$' */) { + return false; } + } - return section.consumer.originalPositionFor({ - line: needle.generatedLine - - (section.generatedOffset.generatedLine - 1), - column: needle.generatedColumn - - (section.generatedOffset.generatedLine === needle.generatedLine - ? section.generatedOffset.generatedColumn - 1 - : 0), - bias: aArgs.bias - }); - }; + return true; +} /** - * Return true if we have the source content for every source in the source - * map, false otherwise. + * Comparator between two mappings where the original positions are compared. + * + * Optionally pass in `true` as `onlyCompareGenerated` to consider two + * mappings with the same original source/line/column, but different generated + * line and column the same. Useful when searching for a mapping with a + * stubbed out mapping. */ -IndexedSourceMapConsumer.prototype.hasContentsOfAllSources = - function IndexedSourceMapConsumer_hasContentsOfAllSources() { - return this._sections.every(function (s) { - return s.consumer.hasContentsOfAllSources(); - }); - }; +function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) { + var cmp = mappingA.source - mappingB.source; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0 || onlyCompareOriginal) { + return cmp; + } -/** - * Returns the original source content. The only argument is the url of the - * original source file. Returns null if no original source content is - * available. - */ -IndexedSourceMapConsumer.prototype.sourceContentFor = - function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { - for (var i = 0; i < this._sections.length; i++) { - var section = this._sections[i]; + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0) { + return cmp; + } - var content = section.consumer.sourceContentFor(aSource, true); - if (content) { - return content; - } - } - if (nullOnMissing) { - return null; - } - else { - throw new Error('"' + aSource + '" is not in the SourceMap.'); - } - }; + cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + return mappingA.name - mappingB.name; +} +exports.compareByOriginalPositions = compareByOriginalPositions; /** - * Returns the generated line and column information for the original source, - * line, and column positions provided. The only argument is an object with - * the following properties: - * - * - source: The filename of the original source. - * - line: The line number in the original source. - * - column: The column number in the original source. - * - * and an object is returned with the following properties: + * Comparator between two mappings with deflated source and name indices where + * the generated positions are compared. * - * - line: The line number in the generated source, or null. - * - column: The column number in the generated source, or null. + * Optionally pass in `true` as `onlyCompareGenerated` to consider two + * mappings with the same generated line and column, but different + * source/name/original line and column the same. Useful when searching for a + * mapping with a stubbed out mapping. */ -IndexedSourceMapConsumer.prototype.generatedPositionFor = - function IndexedSourceMapConsumer_generatedPositionFor(aArgs) { - for (var i = 0; i < this._sections.length; i++) { - var section = this._sections[i]; +function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) { + var cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } - // Only consider this section if the requested source is in the list of - // sources of the consumer. - if (section.consumer.sources.indexOf(util.getArg(aArgs, 'source')) === -1) { - continue; - } - var generatedPosition = section.consumer.generatedPositionFor(aArgs); - if (generatedPosition) { - var ret = { - line: generatedPosition.line + - (section.generatedOffset.generatedLine - 1), - column: generatedPosition.column + - (section.generatedOffset.generatedLine === generatedPosition.line - ? section.generatedOffset.generatedColumn - 1 - : 0) - }; - return ret; - } - } + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0 || onlyCompareGenerated) { + return cmp; + } - return { - line: null, - column: null - }; - }; + cmp = mappingA.source - mappingB.source; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0) { + return cmp; + } + + return mappingA.name - mappingB.name; +} +exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated; + +function strcmp(aStr1, aStr2) { + if (aStr1 === aStr2) { + return 0; + } + + if (aStr1 > aStr2) { + return 1; + } + + return -1; +} /** - * Parse the mappings in a string in to a data structure which we can easily - * query (the ordered arrays in the `this.__generatedMappings` and - * `this.__originalMappings` properties). + * Comparator between two mappings with inflated source and name strings where + * the generated positions are compared. */ -IndexedSourceMapConsumer.prototype._parseMappings = - function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) { - this.__generatedMappings = []; - this.__originalMappings = []; - for (var i = 0; i < this._sections.length; i++) { - var section = this._sections[i]; - var sectionMappings = section.consumer._generatedMappings; - for (var j = 0; j < sectionMappings.length; j++) { - var mapping = sectionMappings[j]; - - var source = section.consumer._sources.at(mapping.source); - if (section.consumer.sourceRoot !== null) { - source = util.join(section.consumer.sourceRoot, source); - } - this._sources.add(source); - source = this._sources.indexOf(source); +function compareByGeneratedPositionsInflated(mappingA, mappingB) { + var cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } - var name = section.consumer._names.at(mapping.name); - this._names.add(name); - name = this._names.indexOf(name); + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0) { + return cmp; + } - // The mappings coming from the consumer for the section have - // generated positions relative to the start of the section, so we - // need to offset them to be relative to the start of the concatenated - // generated file. - var adjustedMapping = { - source: source, - generatedLine: mapping.generatedLine + - (section.generatedOffset.generatedLine - 1), - generatedColumn: mapping.generatedColumn + - (section.generatedOffset.generatedLine === mapping.generatedLine - ? section.generatedOffset.generatedColumn - 1 - : 0), - originalLine: mapping.originalLine, - originalColumn: mapping.originalColumn, - name: name - }; + cmp = strcmp(mappingA.source, mappingB.source); + if (cmp !== 0) { + return cmp; + } - this.__generatedMappings.push(adjustedMapping); - if (typeof adjustedMapping.originalLine === 'number') { - this.__originalMappings.push(adjustedMapping); - } - } - } + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } - quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated); - quickSort(this.__originalMappings, util.compareByOriginalPositions); - }; + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0) { + return cmp; + } -exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer; + return strcmp(mappingA.name, mappingB.name); +} +exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated; /***/ }), -/* 622 */ -/***/ (function(module, exports) { +/* 621 */ +/***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ /* @@ -72864,234 +71752,209 @@ exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer; * http://opensource.org/licenses/BSD-3-Clause */ -exports.GREATEST_LOWER_BOUND = 1; -exports.LEAST_UPPER_BOUND = 2; +var util = __webpack_require__(620); +var has = Object.prototype.hasOwnProperty; +var hasNativeMap = typeof Map !== "undefined"; /** - * Recursive implementation of binary search. - * - * @param aLow Indices here and lower do not contain the needle. - * @param aHigh Indices here and higher do not contain the needle. - * @param aNeedle The element being searched for. - * @param aHaystack The non-empty array being searched. - * @param aCompare Function which takes two elements and returns -1, 0, or 1. - * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or - * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the - * closest element that is smaller than or greater than the one we are - * searching for, respectively, if the exact element cannot be found. + * A data structure which is a combination of an array and a set. Adding a new + * member is O(1), testing for membership is O(1), and finding the index of an + * element is O(1). Removing elements from the set is not supported. Only + * strings are supported for membership. */ -function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) { - // This function terminates when one of the following is true: - // - // 1. We find the exact element we are looking for. - // - // 2. We did not find the exact element, but we can return the index of - // the next-closest element. - // - // 3. We did not find the exact element, and there is no next-closest - // element than the one we are searching for, so we return -1. - var mid = Math.floor((aHigh - aLow) / 2) + aLow; - var cmp = aCompare(aNeedle, aHaystack[mid], true); - if (cmp === 0) { - // Found the element we are looking for. - return mid; - } - else if (cmp > 0) { - // Our needle is greater than aHaystack[mid]. - if (aHigh - mid > 1) { - // The element is in the upper half. - return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias); - } +function ArraySet() { + this._array = []; + this._set = hasNativeMap ? new Map() : Object.create(null); +} - // The exact needle element was not found in this haystack. Determine if - // we are in termination case (3) or (2) and return the appropriate thing. - if (aBias == exports.LEAST_UPPER_BOUND) { - return aHigh < aHaystack.length ? aHigh : -1; - } else { - return mid; - } +/** + * Static method for creating ArraySet instances from an existing array. + */ +ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) { + var set = new ArraySet(); + for (var i = 0, len = aArray.length; i < len; i++) { + set.add(aArray[i], aAllowDuplicates); } - else { - // Our needle is less than aHaystack[mid]. - if (mid - aLow > 1) { - // The element is in the lower half. - return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias); - } + return set; +}; - // we are in termination case (3) or (2) and return the appropriate thing. - if (aBias == exports.LEAST_UPPER_BOUND) { - return mid; +/** + * Return how many unique items are in this ArraySet. If duplicates have been + * added, than those do not count towards the size. + * + * @returns Number + */ +ArraySet.prototype.size = function ArraySet_size() { + return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length; +}; + +/** + * Add the given string to this set. + * + * @param String aStr + */ +ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) { + var sStr = hasNativeMap ? aStr : util.toSetString(aStr); + var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr); + var idx = this._array.length; + if (!isDuplicate || aAllowDuplicates) { + this._array.push(aStr); + } + if (!isDuplicate) { + if (hasNativeMap) { + this._set.set(aStr, idx); } else { - return aLow < 0 ? -1 : aLow; + this._set[sStr] = idx; } } -} +}; /** - * This is an implementation of binary search which will always try and return - * the index of the closest element if there is no exact hit. This is because - * mappings between original and generated line/col pairs are single points, - * and there is an implicit region between each of them, so a miss just means - * that you aren't on the very start of a region. + * Is the given string a member of this set? * - * @param aNeedle The element you are looking for. - * @param aHaystack The array that is being searched. - * @param aCompare A function which takes the needle and an element in the - * array and returns -1, 0, or 1 depending on whether the needle is less - * than, equal to, or greater than the element, respectively. - * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or - * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the - * closest element that is smaller than or greater than the one we are - * searching for, respectively, if the exact element cannot be found. - * Defaults to 'binarySearch.GREATEST_LOWER_BOUND'. + * @param String aStr */ -exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { - if (aHaystack.length === 0) { - return -1; +ArraySet.prototype.has = function ArraySet_has(aStr) { + if (hasNativeMap) { + return this._set.has(aStr); + } else { + var sStr = util.toSetString(aStr); + return has.call(this._set, sStr); } +}; - var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, - aCompare, aBias || exports.GREATEST_LOWER_BOUND); - if (index < 0) { - return -1; +/** + * What is the index of the given string in the array? + * + * @param String aStr + */ +ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) { + if (hasNativeMap) { + var idx = this._set.get(aStr); + if (idx >= 0) { + return idx; + } + } else { + var sStr = util.toSetString(aStr); + if (has.call(this._set, sStr)) { + return this._set[sStr]; + } } - // We have found either the exact element, or the next-closest element than - // the one we are searching for. However, there may be more than one such - // element. Make sure we always return the smallest of these. - while (index - 1 >= 0) { - if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) { - break; - } - --index; + throw new Error('"' + aStr + '" is not in the set.'); +}; + +/** + * What is the element at the given index? + * + * @param Number aIdx + */ +ArraySet.prototype.at = function ArraySet_at(aIdx) { + if (aIdx >= 0 && aIdx < this._array.length) { + return this._array[aIdx]; } + throw new Error('No element indexed by ' + aIdx); +}; - return index; +/** + * Returns the array representation of this set (which has the proper indices + * indicated by indexOf). Note that this is a copy of the internal array used + * for storing the members so that no one can mess with internal state. + */ +ArraySet.prototype.toArray = function ArraySet_toArray() { + return this._array.slice(); }; +exports.ArraySet = ArraySet; + /***/ }), -/* 623 */ -/***/ (function(module, exports) { +/* 622 */ +/***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ /* - * Copyright 2011 Mozilla Foundation and contributors + * Copyright 2014 Mozilla Foundation and contributors * Licensed under the New BSD license. See LICENSE or: * http://opensource.org/licenses/BSD-3-Clause */ -// It turns out that some (most?) JavaScript engines don't self-host -// `Array.prototype.sort`. This makes sense because C++ will likely remain -// faster than JS when doing raw CPU-intensive sorting. However, when using a -// custom comparator function, calling back and forth between the VM's C++ and -// JIT'd JS is rather slow *and* loses JIT type information, resulting in -// worse generated code for the comparator function than would be optimal. In -// fact, when sorting with a comparator, these costs outweigh the benefits of -// sorting in C++. By using our own JS-implemented Quick Sort (below), we get -// a ~3500ms mean speed-up in `bench/bench.html`. +var util = __webpack_require__(620); /** - * Swap the elements indexed by `x` and `y` in the array `ary`. - * - * @param {Array} ary - * The array. - * @param {Number} x - * The index of the first item. - * @param {Number} y - * The index of the second item. + * Determine whether mappingB is after mappingA with respect to generated + * position. */ -function swap(ary, x, y) { - var temp = ary[x]; - ary[x] = ary[y]; - ary[y] = temp; +function generatedPositionAfter(mappingA, mappingB) { + // Optimized for most common case + var lineA = mappingA.generatedLine; + var lineB = mappingB.generatedLine; + var columnA = mappingA.generatedColumn; + var columnB = mappingB.generatedColumn; + return lineB > lineA || lineB == lineA && columnB >= columnA || + util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0; } /** - * Returns a random integer within the range `low .. high` inclusive. - * - * @param {Number} low - * The lower bound on the range. - * @param {Number} high - * The upper bound on the range. + * A data structure to provide a sorted view of accumulated mappings in a + * performance conscious manner. It trades a neglibable overhead in general + * case for a large speedup in case of mappings being added in order. */ -function randomIntInRange(low, high) { - return Math.round(low + (Math.random() * (high - low))); +function MappingList() { + this._array = []; + this._sorted = true; + // Serves as infimum + this._last = {generatedLine: -1, generatedColumn: 0}; } /** - * The Quick Sort algorithm. + * Iterate through internal items. This method takes the same arguments that + * `Array.prototype.forEach` takes. * - * @param {Array} ary - * An array to sort. - * @param {function} comparator - * Function to use to compare two items. - * @param {Number} p - * Start index of the array - * @param {Number} r - * End index of the array + * NOTE: The order of the mappings is NOT guaranteed. */ -function doQuickSort(ary, comparator, p, r) { - // If our lower bound is less than our upper bound, we (1) partition the - // array into two pieces and (2) recurse on each half. If it is not, this is - // the empty array and our base case. - - if (p < r) { - // (1) Partitioning. - // - // The partitioning chooses a pivot between `p` and `r` and moves all - // elements that are less than or equal to the pivot to the before it, and - // all the elements that are greater than it after it. The effect is that - // once partition is done, the pivot is in the exact place it will be when - // the array is put in sorted order, and it will not need to be moved - // again. This runs in O(n) time. - - // Always choose a random pivot so that an input array which is reverse - // sorted does not cause O(n^2) running time. - var pivotIndex = randomIntInRange(p, r); - var i = p - 1; - - swap(ary, pivotIndex, r); - var pivot = ary[r]; - - // Immediately after `j` is incremented in this loop, the following hold - // true: - // - // * Every element in `ary[p .. i]` is less than or equal to the pivot. - // - // * Every element in `ary[i+1 .. j-1]` is greater than the pivot. - for (var j = p; j < r; j++) { - if (comparator(ary[j], pivot) <= 0) { - i += 1; - swap(ary, i, j); - } - } - - swap(ary, i + 1, j); - var q = i + 1; - - // (2) Recurse on each half. +MappingList.prototype.unsortedForEach = + function MappingList_forEach(aCallback, aThisArg) { + this._array.forEach(aCallback, aThisArg); + }; - doQuickSort(ary, comparator, p, q - 1); - doQuickSort(ary, comparator, q + 1, r); +/** + * Add the given source mapping. + * + * @param Object aMapping + */ +MappingList.prototype.add = function MappingList_add(aMapping) { + if (generatedPositionAfter(this._last, aMapping)) { + this._last = aMapping; + this._array.push(aMapping); + } else { + this._sorted = false; + this._array.push(aMapping); } -} +}; /** - * Sort the given array in-place with the given comparator function. + * Returns the flat, sorted array of mappings. The mappings are sorted by + * generated position. * - * @param {Array} ary - * An array to sort. - * @param {function} comparator - * Function to use to compare two items. + * WARNING: This method returns internal data without copying, for + * performance. The return value must NOT be mutated, and should be treated as + * an immutable borrow. If you want to take ownership, you must make your own + * copy. */ -exports.quickSort = function (ary, comparator) { - doQuickSort(ary, comparator, 0, ary.length - 1); +MappingList.prototype.toArray = function MappingList_toArray() { + if (!this._sorted) { + this._array.sort(util.compareByGeneratedPositionsInflated); + this._sorted = true; + } + return this._array; }; +exports.MappingList = MappingList; + /***/ }), -/* 624 */ +/* 623 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -73101,2575 +71964,3112 @@ exports.quickSort = function (ary, comparator) { * http://opensource.org/licenses/BSD-3-Clause */ -var SourceMapGenerator = __webpack_require__(615).SourceMapGenerator; -var util = __webpack_require__(618); +var util = __webpack_require__(620); +var binarySearch = __webpack_require__(624); +var ArraySet = __webpack_require__(621).ArraySet; +var base64VLQ = __webpack_require__(618); +var quickSort = __webpack_require__(625).quickSort; -// Matches a Windows-style `\r\n` newline or a `\n` newline used by all other -// operating systems these days (capturing the result). -var REGEX_NEWLINE = /(\r?\n)/; +function SourceMapConsumer(aSourceMap) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); + } -// Newline character code for charCodeAt() comparisons -var NEWLINE_CODE = 10; + return sourceMap.sections != null + ? new IndexedSourceMapConsumer(sourceMap) + : new BasicSourceMapConsumer(sourceMap); +} -// Private symbol for identifying `SourceNode`s when multiple versions of -// the source-map library are loaded. This MUST NOT CHANGE across -// versions! -var isSourceNode = "$$$isSourceNode$$$"; +SourceMapConsumer.fromSourceMap = function(aSourceMap) { + return BasicSourceMapConsumer.fromSourceMap(aSourceMap); +} /** - * SourceNodes provide a way to abstract over interpolating/concatenating - * snippets of generated JavaScript source code while maintaining the line and - * column information associated with the original source code. - * - * @param aLine The original line number. - * @param aColumn The original column number. - * @param aSource The original source's filename. - * @param aChunks Optional. An array of strings which are snippets of - * generated JS, or other SourceNodes. - * @param aName The original identifier. + * The version of the source mapping spec that we are consuming. */ -function SourceNode(aLine, aColumn, aSource, aChunks, aName) { - this.children = []; - this.sourceContents = {}; - this.line = aLine == null ? null : aLine; - this.column = aColumn == null ? null : aColumn; - this.source = aSource == null ? null : aSource; - this.name = aName == null ? null : aName; - this[isSourceNode] = true; - if (aChunks != null) this.add(aChunks); -} +SourceMapConsumer.prototype._version = 3; + +// `__generatedMappings` and `__originalMappings` are arrays that hold the +// parsed mapping coordinates from the source map's "mappings" attribute. They +// are lazily instantiated, accessed via the `_generatedMappings` and +// `_originalMappings` getters respectively, and we only parse the mappings +// and create these arrays once queried for a source location. We jump through +// these hoops because there can be many thousands of mappings, and parsing +// them is expensive, so we only want to do it if we must. +// +// Each object in the arrays is of the form: +// +// { +// generatedLine: The line number in the generated code, +// generatedColumn: The column number in the generated code, +// source: The path to the original source file that generated this +// chunk of code, +// originalLine: The line number in the original source that +// corresponds to this chunk of generated code, +// originalColumn: The column number in the original source that +// corresponds to this chunk of generated code, +// name: The name of the original symbol which generated this chunk of +// code. +// } +// +// All properties except for `generatedLine` and `generatedColumn` can be +// `null`. +// +// `_generatedMappings` is ordered by the generated positions. +// +// `_originalMappings` is ordered by the original positions. + +SourceMapConsumer.prototype.__generatedMappings = null; +Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', { + get: function () { + if (!this.__generatedMappings) { + this._parseMappings(this._mappings, this.sourceRoot); + } + + return this.__generatedMappings; + } +}); + +SourceMapConsumer.prototype.__originalMappings = null; +Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', { + get: function () { + if (!this.__originalMappings) { + this._parseMappings(this._mappings, this.sourceRoot); + } + + return this.__originalMappings; + } +}); + +SourceMapConsumer.prototype._charIsMappingSeparator = + function SourceMapConsumer_charIsMappingSeparator(aStr, index) { + var c = aStr.charAt(index); + return c === ";" || c === ","; + }; /** - * Creates a SourceNode from generated code and a SourceMapConsumer. + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ +SourceMapConsumer.prototype._parseMappings = + function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { + throw new Error("Subclasses must implement _parseMappings"); + }; + +SourceMapConsumer.GENERATED_ORDER = 1; +SourceMapConsumer.ORIGINAL_ORDER = 2; + +SourceMapConsumer.GREATEST_LOWER_BOUND = 1; +SourceMapConsumer.LEAST_UPPER_BOUND = 2; + +/** + * Iterate over each mapping between an original source/line/column and a + * generated line/column in this source map. * - * @param aGeneratedCode The generated code - * @param aSourceMapConsumer The SourceMap for the generated code - * @param aRelativePath Optional. The path that relative sources in the - * SourceMapConsumer should be relative to. + * @param Function aCallback + * The function that is called with each mapping. + * @param Object aContext + * Optional. If specified, this object will be the value of `this` every + * time that `aCallback` is called. + * @param aOrder + * Either `SourceMapConsumer.GENERATED_ORDER` or + * `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to + * iterate over the mappings sorted by the generated file's line/column + * order or the original's source/line/column order, respectively. Defaults to + * `SourceMapConsumer.GENERATED_ORDER`. */ -SourceNode.fromStringWithSourceMap = - function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) { - // The SourceNode we want to fill with the generated code - // and the SourceMap - var node = new SourceNode(); +SourceMapConsumer.prototype.eachMapping = + function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) { + var context = aContext || null; + var order = aOrder || SourceMapConsumer.GENERATED_ORDER; - // All even indices of this array are one line of the generated code, - // while all odd indices are the newlines between two adjacent lines - // (since `REGEX_NEWLINE` captures its match). - // Processed fragments are accessed by calling `shiftNextLine`. - var remainingLines = aGeneratedCode.split(REGEX_NEWLINE); - var remainingLinesIndex = 0; - var shiftNextLine = function() { - var lineContents = getNextLine(); - // The last line of a file might not have a newline. - var newLine = getNextLine() || ""; - return lineContents + newLine; + var mappings; + switch (order) { + case SourceMapConsumer.GENERATED_ORDER: + mappings = this._generatedMappings; + break; + case SourceMapConsumer.ORIGINAL_ORDER: + mappings = this._originalMappings; + break; + default: + throw new Error("Unknown order of iteration."); + } - function getNextLine() { - return remainingLinesIndex < remainingLines.length ? - remainingLines[remainingLinesIndex++] : undefined; + var sourceRoot = this.sourceRoot; + mappings.map(function (mapping) { + var source = mapping.source === null ? null : this._sources.at(mapping.source); + if (source != null && sourceRoot != null) { + source = util.join(sourceRoot, source); } - }; + return { + source: source, + generatedLine: mapping.generatedLine, + generatedColumn: mapping.generatedColumn, + originalLine: mapping.originalLine, + originalColumn: mapping.originalColumn, + name: mapping.name === null ? null : this._names.at(mapping.name) + }; + }, this).forEach(aCallback, context); + }; - // We need to remember the position of "remainingLines" - var lastGeneratedLine = 1, lastGeneratedColumn = 0; +/** + * Returns all generated line and column information for the original source, + * line, and column provided. If no column is provided, returns all mappings + * corresponding to a either the line we are searching for or the next + * closest line that has any mappings. Otherwise, returns all mappings + * corresponding to the given line and either the column we are searching for + * or the next closest column that has any offsets. + * + * The only argument is an object with the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. + * - column: Optional. the column number in the original source. + * + * and an array of objects is returned, each with the following properties: + * + * - line: The line number in the generated source, or null. + * - column: The column number in the generated source, or null. + */ +SourceMapConsumer.prototype.allGeneratedPositionsFor = + function SourceMapConsumer_allGeneratedPositionsFor(aArgs) { + var line = util.getArg(aArgs, 'line'); - // The generate SourceNodes we need a code range. - // To extract it current and last mapping is used. - // Here we store the last mapping. - var lastMapping = null; + // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping + // returns the index of the closest mapping less than the needle. By + // setting needle.originalColumn to 0, we thus find the last mapping for + // the given line, provided such a mapping exists. + var needle = { + source: util.getArg(aArgs, 'source'), + originalLine: line, + originalColumn: util.getArg(aArgs, 'column', 0) + }; - aSourceMapConsumer.eachMapping(function (mapping) { - if (lastMapping !== null) { - // We add the code from "lastMapping" to "mapping": - // First check if there is a new line in between. - if (lastGeneratedLine < mapping.generatedLine) { - // Associate first line with "lastMapping" - addMappingWithCode(lastMapping, shiftNextLine()); - lastGeneratedLine++; - lastGeneratedColumn = 0; - // The remaining code is added without mapping - } else { - // There is no new line in between. - // Associate the code between "lastGeneratedColumn" and - // "mapping.generatedColumn" with "lastMapping" - var nextLine = remainingLines[remainingLinesIndex]; - var code = nextLine.substr(0, mapping.generatedColumn - - lastGeneratedColumn); - remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn - - lastGeneratedColumn); - lastGeneratedColumn = mapping.generatedColumn; - addMappingWithCode(lastMapping, code); - // No more remaining code, continue - lastMapping = mapping; - return; - } - } - // We add the generated code until the first mapping - // to the SourceNode without any mapping. - // Each line is added as separate string. - while (lastGeneratedLine < mapping.generatedLine) { - node.add(shiftNextLine()); - lastGeneratedLine++; - } - if (lastGeneratedColumn < mapping.generatedColumn) { - var nextLine = remainingLines[remainingLinesIndex]; - node.add(nextLine.substr(0, mapping.generatedColumn)); - remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn); - lastGeneratedColumn = mapping.generatedColumn; - } - lastMapping = mapping; - }, this); - // We have processed all mappings. - if (remainingLinesIndex < remainingLines.length) { - if (lastMapping) { - // Associate the remaining code in the current line with "lastMapping" - addMappingWithCode(lastMapping, shiftNextLine()); - } - // and add the remaining lines without any mapping - node.add(remainingLines.splice(remainingLinesIndex).join("")); + if (this.sourceRoot != null) { + needle.source = util.relative(this.sourceRoot, needle.source); + } + if (!this._sources.has(needle.source)) { + return []; } + needle.source = this._sources.indexOf(needle.source); - // Copy sourcesContent into SourceNode - aSourceMapConsumer.sources.forEach(function (sourceFile) { - var content = aSourceMapConsumer.sourceContentFor(sourceFile); - if (content != null) { - if (aRelativePath != null) { - sourceFile = util.join(aRelativePath, sourceFile); - } - node.setSourceContent(sourceFile, content); - } - }); + var mappings = []; - return node; + var index = this._findMapping(needle, + this._originalMappings, + "originalLine", + "originalColumn", + util.compareByOriginalPositions, + binarySearch.LEAST_UPPER_BOUND); + if (index >= 0) { + var mapping = this._originalMappings[index]; - function addMappingWithCode(mapping, code) { - if (mapping === null || mapping.source === undefined) { - node.add(code); + if (aArgs.column === undefined) { + var originalLine = mapping.originalLine; + + // Iterate until either we run out of mappings, or we run into + // a mapping for a different line than the one we found. Since + // mappings are sorted, this is guaranteed to find all mappings for + // the line we found. + while (mapping && mapping.originalLine === originalLine) { + mappings.push({ + line: util.getArg(mapping, 'generatedLine', null), + column: util.getArg(mapping, 'generatedColumn', null), + lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) + }); + + mapping = this._originalMappings[++index]; + } } else { - var source = aRelativePath - ? util.join(aRelativePath, mapping.source) - : mapping.source; - node.add(new SourceNode(mapping.originalLine, - mapping.originalColumn, - source, - code, - mapping.name)); + var originalColumn = mapping.originalColumn; + + // Iterate until either we run out of mappings, or we run into + // a mapping for a different line than the one we were searching for. + // Since mappings are sorted, this is guaranteed to find all mappings for + // the line we are searching for. + while (mapping && + mapping.originalLine === line && + mapping.originalColumn == originalColumn) { + mappings.push({ + line: util.getArg(mapping, 'generatedLine', null), + column: util.getArg(mapping, 'generatedColumn', null), + lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) + }); + + mapping = this._originalMappings[++index]; + } } } + + return mappings; }; -/** - * Add a chunk of generated JS to this source node. - * - * @param aChunk A string snippet of generated JS code, another instance of - * SourceNode, or an array where each member is one of those things. - */ -SourceNode.prototype.add = function SourceNode_add(aChunk) { - if (Array.isArray(aChunk)) { - aChunk.forEach(function (chunk) { - this.add(chunk); - }, this); - } - else if (aChunk[isSourceNode] || typeof aChunk === "string") { - if (aChunk) { - this.children.push(aChunk); - } - } - else { - throw new TypeError( - "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk - ); - } - return this; -}; +exports.SourceMapConsumer = SourceMapConsumer; /** - * Add a chunk of generated JS to the beginning of this source node. + * A BasicSourceMapConsumer instance represents a parsed source map which we can + * query for information about the original file positions by giving it a file + * position in the generated source. * - * @param aChunk A string snippet of generated JS code, another instance of - * SourceNode, or an array where each member is one of those things. + * The only parameter is the raw source map (either as a JSON string, or + * already parsed to an object). According to the spec, source maps have the + * following attributes: + * + * - version: Which version of the source map spec this map is following. + * - sources: An array of URLs to the original source files. + * - names: An array of identifiers which can be referrenced by individual mappings. + * - sourceRoot: Optional. The URL root from which all sources are relative. + * - sourcesContent: Optional. An array of contents of the original source files. + * - mappings: A string of base64 VLQs which contain the actual mappings. + * - file: Optional. The generated file this source map is associated with. + * + * Here is an example source map, taken from the source map spec[0]: + * + * { + * version : 3, + * file: "out.js", + * sourceRoot : "", + * sources: ["foo.js", "bar.js"], + * names: ["src", "maps", "are", "fun"], + * mappings: "AA,AB;;ABCDE;" + * } + * + * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1# */ -SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) { - if (Array.isArray(aChunk)) { - for (var i = aChunk.length-1; i >= 0; i--) { - this.prepend(aChunk[i]); - } - } - else if (aChunk[isSourceNode] || typeof aChunk === "string") { - this.children.unshift(aChunk); +function BasicSourceMapConsumer(aSourceMap) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); } - else { - throw new TypeError( - "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk - ); + + var version = util.getArg(sourceMap, 'version'); + var sources = util.getArg(sourceMap, 'sources'); + // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which + // requires the array) to play nice here. + var names = util.getArg(sourceMap, 'names', []); + var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null); + var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null); + var mappings = util.getArg(sourceMap, 'mappings'); + var file = util.getArg(sourceMap, 'file', null); + + // Once again, Sass deviates from the spec and supplies the version as a + // string rather than a number, so we use loose equality checking here. + if (version != this._version) { + throw new Error('Unsupported version: ' + version); } - return this; -}; + + sources = sources + .map(String) + // Some source maps produce relative source paths like "./foo.js" instead of + // "foo.js". Normalize these first so that future comparisons will succeed. + // See bugzil.la/1090768. + .map(util.normalize) + // Always ensure that absolute sources are internally stored relative to + // the source root, if the source root is absolute. Not doing this would + // be particularly problematic when the source root is a prefix of the + // source (valid, but why??). See github issue #199 and bugzil.la/1188982. + .map(function (source) { + return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source) + ? util.relative(sourceRoot, source) + : source; + }); + + // Pass `true` below to allow duplicate names and sources. While source maps + // are intended to be compressed and deduplicated, the TypeScript compiler + // sometimes generates source maps with duplicates in them. See Github issue + // #72 and bugzil.la/889492. + this._names = ArraySet.fromArray(names.map(String), true); + this._sources = ArraySet.fromArray(sources, true); + + this.sourceRoot = sourceRoot; + this.sourcesContent = sourcesContent; + this._mappings = mappings; + this.file = file; +} + +BasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); +BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer; /** - * Walk over the tree of JS snippets in this node and its children. The - * walking function is called once for each snippet of JS and is passed that - * snippet and the its original associated source's line/column location. + * Create a BasicSourceMapConsumer from a SourceMapGenerator. * - * @param aFn The traversal function. + * @param SourceMapGenerator aSourceMap + * The source map that will be consumed. + * @returns BasicSourceMapConsumer */ -SourceNode.prototype.walk = function SourceNode_walk(aFn) { - var chunk; - for (var i = 0, len = this.children.length; i < len; i++) { - chunk = this.children[i]; - if (chunk[isSourceNode]) { - chunk.walk(aFn); - } - else { - if (chunk !== '') { - aFn(chunk, { source: this.source, - line: this.line, - column: this.column, - name: this.name }); +BasicSourceMapConsumer.fromSourceMap = + function SourceMapConsumer_fromSourceMap(aSourceMap) { + var smc = Object.create(BasicSourceMapConsumer.prototype); + + var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true); + var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true); + smc.sourceRoot = aSourceMap._sourceRoot; + smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(), + smc.sourceRoot); + smc.file = aSourceMap._file; + + // Because we are modifying the entries (by converting string sources and + // names to indices into the sources and names ArraySets), we have to make + // a copy of the entry or else bad things happen. Shared mutable state + // strikes again! See github issue #191. + + var generatedMappings = aSourceMap._mappings.toArray().slice(); + var destGeneratedMappings = smc.__generatedMappings = []; + var destOriginalMappings = smc.__originalMappings = []; + + for (var i = 0, length = generatedMappings.length; i < length; i++) { + var srcMapping = generatedMappings[i]; + var destMapping = new Mapping; + destMapping.generatedLine = srcMapping.generatedLine; + destMapping.generatedColumn = srcMapping.generatedColumn; + + if (srcMapping.source) { + destMapping.source = sources.indexOf(srcMapping.source); + destMapping.originalLine = srcMapping.originalLine; + destMapping.originalColumn = srcMapping.originalColumn; + + if (srcMapping.name) { + destMapping.name = names.indexOf(srcMapping.name); + } + + destOriginalMappings.push(destMapping); } + + destGeneratedMappings.push(destMapping); } - } -}; + + quickSort(smc.__originalMappings, util.compareByOriginalPositions); + + return smc; + }; /** - * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between - * each of `this.children`. - * - * @param aSep The separator. + * The version of the source mapping spec that we are consuming. */ -SourceNode.prototype.join = function SourceNode_join(aSep) { - var newChildren; - var i; - var len = this.children.length; - if (len > 0) { - newChildren = []; - for (i = 0; i < len-1; i++) { - newChildren.push(this.children[i]); - newChildren.push(aSep); - } - newChildren.push(this.children[i]); - this.children = newChildren; - } - return this; -}; +BasicSourceMapConsumer.prototype._version = 3; /** - * Call String.prototype.replace on the very right-most source snippet. Useful - * for trimming whitespace from the end of a source node, etc. - * - * @param aPattern The pattern to replace. - * @param aReplacement The thing to replace the pattern with. + * The list of original sources. */ -SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) { - var lastChild = this.children[this.children.length - 1]; - if (lastChild[isSourceNode]) { - lastChild.replaceRight(aPattern, aReplacement); - } - else if (typeof lastChild === 'string') { - this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement); - } - else { - this.children.push(''.replace(aPattern, aReplacement)); +Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', { + get: function () { + return this._sources.toArray().map(function (s) { + return this.sourceRoot != null ? util.join(this.sourceRoot, s) : s; + }, this); } - return this; -}; +}); /** - * Set the source content for a source file. This will be added to the SourceMapGenerator - * in the sourcesContent field. - * - * @param aSourceFile The filename of the source file - * @param aSourceContent The content of the source file + * Provide the JIT with a nice shape / hidden class. */ -SourceNode.prototype.setSourceContent = - function SourceNode_setSourceContent(aSourceFile, aSourceContent) { - this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent; - }; +function Mapping() { + this.generatedLine = 0; + this.generatedColumn = 0; + this.source = null; + this.originalLine = null; + this.originalColumn = null; + this.name = null; +} /** - * Walk over the tree of SourceNodes. The walking function is called for each - * source file content and is passed the filename and source content. - * - * @param aFn The traversal function. + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). */ -SourceNode.prototype.walkSourceContents = - function SourceNode_walkSourceContents(aFn) { - for (var i = 0, len = this.children.length; i < len; i++) { - if (this.children[i][isSourceNode]) { - this.children[i].walkSourceContents(aFn); +BasicSourceMapConsumer.prototype._parseMappings = + function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { + var generatedLine = 1; + var previousGeneratedColumn = 0; + var previousOriginalLine = 0; + var previousOriginalColumn = 0; + var previousSource = 0; + var previousName = 0; + var length = aStr.length; + var index = 0; + var cachedSegments = {}; + var temp = {}; + var originalMappings = []; + var generatedMappings = []; + var mapping, str, segment, end, value; + + while (index < length) { + if (aStr.charAt(index) === ';') { + generatedLine++; + index++; + previousGeneratedColumn = 0; } - } + else if (aStr.charAt(index) === ',') { + index++; + } + else { + mapping = new Mapping(); + mapping.generatedLine = generatedLine; - var sources = Object.keys(this.sourceContents); - for (var i = 0, len = sources.length; i < len; i++) { - aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]); + // Because each offset is encoded relative to the previous one, + // many segments often have the same encoding. We can exploit this + // fact by caching the parsed variable length fields of each segment, + // allowing us to avoid a second parse if we encounter the same + // segment again. + for (end = index; end < length; end++) { + if (this._charIsMappingSeparator(aStr, end)) { + break; + } + } + str = aStr.slice(index, end); + + segment = cachedSegments[str]; + if (segment) { + index += str.length; + } else { + segment = []; + while (index < end) { + base64VLQ.decode(aStr, index, temp); + value = temp.value; + index = temp.rest; + segment.push(value); + } + + if (segment.length === 2) { + throw new Error('Found a source, but no line and column'); + } + + if (segment.length === 3) { + throw new Error('Found a source and line, but no column'); + } + + cachedSegments[str] = segment; + } + + // Generated column. + mapping.generatedColumn = previousGeneratedColumn + segment[0]; + previousGeneratedColumn = mapping.generatedColumn; + + if (segment.length > 1) { + // Original source. + mapping.source = previousSource + segment[1]; + previousSource += segment[1]; + + // Original line. + mapping.originalLine = previousOriginalLine + segment[2]; + previousOriginalLine = mapping.originalLine; + // Lines are stored 0-based + mapping.originalLine += 1; + + // Original column. + mapping.originalColumn = previousOriginalColumn + segment[3]; + previousOriginalColumn = mapping.originalColumn; + + if (segment.length > 4) { + // Original name. + mapping.name = previousName + segment[4]; + previousName += segment[4]; + } + } + + generatedMappings.push(mapping); + if (typeof mapping.originalLine === 'number') { + originalMappings.push(mapping); + } + } } + + quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated); + this.__generatedMappings = generatedMappings; + + quickSort(originalMappings, util.compareByOriginalPositions); + this.__originalMappings = originalMappings; }; /** - * Return the string representation of this source node. Walks over the tree - * and concatenates all the various snippets together to one string. + * Find the mapping that best matches the hypothetical "needle" mapping that + * we are searching for in the given "haystack" of mappings. */ -SourceNode.prototype.toString = function SourceNode_toString() { - var str = ""; - this.walk(function (chunk) { - str += chunk; - }); - return str; -}; +BasicSourceMapConsumer.prototype._findMapping = + function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName, + aColumnName, aComparator, aBias) { + // To return the position we are searching for, we must first find the + // mapping for the given position and then return the opposite position it + // points to. Because the mappings are sorted, we can use binary search to + // find the best mapping. + + if (aNeedle[aLineName] <= 0) { + throw new TypeError('Line must be greater than or equal to 1, got ' + + aNeedle[aLineName]); + } + if (aNeedle[aColumnName] < 0) { + throw new TypeError('Column must be greater than or equal to 0, got ' + + aNeedle[aColumnName]); + } + + return binarySearch.search(aNeedle, aMappings, aComparator, aBias); + }; /** - * Returns the string representation of this source node along with a source - * map. + * Compute the last column for each generated mapping. The last column is + * inclusive. */ -SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) { - var generated = { - code: "", - line: 1, - column: 0 - }; - var map = new SourceMapGenerator(aArgs); - var sourceMappingActive = false; - var lastOriginalSource = null; - var lastOriginalLine = null; - var lastOriginalColumn = null; - var lastOriginalName = null; - this.walk(function (chunk, original) { - generated.code += chunk; - if (original.source !== null - && original.line !== null - && original.column !== null) { - if(lastOriginalSource !== original.source - || lastOriginalLine !== original.line - || lastOriginalColumn !== original.column - || lastOriginalName !== original.name) { - map.addMapping({ - source: original.source, - original: { - line: original.line, - column: original.column - }, - generated: { - line: generated.line, - column: generated.column - }, - name: original.name - }); - } - lastOriginalSource = original.source; - lastOriginalLine = original.line; - lastOriginalColumn = original.column; - lastOriginalName = original.name; - sourceMappingActive = true; - } else if (sourceMappingActive) { - map.addMapping({ - generated: { - line: generated.line, - column: generated.column - } - }); - lastOriginalSource = null; - sourceMappingActive = false; - } - for (var idx = 0, length = chunk.length; idx < length; idx++) { - if (chunk.charCodeAt(idx) === NEWLINE_CODE) { - generated.line++; - generated.column = 0; - // Mappings end at eol - if (idx + 1 === length) { - lastOriginalSource = null; - sourceMappingActive = false; - } else if (sourceMappingActive) { - map.addMapping({ - source: original.source, - original: { - line: original.line, - column: original.column - }, - generated: { - line: generated.line, - column: generated.column - }, - name: original.name - }); +BasicSourceMapConsumer.prototype.computeColumnSpans = + function SourceMapConsumer_computeColumnSpans() { + for (var index = 0; index < this._generatedMappings.length; ++index) { + var mapping = this._generatedMappings[index]; + + // Mappings do not contain a field for the last generated columnt. We + // can come up with an optimistic estimate, however, by assuming that + // mappings are contiguous (i.e. given two consecutive mappings, the + // first mapping ends where the second one starts). + if (index + 1 < this._generatedMappings.length) { + var nextMapping = this._generatedMappings[index + 1]; + + if (mapping.generatedLine === nextMapping.generatedLine) { + mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1; + continue; } - } else { - generated.column++; } - } - }); - this.walkSourceContents(function (sourceFile, sourceContent) { - map.setSourceContent(sourceFile, sourceContent); - }); - return { code: generated.code, map: map }; -}; + // The last mapping for each line spans the entire line. + mapping.lastGeneratedColumn = Infinity; + } + }; -exports.SourceNode = SourceNode; +/** + * Returns the original source, line, and column information for the generated + * source's line and column positions provided. The only argument is an object + * with the following properties: + * + * - line: The line number in the generated source. + * - column: The column number in the generated source. + * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or + * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. + * + * and an object is returned with the following properties: + * + * - source: The original source file, or null. + * - line: The line number in the original source, or null. + * - column: The column number in the original source, or null. + * - name: The original identifier, or null. + */ +BasicSourceMapConsumer.prototype.originalPositionFor = + function SourceMapConsumer_originalPositionFor(aArgs) { + var needle = { + generatedLine: util.getArg(aArgs, 'line'), + generatedColumn: util.getArg(aArgs, 'column') + }; + var index = this._findMapping( + needle, + this._generatedMappings, + "generatedLine", + "generatedColumn", + util.compareByGeneratedPositionsDeflated, + util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) + ); -/***/ }), -/* 625 */ -/***/ (function(module, exports, __webpack_require__) { + if (index >= 0) { + var mapping = this._generatedMappings[index]; -// Copyright 2014, 2015, 2016, 2017 Simon Lydell -// X11 (“MIT”) Licensed. (See LICENSE.) + if (mapping.generatedLine === needle.generatedLine) { + var source = util.getArg(mapping, 'source', null); + if (source !== null) { + source = this._sources.at(source); + if (this.sourceRoot != null) { + source = util.join(this.sourceRoot, source); + } + } + var name = util.getArg(mapping, 'name', null); + if (name !== null) { + name = this._names.at(name); + } + return { + source: source, + line: util.getArg(mapping, 'originalLine', null), + column: util.getArg(mapping, 'originalColumn', null), + name: name + }; + } + } -var sourceMappingURL = __webpack_require__(626) -var resolveUrl = __webpack_require__(627) -var decodeUriComponent = __webpack_require__(628) -var urix = __webpack_require__(630) -var atob = __webpack_require__(631) + return { + source: null, + line: null, + column: null, + name: null + }; + }; +/** + * Return true if we have the source content for every source in the source + * map, false otherwise. + */ +BasicSourceMapConsumer.prototype.hasContentsOfAllSources = + function BasicSourceMapConsumer_hasContentsOfAllSources() { + if (!this.sourcesContent) { + return false; + } + return this.sourcesContent.length >= this._sources.size() && + !this.sourcesContent.some(function (sc) { return sc == null; }); + }; +/** + * Returns the original source content. The only argument is the url of the + * original source file. Returns null if no original source content is + * available. + */ +BasicSourceMapConsumer.prototype.sourceContentFor = + function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { + if (!this.sourcesContent) { + return null; + } -function callbackAsync(callback, error, result) { - setImmediate(function() { callback(error, result) }) -} + if (this.sourceRoot != null) { + aSource = util.relative(this.sourceRoot, aSource); + } -function parseMapToJSON(string, data) { - try { - return JSON.parse(string.replace(/^\)\]\}'/, "")) - } catch (error) { - error.sourceMapData = data - throw error - } -} + if (this._sources.has(aSource)) { + return this.sourcesContent[this._sources.indexOf(aSource)]; + } -function readSync(read, url, data) { - var readUrl = decodeUriComponent(url) - try { - return String(read(readUrl)) - } catch (error) { - error.sourceMapData = data - throw error - } -} + var url; + if (this.sourceRoot != null + && (url = util.urlParse(this.sourceRoot))) { + // XXX: file:// URIs and absolute paths lead to unexpected behavior for + // many users. We can help them out when they expect file:// URIs to + // behave like it would if they were running a local HTTP server. See + // https://bugzilla.mozilla.org/show_bug.cgi?id=885597. + var fileUriAbsPath = aSource.replace(/^file:\/\//, ""); + if (url.scheme == "file" + && this._sources.has(fileUriAbsPath)) { + return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)] + } + if ((!url.path || url.path == "/") + && this._sources.has("/" + aSource)) { + return this.sourcesContent[this._sources.indexOf("/" + aSource)]; + } + } + // This function is used recursively from + // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we + // don't want to throw if we can't find the source - we just want to + // return null, so we provide a flag to exit gracefully. + if (nullOnMissing) { + return null; + } + else { + throw new Error('"' + aSource + '" is not in the SourceMap.'); + } + }; -function resolveSourceMap(code, codeUrl, read, callback) { - var mapData - try { - mapData = resolveSourceMapHelper(code, codeUrl) - } catch (error) { - return callbackAsync(callback, error) - } - if (!mapData || mapData.map) { - return callbackAsync(callback, null, mapData) - } - var readUrl = decodeUriComponent(mapData.url) - read(readUrl, function(error, result) { - if (error) { - error.sourceMapData = mapData - return callback(error) +/** + * Returns the generated line and column information for the original source, + * line, and column positions provided. The only argument is an object with + * the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. + * - column: The column number in the original source. + * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or + * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. + * + * and an object is returned with the following properties: + * + * - line: The line number in the generated source, or null. + * - column: The column number in the generated source, or null. + */ +BasicSourceMapConsumer.prototype.generatedPositionFor = + function SourceMapConsumer_generatedPositionFor(aArgs) { + var source = util.getArg(aArgs, 'source'); + if (this.sourceRoot != null) { + source = util.relative(this.sourceRoot, source); } - mapData.map = String(result) - try { - mapData.map = parseMapToJSON(mapData.map, mapData) - } catch (error) { - return callback(error) + if (!this._sources.has(source)) { + return { + line: null, + column: null, + lastColumn: null + }; } - callback(null, mapData) - }) -} - -function resolveSourceMapSync(code, codeUrl, read) { - var mapData = resolveSourceMapHelper(code, codeUrl) - if (!mapData || mapData.map) { - return mapData - } - mapData.map = readSync(read, mapData.url, mapData) - mapData.map = parseMapToJSON(mapData.map, mapData) - return mapData -} + source = this._sources.indexOf(source); -var dataUriRegex = /^data:([^,;]*)(;[^,;]*)*(?:,(.*))?$/ -var jsonMimeTypeRegex = /^(?:application|text)\/json$/ + var needle = { + source: source, + originalLine: util.getArg(aArgs, 'line'), + originalColumn: util.getArg(aArgs, 'column') + }; -function resolveSourceMapHelper(code, codeUrl) { - codeUrl = urix(codeUrl) + var index = this._findMapping( + needle, + this._originalMappings, + "originalLine", + "originalColumn", + util.compareByOriginalPositions, + util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) + ); - var url = sourceMappingURL.getFrom(code) - if (!url) { - return null - } + if (index >= 0) { + var mapping = this._originalMappings[index]; - var dataUri = url.match(dataUriRegex) - if (dataUri) { - var mimeType = dataUri[1] - var lastParameter = dataUri[2] || "" - var encoded = dataUri[3] || "" - var data = { - sourceMappingURL: url, - url: null, - sourcesRelativeTo: codeUrl, - map: encoded - } - if (!jsonMimeTypeRegex.test(mimeType)) { - var error = new Error("Unuseful data uri mime type: " + (mimeType || "text/plain")) - error.sourceMapData = data - throw error + if (mapping.source === needle.source) { + return { + line: util.getArg(mapping, 'generatedLine', null), + column: util.getArg(mapping, 'generatedColumn', null), + lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) + }; + } } - data.map = parseMapToJSON( - lastParameter === ";base64" ? atob(encoded) : decodeURIComponent(encoded), - data - ) - return data - } - - var mapUrl = resolveUrl(codeUrl, url) - return { - sourceMappingURL: url, - url: mapUrl, - sourcesRelativeTo: mapUrl, - map: null - } -} - + return { + line: null, + column: null, + lastColumn: null + }; + }; -function resolveSources(map, mapUrl, read, options, callback) { - if (typeof options === "function") { - callback = options - options = {} - } - var pending = map.sources ? map.sources.length : 0 - var result = { - sourcesResolved: [], - sourcesContent: [] - } - - if (pending === 0) { - callbackAsync(callback, null, result) - return - } +exports.BasicSourceMapConsumer = BasicSourceMapConsumer; - var done = function() { - pending-- - if (pending === 0) { - callback(null, result) - } +/** + * An IndexedSourceMapConsumer instance represents a parsed source map which + * we can query for information. It differs from BasicSourceMapConsumer in + * that it takes "indexed" source maps (i.e. ones with a "sections" field) as + * input. + * + * The only parameter is a raw source map (either as a JSON string, or already + * parsed to an object). According to the spec for indexed source maps, they + * have the following attributes: + * + * - version: Which version of the source map spec this map is following. + * - file: Optional. The generated file this source map is associated with. + * - sections: A list of section definitions. + * + * Each value under the "sections" field has two fields: + * - offset: The offset into the original specified at which this section + * begins to apply, defined as an object with a "line" and "column" + * field. + * - map: A source map definition. This source map could also be indexed, + * but doesn't have to be. + * + * Instead of the "map" field, it's also possible to have a "url" field + * specifying a URL to retrieve a source map from, but that's currently + * unsupported. + * + * Here's an example source map, taken from the source map spec[0], but + * modified to omit a section which uses the "url" field. + * + * { + * version : 3, + * file: "app.js", + * sections: [{ + * offset: {line:100, column:10}, + * map: { + * version : 3, + * file: "section.js", + * sources: ["foo.js", "bar.js"], + * names: ["src", "maps", "are", "fun"], + * mappings: "AAAA,E;;ABCDE;" + * } + * }], + * } + * + * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt + */ +function IndexedSourceMapConsumer(aSourceMap) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); } - resolveSourcesHelper(map, mapUrl, options, function(fullUrl, sourceContent, index) { - result.sourcesResolved[index] = fullUrl - if (typeof sourceContent === "string") { - result.sourcesContent[index] = sourceContent - callbackAsync(done, null) - } else { - var readUrl = decodeUriComponent(fullUrl) - read(readUrl, function(error, source) { - result.sourcesContent[index] = error ? error : String(source) - done() - }) - } - }) -} + var version = util.getArg(sourceMap, 'version'); + var sections = util.getArg(sourceMap, 'sections'); -function resolveSourcesSync(map, mapUrl, read, options) { - var result = { - sourcesResolved: [], - sourcesContent: [] + if (version != this._version) { + throw new Error('Unsupported version: ' + version); } - if (!map.sources || map.sources.length === 0) { - return result - } + this._sources = new ArraySet(); + this._names = new ArraySet(); - resolveSourcesHelper(map, mapUrl, options, function(fullUrl, sourceContent, index) { - result.sourcesResolved[index] = fullUrl - if (read !== null) { - if (typeof sourceContent === "string") { - result.sourcesContent[index] = sourceContent - } else { - var readUrl = decodeUriComponent(fullUrl) - try { - result.sourcesContent[index] = String(read(readUrl)) - } catch (error) { - result.sourcesContent[index] = error - } - } + var lastOffset = { + line: -1, + column: 0 + }; + this._sections = sections.map(function (s) { + if (s.url) { + // The url field will require support for asynchronicity. + // See https://github.com/mozilla/source-map/issues/16 + throw new Error('Support for url field in sections not implemented.'); } - }) - - return result -} - -var endingSlash = /\/?$/ + var offset = util.getArg(s, 'offset'); + var offsetLine = util.getArg(offset, 'line'); + var offsetColumn = util.getArg(offset, 'column'); -function resolveSourcesHelper(map, mapUrl, options, fn) { - options = options || {} - mapUrl = urix(mapUrl) - var fullUrl - var sourceContent - var sourceRoot - for (var index = 0, len = map.sources.length; index < len; index++) { - sourceRoot = null - if (typeof options.sourceRoot === "string") { - sourceRoot = options.sourceRoot - } else if (typeof map.sourceRoot === "string" && options.sourceRoot !== false) { - sourceRoot = map.sourceRoot + if (offsetLine < lastOffset.line || + (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) { + throw new Error('Section offsets must be ordered and non-overlapping.'); } - // If the sourceRoot is the empty string, it is equivalent to not setting - // the property at all. - if (sourceRoot === null || sourceRoot === '') { - fullUrl = resolveUrl(mapUrl, map.sources[index]) - } else { - // Make sure that the sourceRoot ends with a slash, so that `/scripts/subdir` becomes - // `/scripts/subdir/`, not `/scripts/`. Pointing to a file as source root - // does not make sense. - fullUrl = resolveUrl(mapUrl, sourceRoot.replace(endingSlash, "/"), map.sources[index]) + lastOffset = offset; + + return { + generatedOffset: { + // The offset fields are 0-based, but we use 1-based indices when + // encoding/decoding from VLQ. + generatedLine: offsetLine + 1, + generatedColumn: offsetColumn + 1 + }, + consumer: new SourceMapConsumer(util.getArg(s, 'map')) } - sourceContent = (map.sourcesContent || [])[index] - fn(fullUrl, sourceContent, index) - } + }); } +IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); +IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer; +/** + * The version of the source mapping spec that we are consuming. + */ +IndexedSourceMapConsumer.prototype._version = 3; -function resolve(code, codeUrl, read, options, callback) { - if (typeof options === "function") { - callback = options - options = {} - } - if (code === null) { - var mapUrl = codeUrl - var data = { - sourceMappingURL: null, - url: mapUrl, - sourcesRelativeTo: mapUrl, - map: null - } - var readUrl = decodeUriComponent(mapUrl) - read(readUrl, function(error, result) { - if (error) { - error.sourceMapData = data - return callback(error) - } - data.map = String(result) - try { - data.map = parseMapToJSON(data.map, data) - } catch (error) { - return callback(error) - } - _resolveSources(data) - }) - } else { - resolveSourceMap(code, codeUrl, read, function(error, mapData) { - if (error) { - return callback(error) - } - if (!mapData) { - return callback(null, null) - } - _resolveSources(mapData) - }) - } - - function _resolveSources(mapData) { - resolveSources(mapData.map, mapData.sourcesRelativeTo, read, options, function(error, result) { - if (error) { - return callback(error) +/** + * The list of original sources. + */ +Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', { + get: function () { + var sources = []; + for (var i = 0; i < this._sections.length; i++) { + for (var j = 0; j < this._sections[i].consumer.sources.length; j++) { + sources.push(this._sections[i].consumer.sources[j]); } - mapData.sourcesResolved = result.sourcesResolved - mapData.sourcesContent = result.sourcesContent - callback(null, mapData) - }) - } -} - -function resolveSync(code, codeUrl, read, options) { - var mapData - if (code === null) { - var mapUrl = codeUrl - mapData = { - sourceMappingURL: null, - url: mapUrl, - sourcesRelativeTo: mapUrl, - map: null - } - mapData.map = readSync(read, mapUrl, mapData) - mapData.map = parseMapToJSON(mapData.map, mapData) - } else { - mapData = resolveSourceMapSync(code, codeUrl, read) - if (!mapData) { - return null } + return sources; } - var result = resolveSourcesSync(mapData.map, mapData.sourcesRelativeTo, read, options) - mapData.sourcesResolved = result.sourcesResolved - mapData.sourcesContent = result.sourcesContent - return mapData -} +}); +/** + * Returns the original source, line, and column information for the generated + * source's line and column positions provided. The only argument is an object + * with the following properties: + * + * - line: The line number in the generated source. + * - column: The column number in the generated source. + * + * and an object is returned with the following properties: + * + * - source: The original source file, or null. + * - line: The line number in the original source, or null. + * - column: The column number in the original source, or null. + * - name: The original identifier, or null. + */ +IndexedSourceMapConsumer.prototype.originalPositionFor = + function IndexedSourceMapConsumer_originalPositionFor(aArgs) { + var needle = { + generatedLine: util.getArg(aArgs, 'line'), + generatedColumn: util.getArg(aArgs, 'column') + }; + // Find the section containing the generated position we're trying to map + // to an original position. + var sectionIndex = binarySearch.search(needle, this._sections, + function(needle, section) { + var cmp = needle.generatedLine - section.generatedOffset.generatedLine; + if (cmp) { + return cmp; + } -module.exports = { - resolveSourceMap: resolveSourceMap, - resolveSourceMapSync: resolveSourceMapSync, - resolveSources: resolveSources, - resolveSourcesSync: resolveSourcesSync, - resolve: resolve, - resolveSync: resolveSync, - parseMapToJSON: parseMapToJSON -} + return (needle.generatedColumn - + section.generatedOffset.generatedColumn); + }); + var section = this._sections[sectionIndex]; + if (!section) { + return { + source: null, + line: null, + column: null, + name: null + }; + } -/***/ }), -/* 626 */ -/***/ (function(module, exports, __webpack_require__) { + return section.consumer.originalPositionFor({ + line: needle.generatedLine - + (section.generatedOffset.generatedLine - 1), + column: needle.generatedColumn - + (section.generatedOffset.generatedLine === needle.generatedLine + ? section.generatedOffset.generatedColumn - 1 + : 0), + bias: aArgs.bias + }); + }; -var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;// Copyright 2014 Simon Lydell -// X11 (“MIT”) Licensed. (See LICENSE.) +/** + * Return true if we have the source content for every source in the source + * map, false otherwise. + */ +IndexedSourceMapConsumer.prototype.hasContentsOfAllSources = + function IndexedSourceMapConsumer_hasContentsOfAllSources() { + return this._sections.every(function (s) { + return s.consumer.hasContentsOfAllSources(); + }); + }; -void (function(root, factory) { - if (true) { - !(__WEBPACK_AMD_DEFINE_FACTORY__ = (factory), - __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? - (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : - __WEBPACK_AMD_DEFINE_FACTORY__), - __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)) - } else {} -}(this, function() { +/** + * Returns the original source content. The only argument is the url of the + * original source file. Returns null if no original source content is + * available. + */ +IndexedSourceMapConsumer.prototype.sourceContentFor = + function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; - var innerRegex = /[#@] sourceMappingURL=([^\s'"]*)/ + var content = section.consumer.sourceContentFor(aSource, true); + if (content) { + return content; + } + } + if (nullOnMissing) { + return null; + } + else { + throw new Error('"' + aSource + '" is not in the SourceMap.'); + } + }; - var regex = RegExp( - "(?:" + - "/\\*" + - "(?:\\s*\r?\n(?://)?)?" + - "(?:" + innerRegex.source + ")" + - "\\s*" + - "\\*/" + - "|" + - "//(?:" + innerRegex.source + ")" + - ")" + - "\\s*" - ) +/** + * Returns the generated line and column information for the original source, + * line, and column positions provided. The only argument is an object with + * the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. + * - column: The column number in the original source. + * + * and an object is returned with the following properties: + * + * - line: The line number in the generated source, or null. + * - column: The column number in the generated source, or null. + */ +IndexedSourceMapConsumer.prototype.generatedPositionFor = + function IndexedSourceMapConsumer_generatedPositionFor(aArgs) { + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; - return { + // Only consider this section if the requested source is in the list of + // sources of the consumer. + if (section.consumer.sources.indexOf(util.getArg(aArgs, 'source')) === -1) { + continue; + } + var generatedPosition = section.consumer.generatedPositionFor(aArgs); + if (generatedPosition) { + var ret = { + line: generatedPosition.line + + (section.generatedOffset.generatedLine - 1), + column: generatedPosition.column + + (section.generatedOffset.generatedLine === generatedPosition.line + ? section.generatedOffset.generatedColumn - 1 + : 0) + }; + return ret; + } + } + + return { + line: null, + column: null + }; + }; - regex: regex, - _innerRegex: innerRegex, +/** + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ +IndexedSourceMapConsumer.prototype._parseMappings = + function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) { + this.__generatedMappings = []; + this.__originalMappings = []; + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; + var sectionMappings = section.consumer._generatedMappings; + for (var j = 0; j < sectionMappings.length; j++) { + var mapping = sectionMappings[j]; - getFrom: function(code) { - var match = code.match(regex) - return (match ? match[1] || match[2] || "" : null) - }, + var source = section.consumer._sources.at(mapping.source); + if (section.consumer.sourceRoot !== null) { + source = util.join(section.consumer.sourceRoot, source); + } + this._sources.add(source); + source = this._sources.indexOf(source); - existsIn: function(code) { - return regex.test(code) - }, + var name = section.consumer._names.at(mapping.name); + this._names.add(name); + name = this._names.indexOf(name); - removeFrom: function(code) { - return code.replace(regex, "") - }, + // The mappings coming from the consumer for the section have + // generated positions relative to the start of the section, so we + // need to offset them to be relative to the start of the concatenated + // generated file. + var adjustedMapping = { + source: source, + generatedLine: mapping.generatedLine + + (section.generatedOffset.generatedLine - 1), + generatedColumn: mapping.generatedColumn + + (section.generatedOffset.generatedLine === mapping.generatedLine + ? section.generatedOffset.generatedColumn - 1 + : 0), + originalLine: mapping.originalLine, + originalColumn: mapping.originalColumn, + name: name + }; - insertBefore: function(code, string) { - var match = code.match(regex) - if (match) { - return code.slice(0, match.index) + string + code.slice(match.index) - } else { - return code + string + this.__generatedMappings.push(adjustedMapping); + if (typeof adjustedMapping.originalLine === 'number') { + this.__originalMappings.push(adjustedMapping); + } } } - } - -})); - - -/***/ }), -/* 627 */ -/***/ (function(module, exports, __webpack_require__) { -// Copyright 2014 Simon Lydell -// X11 (“MIT”) Licensed. (See LICENSE.) + quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated); + quickSort(this.__originalMappings, util.compareByOriginalPositions); + }; -var url = __webpack_require__(196) +exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer; -function resolveUrl(/* ...urls */) { - return Array.prototype.reduce.call(arguments, function(resolved, nextUrl) { - return url.resolve(resolved, nextUrl) - }) -} -module.exports = resolveUrl +/***/ }), +/* 624 */ +/***/ (function(module, exports) { +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ -/***/ }), -/* 628 */ -/***/ (function(module, exports, __webpack_require__) { +exports.GREATEST_LOWER_BOUND = 1; +exports.LEAST_UPPER_BOUND = 2; -// Copyright 2017 Simon Lydell -// X11 (“MIT”) Licensed. (See LICENSE.) +/** + * Recursive implementation of binary search. + * + * @param aLow Indices here and lower do not contain the needle. + * @param aHigh Indices here and higher do not contain the needle. + * @param aNeedle The element being searched for. + * @param aHaystack The non-empty array being searched. + * @param aCompare Function which takes two elements and returns -1, 0, or 1. + * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or + * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + */ +function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) { + // This function terminates when one of the following is true: + // + // 1. We find the exact element we are looking for. + // + // 2. We did not find the exact element, but we can return the index of + // the next-closest element. + // + // 3. We did not find the exact element, and there is no next-closest + // element than the one we are searching for, so we return -1. + var mid = Math.floor((aHigh - aLow) / 2) + aLow; + var cmp = aCompare(aNeedle, aHaystack[mid], true); + if (cmp === 0) { + // Found the element we are looking for. + return mid; + } + else if (cmp > 0) { + // Our needle is greater than aHaystack[mid]. + if (aHigh - mid > 1) { + // The element is in the upper half. + return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias); + } -var decodeUriComponent = __webpack_require__(629) + // The exact needle element was not found in this haystack. Determine if + // we are in termination case (3) or (2) and return the appropriate thing. + if (aBias == exports.LEAST_UPPER_BOUND) { + return aHigh < aHaystack.length ? aHigh : -1; + } else { + return mid; + } + } + else { + // Our needle is less than aHaystack[mid]. + if (mid - aLow > 1) { + // The element is in the lower half. + return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias); + } -function customDecodeUriComponent(string) { - // `decodeUriComponent` turns `+` into ` `, but that's not wanted. - return decodeUriComponent(string.replace(/\+/g, "%2B")) + // we are in termination case (3) or (2) and return the appropriate thing. + if (aBias == exports.LEAST_UPPER_BOUND) { + return mid; + } else { + return aLow < 0 ? -1 : aLow; + } + } } -module.exports = customDecodeUriComponent - +/** + * This is an implementation of binary search which will always try and return + * the index of the closest element if there is no exact hit. This is because + * mappings between original and generated line/col pairs are single points, + * and there is an implicit region between each of them, so a miss just means + * that you aren't on the very start of a region. + * + * @param aNeedle The element you are looking for. + * @param aHaystack The array that is being searched. + * @param aCompare A function which takes the needle and an element in the + * array and returns -1, 0, or 1 depending on whether the needle is less + * than, equal to, or greater than the element, respectively. + * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or + * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'binarySearch.GREATEST_LOWER_BOUND'. + */ +exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { + if (aHaystack.length === 0) { + return -1; + } -/***/ }), -/* 629 */ -/***/ (function(module, exports, __webpack_require__) { + var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, + aCompare, aBias || exports.GREATEST_LOWER_BOUND); + if (index < 0) { + return -1; + } -"use strict"; + // We have found either the exact element, or the next-closest element than + // the one we are searching for. However, there may be more than one such + // element. Make sure we always return the smallest of these. + while (index - 1 >= 0) { + if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) { + break; + } + --index; + } -var token = '%[a-f0-9]{2}'; -var singleMatcher = new RegExp(token, 'gi'); -var multiMatcher = new RegExp('(' + token + ')+', 'gi'); + return index; +}; -function decodeComponents(components, split) { - try { - // Try to decode the entire string first - return decodeURIComponent(components.join('')); - } catch (err) { - // Do nothing - } - if (components.length === 1) { - return components; - } +/***/ }), +/* 625 */ +/***/ (function(module, exports) { - split = split || 1; +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ - // Split the array in 2 parts - var left = components.slice(0, split); - var right = components.slice(split); +// It turns out that some (most?) JavaScript engines don't self-host +// `Array.prototype.sort`. This makes sense because C++ will likely remain +// faster than JS when doing raw CPU-intensive sorting. However, when using a +// custom comparator function, calling back and forth between the VM's C++ and +// JIT'd JS is rather slow *and* loses JIT type information, resulting in +// worse generated code for the comparator function than would be optimal. In +// fact, when sorting with a comparator, these costs outweigh the benefits of +// sorting in C++. By using our own JS-implemented Quick Sort (below), we get +// a ~3500ms mean speed-up in `bench/bench.html`. - return Array.prototype.concat.call([], decodeComponents(left), decodeComponents(right)); +/** + * Swap the elements indexed by `x` and `y` in the array `ary`. + * + * @param {Array} ary + * The array. + * @param {Number} x + * The index of the first item. + * @param {Number} y + * The index of the second item. + */ +function swap(ary, x, y) { + var temp = ary[x]; + ary[x] = ary[y]; + ary[y] = temp; } -function decode(input) { - try { - return decodeURIComponent(input); - } catch (err) { - var tokens = input.match(singleMatcher); - - for (var i = 1; i < tokens.length; i++) { - input = decodeComponents(tokens, i).join(''); - - tokens = input.match(singleMatcher); - } - - return input; - } +/** + * Returns a random integer within the range `low .. high` inclusive. + * + * @param {Number} low + * The lower bound on the range. + * @param {Number} high + * The upper bound on the range. + */ +function randomIntInRange(low, high) { + return Math.round(low + (Math.random() * (high - low))); } -function customDecodeURIComponent(input) { - // Keep track of all the replacements and prefill the map with the `BOM` - var replaceMap = { - '%FE%FF': '\uFFFD\uFFFD', - '%FF%FE': '\uFFFD\uFFFD' - }; +/** + * The Quick Sort algorithm. + * + * @param {Array} ary + * An array to sort. + * @param {function} comparator + * Function to use to compare two items. + * @param {Number} p + * Start index of the array + * @param {Number} r + * End index of the array + */ +function doQuickSort(ary, comparator, p, r) { + // If our lower bound is less than our upper bound, we (1) partition the + // array into two pieces and (2) recurse on each half. If it is not, this is + // the empty array and our base case. - var match = multiMatcher.exec(input); - while (match) { - try { - // Decode as big chunks as possible - replaceMap[match[0]] = decodeURIComponent(match[0]); - } catch (err) { - var result = decode(match[0]); + if (p < r) { + // (1) Partitioning. + // + // The partitioning chooses a pivot between `p` and `r` and moves all + // elements that are less than or equal to the pivot to the before it, and + // all the elements that are greater than it after it. The effect is that + // once partition is done, the pivot is in the exact place it will be when + // the array is put in sorted order, and it will not need to be moved + // again. This runs in O(n) time. - if (result !== match[0]) { - replaceMap[match[0]] = result; - } - } + // Always choose a random pivot so that an input array which is reverse + // sorted does not cause O(n^2) running time. + var pivotIndex = randomIntInRange(p, r); + var i = p - 1; - match = multiMatcher.exec(input); - } + swap(ary, pivotIndex, r); + var pivot = ary[r]; - // Add `%C2` at the end of the map to make sure it does not replace the combinator before everything else - replaceMap['%C2'] = '\uFFFD'; + // Immediately after `j` is incremented in this loop, the following hold + // true: + // + // * Every element in `ary[p .. i]` is less than or equal to the pivot. + // + // * Every element in `ary[i+1 .. j-1]` is greater than the pivot. + for (var j = p; j < r; j++) { + if (comparator(ary[j], pivot) <= 0) { + i += 1; + swap(ary, i, j); + } + } - var entries = Object.keys(replaceMap); + swap(ary, i + 1, j); + var q = i + 1; - for (var i = 0; i < entries.length; i++) { - // Replace all decoded components - var key = entries[i]; - input = input.replace(new RegExp(key, 'g'), replaceMap[key]); - } + // (2) Recurse on each half. - return input; + doQuickSort(ary, comparator, p, q - 1); + doQuickSort(ary, comparator, q + 1, r); + } } -module.exports = function (encodedURI) { - if (typeof encodedURI !== 'string') { - throw new TypeError('Expected `encodedURI` to be of type `string`, got `' + typeof encodedURI + '`'); - } - - try { - encodedURI = encodedURI.replace(/\+/g, ' '); - - // Try the built in decoder first - return decodeURIComponent(encodedURI); - } catch (err) { - // Fallback to a more advanced decoder - return customDecodeURIComponent(encodedURI); - } +/** + * Sort the given array in-place with the given comparator function. + * + * @param {Array} ary + * An array to sort. + * @param {function} comparator + * Function to use to compare two items. + */ +exports.quickSort = function (ary, comparator) { + doQuickSort(ary, comparator, 0, ary.length - 1); }; /***/ }), -/* 630 */ +/* 626 */ /***/ (function(module, exports, __webpack_require__) { -// Copyright 2014 Simon Lydell -// X11 (“MIT”) Licensed. (See LICENSE.) - -var path = __webpack_require__(4) - -"use strict" - -function urix(aPath) { - if (path.sep === "\\") { - return aPath - .replace(/\\/g, "/") - .replace(/^[a-z]:\/?/i, "/") - } - return aPath -} - -module.exports = urix +/* -*- Mode: js; js-indent-level: 2; -*- */ +/* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ +var SourceMapGenerator = __webpack_require__(617).SourceMapGenerator; +var util = __webpack_require__(620); -/***/ }), -/* 631 */ -/***/ (function(module, exports, __webpack_require__) { +// Matches a Windows-style `\r\n` newline or a `\n` newline used by all other +// operating systems these days (capturing the result). +var REGEX_NEWLINE = /(\r?\n)/; -"use strict"; +// Newline character code for charCodeAt() comparisons +var NEWLINE_CODE = 10; +// Private symbol for identifying `SourceNode`s when multiple versions of +// the source-map library are loaded. This MUST NOT CHANGE across +// versions! +var isSourceNode = "$$$isSourceNode$$$"; -function atob(str) { - return Buffer.from(str, 'base64').toString('binary'); +/** + * SourceNodes provide a way to abstract over interpolating/concatenating + * snippets of generated JavaScript source code while maintaining the line and + * column information associated with the original source code. + * + * @param aLine The original line number. + * @param aColumn The original column number. + * @param aSource The original source's filename. + * @param aChunks Optional. An array of strings which are snippets of + * generated JS, or other SourceNodes. + * @param aName The original identifier. + */ +function SourceNode(aLine, aColumn, aSource, aChunks, aName) { + this.children = []; + this.sourceContents = {}; + this.line = aLine == null ? null : aLine; + this.column = aColumn == null ? null : aColumn; + this.source = aSource == null ? null : aSource; + this.name = aName == null ? null : aName; + this[isSourceNode] = true; + if (aChunks != null) this.add(aChunks); } -module.exports = atob.atob = atob; +/** + * Creates a SourceNode from generated code and a SourceMapConsumer. + * + * @param aGeneratedCode The generated code + * @param aSourceMapConsumer The SourceMap for the generated code + * @param aRelativePath Optional. The path that relative sources in the + * SourceMapConsumer should be relative to. + */ +SourceNode.fromStringWithSourceMap = + function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) { + // The SourceNode we want to fill with the generated code + // and the SourceMap + var node = new SourceNode(); + + // All even indices of this array are one line of the generated code, + // while all odd indices are the newlines between two adjacent lines + // (since `REGEX_NEWLINE` captures its match). + // Processed fragments are accessed by calling `shiftNextLine`. + var remainingLines = aGeneratedCode.split(REGEX_NEWLINE); + var remainingLinesIndex = 0; + var shiftNextLine = function() { + var lineContents = getNextLine(); + // The last line of a file might not have a newline. + var newLine = getNextLine() || ""; + return lineContents + newLine; + function getNextLine() { + return remainingLinesIndex < remainingLines.length ? + remainingLines[remainingLinesIndex++] : undefined; + } + }; -/***/ }), -/* 632 */ -/***/ (function(module, exports, __webpack_require__) { + // We need to remember the position of "remainingLines" + var lastGeneratedLine = 1, lastGeneratedColumn = 0; -"use strict"; + // The generate SourceNodes we need a code range. + // To extract it current and last mapping is used. + // Here we store the last mapping. + var lastMapping = null; + aSourceMapConsumer.eachMapping(function (mapping) { + if (lastMapping !== null) { + // We add the code from "lastMapping" to "mapping": + // First check if there is a new line in between. + if (lastGeneratedLine < mapping.generatedLine) { + // Associate first line with "lastMapping" + addMappingWithCode(lastMapping, shiftNextLine()); + lastGeneratedLine++; + lastGeneratedColumn = 0; + // The remaining code is added without mapping + } else { + // There is no new line in between. + // Associate the code between "lastGeneratedColumn" and + // "mapping.generatedColumn" with "lastMapping" + var nextLine = remainingLines[remainingLinesIndex]; + var code = nextLine.substr(0, mapping.generatedColumn - + lastGeneratedColumn); + remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn - + lastGeneratedColumn); + lastGeneratedColumn = mapping.generatedColumn; + addMappingWithCode(lastMapping, code); + // No more remaining code, continue + lastMapping = mapping; + return; + } + } + // We add the generated code until the first mapping + // to the SourceNode without any mapping. + // Each line is added as separate string. + while (lastGeneratedLine < mapping.generatedLine) { + node.add(shiftNextLine()); + lastGeneratedLine++; + } + if (lastGeneratedColumn < mapping.generatedColumn) { + var nextLine = remainingLines[remainingLinesIndex]; + node.add(nextLine.substr(0, mapping.generatedColumn)); + remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn); + lastGeneratedColumn = mapping.generatedColumn; + } + lastMapping = mapping; + }, this); + // We have processed all mappings. + if (remainingLinesIndex < remainingLines.length) { + if (lastMapping) { + // Associate the remaining code in the current line with "lastMapping" + addMappingWithCode(lastMapping, shiftNextLine()); + } + // and add the remaining lines without any mapping + node.add(remainingLines.splice(remainingLinesIndex).join("")); + } -var fs = __webpack_require__(133); -var path = __webpack_require__(4); -var define = __webpack_require__(594); -var utils = __webpack_require__(613); + // Copy sourcesContent into SourceNode + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + if (aRelativePath != null) { + sourceFile = util.join(aRelativePath, sourceFile); + } + node.setSourceContent(sourceFile, content); + } + }); -/** - * Expose `mixin()`. - * This code is based on `source-maps-support.js` in reworkcss/css - * https://github.com/reworkcss/css/blob/master/lib/stringify/source-map-support.js - * Copyright (c) 2012 TJ Holowaychuk - */ + return node; -module.exports = mixin; + function addMappingWithCode(mapping, code) { + if (mapping === null || mapping.source === undefined) { + node.add(code); + } else { + var source = aRelativePath + ? util.join(aRelativePath, mapping.source) + : mapping.source; + node.add(new SourceNode(mapping.originalLine, + mapping.originalColumn, + source, + code, + mapping.name)); + } + } + }; /** - * Mixin source map support into `compiler`. + * Add a chunk of generated JS to this source node. * - * @param {Object} `compiler` - * @api public + * @param aChunk A string snippet of generated JS code, another instance of + * SourceNode, or an array where each member is one of those things. */ - -function mixin(compiler) { - define(compiler, '_comment', compiler.comment); - compiler.map = new utils.SourceMap.SourceMapGenerator(); - compiler.position = { line: 1, column: 1 }; - compiler.content = {}; - compiler.files = {}; - - for (var key in exports) { - define(compiler, key, exports[key]); +SourceNode.prototype.add = function SourceNode_add(aChunk) { + if (Array.isArray(aChunk)) { + aChunk.forEach(function (chunk) { + this.add(chunk); + }, this); } -} + else if (aChunk[isSourceNode] || typeof aChunk === "string") { + if (aChunk) { + this.children.push(aChunk); + } + } + else { + throw new TypeError( + "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk + ); + } + return this; +}; /** - * Update position. + * Add a chunk of generated JS to the beginning of this source node. * - * @param {String} str + * @param aChunk A string snippet of generated JS code, another instance of + * SourceNode, or an array where each member is one of those things. */ - -exports.updatePosition = function(str) { - var lines = str.match(/\n/g); - if (lines) this.position.line += lines.length; - var i = str.lastIndexOf('\n'); - this.position.column = ~i ? str.length - i : this.position.column + str.length; +SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) { + if (Array.isArray(aChunk)) { + for (var i = aChunk.length-1; i >= 0; i--) { + this.prepend(aChunk[i]); + } + } + else if (aChunk[isSourceNode] || typeof aChunk === "string") { + this.children.unshift(aChunk); + } + else { + throw new TypeError( + "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk + ); + } + return this; }; /** - * Emit `str` with `position`. + * Walk over the tree of JS snippets in this node and its children. The + * walking function is called once for each snippet of JS and is passed that + * snippet and the its original associated source's line/column location. * - * @param {String} str - * @param {Object} [pos] - * @return {String} + * @param aFn The traversal function. */ - -exports.emit = function(str, node) { - var position = node.position || {}; - var source = position.source; - if (source) { - if (position.filepath) { - source = utils.unixify(position.filepath); +SourceNode.prototype.walk = function SourceNode_walk(aFn) { + var chunk; + for (var i = 0, len = this.children.length; i < len; i++) { + chunk = this.children[i]; + if (chunk[isSourceNode]) { + chunk.walk(aFn); } - - this.map.addMapping({ - source: source, - generated: { - line: this.position.line, - column: Math.max(this.position.column - 1, 0) - }, - original: { - line: position.start.line, - column: position.start.column - 1 + else { + if (chunk !== '') { + aFn(chunk, { source: this.source, + line: this.line, + column: this.column, + name: this.name }); } - }); - - if (position.content) { - this.addContent(source, position); - } - if (position.filepath) { - this.addFile(source, position); } - - this.updatePosition(str); - this.output += str; } - return str; }; /** - * Adds a file to the source map output if it has not already been added - * @param {String} `file` - * @param {Object} `pos` + * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between + * each of `this.children`. + * + * @param aSep The separator. */ - -exports.addFile = function(file, position) { - if (typeof position.content !== 'string') return; - if (Object.prototype.hasOwnProperty.call(this.files, file)) return; - this.files[file] = position.content; +SourceNode.prototype.join = function SourceNode_join(aSep) { + var newChildren; + var i; + var len = this.children.length; + if (len > 0) { + newChildren = []; + for (i = 0; i < len-1; i++) { + newChildren.push(this.children[i]); + newChildren.push(aSep); + } + newChildren.push(this.children[i]); + this.children = newChildren; + } + return this; }; /** - * Adds a content source to the source map output if it has not already been added - * @param {String} `source` - * @param {Object} `position` + * Call String.prototype.replace on the very right-most source snippet. Useful + * for trimming whitespace from the end of a source node, etc. + * + * @param aPattern The pattern to replace. + * @param aReplacement The thing to replace the pattern with. */ - -exports.addContent = function(source, position) { - if (typeof position.content !== 'string') return; - if (Object.prototype.hasOwnProperty.call(this.content, source)) return; - this.map.setSourceContent(source, position.content); +SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) { + var lastChild = this.children[this.children.length - 1]; + if (lastChild[isSourceNode]) { + lastChild.replaceRight(aPattern, aReplacement); + } + else if (typeof lastChild === 'string') { + this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement); + } + else { + this.children.push(''.replace(aPattern, aReplacement)); + } + return this; }; /** - * Applies any original source maps to the output and embeds the source file - * contents in the source map. + * Set the source content for a source file. This will be added to the SourceMapGenerator + * in the sourcesContent field. + * + * @param aSourceFile The filename of the source file + * @param aSourceContent The content of the source file */ - -exports.applySourceMaps = function() { - Object.keys(this.files).forEach(function(file) { - var content = this.files[file]; - this.map.setSourceContent(file, content); - - if (this.options.inputSourcemaps === true) { - var originalMap = utils.sourceMapResolve.resolveSync(content, file, fs.readFileSync); - if (originalMap) { - var map = new utils.SourceMap.SourceMapConsumer(originalMap.map); - var relativeTo = originalMap.sourcesRelativeTo; - this.map.applySourceMap(map, file, utils.unixify(path.dirname(relativeTo))); - } - } - }, this); -}; +SourceNode.prototype.setSourceContent = + function SourceNode_setSourceContent(aSourceFile, aSourceContent) { + this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent; + }; /** - * Process comments, drops sourceMap comments. - * @param {Object} node + * Walk over the tree of SourceNodes. The walking function is called for each + * source file content and is passed the filename and source content. + * + * @param aFn The traversal function. */ +SourceNode.prototype.walkSourceContents = + function SourceNode_walkSourceContents(aFn) { + for (var i = 0, len = this.children.length; i < len; i++) { + if (this.children[i][isSourceNode]) { + this.children[i].walkSourceContents(aFn); + } + } -exports.comment = function(node) { - if (/^# sourceMappingURL=/.test(node.comment)) { - return this.emit('', node.position); - } - return this._comment(node); -}; - - -/***/ }), -/* 633 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var use = __webpack_require__(605); -var util = __webpack_require__(111); -var Cache = __webpack_require__(634); -var define = __webpack_require__(594); -var debug = __webpack_require__(607)('snapdragon:parser'); -var Position = __webpack_require__(635); -var utils = __webpack_require__(613); + var sources = Object.keys(this.sourceContents); + for (var i = 0, len = sources.length; i < len; i++) { + aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]); + } + }; /** - * Create a new `Parser` with the given `input` and `options`. - * @param {String} `input` - * @param {Object} `options` - * @api public + * Return the string representation of this source node. Walks over the tree + * and concatenates all the various snippets together to one string. */ - -function Parser(options) { - debug('initializing', __filename); - this.options = utils.extend({source: 'string'}, options); - this.init(this.options); - use(this); -} +SourceNode.prototype.toString = function SourceNode_toString() { + var str = ""; + this.walk(function (chunk) { + str += chunk; + }); + return str; +}; /** - * Prototype methods + * Returns the string representation of this source node along with a source + * map. */ - -Parser.prototype = { - constructor: Parser, - - init: function(options) { - this.orig = ''; - this.input = ''; - this.parsed = ''; - - this.column = 1; - this.line = 1; - - this.regex = new Cache(); - this.errors = this.errors || []; - this.parsers = this.parsers || {}; - this.types = this.types || []; - this.sets = this.sets || {}; - this.fns = this.fns || []; - this.currentType = 'root'; - - var pos = this.position(); - this.bos = pos({type: 'bos', val: ''}); - - this.ast = { - type: 'root', - errors: this.errors, - nodes: [this.bos] - }; - - define(this.bos, 'parent', this.ast); - this.nodes = [this.ast]; - - this.count = 0; - this.setCount = 0; - this.stack = []; - }, - - /** - * Throw a formatted error with the cursor column and `msg`. - * @param {String} `msg` Message to use in the Error. - */ - - error: function(msg, node) { - var pos = node.position || {start: {column: 0, line: 0}}; - var line = pos.start.line; - var column = pos.start.column; - var source = this.options.source; - - var message = source + ' : ' + msg; - var err = new Error(message); - err.source = source; - err.reason = msg; - err.pos = pos; - - if (this.options.silent) { - this.errors.push(err); - } else { - throw err; +SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) { + var generated = { + code: "", + line: 1, + column: 0 + }; + var map = new SourceMapGenerator(aArgs); + var sourceMappingActive = false; + var lastOriginalSource = null; + var lastOriginalLine = null; + var lastOriginalColumn = null; + var lastOriginalName = null; + this.walk(function (chunk, original) { + generated.code += chunk; + if (original.source !== null + && original.line !== null + && original.column !== null) { + if(lastOriginalSource !== original.source + || lastOriginalLine !== original.line + || lastOriginalColumn !== original.column + || lastOriginalName !== original.name) { + map.addMapping({ + source: original.source, + original: { + line: original.line, + column: original.column + }, + generated: { + line: generated.line, + column: generated.column + }, + name: original.name + }); + } + lastOriginalSource = original.source; + lastOriginalLine = original.line; + lastOriginalColumn = original.column; + lastOriginalName = original.name; + sourceMappingActive = true; + } else if (sourceMappingActive) { + map.addMapping({ + generated: { + line: generated.line, + column: generated.column + } + }); + lastOriginalSource = null; + sourceMappingActive = false; } - }, - - /** - * Define a non-enumberable property on the `Parser` instance. - * - * ```js - * parser.define('foo', 'bar'); - * ``` - * @name .define - * @param {String} `key` propery name - * @param {any} `val` property value - * @return {Object} Returns the Parser instance for chaining. - * @api public - */ - - define: function(key, val) { - define(this, key, val); - return this; - }, - - /** - * Mark position and patch `node.position`. - */ - - position: function() { - var start = { line: this.line, column: this.column }; - var self = this; - - return function(node) { - define(node, 'position', new Position(start, self)); - return node; - }; - }, - - /** - * Set parser `name` with the given `fn` - * @param {String} `name` - * @param {Function} `fn` - * @api public - */ - - set: function(type, fn) { - if (this.types.indexOf(type) === -1) { - this.types.push(type); + for (var idx = 0, length = chunk.length; idx < length; idx++) { + if (chunk.charCodeAt(idx) === NEWLINE_CODE) { + generated.line++; + generated.column = 0; + // Mappings end at eol + if (idx + 1 === length) { + lastOriginalSource = null; + sourceMappingActive = false; + } else if (sourceMappingActive) { + map.addMapping({ + source: original.source, + original: { + line: original.line, + column: original.column + }, + generated: { + line: generated.line, + column: generated.column + }, + name: original.name + }); + } + } else { + generated.column++; + } } - this.parsers[type] = fn.bind(this); - return this; - }, - - /** - * Get parser `name` - * @param {String} `name` - * @api public - */ - - get: function(name) { - return this.parsers[name]; - }, - - /** - * Push a `token` onto the `type` stack. - * - * @param {String} `type` - * @return {Object} `token` - * @api public - */ - - push: function(type, token) { - this.sets[type] = this.sets[type] || []; - this.count++; - this.stack.push(token); - return this.sets[type].push(token); - }, - - /** - * Pop a token off of the `type` stack - * @param {String} `type` - * @returns {Object} Returns a token - * @api public - */ - - pop: function(type) { - this.sets[type] = this.sets[type] || []; - this.count--; - this.stack.pop(); - return this.sets[type].pop(); - }, + }); + this.walkSourceContents(function (sourceFile, sourceContent) { + map.setSourceContent(sourceFile, sourceContent); + }); - /** - * Return true if inside a `stack` node. Types are `braces`, `parens` or `brackets`. - * - * @param {String} `type` - * @return {Boolean} - * @api public - */ + return { code: generated.code, map: map }; +}; - isInside: function(type) { - this.sets[type] = this.sets[type] || []; - return this.sets[type].length > 0; - }, +exports.SourceNode = SourceNode; - /** - * Return true if `node` is the given `type`. - * - * ```js - * parser.isType(node, 'brace'); - * ``` - * @param {Object} `node` - * @param {String} `type` - * @return {Boolean} - * @api public - */ - isType: function(node, type) { - return node && node.type === type; - }, +/***/ }), +/* 627 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Get the previous AST node - * @return {Object} - */ +// Copyright 2014, 2015, 2016, 2017 Simon Lydell +// X11 (“MIT”) Licensed. (See LICENSE.) - prev: function(n) { - return this.stack.length > 0 - ? utils.last(this.stack, n) - : utils.last(this.nodes, n); - }, +var sourceMappingURL = __webpack_require__(628) +var resolveUrl = __webpack_require__(629) +var decodeUriComponent = __webpack_require__(630) +var urix = __webpack_require__(632) +var atob = __webpack_require__(633) - /** - * Update line and column based on `str`. - */ - consume: function(len) { - this.input = this.input.substr(len); - }, - /** - * Update column based on `str`. - */ +function callbackAsync(callback, error, result) { + setImmediate(function() { callback(error, result) }) +} - updatePosition: function(str, len) { - var lines = str.match(/\n/g); - if (lines) this.line += lines.length; - var i = str.lastIndexOf('\n'); - this.column = ~i ? len - i : this.column + len; - this.parsed += str; - this.consume(len); - }, +function parseMapToJSON(string, data) { + try { + return JSON.parse(string.replace(/^\)\]\}'/, "")) + } catch (error) { + error.sourceMapData = data + throw error + } +} - /** - * Match `regex`, return captures, and update the cursor position by `match[0]` length. - * @param {RegExp} `regex` - * @return {Object} - */ +function readSync(read, url, data) { + var readUrl = decodeUriComponent(url) + try { + return String(read(readUrl)) + } catch (error) { + error.sourceMapData = data + throw error + } +} - match: function(regex) { - var m = regex.exec(this.input); - if (m) { - this.updatePosition(m[0], m[0].length); - return m; - } - }, - /** - * Capture `type` with the given regex. - * @param {String} `type` - * @param {RegExp} `regex` - * @return {Function} - */ - capture: function(type, regex) { - if (typeof regex === 'function') { - return this.set.apply(this, arguments); +function resolveSourceMap(code, codeUrl, read, callback) { + var mapData + try { + mapData = resolveSourceMapHelper(code, codeUrl) + } catch (error) { + return callbackAsync(callback, error) + } + if (!mapData || mapData.map) { + return callbackAsync(callback, null, mapData) + } + var readUrl = decodeUriComponent(mapData.url) + read(readUrl, function(error, result) { + if (error) { + error.sourceMapData = mapData + return callback(error) } + mapData.map = String(result) + try { + mapData.map = parseMapToJSON(mapData.map, mapData) + } catch (error) { + return callback(error) + } + callback(null, mapData) + }) +} - this.regex.set(type, regex); - this.set(type, function() { - var parsed = this.parsed; - var pos = this.position(); - var m = this.match(regex); - if (!m || !m[0]) return; - - var prev = this.prev(); - var node = pos({ - type: type, - val: m[0], - parsed: parsed, - rest: this.input - }); - - if (m[1]) { - node.inner = m[1]; - } - - define(node, 'inside', this.stack.length > 0); - define(node, 'parent', prev); - prev.nodes.push(node); - }.bind(this)); - return this; - }, +function resolveSourceMapSync(code, codeUrl, read) { + var mapData = resolveSourceMapHelper(code, codeUrl) + if (!mapData || mapData.map) { + return mapData + } + mapData.map = readSync(read, mapData.url, mapData) + mapData.map = parseMapToJSON(mapData.map, mapData) + return mapData +} - /** - * Create a parser with open and close for parens, - * brackets or braces - */ +var dataUriRegex = /^data:([^,;]*)(;[^,;]*)*(?:,(.*))?$/ +var jsonMimeTypeRegex = /^(?:application|text)\/json$/ - capturePair: function(type, openRegex, closeRegex, fn) { - this.sets[type] = this.sets[type] || []; +function resolveSourceMapHelper(code, codeUrl) { + codeUrl = urix(codeUrl) - /** - * Open - */ + var url = sourceMappingURL.getFrom(code) + if (!url) { + return null + } - this.set(type + '.open', function() { - var parsed = this.parsed; - var pos = this.position(); - var m = this.match(openRegex); - if (!m || !m[0]) return; + var dataUri = url.match(dataUriRegex) + if (dataUri) { + var mimeType = dataUri[1] + var lastParameter = dataUri[2] || "" + var encoded = dataUri[3] || "" + var data = { + sourceMappingURL: url, + url: null, + sourcesRelativeTo: codeUrl, + map: encoded + } + if (!jsonMimeTypeRegex.test(mimeType)) { + var error = new Error("Unuseful data uri mime type: " + (mimeType || "text/plain")) + error.sourceMapData = data + throw error + } + data.map = parseMapToJSON( + lastParameter === ";base64" ? atob(encoded) : decodeURIComponent(encoded), + data + ) + return data + } - var val = m[0]; - this.setCount++; - this.specialChars = true; - var open = pos({ - type: type + '.open', - val: val, - rest: this.input - }); + var mapUrl = resolveUrl(codeUrl, url) + return { + sourceMappingURL: url, + url: mapUrl, + sourcesRelativeTo: mapUrl, + map: null + } +} - if (typeof m[1] !== 'undefined') { - open.inner = m[1]; - } - var prev = this.prev(); - var node = pos({ - type: type, - nodes: [open] - }); - define(node, 'rest', this.input); - define(node, 'parsed', parsed); - define(node, 'prefix', m[1]); - define(node, 'parent', prev); - define(open, 'parent', node); +function resolveSources(map, mapUrl, read, options, callback) { + if (typeof options === "function") { + callback = options + options = {} + } + var pending = map.sources ? map.sources.length : 0 + var result = { + sourcesResolved: [], + sourcesContent: [] + } - if (typeof fn === 'function') { - fn.call(this, open, node); - } + if (pending === 0) { + callbackAsync(callback, null, result) + return + } - this.push(type, node); - prev.nodes.push(node); - }); + var done = function() { + pending-- + if (pending === 0) { + callback(null, result) + } + } - /** - * Close - */ + resolveSourcesHelper(map, mapUrl, options, function(fullUrl, sourceContent, index) { + result.sourcesResolved[index] = fullUrl + if (typeof sourceContent === "string") { + result.sourcesContent[index] = sourceContent + callbackAsync(done, null) + } else { + var readUrl = decodeUriComponent(fullUrl) + read(readUrl, function(error, source) { + result.sourcesContent[index] = error ? error : String(source) + done() + }) + } + }) +} - this.set(type + '.close', function() { - var pos = this.position(); - var m = this.match(closeRegex); - if (!m || !m[0]) return; +function resolveSourcesSync(map, mapUrl, read, options) { + var result = { + sourcesResolved: [], + sourcesContent: [] + } - var parent = this.pop(type); - var node = pos({ - type: type + '.close', - rest: this.input, - suffix: m[1], - val: m[0] - }); + if (!map.sources || map.sources.length === 0) { + return result + } - if (!this.isType(parent, type)) { - if (this.options.strict) { - throw new Error('missing opening "' + type + '"'); + resolveSourcesHelper(map, mapUrl, options, function(fullUrl, sourceContent, index) { + result.sourcesResolved[index] = fullUrl + if (read !== null) { + if (typeof sourceContent === "string") { + result.sourcesContent[index] = sourceContent + } else { + var readUrl = decodeUriComponent(fullUrl) + try { + result.sourcesContent[index] = String(read(readUrl)) + } catch (error) { + result.sourcesContent[index] = error } - - this.setCount--; - node.escaped = true; - return node; } + } + }) - if (node.suffix === '\\') { - parent.escaped = true; - node.escaped = true; - } + return result +} - parent.nodes.push(node); - define(node, 'parent', parent); - }); +var endingSlash = /\/?$/ - return this; - }, +function resolveSourcesHelper(map, mapUrl, options, fn) { + options = options || {} + mapUrl = urix(mapUrl) + var fullUrl + var sourceContent + var sourceRoot + for (var index = 0, len = map.sources.length; index < len; index++) { + sourceRoot = null + if (typeof options.sourceRoot === "string") { + sourceRoot = options.sourceRoot + } else if (typeof map.sourceRoot === "string" && options.sourceRoot !== false) { + sourceRoot = map.sourceRoot + } + // If the sourceRoot is the empty string, it is equivalent to not setting + // the property at all. + if (sourceRoot === null || sourceRoot === '') { + fullUrl = resolveUrl(mapUrl, map.sources[index]) + } else { + // Make sure that the sourceRoot ends with a slash, so that `/scripts/subdir` becomes + // `/scripts/subdir/`, not `/scripts/`. Pointing to a file as source root + // does not make sense. + fullUrl = resolveUrl(mapUrl, sourceRoot.replace(endingSlash, "/"), map.sources[index]) + } + sourceContent = (map.sourcesContent || [])[index] + fn(fullUrl, sourceContent, index) + } +} - /** - * Capture end-of-string - */ - eos: function() { - var pos = this.position(); - if (this.input) return; - var prev = this.prev(); - while (prev.type !== 'root' && !prev.visited) { - if (this.options.strict === true) { - throw new SyntaxError('invalid syntax:' + util.inspect(prev, null, 2)); +function resolve(code, codeUrl, read, options, callback) { + if (typeof options === "function") { + callback = options + options = {} + } + if (code === null) { + var mapUrl = codeUrl + var data = { + sourceMappingURL: null, + url: mapUrl, + sourcesRelativeTo: mapUrl, + map: null + } + var readUrl = decodeUriComponent(mapUrl) + read(readUrl, function(error, result) { + if (error) { + error.sourceMapData = data + return callback(error) } - - if (!hasDelims(prev)) { - prev.parent.escaped = true; - prev.escaped = true; + data.map = String(result) + try { + data.map = parseMapToJSON(data.map, data) + } catch (error) { + return callback(error) + } + _resolveSources(data) + }) + } else { + resolveSourceMap(code, codeUrl, read, function(error, mapData) { + if (error) { + return callback(error) + } + if (!mapData) { + return callback(null, null) } + _resolveSources(mapData) + }) + } - visit(prev, function(node) { - if (!hasDelims(node.parent)) { - node.parent.escaped = true; - node.escaped = true; - } - }); + function _resolveSources(mapData) { + resolveSources(mapData.map, mapData.sourcesRelativeTo, read, options, function(error, result) { + if (error) { + return callback(error) + } + mapData.sourcesResolved = result.sourcesResolved + mapData.sourcesContent = result.sourcesContent + callback(null, mapData) + }) + } +} - prev = prev.parent; +function resolveSync(code, codeUrl, read, options) { + var mapData + if (code === null) { + var mapUrl = codeUrl + mapData = { + sourceMappingURL: null, + url: mapUrl, + sourcesRelativeTo: mapUrl, + map: null } + mapData.map = readSync(read, mapUrl, mapData) + mapData.map = parseMapToJSON(mapData.map, mapData) + } else { + mapData = resolveSourceMapSync(code, codeUrl, read) + if (!mapData) { + return null + } + } + var result = resolveSourcesSync(mapData.map, mapData.sourcesRelativeTo, read, options) + mapData.sourcesResolved = result.sourcesResolved + mapData.sourcesContent = result.sourcesContent + return mapData +} - var tok = pos({ - type: 'eos', - val: this.append || '' - }); - define(tok, 'parent', this.ast); - return tok; - }, - /** - * Run parsers to advance the cursor position - */ +module.exports = { + resolveSourceMap: resolveSourceMap, + resolveSourceMapSync: resolveSourceMapSync, + resolveSources: resolveSources, + resolveSourcesSync: resolveSourcesSync, + resolve: resolve, + resolveSync: resolveSync, + parseMapToJSON: parseMapToJSON +} - next: function() { - var parsed = this.parsed; - var len = this.types.length; - var idx = -1; - var tok; - while (++idx < len) { - if ((tok = this.parsers[this.types[idx]].call(this))) { - define(tok, 'rest', this.input); - define(tok, 'parsed', parsed); - this.last = tok; - return tok; - } - } - }, +/***/ }), +/* 628 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Parse the given string. - * @return {Array} - */ +var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;// Copyright 2014 Simon Lydell +// X11 (“MIT”) Licensed. (See LICENSE.) + +void (function(root, factory) { + if (true) { + !(__WEBPACK_AMD_DEFINE_FACTORY__ = (factory), + __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? + (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : + __WEBPACK_AMD_DEFINE_FACTORY__), + __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)) + } else {} +}(this, function() { + + var innerRegex = /[#@] sourceMappingURL=([^\s'"]*)/ + + var regex = RegExp( + "(?:" + + "/\\*" + + "(?:\\s*\r?\n(?://)?)?" + + "(?:" + innerRegex.source + ")" + + "\\s*" + + "\\*/" + + "|" + + "//(?:" + innerRegex.source + ")" + + ")" + + "\\s*" + ) - parse: function(input) { - if (typeof input !== 'string') { - throw new TypeError('expected a string'); - } + return { - this.init(this.options); - this.orig = input; - this.input = input; - var self = this; + regex: regex, + _innerRegex: innerRegex, - function parse() { - // check input before calling `.next()` - input = self.input; + getFrom: function(code) { + var match = code.match(regex) + return (match ? match[1] || match[2] || "" : null) + }, - // get the next AST ndoe - var node = self.next(); - if (node) { - var prev = self.prev(); - if (prev) { - define(node, 'parent', prev); - if (prev.nodes) { - prev.nodes.push(node); - } - } + existsIn: function(code) { + return regex.test(code) + }, - if (self.sets.hasOwnProperty(prev.type)) { - self.currentType = prev.type; - } - } + removeFrom: function(code) { + return code.replace(regex, "") + }, - // if we got here but input is not changed, throw an error - if (self.input && input === self.input) { - throw new Error('no parsers registered for: "' + self.input.slice(0, 5) + '"'); + insertBefore: function(code, string) { + var match = code.match(regex) + if (match) { + return code.slice(0, match.index) + string + code.slice(match.index) + } else { + return code + string } } + } - while (this.input) parse(); - if (this.stack.length && this.options.strict) { - var node = this.stack.pop(); - throw this.error('missing opening ' + node.type + ': "' + this.orig + '"'); - } +})); - var eos = this.eos(); - var tok = this.prev(); - if (tok.type !== 'eos') { - this.ast.nodes.push(eos); - } - return this.ast; - } -}; +/***/ }), +/* 629 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Visit `node` with the given `fn` - */ +// Copyright 2014 Simon Lydell +// X11 (“MIT”) Licensed. (See LICENSE.) -function visit(node, fn) { - if (!node.visited) { - define(node, 'visited', true); - return node.nodes ? mapVisit(node.nodes, fn) : fn(node); - } - return node; +var url = __webpack_require__(197) + +function resolveUrl(/* ...urls */) { + return Array.prototype.reduce.call(arguments, function(resolved, nextUrl) { + return url.resolve(resolved, nextUrl) + }) } -/** - * Map visit over array of `nodes`. - */ +module.exports = resolveUrl -function mapVisit(nodes, fn) { - var len = nodes.length; - var idx = -1; - while (++idx < len) { - visit(nodes[idx], fn); - } -} -function hasOpen(node) { - return node.nodes && node.nodes[0].type === (node.type + '.open'); -} +/***/ }), +/* 630 */ +/***/ (function(module, exports, __webpack_require__) { -function hasClose(node) { - return node.nodes && utils.last(node.nodes).type === (node.type + '.close'); -} +// Copyright 2017 Simon Lydell +// X11 (“MIT”) Licensed. (See LICENSE.) -function hasDelims(node) { - return hasOpen(node) && hasClose(node); -} +var decodeUriComponent = __webpack_require__(631) -/** - * Expose `Parser` - */ +function customDecodeUriComponent(string) { + // `decodeUriComponent` turns `+` into ` `, but that's not wanted. + return decodeUriComponent(string.replace(/\+/g, "%2B")) +} -module.exports = Parser; +module.exports = customDecodeUriComponent /***/ }), -/* 634 */ +/* 631 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/*! - * map-cache - * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. - */ +var token = '%[a-f0-9]{2}'; +var singleMatcher = new RegExp(token, 'gi'); +var multiMatcher = new RegExp('(' + token + ')+', 'gi'); + +function decodeComponents(components, split) { + try { + // Try to decode the entire string first + return decodeURIComponent(components.join('')); + } catch (err) { + // Do nothing + } + + if (components.length === 1) { + return components; + } + split = split || 1; -var hasOwn = Object.prototype.hasOwnProperty; + // Split the array in 2 parts + var left = components.slice(0, split); + var right = components.slice(split); -/** - * Expose `MapCache` - */ + return Array.prototype.concat.call([], decodeComponents(left), decodeComponents(right)); +} -module.exports = MapCache; +function decode(input) { + try { + return decodeURIComponent(input); + } catch (err) { + var tokens = input.match(singleMatcher); -/** - * Creates a cache object to store key/value pairs. - * - * ```js - * var cache = new MapCache(); - * ``` - * - * @api public - */ + for (var i = 1; i < tokens.length; i++) { + input = decodeComponents(tokens, i).join(''); -function MapCache(data) { - this.__data__ = data || {}; + tokens = input.match(singleMatcher); + } + + return input; + } } -/** - * Adds `value` to `key` on the cache. - * - * ```js - * cache.set('foo', 'bar'); - * ``` - * - * @param {String} `key` The key of the value to cache. - * @param {*} `value` The value to cache. - * @returns {Object} Returns the `Cache` object for chaining. - * @api public - */ +function customDecodeURIComponent(input) { + // Keep track of all the replacements and prefill the map with the `BOM` + var replaceMap = { + '%FE%FF': '\uFFFD\uFFFD', + '%FF%FE': '\uFFFD\uFFFD' + }; -MapCache.prototype.set = function mapSet(key, value) { - if (key !== '__proto__') { - this.__data__[key] = value; - } - return this; -}; + var match = multiMatcher.exec(input); + while (match) { + try { + // Decode as big chunks as possible + replaceMap[match[0]] = decodeURIComponent(match[0]); + } catch (err) { + var result = decode(match[0]); -/** - * Gets the cached value for `key`. - * - * ```js - * cache.get('foo'); - * //=> 'bar' - * ``` - * - * @param {String} `key` The key of the value to get. - * @returns {*} Returns the cached value. - * @api public - */ + if (result !== match[0]) { + replaceMap[match[0]] = result; + } + } -MapCache.prototype.get = function mapGet(key) { - return key === '__proto__' ? undefined : this.__data__[key]; -}; + match = multiMatcher.exec(input); + } -/** - * Checks if a cached value for `key` exists. - * - * ```js - * cache.has('foo'); - * //=> true - * ``` - * - * @param {String} `key` The key of the entry to check. - * @returns {Boolean} Returns `true` if an entry for `key` exists, else `false`. - * @api public - */ + // Add `%C2` at the end of the map to make sure it does not replace the combinator before everything else + replaceMap['%C2'] = '\uFFFD'; -MapCache.prototype.has = function mapHas(key) { - return key !== '__proto__' && hasOwn.call(this.__data__, key); -}; + var entries = Object.keys(replaceMap); -/** - * Removes `key` and its value from the cache. - * - * ```js - * cache.del('foo'); - * ``` - * @title .del - * @param {String} `key` The key of the value to remove. - * @returns {Boolean} Returns `true` if the entry was removed successfully, else `false`. - * @api public - */ + for (var i = 0; i < entries.length; i++) { + // Replace all decoded components + var key = entries[i]; + input = input.replace(new RegExp(key, 'g'), replaceMap[key]); + } -MapCache.prototype.del = function mapDelete(key) { - return this.has(key) && delete this.__data__[key]; + return input; +} + +module.exports = function (encodedURI) { + if (typeof encodedURI !== 'string') { + throw new TypeError('Expected `encodedURI` to be of type `string`, got `' + typeof encodedURI + '`'); + } + + try { + encodedURI = encodedURI.replace(/\+/g, ' '); + + // Try the built in decoder first + return decodeURIComponent(encodedURI); + } catch (err) { + // Fallback to a more advanced decoder + return customDecodeURIComponent(encodedURI); + } }; /***/ }), -/* 635 */ +/* 632 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +// Copyright 2014 Simon Lydell +// X11 (“MIT”) Licensed. (See LICENSE.) + +var path = __webpack_require__(4) + +"use strict" + +function urix(aPath) { + if (path.sep === "\\") { + return aPath + .replace(/\\/g, "/") + .replace(/^[a-z]:\/?/i, "/") + } + return aPath +} + +module.exports = urix -var define = __webpack_require__(594); +/***/ }), +/* 633 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Store position for a node - */ +"use strict"; -module.exports = function Position(start, parser) { - this.start = start; - this.end = { line: parser.line, column: parser.column }; - define(this, 'content', parser.orig); - define(this, 'source', parser.options.source); -}; + +function atob(str) { + return Buffer.from(str, 'base64').toString('binary'); +} + +module.exports = atob.atob = atob; /***/ }), -/* 636 */ +/* 634 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var safe = __webpack_require__(637); -var define = __webpack_require__(643); -var extend = __webpack_require__(644); -var not = __webpack_require__(646); -var MAX_LENGTH = 1024 * 64; +var fs = __webpack_require__(134); +var path = __webpack_require__(4); +var define = __webpack_require__(596); +var utils = __webpack_require__(615); /** - * Session cache + * Expose `mixin()`. + * This code is based on `source-maps-support.js` in reworkcss/css + * https://github.com/reworkcss/css/blob/master/lib/stringify/source-map-support.js + * Copyright (c) 2012 TJ Holowaychuk */ -var cache = {}; +module.exports = mixin; /** - * Create a regular expression from the given `pattern` string. + * Mixin source map support into `compiler`. * - * @param {String|RegExp} `pattern` Pattern can be a string or regular expression. - * @param {Object} `options` - * @return {RegExp} + * @param {Object} `compiler` * @api public */ -module.exports = function(patterns, options) { - if (!Array.isArray(patterns)) { - return makeRe(patterns, options); +function mixin(compiler) { + define(compiler, '_comment', compiler.comment); + compiler.map = new utils.SourceMap.SourceMapGenerator(); + compiler.position = { line: 1, column: 1 }; + compiler.content = {}; + compiler.files = {}; + + for (var key in exports) { + define(compiler, key, exports[key]); } - return makeRe(patterns.join('|'), options); -}; +} /** - * Create a regular expression from the given `pattern` string. + * Update position. * - * @param {String|RegExp} `pattern` Pattern can be a string or regular expression. - * @param {Object} `options` - * @return {RegExp} - * @api public + * @param {String} str */ -function makeRe(pattern, options) { - if (pattern instanceof RegExp) { - return pattern; - } - - if (typeof pattern !== 'string') { - throw new TypeError('expected a string'); - } - - if (pattern.length > MAX_LENGTH) { - throw new Error('expected pattern to be less than ' + MAX_LENGTH + ' characters'); - } - - var key = pattern; - // do this before shallow cloning options, it's a lot faster - if (!options || (options && options.cache !== false)) { - key = createKey(pattern, options); - - if (cache.hasOwnProperty(key)) { - return cache[key]; - } - } - - var opts = extend({}, options); - if (opts.contains === true) { - if (opts.negate === true) { - opts.strictNegate = false; - } else { - opts.strict = false; - } - } - - if (opts.strict === false) { - opts.strictOpen = false; - opts.strictClose = false; - } - - var open = opts.strictOpen !== false ? '^' : ''; - var close = opts.strictClose !== false ? '$' : ''; - var flags = opts.flags || ''; - var regex; +exports.updatePosition = function(str) { + var lines = str.match(/\n/g); + if (lines) this.position.line += lines.length; + var i = str.lastIndexOf('\n'); + this.position.column = ~i ? str.length - i : this.position.column + str.length; +}; - if (opts.nocase === true && !/i/.test(flags)) { - flags += 'i'; - } +/** + * Emit `str` with `position`. + * + * @param {String} str + * @param {Object} [pos] + * @return {String} + */ - try { - if (opts.negate || typeof opts.strictNegate === 'boolean') { - pattern = not.create(pattern, opts); +exports.emit = function(str, node) { + var position = node.position || {}; + var source = position.source; + if (source) { + if (position.filepath) { + source = utils.unixify(position.filepath); } - var str = open + '(?:' + pattern + ')' + close; - regex = new RegExp(str, flags); + this.map.addMapping({ + source: source, + generated: { + line: this.position.line, + column: Math.max(this.position.column - 1, 0) + }, + original: { + line: position.start.line, + column: position.start.column - 1 + } + }); - if (opts.safe === true && safe(regex) === false) { - throw new Error('potentially unsafe regular expression: ' + regex.source); + if (position.content) { + this.addContent(source, position); } - - } catch (err) { - if (opts.strictErrors === true || opts.safe === true) { - err.key = key; - err.pattern = pattern; - err.originalOptions = options; - err.createdOptions = opts; - throw err; + if (position.filepath) { + this.addFile(source, position); } - try { - regex = new RegExp('^' + pattern.replace(/(\W)/g, '\\$1') + '$'); - } catch (err) { - regex = /.^/; //<= match nothing - } + this.updatePosition(str); + this.output += str; } + return str; +}; - if (opts.cache !== false) { - memoize(regex, key, pattern, opts); - } - return regex; -} +/** + * Adds a file to the source map output if it has not already been added + * @param {String} `file` + * @param {Object} `pos` + */ + +exports.addFile = function(file, position) { + if (typeof position.content !== 'string') return; + if (Object.prototype.hasOwnProperty.call(this.files, file)) return; + this.files[file] = position.content; +}; /** - * Memoize generated regex. This can result in dramatic speed improvements - * and simplify debugging by adding options and pattern to the regex. It can be - * disabled by passing setting `options.cache` to false. + * Adds a content source to the source map output if it has not already been added + * @param {String} `source` + * @param {Object} `position` */ -function memoize(regex, key, pattern, options) { - define(regex, 'cached', true); - define(regex, 'pattern', pattern); - define(regex, 'options', options); - define(regex, 'key', key); - cache[key] = regex; -} +exports.addContent = function(source, position) { + if (typeof position.content !== 'string') return; + if (Object.prototype.hasOwnProperty.call(this.content, source)) return; + this.map.setSourceContent(source, position.content); +}; /** - * Create the key to use for memoization. The key is generated - * by iterating over the options and concatenating key-value pairs - * to the pattern string. + * Applies any original source maps to the output and embeds the source file + * contents in the source map. */ -function createKey(pattern, options) { - if (!options) return pattern; - var key = pattern; - for (var prop in options) { - if (options.hasOwnProperty(prop)) { - key += ';' + prop + '=' + String(options[prop]); +exports.applySourceMaps = function() { + Object.keys(this.files).forEach(function(file) { + var content = this.files[file]; + this.map.setSourceContent(file, content); + + if (this.options.inputSourcemaps === true) { + var originalMap = utils.sourceMapResolve.resolveSync(content, file, fs.readFileSync); + if (originalMap) { + var map = new utils.SourceMap.SourceMapConsumer(originalMap.map); + var relativeTo = originalMap.sourcesRelativeTo; + this.map.applySourceMap(map, file, utils.unixify(path.dirname(relativeTo))); + } } - } - return key; -} + }, this); +}; /** - * Expose `makeRe` + * Process comments, drops sourceMap comments. + * @param {Object} node */ -module.exports.makeRe = makeRe; +exports.comment = function(node) { + if (/^# sourceMappingURL=/.test(node.comment)) { + return this.emit('', node.position); + } + return this._comment(node); +}; /***/ }), -/* 637 */ +/* 635 */ /***/ (function(module, exports, __webpack_require__) { -var parse = __webpack_require__(638); -var types = parse.types; - -module.exports = function (re, opts) { - if (!opts) opts = {}; - var replimit = opts.limit === undefined ? 25 : opts.limit; - - if (isRegExp(re)) re = re.source; - else if (typeof re !== 'string') re = String(re); - - try { re = parse(re) } - catch (err) { return false } - - var reps = 0; - return (function walk (node, starHeight) { - if (node.type === types.REPETITION) { - starHeight ++; - reps ++; - if (starHeight > 1) return false; - if (reps > replimit) return false; - } - - if (node.options) { - for (var i = 0, len = node.options.length; i < len; i++) { - var ok = walk({ stack: node.options[i] }, starHeight); - if (!ok) return false; - } - } - var stack = node.stack || (node.value && node.value.stack); - if (!stack) return true; - - for (var i = 0; i < stack.length; i++) { - var ok = walk(stack[i], starHeight); - if (!ok) return false; - } - - return true; - })(re, 0); -}; - -function isRegExp (x) { - return {}.toString.call(x) === '[object RegExp]'; -} - +"use strict"; -/***/ }), -/* 638 */ -/***/ (function(module, exports, __webpack_require__) { -var util = __webpack_require__(639); -var types = __webpack_require__(640); -var sets = __webpack_require__(641); -var positions = __webpack_require__(642); +var use = __webpack_require__(607); +var util = __webpack_require__(112); +var Cache = __webpack_require__(636); +var define = __webpack_require__(596); +var debug = __webpack_require__(609)('snapdragon:parser'); +var Position = __webpack_require__(637); +var utils = __webpack_require__(615); +/** + * Create a new `Parser` with the given `input` and `options`. + * @param {String} `input` + * @param {Object} `options` + * @api public + */ -module.exports = function(regexpStr) { - var i = 0, l, c, - start = { type: types.ROOT, stack: []}, +function Parser(options) { + debug('initializing', __filename); + this.options = utils.extend({source: 'string'}, options); + this.init(this.options); + use(this); +} - // Keep track of last clause/group and stack. - lastGroup = start, - last = start.stack, - groupStack = []; +/** + * Prototype methods + */ +Parser.prototype = { + constructor: Parser, - var repeatErr = function(i) { - util.error(regexpStr, 'Nothing to repeat at column ' + (i - 1)); - }; + init: function(options) { + this.orig = ''; + this.input = ''; + this.parsed = ''; - // Decode a few escaped characters. - var str = util.strToChars(regexpStr); - l = str.length; + this.column = 1; + this.line = 1; - // Iterate through each character in string. - while (i < l) { - c = str[i++]; + this.regex = new Cache(); + this.errors = this.errors || []; + this.parsers = this.parsers || {}; + this.types = this.types || []; + this.sets = this.sets || {}; + this.fns = this.fns || []; + this.currentType = 'root'; - switch (c) { - // Handle escaped characters, inclues a few sets. - case '\\': - c = str[i++]; + var pos = this.position(); + this.bos = pos({type: 'bos', val: ''}); - switch (c) { - case 'b': - last.push(positions.wordBoundary()); - break; + this.ast = { + type: 'root', + errors: this.errors, + nodes: [this.bos] + }; - case 'B': - last.push(positions.nonWordBoundary()); - break; + define(this.bos, 'parent', this.ast); + this.nodes = [this.ast]; - case 'w': - last.push(sets.words()); - break; + this.count = 0; + this.setCount = 0; + this.stack = []; + }, - case 'W': - last.push(sets.notWords()); - break; + /** + * Throw a formatted error with the cursor column and `msg`. + * @param {String} `msg` Message to use in the Error. + */ - case 'd': - last.push(sets.ints()); - break; + error: function(msg, node) { + var pos = node.position || {start: {column: 0, line: 0}}; + var line = pos.start.line; + var column = pos.start.column; + var source = this.options.source; - case 'D': - last.push(sets.notInts()); - break; + var message = source + ' : ' + msg; + var err = new Error(message); + err.source = source; + err.reason = msg; + err.pos = pos; - case 's': - last.push(sets.whitespace()); - break; + if (this.options.silent) { + this.errors.push(err); + } else { + throw err; + } + }, - case 'S': - last.push(sets.notWhitespace()); - break; + /** + * Define a non-enumberable property on the `Parser` instance. + * + * ```js + * parser.define('foo', 'bar'); + * ``` + * @name .define + * @param {String} `key` propery name + * @param {any} `val` property value + * @return {Object} Returns the Parser instance for chaining. + * @api public + */ - default: - // Check if c is integer. - // In which case it's a reference. - if (/\d/.test(c)) { - last.push({ type: types.REFERENCE, value: parseInt(c, 10) }); + define: function(key, val) { + define(this, key, val); + return this; + }, - // Escaped character. - } else { - last.push({ type: types.CHAR, value: c.charCodeAt(0) }); - } - } + /** + * Mark position and patch `node.position`. + */ - break; + position: function() { + var start = { line: this.line, column: this.column }; + var self = this; + return function(node) { + define(node, 'position', new Position(start, self)); + return node; + }; + }, - // Positionals. - case '^': - last.push(positions.begin()); - break; + /** + * Set parser `name` with the given `fn` + * @param {String} `name` + * @param {Function} `fn` + * @api public + */ - case '$': - last.push(positions.end()); - break; + set: function(type, fn) { + if (this.types.indexOf(type) === -1) { + this.types.push(type); + } + this.parsers[type] = fn.bind(this); + return this; + }, + /** + * Get parser `name` + * @param {String} `name` + * @api public + */ - // Handle custom sets. - case '[': - // Check if this class is 'anti' i.e. [^abc]. - var not; - if (str[i] === '^') { - not = true; - i++; - } else { - not = false; - } + get: function(name) { + return this.parsers[name]; + }, - // Get all the characters in class. - var classTokens = util.tokenizeClass(str.slice(i), regexpStr); + /** + * Push a `token` onto the `type` stack. + * + * @param {String} `type` + * @return {Object} `token` + * @api public + */ - // Increase index by length of class. - i += classTokens[1]; - last.push({ - type: types.SET, - set: classTokens[0], - not: not, - }); + push: function(type, token) { + this.sets[type] = this.sets[type] || []; + this.count++; + this.stack.push(token); + return this.sets[type].push(token); + }, - break; + /** + * Pop a token off of the `type` stack + * @param {String} `type` + * @returns {Object} Returns a token + * @api public + */ + pop: function(type) { + this.sets[type] = this.sets[type] || []; + this.count--; + this.stack.pop(); + return this.sets[type].pop(); + }, - // Class of any character except \n. - case '.': - last.push(sets.anyChar()); - break; + /** + * Return true if inside a `stack` node. Types are `braces`, `parens` or `brackets`. + * + * @param {String} `type` + * @return {Boolean} + * @api public + */ + isInside: function(type) { + this.sets[type] = this.sets[type] || []; + return this.sets[type].length > 0; + }, - // Push group onto stack. - case '(': - // Create group. - var group = { - type: types.GROUP, - stack: [], - remember: true, - }; + /** + * Return true if `node` is the given `type`. + * + * ```js + * parser.isType(node, 'brace'); + * ``` + * @param {Object} `node` + * @param {String} `type` + * @return {Boolean} + * @api public + */ - c = str[i]; + isType: function(node, type) { + return node && node.type === type; + }, - // If if this is a special kind of group. - if (c === '?') { - c = str[i + 1]; - i += 2; + /** + * Get the previous AST node + * @return {Object} + */ - // Match if followed by. - if (c === '=') { - group.followedBy = true; + prev: function(n) { + return this.stack.length > 0 + ? utils.last(this.stack, n) + : utils.last(this.nodes, n); + }, - // Match if not followed by. - } else if (c === '!') { - group.notFollowedBy = true; + /** + * Update line and column based on `str`. + */ - } else if (c !== ':') { - util.error(regexpStr, - 'Invalid group, character \'' + c + - '\' after \'?\' at column ' + (i - 1)); - } + consume: function(len) { + this.input = this.input.substr(len); + }, - group.remember = false; - } + /** + * Update column based on `str`. + */ - // Insert subgroup into current group stack. - last.push(group); + updatePosition: function(str, len) { + var lines = str.match(/\n/g); + if (lines) this.line += lines.length; + var i = str.lastIndexOf('\n'); + this.column = ~i ? len - i : this.column + len; + this.parsed += str; + this.consume(len); + }, - // Remember the current group for when the group closes. - groupStack.push(lastGroup); + /** + * Match `regex`, return captures, and update the cursor position by `match[0]` length. + * @param {RegExp} `regex` + * @return {Object} + */ - // Make this new group the current group. - lastGroup = group; - last = group.stack; - break; + match: function(regex) { + var m = regex.exec(this.input); + if (m) { + this.updatePosition(m[0], m[0].length); + return m; + } + }, + /** + * Capture `type` with the given regex. + * @param {String} `type` + * @param {RegExp} `regex` + * @return {Function} + */ - // Pop group out of stack. - case ')': - if (groupStack.length === 0) { - util.error(regexpStr, 'Unmatched ) at column ' + (i - 1)); - } - lastGroup = groupStack.pop(); + capture: function(type, regex) { + if (typeof regex === 'function') { + return this.set.apply(this, arguments); + } - // Check if this group has a PIPE. - // To get back the correct last stack. - last = lastGroup.options ? - lastGroup.options[lastGroup.options.length - 1] : lastGroup.stack; - break; + this.regex.set(type, regex); + this.set(type, function() { + var parsed = this.parsed; + var pos = this.position(); + var m = this.match(regex); + if (!m || !m[0]) return; + var prev = this.prev(); + var node = pos({ + type: type, + val: m[0], + parsed: parsed, + rest: this.input + }); - // Use pipe character to give more choices. - case '|': - // Create array where options are if this is the first PIPE - // in this clause. - if (!lastGroup.options) { - lastGroup.options = [lastGroup.stack]; - delete lastGroup.stack; - } + if (m[1]) { + node.inner = m[1]; + } - // Create a new stack and add to options for rest of clause. - var stack = []; - lastGroup.options.push(stack); - last = stack; - break; + define(node, 'inside', this.stack.length > 0); + define(node, 'parent', prev); + prev.nodes.push(node); + }.bind(this)); + return this; + }, + /** + * Create a parser with open and close for parens, + * brackets or braces + */ - // Repetition. - // For every repetition, remove last element from last stack - // then insert back a RANGE object. - // This design is chosen because there could be more than - // one repetition symbols in a regex i.e. `a?+{2,3}`. - case '{': - var rs = /^(\d+)(,(\d+)?)?\}/.exec(str.slice(i)), min, max; - if (rs !== null) { - if (last.length === 0) { - repeatErr(i); - } - min = parseInt(rs[1], 10); - max = rs[2] ? rs[3] ? parseInt(rs[3], 10) : Infinity : min; - i += rs[0].length; + capturePair: function(type, openRegex, closeRegex, fn) { + this.sets[type] = this.sets[type] || []; - last.push({ - type: types.REPETITION, - min: min, - max: max, - value: last.pop(), - }); - } else { - last.push({ - type: types.CHAR, - value: 123, - }); - } - break; + /** + * Open + */ - case '?': - if (last.length === 0) { - repeatErr(i); - } - last.push({ - type: types.REPETITION, - min: 0, - max: 1, - value: last.pop(), - }); - break; + this.set(type + '.open', function() { + var parsed = this.parsed; + var pos = this.position(); + var m = this.match(openRegex); + if (!m || !m[0]) return; - case '+': - if (last.length === 0) { - repeatErr(i); - } - last.push({ - type: types.REPETITION, - min: 1, - max: Infinity, - value: last.pop(), - }); - break; + var val = m[0]; + this.setCount++; + this.specialChars = true; + var open = pos({ + type: type + '.open', + val: val, + rest: this.input + }); - case '*': - if (last.length === 0) { - repeatErr(i); - } - last.push({ - type: types.REPETITION, - min: 0, - max: Infinity, - value: last.pop(), - }); - break; + if (typeof m[1] !== 'undefined') { + open.inner = m[1]; + } + var prev = this.prev(); + var node = pos({ + type: type, + nodes: [open] + }); - // Default is a character that is not `\[](){}?+*^$`. - default: - last.push({ - type: types.CHAR, - value: c.charCodeAt(0), - }); - } + define(node, 'rest', this.input); + define(node, 'parsed', parsed); + define(node, 'prefix', m[1]); + define(node, 'parent', prev); + define(open, 'parent', node); - } + if (typeof fn === 'function') { + fn.call(this, open, node); + } - // Check if any groups have not been closed. - if (groupStack.length !== 0) { - util.error(regexpStr, 'Unterminated group'); - } + this.push(type, node); + prev.nodes.push(node); + }); - return start; -}; + /** + * Close + */ -module.exports.types = types; + this.set(type + '.close', function() { + var pos = this.position(); + var m = this.match(closeRegex); + if (!m || !m[0]) return; + var parent = this.pop(type); + var node = pos({ + type: type + '.close', + rest: this.input, + suffix: m[1], + val: m[0] + }); -/***/ }), -/* 639 */ -/***/ (function(module, exports, __webpack_require__) { + if (!this.isType(parent, type)) { + if (this.options.strict) { + throw new Error('missing opening "' + type + '"'); + } -var types = __webpack_require__(640); -var sets = __webpack_require__(641); + this.setCount--; + node.escaped = true; + return node; + } + if (node.suffix === '\\') { + parent.escaped = true; + node.escaped = true; + } -// All of these are private and only used by randexp. -// It's assumed that they will always be called with the correct input. + parent.nodes.push(node); + define(node, 'parent', parent); + }); -var CTRL = '@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ ?'; -var SLSH = { '0': 0, 't': 9, 'n': 10, 'v': 11, 'f': 12, 'r': 13 }; + return this; + }, -/** - * Finds character representations in str and convert all to - * their respective characters - * - * @param {String} str - * @return {String} - */ -exports.strToChars = function(str) { - /* jshint maxlen: false */ - var chars_regex = /(\[\\b\])|(\\)?\\(?:u([A-F0-9]{4})|x([A-F0-9]{2})|(0?[0-7]{2})|c([@A-Z\[\\\]\^?])|([0tnvfr]))/g; - str = str.replace(chars_regex, function(s, b, lbs, a16, b16, c8, dctrl, eslsh) { - if (lbs) { - return s; - } + /** + * Capture end-of-string + */ - var code = b ? 8 : - a16 ? parseInt(a16, 16) : - b16 ? parseInt(b16, 16) : - c8 ? parseInt(c8, 8) : - dctrl ? CTRL.indexOf(dctrl) : - SLSH[eslsh]; + eos: function() { + var pos = this.position(); + if (this.input) return; + var prev = this.prev(); - var c = String.fromCharCode(code); + while (prev.type !== 'root' && !prev.visited) { + if (this.options.strict === true) { + throw new SyntaxError('invalid syntax:' + util.inspect(prev, null, 2)); + } - // Escape special regex characters. - if (/[\[\]{}\^$.|?*+()]/.test(c)) { - c = '\\' + c; + if (!hasDelims(prev)) { + prev.parent.escaped = true; + prev.escaped = true; + } + + visit(prev, function(node) { + if (!hasDelims(node.parent)) { + node.parent.escaped = true; + node.escaped = true; + } + }); + + prev = prev.parent; } - return c; - }); + var tok = pos({ + type: 'eos', + val: this.append || '' + }); - return str; -}; + define(tok, 'parent', this.ast); + return tok; + }, + /** + * Run parsers to advance the cursor position + */ -/** - * turns class into tokens - * reads str until it encounters a ] not preceeded by a \ - * - * @param {String} str - * @param {String} regexpStr - * @return {Array., Number>} - */ -exports.tokenizeClass = function(str, regexpStr) { - /* jshint maxlen: false */ - var tokens = []; - var regexp = /\\(?:(w)|(d)|(s)|(W)|(D)|(S))|((?:(?:\\)(.)|([^\]\\]))-(?:\\)?([^\]]))|(\])|(?:\\)?(.)/g; - var rs, c; + next: function() { + var parsed = this.parsed; + var len = this.types.length; + var idx = -1; + var tok; + while (++idx < len) { + if ((tok = this.parsers[this.types[idx]].call(this))) { + define(tok, 'rest', this.input); + define(tok, 'parsed', parsed); + this.last = tok; + return tok; + } + } + }, - while ((rs = regexp.exec(str)) != null) { - if (rs[1]) { - tokens.push(sets.words()); + /** + * Parse the given string. + * @return {Array} + */ - } else if (rs[2]) { - tokens.push(sets.ints()); + parse: function(input) { + if (typeof input !== 'string') { + throw new TypeError('expected a string'); + } - } else if (rs[3]) { - tokens.push(sets.whitespace()); + this.init(this.options); + this.orig = input; + this.input = input; + var self = this; - } else if (rs[4]) { - tokens.push(sets.notWords()); + function parse() { + // check input before calling `.next()` + input = self.input; - } else if (rs[5]) { - tokens.push(sets.notInts()); + // get the next AST ndoe + var node = self.next(); + if (node) { + var prev = self.prev(); + if (prev) { + define(node, 'parent', prev); + if (prev.nodes) { + prev.nodes.push(node); + } + } - } else if (rs[6]) { - tokens.push(sets.notWhitespace()); + if (self.sets.hasOwnProperty(prev.type)) { + self.currentType = prev.type; + } + } - } else if (rs[7]) { - tokens.push({ - type: types.RANGE, - from: (rs[8] || rs[9]).charCodeAt(0), - to: rs[10].charCodeAt(0), - }); + // if we got here but input is not changed, throw an error + if (self.input && input === self.input) { + throw new Error('no parsers registered for: "' + self.input.slice(0, 5) + '"'); + } + } - } else if (c = rs[12]) { - tokens.push({ - type: types.CHAR, - value: c.charCodeAt(0), - }); + while (this.input) parse(); + if (this.stack.length && this.options.strict) { + var node = this.stack.pop(); + throw this.error('missing opening ' + node.type + ': "' + this.orig + '"'); + } - } else { - return [tokens, regexp.lastIndex]; + var eos = this.eos(); + var tok = this.prev(); + if (tok.type !== 'eos') { + this.ast.nodes.push(eos); } - } - exports.error(regexpStr, 'Unterminated character class'); + return this.ast; + } }; +/** + * Visit `node` with the given `fn` + */ + +function visit(node, fn) { + if (!node.visited) { + define(node, 'visited', true); + return node.nodes ? mapVisit(node.nodes, fn) : fn(node); + } + return node; +} /** - * Shortcut to throw errors. - * - * @param {String} regexp - * @param {String} msg + * Map visit over array of `nodes`. */ -exports.error = function(regexp, msg) { - throw new SyntaxError('Invalid regular expression: /' + regexp + '/: ' + msg); -}; +function mapVisit(nodes, fn) { + var len = nodes.length; + var idx = -1; + while (++idx < len) { + visit(nodes[idx], fn); + } +} -/***/ }), -/* 640 */ -/***/ (function(module, exports) { +function hasOpen(node) { + return node.nodes && node.nodes[0].type === (node.type + '.open'); +} -module.exports = { - ROOT : 0, - GROUP : 1, - POSITION : 2, - SET : 3, - RANGE : 4, - REPETITION : 5, - REFERENCE : 6, - CHAR : 7, -}; +function hasClose(node) { + return node.nodes && utils.last(node.nodes).type === (node.type + '.close'); +} + +function hasDelims(node) { + return hasOpen(node) && hasClose(node); +} + +/** + * Expose `Parser` + */ + +module.exports = Parser; /***/ }), -/* 641 */ +/* 636 */ /***/ (function(module, exports, __webpack_require__) { -var types = __webpack_require__(640); +"use strict"; +/*! + * map-cache + * + * Copyright (c) 2015, Jon Schlinkert. + * Licensed under the MIT License. + */ -var INTS = function() { - return [{ type: types.RANGE , from: 48, to: 57 }]; -}; -var WORDS = function() { - return [ - { type: types.CHAR, value: 95 }, - { type: types.RANGE, from: 97, to: 122 }, - { type: types.RANGE, from: 65, to: 90 } - ].concat(INTS()); -}; -var WHITESPACE = function() { - return [ - { type: types.CHAR, value: 9 }, - { type: types.CHAR, value: 10 }, - { type: types.CHAR, value: 11 }, - { type: types.CHAR, value: 12 }, - { type: types.CHAR, value: 13 }, - { type: types.CHAR, value: 32 }, - { type: types.CHAR, value: 160 }, - { type: types.CHAR, value: 5760 }, - { type: types.CHAR, value: 6158 }, - { type: types.CHAR, value: 8192 }, - { type: types.CHAR, value: 8193 }, - { type: types.CHAR, value: 8194 }, - { type: types.CHAR, value: 8195 }, - { type: types.CHAR, value: 8196 }, - { type: types.CHAR, value: 8197 }, - { type: types.CHAR, value: 8198 }, - { type: types.CHAR, value: 8199 }, - { type: types.CHAR, value: 8200 }, - { type: types.CHAR, value: 8201 }, - { type: types.CHAR, value: 8202 }, - { type: types.CHAR, value: 8232 }, - { type: types.CHAR, value: 8233 }, - { type: types.CHAR, value: 8239 }, - { type: types.CHAR, value: 8287 }, - { type: types.CHAR, value: 12288 }, - { type: types.CHAR, value: 65279 } - ]; -}; +var hasOwn = Object.prototype.hasOwnProperty; -var NOTANYCHAR = function() { - return [ - { type: types.CHAR, value: 10 }, - { type: types.CHAR, value: 13 }, - { type: types.CHAR, value: 8232 }, - { type: types.CHAR, value: 8233 }, - ]; -}; +/** + * Expose `MapCache` + */ -// Predefined class objects. -exports.words = function() { - return { type: types.SET, set: WORDS(), not: false }; -}; +module.exports = MapCache; -exports.notWords = function() { - return { type: types.SET, set: WORDS(), not: true }; -}; +/** + * Creates a cache object to store key/value pairs. + * + * ```js + * var cache = new MapCache(); + * ``` + * + * @api public + */ -exports.ints = function() { - return { type: types.SET, set: INTS(), not: false }; -}; +function MapCache(data) { + this.__data__ = data || {}; +} -exports.notInts = function() { - return { type: types.SET, set: INTS(), not: true }; -}; +/** + * Adds `value` to `key` on the cache. + * + * ```js + * cache.set('foo', 'bar'); + * ``` + * + * @param {String} `key` The key of the value to cache. + * @param {*} `value` The value to cache. + * @returns {Object} Returns the `Cache` object for chaining. + * @api public + */ -exports.whitespace = function() { - return { type: types.SET, set: WHITESPACE(), not: false }; +MapCache.prototype.set = function mapSet(key, value) { + if (key !== '__proto__') { + this.__data__[key] = value; + } + return this; }; -exports.notWhitespace = function() { - return { type: types.SET, set: WHITESPACE(), not: true }; -}; +/** + * Gets the cached value for `key`. + * + * ```js + * cache.get('foo'); + * //=> 'bar' + * ``` + * + * @param {String} `key` The key of the value to get. + * @returns {*} Returns the cached value. + * @api public + */ -exports.anyChar = function() { - return { type: types.SET, set: NOTANYCHAR(), not: true }; +MapCache.prototype.get = function mapGet(key) { + return key === '__proto__' ? undefined : this.__data__[key]; }; +/** + * Checks if a cached value for `key` exists. + * + * ```js + * cache.has('foo'); + * //=> true + * ``` + * + * @param {String} `key` The key of the entry to check. + * @returns {Boolean} Returns `true` if an entry for `key` exists, else `false`. + * @api public + */ -/***/ }), -/* 642 */ -/***/ (function(module, exports, __webpack_require__) { - -var types = __webpack_require__(640); - -exports.wordBoundary = function() { - return { type: types.POSITION, value: 'b' }; -}; - -exports.nonWordBoundary = function() { - return { type: types.POSITION, value: 'B' }; +MapCache.prototype.has = function mapHas(key) { + return key !== '__proto__' && hasOwn.call(this.__data__, key); }; -exports.begin = function() { - return { type: types.POSITION, value: '^' }; -}; +/** + * Removes `key` and its value from the cache. + * + * ```js + * cache.del('foo'); + * ``` + * @title .del + * @param {String} `key` The key of the value to remove. + * @returns {Boolean} Returns `true` if the entry was removed successfully, else `false`. + * @api public + */ -exports.end = function() { - return { type: types.POSITION, value: '$' }; +MapCache.prototype.del = function mapDelete(key) { + return this.has(key) && delete this.__data__[key]; }; /***/ }), -/* 643 */ +/* 637 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/*! - * define-property - * - * Copyright (c) 2015-2018, Jon Schlinkert. - * Released under the MIT License. - */ - - - -var isobject = __webpack_require__(545); -var isDescriptor = __webpack_require__(559); -var define = (typeof Reflect !== 'undefined' && Reflect.defineProperty) - ? Reflect.defineProperty - : Object.defineProperty; - -module.exports = function defineProperty(obj, key, val) { - if (!isobject(obj) && typeof obj !== 'function' && !Array.isArray(obj)) { - throw new TypeError('expected an object, function, or array'); - } - if (typeof key !== 'string') { - throw new TypeError('expected "key" to be a string'); - } - if (isDescriptor(val)) { - define(obj, key, val); - return obj; - } +var define = __webpack_require__(596); - define(obj, key, { - configurable: true, - enumerable: false, - writable: true, - value: val - }); +/** + * Store position for a node + */ - return obj; +module.exports = function Position(start, parser) { + this.start = start; + this.end = { line: parser.line, column: parser.column }; + define(this, 'content', parser.orig); + define(this, 'source', parser.options.source); }; /***/ }), -/* 644 */ +/* 638 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(645); -var assignSymbols = __webpack_require__(546); +var isExtendable = __webpack_require__(639); +var assignSymbols = __webpack_require__(544); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -75729,7 +75129,7 @@ function isEnum(obj, key) { /***/ }), -/* 645 */ +/* 639 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -75742,7 +75142,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(544); +var isPlainObject = __webpack_require__(543); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -75750,93 +75150,14 @@ module.exports = function isExtendable(val) { /***/ }), -/* 646 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var extend = __webpack_require__(644); -var safe = __webpack_require__(637); - -/** - * The main export is a function that takes a `pattern` string and an `options` object. - * - * ```js - & var not = require('regex-not'); - & console.log(not('foo')); - & //=> /^(?:(?!^(?:foo)$).)*$/ - * ``` - * - * @param {String} `pattern` - * @param {Object} `options` - * @return {RegExp} Converts the given `pattern` to a regex using the specified `options`. - * @api public - */ - -function toRegex(pattern, options) { - return new RegExp(toRegex.create(pattern, options)); -} - -/** - * Create a regex-compatible string from the given `pattern` and `options`. - * - * ```js - & var not = require('regex-not'); - & console.log(not.create('foo')); - & //=> '^(?:(?!^(?:foo)$).)*$' - * ``` - * @param {String} `pattern` - * @param {Object} `options` - * @return {String} - * @api public - */ - -toRegex.create = function(pattern, options) { - if (typeof pattern !== 'string') { - throw new TypeError('expected a string'); - } - - var opts = extend({}, options); - if (opts.contains === true) { - opts.strictNegate = false; - } - - var open = opts.strictOpen !== false ? '^' : ''; - var close = opts.strictClose !== false ? '$' : ''; - var endChar = opts.endChar ? opts.endChar : '+'; - var str = pattern; - - if (opts.strictNegate === false) { - str = '(?:(?!(?:' + pattern + ')).)' + endChar; - } else { - str = '(?:(?!^(?:' + pattern + ')$).)' + endChar; - } - - var res = open + str + close; - if (opts.safe === true && safe(res) === false) { - throw new Error('potentially unsafe regular expression: ' + res); - } - - return res; -}; - -/** - * Expose `toRegex` - */ - -module.exports = toRegex; - - -/***/ }), -/* 647 */ +/* 640 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var nanomatch = __webpack_require__(648); -var extglob = __webpack_require__(664); +var nanomatch = __webpack_require__(641); +var extglob = __webpack_require__(656); module.exports = function(snapdragon) { var compilers = snapdragon.compiler.compilers; @@ -75913,7 +75234,7 @@ function escapeExtglobs(compiler) { /***/ }), -/* 648 */ +/* 641 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -75923,18 +75244,18 @@ function escapeExtglobs(compiler) { * Module dependencies */ -var util = __webpack_require__(111); -var toRegex = __webpack_require__(649); -var extend = __webpack_require__(650); +var util = __webpack_require__(112); +var toRegex = __webpack_require__(526); +var extend = __webpack_require__(642); /** * Local dependencies */ -var compilers = __webpack_require__(652); -var parsers = __webpack_require__(653); -var cache = __webpack_require__(656); -var utils = __webpack_require__(658); +var compilers = __webpack_require__(644); +var parsers = __webpack_require__(645); +var cache = __webpack_require__(648); +var utils = __webpack_require__(650); var MAX_LENGTH = 1024 * 64; /** @@ -76758,169 +76079,14 @@ module.exports = nanomatch; /***/ }), -/* 649 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var define = __webpack_require__(594); -var extend = __webpack_require__(536); -var not = __webpack_require__(535); -var MAX_LENGTH = 1024 * 64; - -/** - * Session cache - */ - -var cache = {}; - -/** - * Create a regular expression from the given `pattern` string. - * - * @param {String|RegExp} `pattern` Pattern can be a string or regular expression. - * @param {Object} `options` - * @return {RegExp} - * @api public - */ - -module.exports = function(patterns, options) { - if (!Array.isArray(patterns)) { - return makeRe(patterns, options); - } - return makeRe(patterns.join('|'), options); -}; - -/** - * Create a regular expression from the given `pattern` string. - * - * @param {String|RegExp} `pattern` Pattern can be a string or regular expression. - * @param {Object} `options` - * @return {RegExp} - * @api public - */ - -function makeRe(pattern, options) { - if (pattern instanceof RegExp) { - return pattern; - } - - if (typeof pattern !== 'string') { - throw new TypeError('expected a string'); - } - - if (pattern.length > MAX_LENGTH) { - throw new Error('expected pattern to be less than ' + MAX_LENGTH + ' characters'); - } - - var key = pattern; - // do this before shallow cloning options, it's a lot faster - if (!options || (options && options.cache !== false)) { - key = createKey(pattern, options); - - if (cache.hasOwnProperty(key)) { - return cache[key]; - } - } - - var opts = extend({}, options); - if (opts.contains === true) { - if (opts.negate === true) { - opts.strictNegate = false; - } else { - opts.strict = false; - } - } - - if (opts.strict === false) { - opts.strictOpen = false; - opts.strictClose = false; - } - - var open = opts.strictOpen !== false ? '^' : ''; - var close = opts.strictClose !== false ? '$' : ''; - var flags = opts.flags || ''; - var regex; - - if (opts.nocase === true && !/i/.test(flags)) { - flags += 'i'; - } - - try { - if (opts.negate || typeof opts.strictNegate === 'boolean') { - pattern = not.create(pattern, opts); - } - var str = open + '(?:' + pattern + ')' + close; - regex = new RegExp(str, flags); - } catch (err) { - if (opts.strictErrors === true) { - err.key = key; - err.pattern = pattern; - err.originalOptions = options; - err.createdOptions = opts; - throw err; - } - - try { - regex = new RegExp('^' + pattern.replace(/(\W)/g, '\\$1') + '$'); - } catch (err) { - regex = /.^/; //<= match nothing - } - } - - if (opts.cache !== false) { - cacheRegex(regex, key, pattern, opts); - } - return regex; -} - -/** - * Cache generated regex. This can result in dramatic speed improvements - * and simplify debugging by adding options and pattern to the regex. It can be - * disabled by passing setting `options.cache` to false. - */ - -function cacheRegex(regex, key, pattern, options) { - define(regex, 'cached', true); - define(regex, 'pattern', pattern); - define(regex, 'options', options); - define(regex, 'key', key); - cache[key] = regex; -} - -/** - * Create the key to use for memoization. The key is generated - * by iterating over the options and concatenating key-value pairs - * to the pattern string. - */ - -function createKey(pattern, options) { - if (!options) return pattern; - var key = pattern; - for (var prop in options) { - if (options.hasOwnProperty(prop)) { - key += ';' + prop + '=' + String(options[prop]); - } - } - return key; -} - -/** - * Expose `makeRe` - */ - -module.exports.makeRe = makeRe; - - -/***/ }), -/* 650 */ +/* 642 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(651); -var assignSymbols = __webpack_require__(546); +var isExtendable = __webpack_require__(643); +var assignSymbols = __webpack_require__(544); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -76980,7 +76146,7 @@ function isEnum(obj, key) { /***/ }), -/* 651 */ +/* 643 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -76993,7 +76159,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(544); +var isPlainObject = __webpack_require__(543); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -77001,7 +76167,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 652 */ +/* 644 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -77347,15 +76513,15 @@ module.exports = function(nanomatch, options) { /***/ }), -/* 653 */ +/* 645 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var regexNot = __webpack_require__(535); -var toRegex = __webpack_require__(649); -var isOdd = __webpack_require__(654); +var regexNot = __webpack_require__(545); +var toRegex = __webpack_require__(526); +var isOdd = __webpack_require__(646); /** * Characters to use in negation regex (we want to "not" match @@ -77741,7 +76907,7 @@ module.exports.not = NOT_REGEX; /***/ }), -/* 654 */ +/* 646 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -77754,7 +76920,7 @@ module.exports.not = NOT_REGEX; -var isNumber = __webpack_require__(655); +var isNumber = __webpack_require__(647); module.exports = function isOdd(i) { if (!isNumber(i)) { @@ -77768,7 +76934,7 @@ module.exports = function isOdd(i) { /***/ }), -/* 655 */ +/* 647 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -77796,14 +76962,14 @@ module.exports = function isNumber(num) { /***/ }), -/* 656 */ +/* 648 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = new (__webpack_require__(657))(); +module.exports = new (__webpack_require__(649))(); /***/ }), -/* 657 */ +/* 649 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -77816,7 +76982,7 @@ module.exports = new (__webpack_require__(657))(); -var MapCache = __webpack_require__(634); +var MapCache = __webpack_require__(636); /** * Create a new `FragmentCache` with an optional object to use for `caches`. @@ -77938,7 +77104,7 @@ exports = module.exports = FragmentCache; /***/ }), -/* 658 */ +/* 650 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -77951,14 +77117,14 @@ var path = __webpack_require__(4); * Module dependencies */ -var isWindows = __webpack_require__(659)(); -var Snapdragon = __webpack_require__(567); -utils.define = __webpack_require__(660); -utils.diff = __webpack_require__(661); -utils.extend = __webpack_require__(650); -utils.pick = __webpack_require__(662); -utils.typeOf = __webpack_require__(663); -utils.unique = __webpack_require__(538); +var isWindows = __webpack_require__(651)(); +var Snapdragon = __webpack_require__(569); +utils.define = __webpack_require__(652); +utils.diff = __webpack_require__(653); +utils.extend = __webpack_require__(642); +utils.pick = __webpack_require__(654); +utils.typeOf = __webpack_require__(655); +utils.unique = __webpack_require__(548); /** * Returns true if the given value is effectively an empty string @@ -78324,7 +77490,7 @@ utils.unixify = function(options) { /***/ }), -/* 659 */ +/* 651 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! @@ -78352,7 +77518,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ /***/ }), -/* 660 */ +/* 652 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -78365,8 +77531,8 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ -var isobject = __webpack_require__(545); -var isDescriptor = __webpack_require__(559); +var isobject = __webpack_require__(534); +var isDescriptor = __webpack_require__(535); var define = (typeof Reflect !== 'undefined' && Reflect.defineProperty) ? Reflect.defineProperty : Object.defineProperty; @@ -78397,7 +77563,7 @@ module.exports = function defineProperty(obj, key, val) { /***/ }), -/* 661 */ +/* 653 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -78451,7 +77617,7 @@ function diffArray(one, two) { /***/ }), -/* 662 */ +/* 654 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -78464,7 +77630,7 @@ function diffArray(one, two) { -var isObject = __webpack_require__(545); +var isObject = __webpack_require__(534); module.exports = function pick(obj, keys) { if (!isObject(obj) && typeof obj !== 'function') { @@ -78493,7 +77659,7 @@ module.exports = function pick(obj, keys) { /***/ }), -/* 663 */ +/* 655 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -78628,7 +77794,7 @@ function isBuffer(val) { /***/ }), -/* 664 */ +/* 656 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -78638,18 +77804,18 @@ function isBuffer(val) { * Module dependencies */ -var extend = __webpack_require__(536); -var unique = __webpack_require__(538); -var toRegex = __webpack_require__(649); +var extend = __webpack_require__(549); +var unique = __webpack_require__(548); +var toRegex = __webpack_require__(526); /** * Local dependencies */ -var compilers = __webpack_require__(665); -var parsers = __webpack_require__(676); -var Extglob = __webpack_require__(679); -var utils = __webpack_require__(678); +var compilers = __webpack_require__(657); +var parsers = __webpack_require__(668); +var Extglob = __webpack_require__(671); +var utils = __webpack_require__(670); var MAX_LENGTH = 1024 * 64; /** @@ -78966,13 +78132,13 @@ module.exports = extglob; /***/ }), -/* 665 */ +/* 657 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var brackets = __webpack_require__(666); +var brackets = __webpack_require__(658); /** * Extglob compilers @@ -79142,7 +78308,7 @@ module.exports = function(extglob) { /***/ }), -/* 666 */ +/* 658 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79152,17 +78318,17 @@ module.exports = function(extglob) { * Local dependencies */ -var compilers = __webpack_require__(667); -var parsers = __webpack_require__(669); +var compilers = __webpack_require__(659); +var parsers = __webpack_require__(661); /** * Module dependencies */ -var debug = __webpack_require__(671)('expand-brackets'); -var extend = __webpack_require__(536); -var Snapdragon = __webpack_require__(567); -var toRegex = __webpack_require__(649); +var debug = __webpack_require__(663)('expand-brackets'); +var extend = __webpack_require__(549); +var Snapdragon = __webpack_require__(569); +var toRegex = __webpack_require__(526); /** * Parses the given POSIX character class `pattern` and returns a @@ -79360,13 +78526,13 @@ module.exports = brackets; /***/ }), -/* 667 */ +/* 659 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var posix = __webpack_require__(668); +var posix = __webpack_require__(660); module.exports = function(brackets) { brackets.compiler @@ -79454,7 +78620,7 @@ module.exports = function(brackets) { /***/ }), -/* 668 */ +/* 660 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79483,14 +78649,14 @@ module.exports = { /***/ }), -/* 669 */ +/* 661 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var utils = __webpack_require__(670); -var define = __webpack_require__(594); +var utils = __webpack_require__(662); +var define = __webpack_require__(596); /** * Text regex @@ -79709,14 +78875,14 @@ module.exports.TEXT_REGEX = TEXT_REGEX; /***/ }), -/* 670 */ +/* 662 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var toRegex = __webpack_require__(649); -var regexNot = __webpack_require__(535); +var toRegex = __webpack_require__(526); +var regexNot = __webpack_require__(545); var cached; /** @@ -79750,7 +78916,7 @@ exports.createRegex = function(pattern, include) { /***/ }), -/* 671 */ +/* 663 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -79759,14 +78925,14 @@ exports.createRegex = function(pattern, include) { */ if (typeof process !== 'undefined' && process.type === 'renderer') { - module.exports = __webpack_require__(672); + module.exports = __webpack_require__(664); } else { - module.exports = __webpack_require__(675); + module.exports = __webpack_require__(667); } /***/ }), -/* 672 */ +/* 664 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -79775,7 +78941,7 @@ if (typeof process !== 'undefined' && process.type === 'renderer') { * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(673); +exports = module.exports = __webpack_require__(665); exports.log = log; exports.formatArgs = formatArgs; exports.save = save; @@ -79957,7 +79123,7 @@ function localstorage() { /***/ }), -/* 673 */ +/* 665 */ /***/ (function(module, exports, __webpack_require__) { @@ -79973,7 +79139,7 @@ exports.coerce = coerce; exports.disable = disable; exports.enable = enable; exports.enabled = enabled; -exports.humanize = __webpack_require__(674); +exports.humanize = __webpack_require__(666); /** * The currently active debug mode names, and names to skip. @@ -80165,7 +79331,7 @@ function coerce(val) { /***/ }), -/* 674 */ +/* 666 */ /***/ (function(module, exports) { /** @@ -80323,15 +79489,15 @@ function plural(ms, n, name) { /***/ }), -/* 675 */ +/* 667 */ /***/ (function(module, exports, __webpack_require__) { /** * Module dependencies. */ -var tty = __webpack_require__(121); -var util = __webpack_require__(111); +var tty = __webpack_require__(122); +var util = __webpack_require__(112); /** * This is the Node.js implementation of `debug()`. @@ -80339,7 +79505,7 @@ var util = __webpack_require__(111); * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(673); +exports = module.exports = __webpack_require__(665); exports.init = init; exports.log = log; exports.formatArgs = formatArgs; @@ -80511,14 +79677,14 @@ function createWritableStdioStream (fd) { break; case 'FILE': - var fs = __webpack_require__(133); + var fs = __webpack_require__(134); stream = new fs.SyncWriteStream(fd, { autoClose: false }); stream._type = 'fs'; break; case 'PIPE': case 'TCP': - var net = __webpack_require__(612); + var net = __webpack_require__(614); stream = new net.Socket({ fd: fd, readable: false, @@ -80577,15 +79743,15 @@ exports.enable(load()); /***/ }), -/* 676 */ +/* 668 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var brackets = __webpack_require__(666); -var define = __webpack_require__(677); -var utils = __webpack_require__(678); +var brackets = __webpack_require__(658); +var define = __webpack_require__(669); +var utils = __webpack_require__(670); /** * Characters to use in text regex (we want to "not" match @@ -80740,7 +79906,7 @@ module.exports = parsers; /***/ }), -/* 677 */ +/* 669 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -80753,7 +79919,7 @@ module.exports = parsers; -var isDescriptor = __webpack_require__(559); +var isDescriptor = __webpack_require__(535); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -80778,14 +79944,14 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 678 */ +/* 670 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var regex = __webpack_require__(535); -var Cache = __webpack_require__(657); +var regex = __webpack_require__(545); +var Cache = __webpack_require__(649); /** * Utils @@ -80854,7 +80020,7 @@ utils.createRegex = function(str) { /***/ }), -/* 679 */ +/* 671 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -80864,16 +80030,16 @@ utils.createRegex = function(str) { * Module dependencies */ -var Snapdragon = __webpack_require__(567); -var define = __webpack_require__(677); -var extend = __webpack_require__(536); +var Snapdragon = __webpack_require__(569); +var define = __webpack_require__(669); +var extend = __webpack_require__(549); /** * Local dependencies */ -var compilers = __webpack_require__(665); -var parsers = __webpack_require__(676); +var compilers = __webpack_require__(657); +var parsers = __webpack_require__(668); /** * Customize Snapdragon parser and renderer @@ -80939,16 +80105,16 @@ module.exports = Extglob; /***/ }), -/* 680 */ +/* 672 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extglob = __webpack_require__(664); -var nanomatch = __webpack_require__(648); -var regexNot = __webpack_require__(535); -var toRegex = __webpack_require__(636); +var extglob = __webpack_require__(656); +var nanomatch = __webpack_require__(641); +var regexNot = __webpack_require__(545); +var toRegex = __webpack_require__(526); var not; /** @@ -81029,14 +80195,14 @@ function textRegex(pattern) { /***/ }), -/* 681 */ +/* 673 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = new (__webpack_require__(657))(); +module.exports = new (__webpack_require__(649))(); /***/ }), -/* 682 */ +/* 674 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81049,13 +80215,13 @@ var path = __webpack_require__(4); * Module dependencies */ -var Snapdragon = __webpack_require__(567); -utils.define = __webpack_require__(643); -utils.diff = __webpack_require__(661); -utils.extend = __webpack_require__(644); -utils.pick = __webpack_require__(662); -utils.typeOf = __webpack_require__(683); -utils.unique = __webpack_require__(538); +var Snapdragon = __webpack_require__(569); +utils.define = __webpack_require__(675); +utils.diff = __webpack_require__(653); +utils.extend = __webpack_require__(638); +utils.pick = __webpack_require__(654); +utils.typeOf = __webpack_require__(676); +utils.unique = __webpack_require__(548); /** * Returns true if the platform is windows, or `path.sep` is `\\`. @@ -81352,7 +80518,52 @@ utils.unixify = function(options) { /***/ }), -/* 683 */ +/* 675 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/*! + * define-property + * + * Copyright (c) 2015-2018, Jon Schlinkert. + * Released under the MIT License. + */ + + + +var isobject = __webpack_require__(534); +var isDescriptor = __webpack_require__(535); +var define = (typeof Reflect !== 'undefined' && Reflect.defineProperty) + ? Reflect.defineProperty + : Object.defineProperty; + +module.exports = function defineProperty(obj, key, val) { + if (!isobject(obj) && typeof obj !== 'function' && !Array.isArray(obj)) { + throw new TypeError('expected an object, function, or array'); + } + + if (typeof key !== 'string') { + throw new TypeError('expected "key" to be a string'); + } + + if (isDescriptor(val)) { + define(obj, key, val); + return obj; + } + + define(obj, key, { + configurable: true, + enumerable: false, + writable: true, + value: val + }); + + return obj; +}; + + +/***/ }), +/* 676 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -81487,7 +80698,7 @@ function isBuffer(val) { /***/ }), -/* 684 */ +/* 677 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81506,9 +80717,9 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var readdir = __webpack_require__(685); -var reader_1 = __webpack_require__(698); -var fs_stream_1 = __webpack_require__(702); +var readdir = __webpack_require__(678); +var reader_1 = __webpack_require__(691); +var fs_stream_1 = __webpack_require__(695); var ReaderAsync = /** @class */ (function (_super) { __extends(ReaderAsync, _super); function ReaderAsync() { @@ -81569,15 +80780,15 @@ exports.default = ReaderAsync; /***/ }), -/* 685 */ +/* 678 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const readdirSync = __webpack_require__(686); -const readdirAsync = __webpack_require__(694); -const readdirStream = __webpack_require__(697); +const readdirSync = __webpack_require__(679); +const readdirAsync = __webpack_require__(687); +const readdirStream = __webpack_require__(690); module.exports = exports = readdirAsyncPath; exports.readdir = exports.readdirAsync = exports.async = readdirAsyncPath; @@ -81661,7 +80872,7 @@ function readdirStreamStat (dir, options) { /***/ }), -/* 686 */ +/* 679 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81669,11 +80880,11 @@ function readdirStreamStat (dir, options) { module.exports = readdirSync; -const DirectoryReader = __webpack_require__(687); +const DirectoryReader = __webpack_require__(680); let syncFacade = { - fs: __webpack_require__(692), - forEach: __webpack_require__(693), + fs: __webpack_require__(685), + forEach: __webpack_require__(686), sync: true }; @@ -81702,18 +80913,18 @@ function readdirSync (dir, options, internalOptions) { /***/ }), -/* 687 */ +/* 680 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const Readable = __webpack_require__(137).Readable; -const EventEmitter = __webpack_require__(155).EventEmitter; +const Readable = __webpack_require__(138).Readable; +const EventEmitter = __webpack_require__(156).EventEmitter; const path = __webpack_require__(4); -const normalizeOptions = __webpack_require__(688); -const stat = __webpack_require__(690); -const call = __webpack_require__(691); +const normalizeOptions = __webpack_require__(681); +const stat = __webpack_require__(683); +const call = __webpack_require__(684); /** * Asynchronously reads the contents of a directory and streams the results @@ -82089,14 +81300,14 @@ module.exports = DirectoryReader; /***/ }), -/* 688 */ +/* 681 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const globToRegExp = __webpack_require__(689); +const globToRegExp = __webpack_require__(682); module.exports = normalizeOptions; @@ -82273,7 +81484,7 @@ function normalizeOptions (options, internalOptions) { /***/ }), -/* 689 */ +/* 682 */ /***/ (function(module, exports) { module.exports = function (glob, opts) { @@ -82410,13 +81621,13 @@ module.exports = function (glob, opts) { /***/ }), -/* 690 */ +/* 683 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const call = __webpack_require__(691); +const call = __webpack_require__(684); module.exports = stat; @@ -82491,7 +81702,7 @@ function symlinkStat (fs, path, lstats, callback) { /***/ }), -/* 691 */ +/* 684 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82552,14 +81763,14 @@ function callOnce (fn) { /***/ }), -/* 692 */ +/* 685 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fs = __webpack_require__(133); -const call = __webpack_require__(691); +const fs = __webpack_require__(134); +const call = __webpack_require__(684); /** * A facade around {@link fs.readdirSync} that allows it to be called @@ -82623,7 +81834,7 @@ exports.lstat = function (path, callback) { /***/ }), -/* 693 */ +/* 686 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82652,7 +81863,7 @@ function syncForEach (array, iterator, done) { /***/ }), -/* 694 */ +/* 687 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82660,12 +81871,12 @@ function syncForEach (array, iterator, done) { module.exports = readdirAsync; -const maybe = __webpack_require__(695); -const DirectoryReader = __webpack_require__(687); +const maybe = __webpack_require__(688); +const DirectoryReader = __webpack_require__(680); let asyncFacade = { - fs: __webpack_require__(133), - forEach: __webpack_require__(696), + fs: __webpack_require__(134), + forEach: __webpack_require__(689), async: true }; @@ -82707,7 +81918,7 @@ function readdirAsync (dir, options, callback, internalOptions) { /***/ }), -/* 695 */ +/* 688 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82734,7 +81945,7 @@ module.exports = function maybe (cb, promise) { /***/ }), -/* 696 */ +/* 689 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82770,7 +81981,7 @@ function asyncForEach (array, iterator, done) { /***/ }), -/* 697 */ +/* 690 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82778,11 +81989,11 @@ function asyncForEach (array, iterator, done) { module.exports = readdirStream; -const DirectoryReader = __webpack_require__(687); +const DirectoryReader = __webpack_require__(680); let streamFacade = { - fs: __webpack_require__(133), - forEach: __webpack_require__(696), + fs: __webpack_require__(134), + forEach: __webpack_require__(689), async: true }; @@ -82802,16 +82013,16 @@ function readdirStream (dir, options, internalOptions) { /***/ }), -/* 698 */ +/* 691 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var path = __webpack_require__(4); -var deep_1 = __webpack_require__(699); -var entry_1 = __webpack_require__(701); -var pathUtil = __webpack_require__(700); +var deep_1 = __webpack_require__(692); +var entry_1 = __webpack_require__(694); +var pathUtil = __webpack_require__(693); var Reader = /** @class */ (function () { function Reader(options) { this.options = options; @@ -82877,14 +82088,14 @@ exports.default = Reader; /***/ }), -/* 699 */ +/* 692 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var pathUtils = __webpack_require__(700); -var patternUtils = __webpack_require__(517); +var pathUtils = __webpack_require__(693); +var patternUtils = __webpack_require__(520); var DeepFilter = /** @class */ (function () { function DeepFilter(options, micromatchOptions) { this.options = options; @@ -82967,7 +82178,7 @@ exports.default = DeepFilter; /***/ }), -/* 700 */ +/* 693 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82998,14 +82209,14 @@ exports.makeAbsolute = makeAbsolute; /***/ }), -/* 701 */ +/* 694 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var pathUtils = __webpack_require__(700); -var patternUtils = __webpack_require__(517); +var pathUtils = __webpack_require__(693); +var patternUtils = __webpack_require__(520); var EntryFilter = /** @class */ (function () { function EntryFilter(options, micromatchOptions) { this.options = options; @@ -83090,7 +82301,7 @@ exports.default = EntryFilter; /***/ }), -/* 702 */ +/* 695 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83109,9 +82320,9 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var stream = __webpack_require__(137); -var fsStat = __webpack_require__(703); -var fs_1 = __webpack_require__(707); +var stream = __webpack_require__(138); +var fsStat = __webpack_require__(696); +var fs_1 = __webpack_require__(700); var FileSystemStream = /** @class */ (function (_super) { __extends(FileSystemStream, _super); function FileSystemStream() { @@ -83161,14 +82372,14 @@ exports.default = FileSystemStream; /***/ }), -/* 703 */ +/* 696 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const optionsManager = __webpack_require__(704); -const statProvider = __webpack_require__(706); +const optionsManager = __webpack_require__(697); +const statProvider = __webpack_require__(699); /** * Asynchronous API. */ @@ -83199,13 +82410,13 @@ exports.statSync = statSync; /***/ }), -/* 704 */ +/* 697 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fsAdapter = __webpack_require__(705); +const fsAdapter = __webpack_require__(698); function prepare(opts) { const options = Object.assign({ fs: fsAdapter.getFileSystemAdapter(opts ? opts.fs : undefined), @@ -83218,13 +82429,13 @@ exports.prepare = prepare; /***/ }), -/* 705 */ +/* 698 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(133); +const fs = __webpack_require__(134); exports.FILE_SYSTEM_ADAPTER = { lstat: fs.lstat, stat: fs.stat, @@ -83241,7 +82452,7 @@ exports.getFileSystemAdapter = getFileSystemAdapter; /***/ }), -/* 706 */ +/* 699 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83293,7 +82504,7 @@ exports.isFollowedSymlink = isFollowedSymlink; /***/ }), -/* 707 */ +/* 700 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83324,7 +82535,7 @@ exports.default = FileSystem; /***/ }), -/* 708 */ +/* 701 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83343,10 +82554,10 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var stream = __webpack_require__(137); -var readdir = __webpack_require__(685); -var reader_1 = __webpack_require__(698); -var fs_stream_1 = __webpack_require__(702); +var stream = __webpack_require__(138); +var readdir = __webpack_require__(678); +var reader_1 = __webpack_require__(691); +var fs_stream_1 = __webpack_require__(695); var TransformStream = /** @class */ (function (_super) { __extends(TransformStream, _super); function TransformStream(reader) { @@ -83414,7 +82625,7 @@ exports.default = ReaderStream; /***/ }), -/* 709 */ +/* 702 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83433,9 +82644,9 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var readdir = __webpack_require__(685); -var reader_1 = __webpack_require__(698); -var fs_sync_1 = __webpack_require__(710); +var readdir = __webpack_require__(678); +var reader_1 = __webpack_require__(691); +var fs_sync_1 = __webpack_require__(703); var ReaderSync = /** @class */ (function (_super) { __extends(ReaderSync, _super); function ReaderSync() { @@ -83495,7 +82706,7 @@ exports.default = ReaderSync; /***/ }), -/* 710 */ +/* 703 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83514,8 +82725,8 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var fsStat = __webpack_require__(703); -var fs_1 = __webpack_require__(707); +var fsStat = __webpack_require__(696); +var fs_1 = __webpack_require__(700); var FileSystemSync = /** @class */ (function (_super) { __extends(FileSystemSync, _super); function FileSystemSync() { @@ -83561,7 +82772,7 @@ exports.default = FileSystemSync; /***/ }), -/* 711 */ +/* 704 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83577,13 +82788,13 @@ exports.flatten = flatten; /***/ }), -/* 712 */ +/* 705 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var merge2 = __webpack_require__(292); +var merge2 = __webpack_require__(284); /** * Merge multiple streams and propagate their errors into one stream in parallel. */ @@ -83598,13 +82809,13 @@ exports.merge = merge; /***/ }), -/* 713 */ +/* 706 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const pathType = __webpack_require__(714); +const pathType = __webpack_require__(707); const getExtensions = extensions => extensions.length > 1 ? `{${extensions.join(',')}}` : extensions[0]; @@ -83670,13 +82881,13 @@ module.exports.sync = (input, opts) => { /***/ }), -/* 714 */ +/* 707 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fs = __webpack_require__(133); -const pify = __webpack_require__(715); +const fs = __webpack_require__(134); +const pify = __webpack_require__(708); function type(fn, fn2, fp) { if (typeof fp !== 'string') { @@ -83719,7 +82930,7 @@ exports.symlinkSync = typeSync.bind(null, 'lstatSync', 'isSymbolicLink'); /***/ }), -/* 715 */ +/* 708 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83810,17 +83021,17 @@ module.exports = (obj, opts) => { /***/ }), -/* 716 */ +/* 709 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fs = __webpack_require__(133); +const fs = __webpack_require__(134); const path = __webpack_require__(4); -const fastGlob = __webpack_require__(513); -const gitIgnore = __webpack_require__(717); -const pify = __webpack_require__(718); -const slash = __webpack_require__(719); +const fastGlob = __webpack_require__(516); +const gitIgnore = __webpack_require__(710); +const pify = __webpack_require__(711); +const slash = __webpack_require__(712); const DEFAULT_IGNORE = [ '**/node_modules/**', @@ -83918,7 +83129,7 @@ module.exports.sync = options => { /***/ }), -/* 717 */ +/* 710 */ /***/ (function(module, exports) { // A simple implementation of make-array @@ -84387,7 +83598,7 @@ module.exports = options => new IgnoreBase(options) /***/ }), -/* 718 */ +/* 711 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -84462,7 +83673,7 @@ module.exports = (input, options) => { /***/ }), -/* 719 */ +/* 712 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -84480,71 +83691,17 @@ module.exports = input => { /***/ }), -/* 720 */ -/***/ (function(module, exports, __webpack_require__) { - -/*! - * is-glob - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ - -var isExtglob = __webpack_require__(303); -var chars = { '{': '}', '(': ')', '[': ']'}; -var strictRegex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; -var relaxedRegex = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; - -module.exports = function isGlob(str, options) { - if (typeof str !== 'string' || str === '') { - return false; - } - - if (isExtglob(str)) { - return true; - } - - var regex = strictRegex; - var match; - - // optionally relax regex - if (options && options.strict === false) { - regex = relaxedRegex; - } - - while ((match = regex.exec(str))) { - if (match[2]) return true; - var idx = match.index + match[0].length; - - // if an open bracket/brace/paren is escaped, - // set the index to the next closing character - var open = match[1]; - var close = open ? chars[open] : null; - if (open && close) { - var n = str.indexOf(close, idx); - if (n !== -1) { - idx = n + 1; - } - } - - str = str.slice(idx); - } - return false; -}; - - -/***/ }), -/* 721 */ +/* 713 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const {constants: fsConstants} = __webpack_require__(133); -const pEvent = __webpack_require__(722); -const CpFileError = __webpack_require__(725); -const fs = __webpack_require__(729); -const ProgressEmitter = __webpack_require__(732); +const {constants: fsConstants} = __webpack_require__(134); +const pEvent = __webpack_require__(714); +const CpFileError = __webpack_require__(717); +const fs = __webpack_require__(719); +const ProgressEmitter = __webpack_require__(722); const cpFileAsync = async (source, destination, options, progressEmitter) => { let readError; @@ -84658,12 +83815,12 @@ module.exports.sync = (source, destination, options) => { /***/ }), -/* 722 */ +/* 714 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pTimeout = __webpack_require__(723); +const pTimeout = __webpack_require__(715); const symbolAsyncIterator = Symbol.asyncIterator || '@@asyncIterator'; @@ -84954,12 +84111,12 @@ module.exports.iterator = (emitter, event, options) => { /***/ }), -/* 723 */ +/* 715 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pFinally = __webpack_require__(724); +const pFinally = __webpack_require__(716); class TimeoutError extends Error { constructor(message) { @@ -85005,7 +84162,7 @@ module.exports.TimeoutError = TimeoutError; /***/ }), -/* 724 */ +/* 716 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85027,12 +84184,12 @@ module.exports = (promise, onFinally) => { /***/ }), -/* 725 */ +/* 717 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const NestedError = __webpack_require__(726); +const NestedError = __webpack_require__(718); class CpFileError extends NestedError { constructor(message, nested) { @@ -85046,15 +84203,17 @@ module.exports = CpFileError; /***/ }), -/* 726 */ +/* 718 */ /***/ (function(module, exports, __webpack_require__) { -var inherits = __webpack_require__(727); +var inherits = __webpack_require__(112).inherits; var NestedError = function (message, nested) { this.nested = nested; - if (typeof message !== 'undefined') { + if (message instanceof Error) { + nested = message; + } else if (typeof message !== 'undefined') { Object.defineProperty(this, 'message', { value: message, writable: true, @@ -85100,58 +84259,16 @@ module.exports = NestedError; /***/ }), -/* 727 */ -/***/ (function(module, exports, __webpack_require__) { - -try { - var util = __webpack_require__(111); - if (typeof util.inherits !== 'function') throw ''; - module.exports = util.inherits; -} catch (e) { - module.exports = __webpack_require__(728); -} - - -/***/ }), -/* 728 */ -/***/ (function(module, exports) { - -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor - } -} - - -/***/ }), -/* 729 */ +/* 719 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const {promisify} = __webpack_require__(111); -const fs = __webpack_require__(132); -const makeDir = __webpack_require__(730); -const pEvent = __webpack_require__(722); -const CpFileError = __webpack_require__(725); +const {promisify} = __webpack_require__(112); +const fs = __webpack_require__(133); +const makeDir = __webpack_require__(720); +const pEvent = __webpack_require__(714); +const CpFileError = __webpack_require__(717); const stat = promisify(fs.stat); const lstat = promisify(fs.lstat); @@ -85248,15 +84365,15 @@ exports.copyFileSync = (source, destination, flags) => { /***/ }), -/* 730 */ +/* 720 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fs = __webpack_require__(133); +const fs = __webpack_require__(134); const path = __webpack_require__(4); -const {promisify} = __webpack_require__(111); -const semver = __webpack_require__(731); +const {promisify} = __webpack_require__(112); +const semver = __webpack_require__(721); const useNativeRecursiveOption = semver.satisfies(process.version, '>=10.12.0'); @@ -85411,7 +84528,7 @@ module.exports.sync = (input, options) => { /***/ }), -/* 731 */ +/* 721 */ /***/ (function(module, exports) { exports = module.exports = SemVer @@ -87013,12 +86130,12 @@ function coerce (version, options) { /***/ }), -/* 732 */ +/* 722 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const EventEmitter = __webpack_require__(155); +const EventEmitter = __webpack_require__(156); const written = new WeakMap(); @@ -87054,7 +86171,7 @@ module.exports = ProgressEmitter; /***/ }), -/* 733 */ +/* 723 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -87100,12 +86217,12 @@ exports.default = module.exports; /***/ }), -/* 734 */ +/* 724 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const NestedError = __webpack_require__(735); +const NestedError = __webpack_require__(718); class CpyError extends NestedError { constructor(message, nested) { @@ -87118,61 +86235,5 @@ class CpyError extends NestedError { module.exports = CpyError; -/***/ }), -/* 735 */ -/***/ (function(module, exports, __webpack_require__) { - -var inherits = __webpack_require__(111).inherits; - -var NestedError = function (message, nested) { - this.nested = nested; - - if (message instanceof Error) { - nested = message; - } else if (typeof message !== 'undefined') { - Object.defineProperty(this, 'message', { - value: message, - writable: true, - enumerable: false, - configurable: true - }); - } - - Error.captureStackTrace(this, this.constructor); - var oldStackDescriptor = Object.getOwnPropertyDescriptor(this, 'stack'); - var stackDescriptor = buildStackDescriptor(oldStackDescriptor, nested); - Object.defineProperty(this, 'stack', stackDescriptor); -}; - -function buildStackDescriptor(oldStackDescriptor, nested) { - if (oldStackDescriptor.get) { - return { - get: function () { - var stack = oldStackDescriptor.get.call(this); - return buildCombinedStacks(stack, this.nested); - } - }; - } else { - var stack = oldStackDescriptor.value; - return { - value: buildCombinedStacks(stack, nested) - }; - } -} - -function buildCombinedStacks(stack, nested) { - if (nested) { - stack += '\nCaused By: ' + nested.stack; - } - return stack; -} - -inherits(NestedError, Error); -NestedError.prototype.name = 'NestedError'; - - -module.exports = NestedError; - - /***/ }) /******/ ]); \ No newline at end of file diff --git a/packages/kbn-pm/package.json b/packages/kbn-pm/package.json index 1fb94e4c92ce1..8ffd86b84bf76 100644 --- a/packages/kbn-pm/package.json +++ b/packages/kbn-pm/package.json @@ -10,7 +10,7 @@ "prettier": "prettier --write './src/**/*.ts'" }, "devDependencies": { - "@babel/core": "^7.11.1", + "@babel/core": "^7.11.6", "@babel/plugin-proposal-class-properties": "^7.10.4", "@babel/plugin-proposal-object-rest-spread": "^7.11.0", "@babel/preset-env": "^7.11.0", @@ -19,8 +19,8 @@ "@types/cpy": "^5.1.0", "@types/dedent": "^0.7.0", "@types/getopts": "^2.0.1", - "@types/glob": "^5.0.35", - "@types/globby": "^6.1.0", + "@types/glob": "^7.1.2", + "@types/globby": "^8.0.0", "@types/has-ansi": "^3.0.0", "@types/lodash": "^4.14.159", "@types/log-symbols": "^2.0.0", @@ -28,7 +28,7 @@ "@types/node": ">=10.17.17 <10.20.0", "@types/ora": "^1.3.5", "@types/read-pkg": "^4.0.0", - "@types/strip-ansi": "^3.0.0", + "@types/strip-ansi": "^5.2.1", "@types/strong-log-transformer": "^1.0.0", "@types/tempy": "^0.2.0", "@types/write-pkg": "^3.1.0", @@ -41,22 +41,22 @@ "dedent": "^0.7.0", "del": "^5.1.0", "execa": "^4.0.2", - "getopts": "^2.2.4", + "getopts": "^2.2.5", "glob": "^7.1.2", "globby": "^8.0.1", "has-ansi": "^3.0.0", "is-path-inside": "^3.0.2", - "lodash": "^4.17.15", + "lodash": "^4.17.20", "log-symbols": "^2.2.0", "multimatch": "^4.0.0", "ncp": "^2.0.0", - "ora": "^1.4.0", + "ora": "^4.0.4", "prettier": "^2.1.1", "read-pkg": "^5.2.0", "rxjs": "^6.5.5", "spawn-sync": "^1.0.15", "string-replace-loader": "^2.2.0", - "strip-ansi": "^4.0.0", + "strip-ansi": "^6.0.0", "strong-log-transformer": "^2.1.0", "tempy": "^0.3.0", "typescript": "4.0.2", diff --git a/packages/kbn-pm/src/utils/validate_yarn_lock.ts b/packages/kbn-pm/src/utils/validate_yarn_lock.ts index e110dc4d921cf..ec853a3a958fb 100644 --- a/packages/kbn-pm/src/utils/validate_yarn_lock.ts +++ b/packages/kbn-pm/src/utils/validate_yarn_lock.ts @@ -25,6 +25,7 @@ import { writeFile } from './fs'; import { Kibana } from './kibana'; import { YarnLock } from './yarn_lock'; import { log } from './log'; +import { Project } from './project'; export async function validateYarnLock(kbn: Kibana, yarnLock: YarnLock) { // look through all of the packages in the yarn.lock file to see if @@ -95,5 +96,66 @@ export async function validateYarnLock(kbn: Kibana, yarnLock: YarnLock) { process.exit(1); } + // TODO: remove this once we move into a single package.json + // look through all the package.json files to find packages which have mismatched version ranges + const depRanges = new Map>(); + for (const project of kbn.getAllProjects().values()) { + for (const [dep, range] of Object.entries(project.allDependencies)) { + const existingDep = depRanges.get(dep); + if (!existingDep) { + depRanges.set(dep, [ + { + range, + projects: [project], + }, + ]); + continue; + } + + const existingRange = existingDep.find((existing) => existing.range === range); + if (!existingRange) { + existingDep.push({ + range, + projects: [project], + }); + continue; + } + + existingRange.projects.push(project); + } + } + + const duplicateRanges = Array.from(depRanges.entries()) + .filter(([, ranges]) => ranges.length > 1) + .reduce( + (acc: string[], [dep, ranges]) => [ + ...acc, + dep, + ...ranges.map( + ({ range, projects }) => ` ${range} => ${projects.map((p) => p.name).join(', ')}` + ), + ], + [] + ) + .join('\n '); + + if (duplicateRanges) { + log.error(dedent` + + [single_version_dependencies] Multiple version ranges for the same dependency + were found declared across different package.json files. Please consolidate + those to match across all package.json files. Different versions for the + same dependency is not supported. + + If you have questions about this please reach out to the operations team. + + The conflicting dependencies are: + + ${duplicateRanges} + `); + + process.exit(1); + } + log.success('yarn.lock analysis completed without any issues'); } diff --git a/packages/kbn-release-notes/package.json b/packages/kbn-release-notes/package.json index f8971fa02aa87..268530c22399a 100644 --- a/packages/kbn-release-notes/package.json +++ b/packages/kbn-release-notes/package.json @@ -13,7 +13,7 @@ "axios": "^0.19.2", "cheerio": "0.22.0", "dedent": "^0.7.0", - "graphql": "^14.0.0", + "graphql": "^0.13.2", "graphql-tag": "^2.10.3", "terminal-link": "^2.1.1" }, diff --git a/packages/kbn-spec-to-console/package.json b/packages/kbn-spec-to-console/package.json index 63ce93ac54f46..557f38ec740fc 100644 --- a/packages/kbn-spec-to-console/package.json +++ b/packages/kbn-spec-to-console/package.json @@ -17,11 +17,11 @@ }, "homepage": "https://github.com/jbudz/spec-to-console#readme", "devDependencies": { - "jest": "^25.5.4", + "jest": "^26.4.2", "prettier": "^2.1.1" }, "dependencies": { - "commander": "^3.0.0", + "commander": "^3.0.2", "glob": "^7.1.2" } -} \ No newline at end of file +} diff --git a/packages/kbn-std/package.json b/packages/kbn-std/package.json index 2cc9fd72082be..a931dd3f3154d 100644 --- a/packages/kbn-std/package.json +++ b/packages/kbn-std/package.json @@ -15,6 +15,6 @@ }, "dependencies": { "@kbn/utility-types": "1.0.0", - "lodash": "^4.17.15" + "lodash": "^4.17.20" } } diff --git a/packages/kbn-std/src/index.ts b/packages/kbn-std/src/index.ts index 7cf70a0e28e2c..d9d3ec4b0d52b 100644 --- a/packages/kbn-std/src/index.ts +++ b/packages/kbn-std/src/index.ts @@ -24,6 +24,6 @@ export { mapToObject } from './map_to_object'; export { merge } from './merge'; export { pick } from './pick'; export { withTimeout } from './promise'; -export { isRelativeUrl, modifyUrl, URLMeaningfulParts } from './url'; +export { isRelativeUrl, modifyUrl, getUrlOrigin, URLMeaningfulParts } from './url'; export { unset } from './unset'; export { getFlattenedObject } from './get_flattened_object'; diff --git a/packages/kbn-std/src/merge.ts b/packages/kbn-std/src/merge.ts index dca8077435657..43878c27b1e19 100644 --- a/packages/kbn-std/src/merge.ts +++ b/packages/kbn-std/src/merge.ts @@ -16,9 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -// Prefer importing entire lodash library, e.g. import { get } from "lodash" -// eslint-disable-next-line no-restricted-imports -import isPlainObject from 'lodash/isPlainObject'; +import { isPlainObject } from 'lodash'; /** * Deeply merges two objects, omitting undefined values, and not deeply merging Arrays. * diff --git a/packages/kbn-std/src/url.test.ts b/packages/kbn-std/src/url.test.ts index 7e9b6adfd3f49..4d5c5a1808c55 100644 --- a/packages/kbn-std/src/url.test.ts +++ b/packages/kbn-std/src/url.test.ts @@ -17,7 +17,7 @@ * under the License. */ -import { modifyUrl, isRelativeUrl } from './url'; +import { modifyUrl, isRelativeUrl, getUrlOrigin } from './url'; describe('modifyUrl()', () => { test('throws an error with invalid input', () => { @@ -83,3 +83,27 @@ describe('isRelativeUrl()', () => { expect(isRelativeUrl(' //evil.com')).toBe(false); }); }); + +describe('getOrigin', () => { + describe('when passing an absolute url', () => { + it('return origin without port when the url does not have a port', () => { + expect(getUrlOrigin('https://example.com/file/to/path?example')).toEqual( + 'https://example.com' + ); + }); + it('return origin with port when the url does have a port', () => { + expect(getUrlOrigin('http://example.com:80/path/to/file')).toEqual('http://example.com:80'); + }); + }); + describe('when passing a non absolute url', () => { + it('returns null for relative url', () => { + expect(getUrlOrigin('./path/to/file')).toBeNull(); + }); + it('returns null for absolute path', () => { + expect(getUrlOrigin('/path/to/file')).toBeNull(); + }); + it('returns null for empty url', () => { + expect(getUrlOrigin('')).toBeNull(); + }); + }); +}); diff --git a/packages/kbn-std/src/url.ts b/packages/kbn-std/src/url.ts index edcdebbd2bc81..745ed05751b10 100644 --- a/packages/kbn-std/src/url.ts +++ b/packages/kbn-std/src/url.ts @@ -125,3 +125,14 @@ export function isRelativeUrl(candidatePath: string) { } return true; } + +/** + * Returns the origin (protocol + host + port) from given `url` if `url` is a valid absolute url, or null otherwise + */ +export function getUrlOrigin(url: string): string | null { + const obj = parseUrl(url); + if (!obj.protocol && !obj.hostname) { + return null; + } + return `${obj.protocol}//${obj.hostname}${obj.port ? `:${obj.port}` : ''}`; +} diff --git a/packages/kbn-storybook/README.md b/packages/kbn-storybook/README.md index c9195f41ebf26..eea8912c8715e 100644 --- a/packages/kbn-storybook/README.md +++ b/packages/kbn-storybook/README.md @@ -2,32 +2,40 @@ This package provides ability to add [Storybook](https://storybook.js.org/) to any Kibana plugin. -- [Setup Instructions](#setup-instructions) - +- [Kibana Storybook](#kibana-storybook) + - [Setup Instructions](#setup-instructions) + - [Customizing configuration](#customizing-configuration) ## Setup Instructions -1. Add `storybook.js` launcher file to your plugin. For example, create a file at - `src/plugins//scripts/storybook.js`, with the following contents: - - ```js - import { join } from 'path'; - - // eslint-disable-next-line - require('@kbn/storybook').runStorybookCli({ - name: '', - storyGlobs: [join(__dirname, '..', 'public', 'components', '**', '*.examples.tsx')], - }); - ``` -2. Add your plugin alias to `src/dev/storybook/aliases.ts` config. -3. Create sample Storybook stories. For example, in your plugin create create a file at - `src/plugins//public/components/hello_world/__examples__/hello_world.examples.tsx` with - the following contents: - - ```jsx - import * as React from 'react'; - import { storiesOf } from '@storybook/react'; - - storiesOf('Hello world', module).add('default', () =>
Hello world!
); - ``` -4. Launch Storybook with `yarn storybook `. +- Add a `.storybook/main.js` configuration file to your plugin. For example, create a file at + `src/plugins//.storybook/main.js`, with the following contents: + + ```js + module.exports = require('@kbn/storybook').defaultConfig; + ``` + +- Add your plugin alias to `src/dev/storybook/aliases.ts` config. +- Create sample Storybook stories. For example, in your plugin create a file at + `src/plugins//public/components/hello_world/hello_world.stories.tsx` with + the following [Component Story Format](https://storybook.js.org/docs/react/api/csf) contents: + + ```jsx + import { MyComponent } from './my_component'; + + export default { + component: MyComponent, + title: 'Path/In/Side/Navigation/ToComponent', + }; + + export function Example() { + return ; + } + ``` + +- Launch Storybook with `yarn storybook `, or build a static site with `yarn storybook --site `. + +## Customizing configuration + +The `defaultConfig` object provided by the @kbn/storybook package should be all you need to get running, but you can +override this in your .storybook/main.js. Using [Storybook's configuration options](https://storybook.js.org/docs/react/configure/overview). diff --git a/packages/kbn-storybook/index.js b/packages/kbn-storybook/index.js deleted file mode 100644 index 77d457f2bb3c0..0000000000000 --- a/packages/kbn-storybook/index.js +++ /dev/null @@ -1,87 +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. - */ - -const fs = require('fs'); -const { join } = require('path'); -const Rx = require('rxjs'); -const { first } = require('rxjs/operators'); -const storybook = require('@storybook/react/standalone'); -const { run } = require('@kbn/dev-utils'); -const { generateStorybookEntry } = require('./lib/storybook_entry'); -const { ASSET_DIR, CURRENT_CONFIG } = require('./lib/constants'); -const { buildDll } = require('./lib/dll'); - -exports.runStorybookCli = (config) => { - const { name, storyGlobs } = config; - run( - async ({ flags, log, procRunner }) => { - log.debug('Global config:\n', require('./lib/constants')); - - const currentConfig = JSON.stringify(config, null, 2); - const currentConfigDir = join(CURRENT_CONFIG, '..'); - await fs.promises.mkdir(currentConfigDir, { recursive: true }); - log.debug('Writing currentConfig:\n', CURRENT_CONFIG + '\n', currentConfig); - await fs.promises.writeFile(CURRENT_CONFIG, `exports.currentConfig = ${currentConfig};`); - - await buildDll({ - rebuildDll: flags.rebuildDll, - log, - procRunner, - }); - - const subj = new Rx.ReplaySubject(1); - generateStorybookEntry({ log, storyGlobs }).subscribe(subj); - - await subj.pipe(first()).toPromise(); - - await Promise.all([ - // route errors - subj.toPromise(), - - new Promise(async () => { - // storybook never completes, so neither will this promise - const configDir = join(__dirname, 'storybook_config'); - log.debug('Config dir:', configDir); - - const config = { - mode: flags.site ? 'static' : 'dev', - port: 9001, - configDir, - }; - if (flags.site) { - config.outputDir = join(ASSET_DIR, name); - } - - await storybook(config); - - // Line is only reached when building the static version - if (flags.site) process.exit(); - }), - ]); - }, - { - flags: { - boolean: ['rebuildDll', 'site'], - }, - description: ` - Run the storybook examples for ${name} - `, - } - ); -}; diff --git a/packages/kbn-storybook/index.ts b/packages/kbn-storybook/index.ts new file mode 100644 index 0000000000000..a0c944f9a6e28 --- /dev/null +++ b/packages/kbn-storybook/index.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 { defaultConfig } from './lib/default_config'; +export { runStorybookCli } from './lib/run_storybook_cli'; diff --git a/packages/kbn-storybook/lib/constants.js b/packages/kbn-storybook/lib/constants.js deleted file mode 100644 index 4d8ca0adbfe17..0000000000000 --- a/packages/kbn-storybook/lib/constants.js +++ /dev/null @@ -1,27 +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. - */ - -const { resolve } = require('path'); -const { REPO_ROOT } = require('@kbn/utils'); - -exports.ASSET_DIR = resolve(REPO_ROOT, 'built_assets/storybook'); -exports.CURRENT_CONFIG = resolve(exports.ASSET_DIR, 'current.config.js'); -exports.STORY_ENTRY_PATH = resolve(exports.ASSET_DIR, 'stories.entry.js'); -exports.DLL_DIST_DIR = resolve(exports.ASSET_DIR, 'dll'); -exports.DLL_NAME = 'storybook_dll'; diff --git a/packages/kbn-storybook/lib/constants.ts b/packages/kbn-storybook/lib/constants.ts new file mode 100644 index 0000000000000..7ca0ff349af97 --- /dev/null +++ b/packages/kbn-storybook/lib/constants.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. + */ + +import { resolve } from 'path'; +import { REPO_ROOT as KIBANA_ROOT } from '@kbn/dev-utils'; + +export const REPO_ROOT = KIBANA_ROOT; +export const ASSET_DIR = resolve(KIBANA_ROOT, 'built_assets/storybook'); diff --git a/packages/kbn-storybook/lib/default_config.ts b/packages/kbn-storybook/lib/default_config.ts new file mode 100644 index 0000000000000..1fad9e2a3e087 --- /dev/null +++ b/packages/kbn-storybook/lib/default_config.ts @@ -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. + */ + +import { StorybookConfig } from '@storybook/core/types'; + +export const defaultConfig: StorybookConfig = { + addons: ['@kbn/storybook/preset', '@storybook/addon-knobs', '@storybook/addon-essentials'], + stories: ['../**/*.stories.tsx'], + typescript: { + reactDocgen: false, + }, +}; diff --git a/packages/kbn-storybook/lib/dll.js b/packages/kbn-storybook/lib/dll.js deleted file mode 100644 index 55bc8e43a02ec..0000000000000 --- a/packages/kbn-storybook/lib/dll.js +++ /dev/null @@ -1,42 +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. - */ - -const { resolve } = require('path'); -const { existsSync } = require('fs'); - -const { REPO_ROOT } = require('@kbn/utils'); -const { DLL_DIST_DIR } = require('./constants'); - -exports.buildDll = async ({ rebuildDll, log, procRunner }) => { - if (rebuildDll) { - log.info('rebuilding dll'); - } else if (!existsSync(resolve(DLL_DIST_DIR, 'dll.js'))) { - log.info('dll missing, rebuilding'); - } else { - log.info('dll exists'); - return; - } - - await procRunner.run('build dll ', { - cmd: require.resolve('webpack/bin/webpack'), - args: ['--config', require.resolve('./webpack.dll.config.js')], - cwd: REPO_ROOT, - wait: true, - }); -}; diff --git a/packages/kbn-storybook/lib/register.ts b/packages/kbn-storybook/lib/register.ts new file mode 100644 index 0000000000000..5121b6f614902 --- /dev/null +++ b/packages/kbn-storybook/lib/register.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. + */ + +import { addons } from '@storybook/addons'; +import { create } from '@storybook/theming'; + +// This configures the "Manager", or main outer view of Storybook. It is an +// addon that's loaded by the `managerEntries` part of the preset in ../preset.js. +addons.setConfig({ + theme: create({ + base: 'light', + brandTitle: 'Kibana Storybook', + brandUrl: 'https://github.com/elastic/kibana/tree/master/packages/kbn-storybook', + }), + showPanel: false, + isFullscreen: false, + panelPosition: 'bottom', + isToolshown: true, +}); diff --git a/packages/kbn-storybook/lib/run_storybook_cli.ts b/packages/kbn-storybook/lib/run_storybook_cli.ts new file mode 100644 index 0000000000000..3c4cdbf3dcf84 --- /dev/null +++ b/packages/kbn-storybook/lib/run_storybook_cli.ts @@ -0,0 +1,75 @@ +/* + * 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 { join } from 'path'; +import { logger } from '@storybook/node-logger'; +import buildStandalone from '@storybook/react/standalone'; +import { Flags, run } from '@kbn/dev-utils'; +import { distDir } from '@kbn/ui-shared-deps'; +import * as constants from './constants'; + +// Convert the flags to a Storybook loglevel +function getLogLevelFromFlags(flags: Flags) { + if (flags.debug) { + return 'silly'; + } + if (flags.verbose) { + return 'verbose'; + } + if (flags.quiet) { + return 'warn'; + } + if (flags.silent) { + return 'silent'; + } + return 'info'; +} + +export function runStorybookCli({ configDir, name }: { configDir: string; name: string }) { + run( + async ({ flags, log }) => { + log.debug('Global config:\n', constants); + + const staticDir = [distDir]; + const config: Record = { + configDir, + mode: flags.site ? 'static' : 'dev', + port: 9001, + staticDir, + }; + if (flags.site) { + config.outputDir = join(constants.ASSET_DIR, name); + } + + logger.setLevel(getLogLevelFromFlags(flags)); + await buildStandalone(config); + + // Line is only reached when building the static version + if (flags.site) process.exit(); + }, + { + flags: { + boolean: ['site'], + }, + description: ` + Run the storybook examples for ${name} + `, + } + ); +} diff --git a/packages/kbn-storybook/lib/storybook_entry.js b/packages/kbn-storybook/lib/storybook_entry.js deleted file mode 100644 index fc970b1ff9d2a..0000000000000 --- a/packages/kbn-storybook/lib/storybook_entry.js +++ /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. - */ - -const { resolve, relative, dirname } = require('path'); -const Fs = require('fs'); -const Rx = require('rxjs'); -const { mergeMap, map, debounceTime } = require('rxjs/operators'); -const normalize = require('normalize-path'); -const { promisify } = require('util'); - -const watch = require('glob-watcher'); -const mkdirp = require('mkdirp'); // eslint-disable-line -const glob = require('fast-glob'); -const { REPO_ROOT } = require('@kbn/utils'); - -const mkdirpAsync = promisify(mkdirp); -const writeFileAsync = promisify(Fs.writeFile); - -const { STORY_ENTRY_PATH } = require('./constants'); -const STORE_ENTRY_DIR = dirname(STORY_ENTRY_PATH); - -exports.generateStorybookEntry = ({ log, storyGlobs }) => { - const globs = [...storyGlobs]; - log.info('Storybook globs:\n', globs); - const norm = (p) => normalize(relative(STORE_ENTRY_DIR, p)); - - return Rx.defer(() => - glob(globs, { - absolute: true, - cwd: REPO_ROOT, - onlyFiles: true, - }) - ).pipe( - map((paths) => { - log.info('Discovered Storybook entry points:\n', paths); - return new Set(paths.map(norm)); - }), - mergeMap( - (paths) => - new Rx.Observable((observer) => { - observer.next(paths); - - const chokidar = watch(globs, { cwd: REPO_ROOT }) - .on('add', (path) => { - observer.next(paths.add(norm(resolve(REPO_ROOT, path)))); - }) - .on('unlink', (path) => { - observer.next(paths.delete(norm(resolve(REPO_ROOT, path)))); - }); - - return () => { - chokidar.close(); - }; - }) - ), - debounceTime(200), - mergeMap(async (paths, i) => { - await mkdirpAsync(STORE_ENTRY_DIR); - - let content = ''; - for (const path of paths) { - content += `require('${path}');\n`; - } - - await writeFileAsync(STORY_ENTRY_PATH, content); - - if (i === 0) { - log.info('%d paths written to entry file', paths.size); - } else { - log.info('entry file updated'); - } - }) - ); -}; diff --git a/packages/kbn-storybook/lib/templates/index.ejs b/packages/kbn-storybook/lib/templates/index.ejs new file mode 100644 index 0000000000000..a4f8204c95d7a --- /dev/null +++ b/packages/kbn-storybook/lib/templates/index.ejs @@ -0,0 +1,59 @@ + + + + + + <%= options.title || 'Storybook'%> + + <% if (files.favicon) { %> + + <% } %> + + + + + + + + + + + + <% if (typeof headHtmlSnippet !== 'undefined') { %> <%= headHtmlSnippet %> <% } %> <% + files.css.forEach(file => { %> + + <% }); %> + + + + + <% if (typeof bodyHtmlSnippet !== 'undefined') { %> <%= bodyHtmlSnippet %> <% } %> + +
+
+ + <% if (typeof globals !== 'undefined' && Object.keys(globals).length) { %> + + <% } %> <% dlls.forEach(file => { %> + + <% }); %> <% files.js.forEach(file => { %> + + <% }); %> + + diff --git a/packages/kbn-storybook/lib/webpack.dll.config.js b/packages/kbn-storybook/lib/webpack.dll.config.js deleted file mode 100644 index 6e3b4d41bd7f0..0000000000000 --- a/packages/kbn-storybook/lib/webpack.dll.config.js +++ /dev/null @@ -1,131 +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. - */ - -const webpack = require('webpack'); -const path = require('path'); -const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const { REPO_ROOT } = require('@kbn/utils'); - -const { DLL_NAME, DLL_DIST_DIR } = require('./constants'); - -// This is the Webpack config for the DLL of CSS and JS assets that are -// not expected to change during development. This saves compile and run -// times considerably. -module.exports = { - context: REPO_ROOT, - mode: 'development', - - // This is a (potentially growing) list of modules that can be safely - // included in the DLL. Only add to this list modules or other code - // which Storybook stories and their components would require, but don't - // change during development. - entry: [ - '@elastic/eui/dist/eui_theme_light.css', - '@kbn/ui-framework/dist/kui_light.css', - '@storybook/addon-info', - '@storybook/addon-knobs', - '@storybook/addon-knobs/react', - '@storybook/addon-knobs/register', - '@storybook/addon-options', - '@storybook/addon-options/register', - '@storybook/core', - '@storybook/core/dist/server/common/polyfills.js', - '@storybook/react', - '@storybook/theming', - 'angular-mocks', - 'angular', - 'brace', - 'chroma-js', - 'highlight.js', - 'html-entities', - 'jquery', - 'lodash', - 'markdown-it', - 'mocha', - 'prop-types', - 'react-ace', - 'react-beautiful-dnd', - 'react-dom', - 'react-focus-lock', - 'react-markdown', - 'react-resize-detector', - 'react-virtualized', - 'react', - 'recompose', - 'redux-actions', - 'remark-parse', - 'rxjs', - 'sinon', - 'tinycolor2', - ], - plugins: [ - // Produce the DLL and its manifest - new webpack.DllPlugin({ - name: DLL_NAME, - path: path.resolve(DLL_DIST_DIR, 'manifest.json'), - }), - // Produce the DLL CSS file - new MiniCssExtractPlugin({ - filename: 'dll.css', - }), - ], - // Output the DLL JS file - output: { - path: DLL_DIST_DIR, - filename: 'dll.js', - library: DLL_NAME, - }, - // Include a require alias for legacy UI code and styles - resolve: { - alias: { - ui: path.resolve(REPO_ROOT, 'src/legacy/ui/public'), - }, - mainFields: ['browser', 'main'], - }, - module: { - rules: [ - { - test: /\.css$/, - use: [ - { - loader: MiniCssExtractPlugin.loader, - options: {}, - }, - { loader: 'css-loader' }, - { - loader: 'string-replace-loader', - options: { - search: '__REPLACE_WITH_PUBLIC_PATH__', - replace: '/', - flags: 'g', - }, - }, - ], - }, - { - test: /\.(woff|woff2|ttf|eot|svg|ico)(\?|$)/, - loader: 'file-loader', - }, - ], - }, - node: { - fs: 'empty', - child_process: 'empty', - }, -}; diff --git a/packages/kbn-storybook/package.json b/packages/kbn-storybook/package.json index 5271ddb96d842..58359159e950d 100644 --- a/packages/kbn-storybook/package.json +++ b/packages/kbn-storybook/package.json @@ -3,18 +3,21 @@ "version": "1.0.0", "private": true, "license": "Apache-2.0", + "main": "./target/index.js", "dependencies": { - "@kbn/babel-preset": "1.0.0", "@kbn/dev-utils": "1.0.0", + "@storybook/addon-actions": "^6.0.16", + "@storybook/addon-essentials": "^6.0.16", + "@storybook/addon-knobs": "^6.0.16", + "@storybook/addon-storyshots": "^6.0.16", + "@storybook/core": "^6.0.16", + "@storybook/react": "^6.0.16", + "@storybook/theming": "^6.0.16", + "@types/loader-utils": "^1.1.3", + "@types/webpack": "^4.41.3", + "@types/webpack-env": "^1.15.2", + "@types/webpack-merge": "^4.1.5", "@kbn/utils": "1.0.0", - "@storybook/addon-actions": "^5.3.19", - "@storybook/addon-console": "^1.2.1", - "@storybook/addon-info": "^5.3.19", - "@storybook/addon-knobs": "^5.3.19", - "@storybook/addon-options": "^5.3.19", - "@storybook/addon-storyshots": "^5.3.19", - "@storybook/react": "^5.3.19", - "@storybook/theming": "^5.3.19", "babel-loader": "^8.0.6", "copy-webpack-plugin": "^6.0.2", "fast-glob": "2.2.7", @@ -22,12 +25,17 @@ "jest-specific-snapshot": "2.0.0", "jest-styled-components": "^7.0.2", "mkdirp": "0.5.1", - "mini-css-extract-plugin": "0.7.0", - "normalize-path": "3.0.0", - "react-docgen-typescript-loader": "3.1.0", - "rxjs": "6.5.5", + "mini-css-extract-plugin": "0.8.0", + "normalize-path": "^3.0.0", + "react-docgen-typescript-loader": "^3.1.1", + "rxjs": "^6.5.5", "serve-static": "1.14.1", "styled-components": "^5.1.0", "webpack": "^4.41.5" + }, + "scripts": { + "build": "tsc", + "kbn:bootstrap": "yarn build", + "watch": "yarn build --watch" } -} \ No newline at end of file +} diff --git a/packages/kbn-storybook/preset.js b/packages/kbn-storybook/preset.js new file mode 100644 index 0000000000000..8c17f78e208d8 --- /dev/null +++ b/packages/kbn-storybook/preset.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. + */ + +const webpackConfig = require('./target/webpack.config').default; + +module.exports = { + managerEntries: (entry = []) => { + return [...entry, require.resolve('./target/lib/register')]; + }, + webpackFinal: (config) => { + return webpackConfig({ config }); + }, +}; diff --git a/packages/kbn-storybook/storybook_config/addons.js b/packages/kbn-storybook/storybook_config/addons.js deleted file mode 100644 index f439d1d8892f8..0000000000000 --- a/packages/kbn-storybook/storybook_config/addons.js +++ /dev/null @@ -1,23 +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 '@storybook/addon-options/register'; -import '@storybook/addon-actions/register'; -import '@storybook/addon-knobs/register'; -import '@storybook/addon-console'; diff --git a/packages/kbn-storybook/storybook_config/config.js b/packages/kbn-storybook/storybook_config/config.js deleted file mode 100644 index d97bd3f7c2dcc..0000000000000 --- a/packages/kbn-storybook/storybook_config/config.js +++ /dev/null @@ -1,68 +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 { configure, addDecorator, addParameters } from '@storybook/react'; -import { withKnobs } from '@storybook/addon-knobs/react'; -import { withInfo } from '@storybook/addon-info'; -import { create } from '@storybook/theming'; - -// If we're running Storyshots, be sure to register the require context hook. -// Otherwise, add the other decorators. -if (process.env.NODE_ENV === 'test') { - // eslint-disable-next-line - require('babel-plugin-require-context-hook/register')(); -} else { - // Customize the info for each story. - addDecorator( - withInfo({ - inline: true, - styles: { - infoBody: { - margin: 20, - }, - infoStory: { - margin: '40px 60px', - }, - }, - }) - ); - - // Add optional knobs to customize each story. - addDecorator(withKnobs); -} - -// Set up the Storybook environment with custom settings. -addParameters({ - options: { - theme: create({ - base: 'light', - brandTitle: 'Kibana Storybook', - brandUrl: 'https://github.com/elastic/kibana/tree/master/packages/kbn-storybook', - }), - showPanel: false, - isFullscreen: false, - panelPosition: 'bottom', - isToolshown: true, - }, -}); - -configure(() => { - // eslint-disable-next-line - require('../../../built_assets/storybook/stories.entry.js'); -}, module); diff --git a/packages/kbn-storybook/storybook_config/middleware.js b/packages/kbn-storybook/storybook_config/middleware.js deleted file mode 100644 index 9410bb66030d9..0000000000000 --- a/packages/kbn-storybook/storybook_config/middleware.js +++ /dev/null @@ -1,26 +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. - */ - -const serve = require('serve-static'); -const path = require('path'); - -// Extend the Storybook Middleware to include a route to access Legacy UI assets -module.exports = function (router) { - router.get('/ui', serve(path.resolve(__dirname, '../../../src/core/server/core_app/assets'))); -}; diff --git a/packages/kbn-storybook/storybook_config/mocks/absolute_to_parsed_url.js b/packages/kbn-storybook/storybook_config/mocks/absolute_to_parsed_url.js deleted file mode 100644 index 65a27b095f84e..0000000000000 --- a/packages/kbn-storybook/storybook_config/mocks/absolute_to_parsed_url.js +++ /dev/null @@ -1,23 +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 const absoluteToParsedUrl = () => { - getAbsoluteUrl: () => - 'http://localhost:5601/kbp/app/canvas#/workpad/workpad-24d56dad-ae70-42b8-9ef1-c5350ecd426c/page/1'; -}; // noop diff --git a/packages/kbn-storybook/storybook_config/mocks/noop.js b/packages/kbn-storybook/storybook_config/mocks/noop.js deleted file mode 100755 index e78d222eaa560..0000000000000 --- a/packages/kbn-storybook/storybook_config/mocks/noop.js +++ /dev/null @@ -1,20 +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 default function () {} diff --git a/packages/kbn-storybook/storybook_config/mocks/state_store.js b/packages/kbn-storybook/storybook_config/mocks/state_store.js deleted file mode 100644 index 11bdf6632321d..0000000000000 --- a/packages/kbn-storybook/storybook_config/mocks/state_store.js +++ /dev/null @@ -1,26 +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 function getState() { - return { - assets: { - yay: { value: 'here is your image' }, - }, - }; -} diff --git a/packages/kbn-storybook/storybook_config/mocks/ui_storage.js b/packages/kbn-storybook/storybook_config/mocks/ui_storage.js deleted file mode 100644 index 4bd8cdeddfc22..0000000000000 --- a/packages/kbn-storybook/storybook_config/mocks/ui_storage.js +++ /dev/null @@ -1,28 +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 class Storage { - get(key) { - return this[key]; - } - - set(key, value) { - this[key] = value; - } -} diff --git a/packages/kbn-storybook/storybook_config/preview-head.html b/packages/kbn-storybook/storybook_config/preview-head.html deleted file mode 100644 index 16754ad550da0..0000000000000 --- a/packages/kbn-storybook/storybook_config/preview-head.html +++ /dev/null @@ -1,6 +0,0 @@ - - - diff --git a/packages/kbn-storybook/storybook_config/webpack.config.js b/packages/kbn-storybook/storybook_config/webpack.config.js deleted file mode 100644 index 60b6b6add66d1..0000000000000 --- a/packages/kbn-storybook/storybook_config/webpack.config.js +++ /dev/null @@ -1,147 +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. - */ - -const { resolve } = require('path'); -const webpack = require('webpack'); -const webpackMerge = require('webpack-merge'); -const { stringifyRequest } = require('loader-utils'); -const CopyWebpackPlugin = require('copy-webpack-plugin'); -const { REPO_ROOT } = require('@kbn/utils'); -const { DLL_DIST_DIR } = require('../lib/constants'); -// eslint-disable-next-line import/no-unresolved -const { currentConfig } = require('../../../built_assets/storybook/current.config'); - -// Extend the Storybook Webpack config with some customizations -module.exports = async ({ config: storybookConfig }) => { - let config = { - module: { - rules: [ - // Include the React preset from Kibana for JS(X) and TS(X) - { - test: /\.(j|t)sx?$/, - exclude: /node_modules/, - loaders: 'babel-loader', - options: { - presets: [require.resolve('@kbn/babel-preset/webpack_preset')], - }, - }, - { - test: /\.(html|md|txt|tmpl)$/, - use: { - loader: 'raw-loader', - }, - }, - // Parse props data for .tsx files - // This is notoriously slow, and is making Storybook unusable. Disabling for now. - // See: https://github.com/storybookjs/storybook/issues/7998 - // - // { - // test: /\.tsx$/, - // // Exclude example files, as we don't display props info for them - // exclude: /\.stories.tsx$/, - // use: [ - // // Parse TS comments to create Props tables in the UI - // require.resolve('react-docgen-typescript-loader'), - // ], - // }, - { - test: /\.scss$/, - exclude: /\.module.(s(a|c)ss)$/, - use: [ - { loader: 'style-loader' }, - { loader: 'css-loader', options: { importLoaders: 2 } }, - { - loader: 'postcss-loader', - options: { - config: { - path: require.resolve('@kbn/optimizer/postcss.config.js'), - }, - }, - }, - { - loader: 'sass-loader', - options: { - prependData(loaderContext) { - return `@import ${stringifyRequest( - loaderContext, - resolve(REPO_ROOT, 'src/core/public/core_app/styles/_globals_v7light.scss') - )};\n`; - }, - sassOptions: { - includePaths: [resolve(REPO_ROOT, 'node_modules')], - }, - }, - }, - ], - }, - ], - }, - plugins: [ - // Reference the built DLL file of static(ish) dependencies, which are removed - // during kbn:bootstrap and rebuilt if missing. - new webpack.DllReferencePlugin({ - manifest: resolve(DLL_DIST_DIR, 'manifest.json'), - context: REPO_ROOT, - }), - // Copy the DLL files to the Webpack build for use in the Storybook UI - - new CopyWebpackPlugin({ - patterns: [ - { - from: resolve(DLL_DIST_DIR, 'dll.js'), - to: 'dll.js', - }, - { - from: resolve(DLL_DIST_DIR, 'dll.css'), - to: 'dll.css', - }, - ], - }), - ], - resolve: { - // Tell Webpack about the ts/x extensions - extensions: ['.ts', '.tsx', '.scss'], - alias: { - core_app_image_assets: resolve(REPO_ROOT, 'src/core/public/core_app/images'), - }, - }, - }; - - // Find and alter the CSS rule to replace the Kibana public path string with a path - // to the route we've added in middleware.js - const cssRule = storybookConfig.module.rules.find((rule) => rule.test.source.includes('.css$')); - cssRule.use.push({ - loader: 'string-replace-loader', - options: { - search: '__REPLACE_WITH_PUBLIC_PATH__', - replace: '/', - flags: 'g', - }, - }); - - config = webpackMerge(storybookConfig, config); - - // Load custom Webpack config specified by a plugin. - if (currentConfig.webpackHook) { - // eslint-disable-next-line import/no-dynamic-require - return await require(currentConfig.webpackHook)({ config }); - } - - return config; -}; diff --git a/packages/kbn-storybook/tsconfig.json b/packages/kbn-storybook/tsconfig.json new file mode 100644 index 0000000000000..814a3963c9f49 --- /dev/null +++ b/packages/kbn-storybook/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "declaration": true, + "outDir": "target", + "skipLibCheck": true + }, + "include": ["*.ts", "lib/*.ts"] +} diff --git a/packages/kbn-storybook/typings.d.ts b/packages/kbn-storybook/typings.d.ts new file mode 100644 index 0000000000000..a20af34a0eb06 --- /dev/null +++ b/packages/kbn-storybook/typings.d.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. + */ + +// Storybook react doesn't declare this in its typings, but it's there. +declare module '@storybook/react/standalone'; diff --git a/packages/kbn-storybook/webpack.config.ts b/packages/kbn-storybook/webpack.config.ts new file mode 100644 index 0000000000000..84f8cfaefd669 --- /dev/null +++ b/packages/kbn-storybook/webpack.config.ts @@ -0,0 +1,104 @@ +/* + * 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 { resolve } from 'path'; +import { stringifyRequest } from 'loader-utils'; +import { Configuration, Stats } from 'webpack'; +import webpackMerge from 'webpack-merge'; +import { externals } from '@kbn/ui-shared-deps'; +import { REPO_ROOT } from './lib/constants'; + +const stats = { + ...Stats.presetToOptions('minimal'), + colors: true, + errorDetails: true, + errors: true, + moduleTrace: true, + warningsFilter: /(export .* was not found in)|(entrypoint size limit)/, +}; + +// Extend the Storybook Webpack config with some customizations +/* eslint-disable import/no-default-export */ +export default function ({ config: storybookConfig }: { config: Configuration }) { + const config = { + devServer: { + stats, + }, + externals, + module: { + rules: [ + { + test: /\.(html|md|txt|tmpl)$/, + use: { + loader: 'raw-loader', + }, + }, + { + test: /\.scss$/, + exclude: /\.module.(s(a|c)ss)$/, + use: [ + { loader: 'style-loader' }, + { loader: 'css-loader', options: { importLoaders: 2 } }, + { + loader: 'postcss-loader', + options: { + config: { + path: require.resolve('@kbn/optimizer/postcss.config.js'), + }, + }, + }, + { + loader: 'sass-loader', + options: { + prependData(loaderContext: any) { + return `@import ${stringifyRequest( + loaderContext, + resolve(REPO_ROOT, 'src/core/public/core_app/styles/_globals_v7light.scss') + )};\n`; + }, + sassOptions: { + includePaths: [resolve(REPO_ROOT, 'node_modules')], + }, + }, + }, + ], + }, + ], + }, + resolve: { + // Tell Webpack about the scss extension + extensions: ['.scss'], + alias: { + core_app_image_assets: resolve(REPO_ROOT, 'src/core/public/core_app/images'), + }, + }, + stats, + }; + + // This is the hacky part. We find something that looks like the + // HtmlWebpackPlugin and mutate its `options.template` to point at our + // revised template. + const htmlWebpackPlugin: any = (storybookConfig.plugins || []).find((plugin: any) => { + return plugin.options && typeof plugin.options.template === 'string'; + }); + if (htmlWebpackPlugin) { + htmlWebpackPlugin.options.template = require.resolve('../lib/templates/index.ejs'); + } + return webpackMerge(storybookConfig, config); +} diff --git a/packages/kbn-telemetry-tools/src/tools/__fixture__/parsed_schema_defined_with_spreads_collector.ts b/packages/kbn-telemetry-tools/src/tools/__fixture__/parsed_schema_defined_with_spreads_collector.ts new file mode 100644 index 0000000000000..833344fa368b0 --- /dev/null +++ b/packages/kbn-telemetry-tools/src/tools/__fixture__/parsed_schema_defined_with_spreads_collector.ts @@ -0,0 +1,69 @@ +/* + * 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 { SyntaxKind } from 'typescript'; +import { ParsedUsageCollection } from '../ts_parser'; + +export const parsedSchemaDefinedWithSpreadsCollector: ParsedUsageCollection = [ + 'src/fixtures/telemetry_collectors/schema_defined_with_spreads_collector.ts', + { + collectorName: 'schema_defined_with_spreads', + schema: { + value: { + flat: { + type: 'keyword', + }, + my_str: { + type: 'text', + }, + my_objects: { + total: { + type: 'number', + }, + type: { + type: 'boolean', + }, + }, + }, + }, + fetch: { + typeName: 'Usage', + typeDescriptor: { + flat: { + kind: SyntaxKind.StringKeyword, + type: 'StringKeyword', + }, + my_str: { + kind: SyntaxKind.StringKeyword, + type: 'StringKeyword', + }, + my_objects: { + total: { + kind: SyntaxKind.NumberKeyword, + type: 'NumberKeyword', + }, + type: { + kind: SyntaxKind.BooleanKeyword, + type: 'BooleanKeyword', + }, + }, + }, + }, + }, +]; diff --git a/packages/kbn-telemetry-tools/src/tools/__snapshots__/extract_collectors.test.ts.snap b/packages/kbn-telemetry-tools/src/tools/__snapshots__/extract_collectors.test.ts.snap index 206f573b0af78..4725be77533af 100644 --- a/packages/kbn-telemetry-tools/src/tools/__snapshots__/extract_collectors.test.ts.snap +++ b/packages/kbn-telemetry-tools/src/tools/__snapshots__/extract_collectors.test.ts.snap @@ -142,6 +142,53 @@ Array [ }, }, ], + Array [ + "src/fixtures/telemetry_collectors/schema_defined_with_spreads_collector.ts", + Object { + "collectorName": "schema_defined_with_spreads", + "fetch": Object { + "typeDescriptor": Object { + "flat": Object { + "kind": 146, + "type": "StringKeyword", + }, + "my_objects": Object { + "total": Object { + "kind": 143, + "type": "NumberKeyword", + }, + "type": Object { + "kind": 131, + "type": "BooleanKeyword", + }, + }, + "my_str": Object { + "kind": 146, + "type": "StringKeyword", + }, + }, + "typeName": "Usage", + }, + "schema": Object { + "value": Object { + "flat": Object { + "type": "keyword", + }, + "my_objects": Object { + "total": Object { + "type": "number", + }, + "type": Object { + "type": "boolean", + }, + }, + "my_str": Object { + "type": "text", + }, + }, + }, + }, + ], Array [ "src/fixtures/telemetry_collectors/working_collector.ts", Object { diff --git a/packages/kbn-telemetry-tools/src/tools/extract_collectors.test.ts b/packages/kbn-telemetry-tools/src/tools/extract_collectors.test.ts index 0517cb9034d0a..b03db75b219f6 100644 --- a/packages/kbn-telemetry-tools/src/tools/extract_collectors.test.ts +++ b/packages/kbn-telemetry-tools/src/tools/extract_collectors.test.ts @@ -34,7 +34,7 @@ describe('extractCollectors', () => { const programPaths = await getProgramPaths(configs[0]); const results = [...extractCollectors(programPaths, tsConfig)]; - expect(results).toHaveLength(7); + expect(results).toHaveLength(8); expect(results).toMatchSnapshot(); }); }); diff --git a/packages/kbn-telemetry-tools/src/tools/serializer.test.ts b/packages/kbn-telemetry-tools/src/tools/serializer.test.ts index 02d663f4d29eb..85fb84c714e20 100644 --- a/packages/kbn-telemetry-tools/src/tools/serializer.test.ts +++ b/packages/kbn-telemetry-tools/src/tools/serializer.test.ts @@ -124,4 +124,36 @@ describe('getDescriptor', () => { '@@INDEX@@': { kind: ts.SyntaxKind.NumberKeyword, type: 'NumberKeyword' }, }); }); + + it('serializes MappedTypes', () => { + const usageInterface = usageInterfaces.get('MappedTypes')!; + const descriptor = getDescriptor(usageInterface, tsProgram); + expect(descriptor).toEqual({ + mappedTypeWithExternallyDefinedProps: { + prop1: { kind: ts.SyntaxKind.NumberKeyword, type: 'NumberKeyword' }, + prop2: { kind: ts.SyntaxKind.NumberKeyword, type: 'NumberKeyword' }, + }, + mappedTypeWithOneInlineProp: { + prop3: { kind: ts.SyntaxKind.NumberKeyword, type: 'NumberKeyword' }, + }, + }); + }); + + it('serializes RecordWithKnownProps', () => { + const usageInterface = usageInterfaces.get('RecordWithKnownProps')!; + const descriptor = getDescriptor(usageInterface, tsProgram); + expect(descriptor).toEqual({ + prop1: { kind: ts.SyntaxKind.NumberKeyword, type: 'NumberKeyword' }, + prop2: { kind: ts.SyntaxKind.NumberKeyword, type: 'NumberKeyword' }, + }); + }); + + it('serializes IndexedAccessType', () => { + const usageInterface = usageInterfaces.get('IndexedAccessType')!; + const descriptor = getDescriptor(usageInterface, tsProgram); + expect(descriptor).toEqual({ + prop1: { kind: ts.SyntaxKind.StringKeyword, type: 'StringKeyword' }, + prop2: { kind: ts.SyntaxKind.StringKeyword, type: 'StringKeyword' }, + }); + }); }); diff --git a/packages/kbn-telemetry-tools/src/tools/serializer.ts b/packages/kbn-telemetry-tools/src/tools/serializer.ts index 422b298c58374..ea5f184008026 100644 --- a/packages/kbn-telemetry-tools/src/tools/serializer.ts +++ b/packages/kbn-telemetry-tools/src/tools/serializer.ts @@ -18,7 +18,7 @@ */ import * as ts from 'typescript'; -import { uniqBy } from 'lodash'; +import { uniqBy, pick } from 'lodash'; import { getResolvedModuleSourceFile, getIdentifierDeclarationFromSource, @@ -71,6 +71,42 @@ export function kindToDescriptorName(kind: number) { } } +export function getConstraints(node: ts.Node, program: ts.Program): any { + if (ts.isTypeReferenceNode(node)) { + const typeChecker = program.getTypeChecker(); + const symbol = typeChecker.getSymbolAtLocation(node.typeName); + const declaration = (symbol?.getDeclarations() || [])[0]; + if (declaration) { + return getConstraints(declaration, program); + } + return getConstraints(node.typeName, program); + } + + if (ts.isTypeAliasDeclaration(node)) { + return getConstraints(node.type, program); + } + + if (ts.isUnionTypeNode(node)) { + const types = node.types.filter(discardNullOrUndefined); + return types.map((typeNode) => getConstraints(typeNode, program)); + } + + if (ts.isLiteralTypeNode(node) && ts.isLiteralExpression(node.literal)) { + return node.literal.text; + } + + if (ts.isImportSpecifier(node)) { + const source = node.getSourceFile(); + const importedModuleName = getModuleSpecifier(node); + + const declarationSource = getResolvedModuleSourceFile(source, program, importedModuleName); + const declarationNode = getIdentifierDeclarationFromSource(node.name, declarationSource); + return getConstraints(declarationNode, program); + } + + throw Error(`Unsupported constraint of kind ${node.kind} [${ts.SyntaxKind[node.kind]}]`); +} + export function getDescriptor(node: ts.Node, program: ts.Program): Descriptor | DescriptorValue { if (ts.isMethodSignature(node) || ts.isPropertySignature(node)) { if (node.type) { @@ -89,8 +125,19 @@ export function getDescriptor(node: ts.Node, program: ts.Program): Descriptor | } // If it's defined as signature { [key: string]: OtherInterface } - if (ts.isIndexSignatureDeclaration(node) && node.type) { - return { '@@INDEX@@': getDescriptor(node.type, program) }; + if ((ts.isIndexSignatureDeclaration(node) || ts.isMappedTypeNode(node)) && node.type) { + const descriptor = getDescriptor(node.type, program); + + // If we know the constraints of `string` ({ [key in 'prop1' | 'prop2']: value }) + const constraint = (node as ts.MappedTypeNode).typeParameter?.constraint; + if (constraint) { + const constraints = getConstraints(constraint, program); + const constraintsArray = Array.isArray(constraints) ? constraints : [constraints]; + if (typeof constraintsArray[0] === 'string') { + return constraintsArray.reduce((acc, c) => ({ ...acc, [c]: descriptor }), {}); + } + } + return { '@@INDEX@@': descriptor }; } if (ts.SyntaxKind.FirstNode === node.kind) { @@ -119,9 +166,25 @@ export function getDescriptor(node: ts.Node, program: ts.Program): Descriptor | return { kind: TelemetryKinds.Date, type: 'Date' }; } // Support `Record` - if (symbolName === 'Record' && node.typeArguments![0].kind === ts.SyntaxKind.StringKeyword) { - return { '@@INDEX@@': getDescriptor(node.typeArguments![1], program) }; + if (symbolName === 'Record') { + const descriptor = getDescriptor(node.typeArguments![1], program); + if (node.typeArguments![0].kind === ts.SyntaxKind.StringKeyword) { + return { '@@INDEX@@': descriptor }; + } + const constraints = getConstraints(node.typeArguments![0], program); + const constraintsArray = Array.isArray(constraints) ? constraints : [constraints]; + if (typeof constraintsArray[0] === 'string') { + return constraintsArray.reduce((acc, c) => ({ ...acc, [c]: descriptor }), {}); + } + } + + // Support `Pick` + if (symbolName === 'Pick') { + const parentDescriptor = getDescriptor(node.typeArguments![0], program); + const pickPropNames = getConstraints(node.typeArguments![1], program); + return pick(parentDescriptor, pickPropNames); } + const declaration = (symbol?.getDeclarations() || [])[0]; if (declaration) { return getDescriptor(declaration, program); diff --git a/packages/kbn-telemetry-tools/src/tools/ts_parser.test.ts b/packages/kbn-telemetry-tools/src/tools/ts_parser.test.ts index b7ca33a7bcd74..d036b93a7bbf9 100644 --- a/packages/kbn-telemetry-tools/src/tools/ts_parser.test.ts +++ b/packages/kbn-telemetry-tools/src/tools/ts_parser.test.ts @@ -25,6 +25,7 @@ import { parsedNestedCollector } from './__fixture__/parsed_nested_collector'; import { parsedExternallyDefinedCollector } from './__fixture__/parsed_externally_defined_collector'; import { parsedImportedUsageInterface } from './__fixture__/parsed_imported_usage_interface'; import { parsedImportedSchemaCollector } from './__fixture__/parsed_imported_schema'; +import { parsedSchemaDefinedWithSpreadsCollector } from './__fixture__/parsed_schema_defined_with_spreads_collector'; export function loadFixtureProgram(fixtureName: string) { const fixturePath = path.resolve( @@ -62,6 +63,12 @@ describe('parseUsageCollection', () => { expect(result).toEqual([parsedWorkingCollector]); }); + it('parses collector with schema defined as union of spreads', () => { + const { program, sourceFile } = loadFixtureProgram('schema_defined_with_spreads_collector'); + const result = [...parseUsageCollection(sourceFile, program)]; + expect(result).toEqual([parsedSchemaDefinedWithSpreadsCollector]); + }); + it('parses nested collectors', () => { const { program, sourceFile } = loadFixtureProgram('nested_collector'); const result = [...parseUsageCollection(sourceFile, program)]; diff --git a/packages/kbn-telemetry-tools/src/tools/utils.ts b/packages/kbn-telemetry-tools/src/tools/utils.ts index e8e1b3fed1aef..90ba7f4d9168f 100644 --- a/packages/kbn-telemetry-tools/src/tools/utils.ts +++ b/packages/kbn-telemetry-tools/src/tools/utils.ts @@ -78,14 +78,14 @@ export function getIdentifierDeclarationFromSource(node: ts.Node, source: ts.Sou const identifierName = node.getText(); const identifierDefinition: ts.Node = (source as any).locals.get(identifierName); if (!identifierDefinition) { - throw new Error(`Unable to fine identifier in source ${identifierName}`); + throw new Error(`Unable to find identifier in source ${identifierName}`); } const declarations = (identifierDefinition as any).declarations as ts.Node[]; const latestDeclaration: ts.Node | false | undefined = Array.isArray(declarations) && declarations[declarations.length - 1]; if (!latestDeclaration) { - throw new Error(`Unable to fine declaration for identifier ${identifierName}`); + throw new Error(`Unable to find declaration for identifier ${identifierName}`); } return latestDeclaration; @@ -100,42 +100,57 @@ export function getIdentifierDeclaration(node: ts.Node) { return getIdentifierDeclarationFromSource(node, source); } -export function getVariableValue(node: ts.Node): string | Record { +export function getVariableValue(node: ts.Node, program: ts.Program): string | Record { if (ts.isStringLiteral(node) || ts.isNumericLiteral(node)) { return node.text; } if (ts.isObjectLiteralExpression(node)) { - return serializeObject(node); + return serializeObject(node, program); } if (ts.isIdentifier(node)) { const declaration = getIdentifierDeclaration(node); if (ts.isVariableDeclaration(declaration) && declaration.initializer) { - return getVariableValue(declaration.initializer); + return getVariableValue(declaration.initializer, program); + } else { + // Go fetch it in another file + return getIdentifierValue(node, node, program, { chaseImport: true }); } - // TODO: If this is another imported value from another file, we'll need to go fetch it like in getPropertyValue } - throw Error(`Unsuppored Node: cannot get value of node (${node.getText()}) of kind ${node.kind}`); + if (ts.isSpreadAssignment(node)) { + return getVariableValue(node.expression, program); + } + + throw Error( + `Unsupported Node: cannot get value of node (${node.getText()}) of kind ${node.kind} [${ + ts.SyntaxKind[node.kind] + }]` + ); } -export function serializeObject(node: ts.Node) { +export function serializeObject(node: ts.Node, program: ts.Program) { if (!ts.isObjectLiteralExpression(node)) { throw new Error(`Expecting Object literal Expression got ${node.getText()}`); } - const value: Record = {}; + let value: Record = {}; for (const property of node.properties) { const propertyName = property.name?.getText(); + const val = ts.isPropertyAssignment(property) + ? getVariableValue(property.initializer, program) + : getVariableValue(property, program); + if (typeof propertyName === 'undefined') { - throw new Error(`Unable to get property name ${property.getText()}`); - } - const cleanPropertyName = propertyName.replace(/["']/g, ''); - if (ts.isPropertyAssignment(property)) { - value[cleanPropertyName] = getVariableValue(property.initializer); + if (typeof val === 'object') { + value = { ...value, ...val }; + } else { + throw new Error(`Unable to get property name ${property.getText()}`); + } } else { - value[cleanPropertyName] = getVariableValue(property); + const cleanPropertyName = propertyName.replace(/["']/g, ''); + value[cleanPropertyName] = val; } } @@ -155,45 +170,53 @@ export function getResolvedModuleSourceFile( return resolvedModuleSourceFile; } -export function getPropertyValue( +export function getIdentifierValue( node: ts.Node, + initializer: ts.Identifier, program: ts.Program, config: Optional<{ chaseImport: boolean }> = {} ) { const { chaseImport = false } = config; + const identifierName = initializer.getText(); + const declaration = getIdentifierDeclaration(initializer); + if (ts.isImportSpecifier(declaration)) { + if (!chaseImport) { + throw new Error( + `Value of node ${identifierName} is imported from another file. Chasing imports is not allowed.` + ); + } - if (ts.isPropertyAssignment(node)) { - const { initializer } = node; + const importedModuleName = getModuleSpecifier(declaration); - if (ts.isIdentifier(initializer)) { - const identifierName = initializer.getText(); - const declaration = getIdentifierDeclaration(initializer); - if (ts.isImportSpecifier(declaration)) { - if (!chaseImport) { - throw new Error( - `Value of node ${identifierName} is imported from another file. Chasing imports is not allowed.` - ); - } + const source = node.getSourceFile(); + const declarationSource = getResolvedModuleSourceFile(source, program, importedModuleName); + const declarationNode = getIdentifierDeclarationFromSource(initializer, declarationSource); + if (!ts.isVariableDeclaration(declarationNode)) { + throw new Error(`Expected ${identifierName} to be variable declaration.`); + } + if (!declarationNode.initializer) { + throw new Error(`Expected ${identifierName} to be initialized.`); + } + const serializedObject = serializeObject(declarationNode.initializer, program); + return serializedObject; + } - const importedModuleName = getModuleSpecifier(declaration); + return getVariableValue(declaration, program); +} - const source = node.getSourceFile(); - const declarationSource = getResolvedModuleSourceFile(source, program, importedModuleName); - const declarationNode = getIdentifierDeclarationFromSource(initializer, declarationSource); - if (!ts.isVariableDeclaration(declarationNode)) { - throw new Error(`Expected ${identifierName} to be variable declaration.`); - } - if (!declarationNode.initializer) { - throw new Error(`Expected ${identifierName} to be initialized.`); - } - const serializedObject = serializeObject(declarationNode.initializer); - return serializedObject; - } +export function getPropertyValue( + node: ts.Node, + program: ts.Program, + config: Optional<{ chaseImport: boolean }> = {} +) { + if (ts.isPropertyAssignment(node)) { + const { initializer } = node; - return getVariableValue(declaration); + if (ts.isIdentifier(initializer)) { + return getIdentifierValue(node, initializer, program, config); } - return getVariableValue(initializer); + return getVariableValue(initializer, program); } } diff --git a/packages/kbn-test/package.json b/packages/kbn-test/package.json index 8a4ff55dcf68f..4e86ec4bd72e0 100644 --- a/packages/kbn-test/package.json +++ b/packages/kbn-test/package.json @@ -26,15 +26,14 @@ "dedent": "^0.7.0", "del": "^5.1.0", "exit-hook": "^2.2.0", - "getopts": "^2.2.4", + "getopts": "^2.2.5", "glob": "^7.1.2", "joi": "^13.5.2", - "lodash": "^4.17.15", + "lodash": "^4.17.20", "parse-link-header": "^1.0.1", "rxjs": "^6.5.5", - "strip-ansi": "^5.2.0", + "strip-ansi": "^6.0.0", "tar-fs": "^2.1.0", - "tmp": "^0.1.0", "xml2js": "^0.4.22", "zlib": "^1.0.5" } diff --git a/packages/kbn-test/src/functional_tests/lib/babel_register_for_test_plugins.js b/packages/kbn-test/src/functional_tests/lib/babel_register_for_test_plugins.js new file mode 100644 index 0000000000000..44ff579411bd9 --- /dev/null +++ b/packages/kbn-test/src/functional_tests/lib/babel_register_for_test_plugins.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. + */ + +const Path = require('path'); + +const { REPO_ROOT } = require('@kbn/dev-utils'); + +// modifies all future calls to require() to automatically +// compile the required source with babel +require('@babel/register')({ + ignore: [/[\/\\](node_modules|target|dist)[\/\\]/], + only: [ + Path.resolve(REPO_ROOT, 'test'), + Path.resolve(REPO_ROOT, 'x-pack/test'), + Path.resolve(REPO_ROOT, 'examples'), + Path.resolve(REPO_ROOT, 'x-pack/examples'), + // TODO: should should probably remove this link back to the source + Path.resolve(REPO_ROOT, 'x-pack/plugins/task_manager/server/config.ts'), + ], + babelrc: false, + presets: [require.resolve('@kbn/babel-preset/node_preset')], + extensions: ['.js', '.ts', '.tsx'], +}); diff --git a/packages/kbn-test/src/functional_tests/lib/run_kibana_server.js b/packages/kbn-test/src/functional_tests/lib/run_kibana_server.js index fb9f8f7a52408..e7ec99467ecfd 100644 --- a/packages/kbn-test/src/functional_tests/lib/run_kibana_server.js +++ b/packages/kbn-test/src/functional_tests/lib/run_kibana_server.js @@ -17,9 +17,26 @@ * under the License. */ -import { resolve } from 'path'; +import { resolve, relative } from 'path'; import { KIBANA_ROOT, KIBANA_EXEC, KIBANA_EXEC_PATH } from './paths'; +function extendNodeOptions(installDir) { + if (!installDir) { + return {}; + } + + const testOnlyRegisterPath = relative( + installDir, + require.resolve('./babel_register_for_test_plugins') + ); + + return { + NODE_OPTIONS: `--require=${testOnlyRegisterPath}${ + process.env.NODE_OPTIONS ? ` ${process.env.NODE_OPTIONS}` : '' + }`, + }; +} + export async function runKibanaServer({ procs, config, options }) { const { installDir } = options; @@ -29,6 +46,7 @@ export async function runKibanaServer({ procs, config, options }) { env: { FORCE_COLOR: 1, ...process.env, + ...extendNodeOptions(installDir), }, cwd: installDir || KIBANA_ROOT, wait: /http server running/, diff --git a/packages/kbn-ui-framework/package.json b/packages/kbn-ui-framework/package.json index 363f97522a901..639d4e17d0e71 100644 --- a/packages/kbn-ui-framework/package.json +++ b/packages/kbn-ui-framework/package.json @@ -17,7 +17,7 @@ "dependencies": { "classnames": "2.2.6", "focus-trap-react": "^3.1.1", - "lodash": "^4.17.15", + "lodash": "^4.17.20", "prop-types": "^15.7.2", "react": "^16.12.0", "react-ace": "^5.9.0", @@ -30,15 +30,15 @@ "enzyme-adapter-react-16": "^1.9.1" }, "devDependencies": { - "@babel/core": "^7.11.1", - "@elastic/eui": "0.0.55", + "@babel/core": "^7.11.6", + "@elastic/eui": "29.0.0", "@kbn/babel-preset": "1.0.0", "@kbn/optimizer": "1.0.0", "babel-loader": "^8.0.6", "brace": "0.11.1", "chalk": "^4.1.0", - "chokidar": "3.2.1", - "core-js": "^3.6.4", + "chokidar": "^3.4.2", + "core-js": "^3.6.5", "css-loader": "^3.4.2", "expose-loader": "^0.7.5", "file-loader": "^4.2.0", @@ -58,11 +58,11 @@ "postcss-loader": "^3.0.0", "raw-loader": "^3.1.0", "react-dom": "^16.12.0", - "react-redux": "^5.1.2", - "react-router": "^3.2.0", + "react-redux": "^7.2.0", + "react-router": "^5.2.0", "react-router-redux": "^4.0.8", - "redux": "3.7.2", - "redux-thunk": "2.2.0", + "redux": "^4.0.5", + "redux-thunk": "^2.3.0", "regenerator-runtime": "^0.13.3", "sass-loader": "^8.0.2", "sinon": "^7.4.2", diff --git a/packages/kbn-ui-shared-deps/package.json b/packages/kbn-ui-shared-deps/package.json index 278e8efd2d29e..d2a590d29947b 100644 --- a/packages/kbn-ui-shared-deps/package.json +++ b/packages/kbn-ui-shared-deps/package.json @@ -9,7 +9,7 @@ "kbn:watch": "node scripts/build --dev --watch" }, "dependencies": { - "@elastic/charts": "21.1.2", + "@elastic/charts": "23.0.0", "@elastic/eui": "29.0.0", "@elastic/numeral": "^2.5.0", "@kbn/i18n": "1.0.0", @@ -17,7 +17,7 @@ "abortcontroller-polyfill": "^1.4.0", "angular": "^1.8.0", "compression-webpack-plugin": "^4.0.0", - "core-js": "^3.6.4", + "core-js": "^3.6.5", "custom-event-polyfill": "^0.3.0", "jquery": "^3.5.0", "lodash": "^4.17.20", diff --git a/packages/kbn-ui-shared-deps/scripts/build.js b/packages/kbn-ui-shared-deps/scripts/build.js index af4e3481e624d..86251536b8876 100644 --- a/packages/kbn-ui-shared-deps/scripts/build.js +++ b/packages/kbn-ui-shared-deps/scripts/build.js @@ -18,18 +18,21 @@ */ const Path = require('path'); +const Fs = require('fs'); -const { run, createFailError } = require('@kbn/dev-utils'); +const { run, createFailError, CiStatsReporter } = require('@kbn/dev-utils'); const webpack = require('webpack'); const Stats = require('webpack/lib/Stats'); const del = require('del'); const { getWebpackConfig } = require('../webpack.config'); +const DIST_DIR = Path.resolve(__dirname, '../target'); + run( async ({ log, flags }) => { log.info('cleaning previous build output'); - await del(Path.resolve(__dirname, '../target')); + await del(DIST_DIR); const compiler = webpack( getWebpackConfig({ @@ -38,10 +41,38 @@ run( ); /** @param {webpack.Stats} stats */ - const onCompilationComplete = (stats) => { + const onCompilationComplete = async (stats) => { const took = Math.round((stats.endTime - stats.startTime) / 1000); if (!stats.hasErrors() && !stats.hasWarnings()) { + if (!flags.dev) { + const reporter = CiStatsReporter.fromEnv(log); + + const metrics = [ + { + group: '@kbn/ui-shared-deps asset size', + id: 'kbn-ui-shared-deps.js', + value: Fs.statSync(Path.resolve(DIST_DIR, 'kbn-ui-shared-deps.js')).size, + }, + { + group: '@kbn/ui-shared-deps asset size', + id: 'kbn-ui-shared-deps.@elastic.js', + value: Fs.statSync(Path.resolve(DIST_DIR, 'kbn-ui-shared-deps.@elastic.js')).size, + }, + { + group: '@kbn/ui-shared-deps asset size', + id: 'css', + value: + Fs.statSync(Path.resolve(DIST_DIR, 'kbn-ui-shared-deps.css')).size + + Fs.statSync(Path.resolve(DIST_DIR, 'kbn-ui-shared-deps.v7.light.css')).size, + }, + ]; + + log.debug('metrics:', metrics); + + await reporter.metrics(metrics); + } + log.success(`webpack completed in about ${took} seconds`); return; } @@ -56,11 +87,9 @@ run( if (flags.watch) { compiler.hooks.done.tap('report on stats', (stats) => { - try { - onCompilationComplete(stats); - } catch (error) { + onCompilationComplete(stats).catch((error) => { log.error(error.message); - } + }); }); compiler.hooks.watchRun.tap('report on start', () => { @@ -83,7 +112,7 @@ run( return; } - onCompilationComplete( + await onCompilationComplete( await new Promise((resolve, reject) => { compiler.run((error, stats) => { if (error) { diff --git a/packages/kbn-utils/src/repo_root.ts b/packages/kbn-utils/src/repo_root.ts index b33b28d8d6e2f..ed3516a7304f9 100644 --- a/packages/kbn-utils/src/repo_root.ts +++ b/packages/kbn-utils/src/repo_root.ts @@ -22,38 +22,50 @@ import Fs from 'fs'; import loadJsonFile from 'load-json-file'; -const isKibanaDir = (dir: string) => { +const readKibanaPkgJson = (dir: string) => { try { const path = Path.resolve(dir, 'package.json'); const json = loadJsonFile.sync(path); if (json && typeof json === 'object' && 'name' in json && json.name === 'kibana') { - return true; + return json; } } catch (error) { if (error && error.code === 'ENOENT') { - return false; + return; } throw error; } }; -// search for the kibana directory, since this file is moved around it might -// not be where we think but should always be a relatively close parent -// of this directory -const startDir = Fs.realpathSync(__dirname); -const { root: rootDir } = Path.parse(startDir); -let cursor = startDir; -while (true) { - if (isKibanaDir(cursor)) { - break; - } +const findKibanaPackageJson = () => { + // search for the kibana directory, since this file is moved around it might + // not be where we think but should always be a relatively close parent + // of this directory + const startDir = Fs.realpathSync(__dirname); + const { root: rootDir } = Path.parse(startDir); + let cursor = startDir; + while (true) { + const kibanaPkgJson = readKibanaPkgJson(cursor); + if (kibanaPkgJson) { + return { + kibanaDir: cursor, + kibanaPkgJson: kibanaPkgJson as { + name: string; + branch: string; + }, + }; + } - const parent = Path.dirname(cursor); - if (parent === rootDir) { - throw new Error(`unable to find kibana directory from ${startDir}`); + const parent = Path.dirname(cursor); + if (parent === rootDir) { + throw new Error(`unable to find kibana directory from ${startDir}`); + } + cursor = parent; } - cursor = parent; -} +}; + +const { kibanaDir, kibanaPkgJson } = findKibanaPackageJson(); -export const REPO_ROOT = cursor; +export const REPO_ROOT = kibanaDir; +export const UPSTREAM_BRANCH = kibanaPkgJson.branch; diff --git a/plugins/.empty b/plugins/.empty new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/rfcs/text/0013_saved_object_migrations.md b/rfcs/text/0013_saved_object_migrations.md new file mode 100644 index 0000000000000..c5069625cb8a6 --- /dev/null +++ b/rfcs/text/0013_saved_object_migrations.md @@ -0,0 +1,745 @@ +- Start Date: 2020-05-11 +- RFC PR: (leave this empty) +- Kibana Issue: (leave this empty) + +--- +- [1. Summary](#1-summary) +- [2. Motivation](#2-motivation) +- [3. Saved Object Migration Errors](#3-saved-object-migration-errors) +- [4. Design](#4-design) + - [4.0 Assumptions and tradeoffs](#40-assumptions-and-tradeoffs) + - [4.1 Discover and remedy potential failures before any downtime](#41-discover-and-remedy-potential-failures-before-any-downtime) + - [4.2 Automatically retry failed migrations until they succeed](#42-automatically-retry-failed-migrations-until-they-succeed) + - [4.2.1 Idempotent migrations performed without coordination](#421-idempotent-migrations-performed-without-coordination) + - [4.2.1.1 Restrictions](#4211-restrictions) + - [4.2.1.2 Migration algorithm: Cloned index per version](#4212-migration-algorithm-cloned-index-per-version) + - [4.2.1.3 Upgrade and rollback procedure](#4213-upgrade-and-rollback-procedure) + - [4.2.1.4 Handling documents that belong to a disabled plugin](#4214-handling-documents-that-belong-to-a-disabled-plugin) +- [5. Alternatives](#5-alternatives) + - [5.1 Rolling upgrades](#51-rolling-upgrades) + - [5.2 Single node migrations coordinated through a lease/lock](#52-single-node-migrations-coordinated-through-a-leaselock) + - [5.2.1 Migration algorithm](#521-migration-algorithm) + - [5.2.2 Document lock algorithm](#522-document-lock-algorithm) + - [5.2.3 Checking for "weak lease" expiry](#523-checking-for-weak-lease-expiry) + - [5.3 Minimize data loss with mixed Kibana versions during 7.x](#53-minimize-data-loss-with-mixed-kibana-versions-during-7x) + - [5.4 In-place migrations that re-use the same index (8.0)](#54-in-place-migrations-that-re-use-the-same-index-80) + - [5.4.1 Migration algorithm (8.0):](#541-migration-algorithm-80) + - [5.4.2 Minimizing data loss with unsupported upgrade configurations (8.0)](#542-minimizing-data-loss-with-unsupported-upgrade-configurations-80) + - [5.5 Tag objects as “invalid” if their transformation fails](#55-tag-objects-as-invalid-if-their-transformation-fails) +- [6. How we teach this](#6-how-we-teach-this) +- [7. Unresolved questions](#7-unresolved-questions) + +# 1. Summary + +Improve the Saved Object migration algorithm to ensure a smooth Kibana upgrade +procedure. + +# 2. Motivation + +Kibana version upgrades should have a minimal operational impact. To achieve +this, users should be able to rely on: + +1. A predictable downtime window. +2. A small downtime window. + 1. (future) provide a small downtime window on indices with 10k or even + a 100k documents. +3. The ability to discover and remedy potential failures before initiating the + downtime window. +4. Quick roll-back in case of failure. +5. Detailed documentation about the impact of downtime on the features they + are using (e.g. actions, task manager, fleet, reporting). +6. Mixed Kibana versions shouldn’t cause data loss. +7. (stretch goal) Maintain read-only functionality during the downtime window. + +The biggest hurdle to achieving the above is Kibana’s Saved Object migrations. +Migrations aren’t resilient and require manual intervention anytime an error +occurs (see [3. Saved Object Migration +Errors](#3-saved-object-migration-errors)). + +It is impossible to discover these failures before initiating downtime. Errors +often force users to roll-back to a previous version of Kibana or cause hours +of downtime. To retry the migration, users are asked to manually delete a +`.kibana_x` index. If done incorrectly this can lead to data loss, making it a +terrifying experience (restoring from a pre-upgrade snapshot is a safer +alternative but not mentioned in the docs or logs). + +Cloud users don’t have access to Kibana logs to be able to identify and remedy +the cause of the migration failure. Apart from blindly retrying migrations by +restoring a previous snapshot, cloud users are unable to remedy a failed +migration and have to escalate to support which can further delay resolution. + +Taken together, version upgrades are a major operational risk and discourage +users from adopting the latest features. + +# 3. Saved Object Migration Errors + +Any of the following classes of errors could result in a Saved Object +migration failure which requires manual intervention to resolve: + +1. A bug in a plugin’s registered document transformation function causes it + to throw an exception on _valid_ data. +2. _Invalid_ data stored in Elasticsearch causes a plugin’s registered + document transformation function to throw an exception . +3. Failures resulting from an unhealthy Elasticsearch cluster: + 1. Maximum shards open + 2. Too many scroll contexts + 3. `circuit_breaking_exception` (insufficient heap memory) + 4. `process_cluster_event_timeout_exception` for index-aliases, create-index, put-mappings + 5. Read-only indices due to low disk space (hitting the flood_stage watermark) + 6. Re-index failed: search rejected due to missing shards + 7. `TooManyRequests` while doing a `count` of documents requiring a migration + 8. Bulk write failed: primary shard is not active +4. The Kibana process is killed while migrations are in progress. + +# 4. Design +## 4.0 Assumptions and tradeoffs +The proposed design makes several important assumptions and tradeoffs. + +**Background:** + +The 7.x upgrade documentation lists taking an Elasticsearch snapshot as a +required step, but we instruct users to retry migrations and perform rollbacks +by deleting the failed `.kibana_n` index and pointing the `.kibana` alias to +`.kibana_n-1`: + - [Handling errors during saved object +migrations.](https://github.com/elastic/kibana/blob/75444a9f1879c5702f9f2b8ad4a70a3a0e75871d/docs/setup/upgrade/upgrade-migrations.asciidoc#handling-errors-during-saved-object-migrations) + - [Rolling back to a previous version of Kibana.](https://github.com/elastic/kibana/blob/75444a9f1879c5702f9f2b8ad4a70a3a0e75871d/docs/setup/upgrade/upgrade-migrations.asciidoc#rolling-back-to-a-previous-version-of-kib) + - Server logs from failed migrations. + +**Assumptions and tradeoffs:** +1. It is critical to maintain a backup index during 7.x to ensure that anyone + following the existing upgrade / rollback procedures don't end up in a + position where they no longer can recover their data. + 1. This excludes us from introducing in-place migrations to support huge + indices during 7.x. +2. The simplicity of idempotent, coordination-free migrations outweighs the + restrictions this will impose on the kinds of migrations we're able to + support in the future. See (4.2.1) +3. A saved object type (and it's associated migrations) will only ever be + owned by one plugin. If pluginA registers saved object type `plugin_a_type` + then pluginB must never register that same type, even if pluginA is + disabled. Although we cannot enforce it on third-party plugins, breaking + this assumption may lead to data loss. + +## 4.1 Discover and remedy potential failures before any downtime + +> Achieves goals: (2.3) +> Mitigates errors: (3.1), (3.2) + +1. Introduce a CLI option to perform a dry run migration to allow + administrators to locate and fix potential migration failures without + taking their existing Kibana node(s) offline. +2. To have the highest chance of surfacing potential failures such as low disk + space, dry run migrations should not be mere simulations. A dry run should + perform a real migration in a way that doesn’t impact the existing Kibana + cluster. +3. The CLI should generate a migration report to make it easy to create a + support request from a failed migration dry run. + 1. The report would be an NDJSON export of all failed objects. + 2. If support receives such a report, we could modify all the objects to + ensure the migration would pass and send this back to the client. + 3. The client can then import the updated objects using the standard Saved + Objects NDJSON import and run another dry run to verify all problems + have been fixed. +4. Make running dry run migrations a required step in the upgrade procedure + documentation. +5. (Optional) Add dry run migrations to the standard cloud upgrade procedure? + +## 4.2 Automatically retry failed migrations until they succeed + +> Achieves goals: (2.2), (2.6) +> Mitigates errors (3.3) and (3.4) + +External conditions such as failures from an unhealthy Elasticsearch cluster +(3.3) can cause the migration to fail. The Kibana cluster should be able to +recover automatically once these external conditions are resolved. There are +two broad approaches to solving this problem based on whether or not +migrations are idempotent: + +| Idempotent migrations |Description | +| --------------------- | --------------------------------------------------------- | +| Yes | Idempotent migrations performed without coordination | +| No | Single node migrations coordinated through a lease / lock | + +Idempotent migrations don't require coordination making the algorithm +significantly less complex and will never require manual intervention to +retry. We, therefore, prefer this solution, even though it introduces +restrictions on migrations (4.2.1.1). For other alternatives that were +considered see section [(5)](#5-alternatives). + +## 4.2.1 Idempotent migrations performed without coordination + +The migration system can be said to be idempotent if the same results are +produced whether the migration was run once or multiple times. This property +should hold even if new (up to date) writes occur in between migration runs +which introduces the following restrictions: + +### 4.2.1.1 Restrictions + +1. All document transforms need to be deterministic, that is a document + transform will always return the same result for the same set of inputs. +2. It should always be possible to construct the exact set of inputs required + for (1) at any point during the migration process (before, during, after). + +Although these restrictions require significant changes, it does not prevent +known upcoming migrations such as [sharing saved-objects in multiple spaces](https://github.com/elastic/kibana/issues/27004) or [splitting a saved +object into multiple child +documents](https://github.com/elastic/kibana/issues/26602). To ensure that +these migrations are idempotent, they will have to generate new saved object +id's deterministically with e.g. UUIDv5. + + +### 4.2.1.2 Migration algorithm: Cloned index per version +Note: +- The description below assumes the migration algorithm is released in 7.10.0. + So < 7.10.0 will use `.kibana` and >= 7.10.0 will use `.kibana_current`. +- We refer to the alias and index that outdated nodes use as the source alias + and source index. +- Every version performs a migration even if mappings or documents aren't outdated. + +1. Locate the source index by fetching aliases (including `.kibana` for + versions prior to v7.10.0) + + ``` + GET '/_alias/.kibana_current,.kibana_7.10.0,.kibana' + ``` + + The source index is: + 1. the index the `.kibana_current` alias points to, or if it doesn’t exist, + 2. the index the `.kibana` alias points to, or if it doesn't exist, + 3. the v6.x `.kibana` index + + If none of the aliases exists, this is a new Elasticsearch cluster and no + migrations are necessary. Create the `.kibana_7.10.0_001` index with the + following aliases: `.kibana_current` and `.kibana_7.10.0`. +2. If `.kibana_current` and `.kibana_7.10.0` both exists and are pointing to the same index this version's migration has already been completed. + 1. Because the same version can have plugins enabled at any point in time, + perform the mappings update in step (6) and migrate outdated documents + with step (7). + 2. Skip to step (9) to start serving traffic. +3. Fail the migration if: + 1. `.kibana_current` is pointing to an index that belongs to a later version of Kibana .e.g. `.kibana_7.12.0_001` + 2. (Only in 8.x) The source index contains documents that belong to an unknown Saved Object type (from a disabled plugin). Log an error explaining that the plugin that created these documents needs to be enabled again or that these objects should be deleted. See section (4.2.1.4). +4. Mark the source index as read-only and wait for all in-flight operations to drain (requires https://github.com/elastic/elasticsearch/pull/58094). This prevents any further writes from outdated nodes. Assuming this API is similar to the existing `//_close` API, we expect to receive `"acknowledged" : true` and `"shards_acknowledged" : true`. If all shards don’t acknowledge within the timeout, retry the operation until it succeeds. +5. Clone the source index into a new target index which has writes enabled. All nodes on the same version will use the same fixed index name e.g. `.kibana_7.10.0_001`. The `001` postfix isn't used by Kibana, but allows for re-indexing an index should this be required by an Elasticsearch upgrade. E.g. re-index `.kibana_7.10.0_001` into `.kibana_7.10.0_002` and point the `.kibana_7.10.0` alias to `.kibana_7.10.0_002`. + 1. `POST /.kibana_n/_clone/.kibana_7.10.0_001?wait_for_active_shards=all {"settings": {"index.blocks.write": false}}`. Ignore errors if the clone already exists. + 2. Wait for the cloning to complete `GET /_cluster/health/.kibana_7.10.0_001?wait_for_status=green&timeout=60s` If cloning doesn’t complete within the 60s timeout, log a warning for visibility and poll again. +6. Update the mappings of the target index + 1. Retrieve the existing mappings including the `migrationMappingPropertyHashes` metadata. + 2. Update the mappings with `PUT /.kibana_7.10.0_001/_mapping`. The API deeply merges any updates so this won't remove the mappings of any plugins that were enabled in a previous version but are now disabled. + 3. Ensure that fields are correctly indexed using the target index's latest mappings `POST /.kibana_7.10.0_001/_update_by_query?conflicts=proceed`. In the future we could optimize this query by only targeting documents: + 1. That belong to a known saved object type. + 2. Which don't have outdated migrationVersion numbers since these will be transformed anyway. + 3. That belong to a type whose mappings were changed by comparing the `migrationMappingPropertyHashes`. (Metadata, unlike the mappings isn't commutative, so there is a small chance that the metadata hashes do not accurately reflect the latest mappings, however, this will just result in an less efficient query). +7. Transform documents by reading batches of outdated documents from the target index then transforming and updating them with optimistic concurrency control. + 1. Ignore any version conflict errors. + 2. If a document transform throws an exception, add the document to a failure list and continue trying to transform all other documents. If any failures occured, log the complete list of documents that failed to transform. Fail the migration. +8. Mark the migration as complete by doing a single atomic operation (requires https://github.com/elastic/elasticsearch/pull/58100) that: + 1. Checks that `.kibana-current` alias is still pointing to the source index + 2. Points the `.kibana-7.10.0` and `.kibana_current` aliases to the target index. + 3. If this fails with a "required alias [.kibana_current] does not exist" error fetch `.kibana_current` again: + 1. If `.kibana_current` is _not_ pointing to our target index fail the migration. + 2. If `.kibana_current` is pointing to our target index the migration has succeeded and we can proceed to step (9). +9. Start serving traffic. + +Together with the limitations, this algorithm ensures that migrations are +idempotent. If two nodes are started simultaneously, both of them will start +transforming documents in that version's target index, but because migrations are idempotent, it doesn’t matter which node’s writes win. + +
+ In the future, this algorithm could enable (2.6) "read-only functionality during the downtime window" but this is outside of the scope of this RFC. + + Although the migration algorithm guarantees there's no data loss while providing read-only access to outdated nodes, this could cause plugins to behave in unexpected ways. If we wish to persue it in the future, enabling read-only functionality during the downtime window will be it's own project and must include an audit of all plugins' behaviours. +
+ +### 4.2.1.3 Upgrade and rollback procedure +When a newer Kibana starts an upgrade, it blocks all writes to the outdated index to prevent data loss. Since Kibana is not designed to gracefully handle a read-only index this could have unintended consequences such as a task executing multiple times but never being able to write that the task was completed successfully. To prevent unintended consequences, the following procedure should be followed when upgrading Kibana: + +1. Gracefully shutdown outdated nodes by sending a `SIGTERM` signal + 1. Node starts returning `503` from it's healthcheck endpoint to signal to + the load balancer that it's no longer accepting new traffic (requires https://github.com/elastic/kibana/issues/46984). + 2. Allows ungoing HTTP requests to complete with a configurable timeout + before forcefully terminating any open connections. + 3. Closes any keep-alive sockets by sending a `connection: close` header. + 4. Shutdown all plugins and Core services. +2. (recommended) Take a snapshot of all Kibana's Saved Objects indices. This simplifies doing a rollback to a simple snapshot restore, but is not required in order to do a rollback if a migration fails. +3. Start the upgraded Kibana nodes. All running Kibana nodes should be on the same version, have the same plugins enabled and use the same configuration. + +To rollback to a previous version of Kibana with a snapshot +1. Shutdown all Kibana nodes. +2. Restore the Saved Object indices and aliases from the snapshot +3. Start the rollback Kibana nodes. All running Kibana nodes should be on the same rollback version, have the same plugins enabled and use the same configuration. + +To rollback to a previous version of Kibana without a snapshot: +(Assumes the migration to 7.11.0 failed) +1. Shutdown all Kibana nodes. +2. Remove the index created by the failed Kibana migration by using the version-specific alias e.g. `DELETE /.kibana_7.11.0` +3. Identify the rollback index: + 1. If rolling back to a Kibana version < 7.10.0 use `.kibana` + 2. If rolling back to a Kibana version >= 7.10.0 use the version alias of the Kibana version you wish to rollback to e.g. `.kibana_7.10.0` +4. Point the `.kibana_current` alias to the rollback index. +5. Remove the write block from the rollback index. +6. Start the rollback Kibana nodes. All running Kibana nodes should be on the same rollback version, have the same plugins enabled and use the same configuration. + +### 4.2.1.4 Handling documents that belong to a disabled plugin +It is possible for a plugin to create documents in one version of Kibana, but then when upgrading Kibana to a newer version, that plugin is disabled. Because the plugin is disabled it cannot register it's Saved Objects type including the mappings or any migration transformation functions. These "orphan" documents could cause future problems: + - A major version introduces breaking mapping changes that cannot be applied to the data in these documents. + - Two majors later migrations will no longer be able to migrate this old schema and could fail unexpectadly when the plugin is suddenly enabled. + +As a concrete example of the above, consider a user taking the following steps: +1. Installs Kibana 7.6.0 with spaces=enabled. The spaces plugin creates a default space saved object. +2. User upgrades to 7.10.0 but uses the OSS download which has spaces=disabled. Although the 7.10.0 spaces plugin includes a migration for space documents, the OSS release cannot migrate the documents or update it's mappings. +3. User realizes they made a mistake and use Kibana 7.10.0 with x-pack and the spaces plugin enabled. At this point we have a completed migration for 7.10.0 but there's outdated spaces documents with migrationVersion=7.6.0 instead of 7.10.0. + +There are several approaches we could take to dealing with these orphan documents: + +1. Start up but refuse to query on types with outdated documents until a user manually triggers a re-migration + + Advantages: + - The impact is limited to a single plugin + + Disadvantages: + - It might be less obvious that a plugin is in a degraded state unless you read the logs (not possible on Cloud) or view the `/status` endpoint. + - If a user doesn't care that the plugin is degraded, orphan documents are carried forward indefinitely. + - Since Kibana has started receiving traffic, users can no longer + downgrade without losing data. They have to re-migrate, but if that + fails they're stuck. + - Introduces a breaking change in the upgrade behaviour + + To perform a re-migration: + - Remove the `.kibana_7.10.0` alias + - Take a snapshot OR set the configuration option `migrations.target_index_postfix: '002'` to create a new target index `.kibana_7.10.0_002` and keep the `.kibana_7.10.0_001` index to be able to perform a rollback. + - Start up Kibana + +2. Refuse to start Kibana until the plugin is enabled or it's data deleted + + Advantages: + - Admin’s are forced to deal with the problem as soon as they disable a plugin + + Disadvantages: + - Cannot temporarily disable a plugin to aid in debugging or to reduce the load a Kibana plugin places on an ES cluster. + - Introduces a breaking change + +3. Refuse to start a migration until the plugin is enabled or it's data deleted + + Advantages: + - We force users to enable a plugin or delete the documents which prevents these documents from creating future problems like a mapping update not being compatible because there are fields which are assumed to have been migrated. + - We keep the index “clean”. + + Disadvantages: + - Since users have to take down outdated nodes before they can start the upgrade, they have to enter the downtime window before they know about this problem. This prolongs the downtime window and in many cases might cause an operations team to have to reschedule their downtime window to give them time to investigate the documents that need to be deleted. Logging an error on every startup could warn users ahead of time to mitigate this. + - We don’t expose Kibana logs on Cloud so this will have to be escalated to support and could take 48hrs to resolve (users can safely rollback, but without visibility into the logs they might not know this). Exposing Kibana logs is on the cloud team’s roadmap. + - It might not be obvious just from the saved object type, which plugin created these objects. + - Introduces a breaking change in the upgrade behaviour + +4. Use a hash of enabled plugins as part of the target index name + Using a migration target index name like + `.kibana_7.10.0_${hash(enabled_plugins)}_001` we can migrate all documents + every time a plugin is enabled / disabled. + + Advantages: + - Outdated documents belonging to disabled plugins will be upgraded as soon + as the plugin is enabled again. + + Disadvantages: + - Disabling / enabling a plugin will cause downtime (breaking change). + - When a plugin is enabled, disabled and enabled again our target index + will be an existing outdated index which needs to be deleted and + re-cloned. Without a way to check if the index is outdated, we cannot + deterministically perform the delete and re-clone operation without + coordination. + +5. Transform outdated documents (step 7) on every startup + Advantages: + - Outdated documents belonging to disabled plugins will be upgraded as soon + as the plugin is enabled again. + + Disadvantages: + - Orphan documents are retained indefinitely so there's still a potential + for future problems. + - Slightly slower startup time since we have to query for outdated + documents every time. + +We prefer option (3) since it provides flexibility for disabling plugins in +the same version while also protecting users' data in all cases during an +upgrade migration. However, because this is a breaking change we will +implement (5) during 7.x and only implement (3) during 8.x. + +# 5. Alternatives +## 5.1 Rolling upgrades +We considered implementing rolling upgrades to provide zero downtime +migrations. However, this would introduce significant complexity for plugins: +they will need to maintain up and down migration transformations and ensure +that queries match both current and outdated documents across all +versions. Although we can afford the once-off complexity of implementing +rolling upgrades, the complexity burden of maintaining plugins that support +rolling-upgrades will slow down all development in Kibana. Since a predictable +downtime window is sufficient for our users, we decided against trying to +achieve zero downtime with rolling upgrades. See "Rolling upgrades" in +https://github.com/elastic/kibana/issues/52202 for more information. + +## 5.2 Single node migrations coordinated through a lease/lock +This alternative is a proposed algorithm for coordinating migrations so that +these only happen on a single node and therefore don't have the restrictions +found in [(4.2.1.1)](#4311-restrictions). We decided against this algorithm +primarily because it is a lot more complex, but also because it could still +require manual intervention to retry from certain unlikely edge cases. + +
+ It's impossible to guarantee that a single node performs the + migration and automatically retry failed migrations. + +Coordination should ensure that only one Kibana node performs the migration at +a given time which can be achived with a distributed lock built on top of +Elasticsearch. For the Kibana cluster to be able to retry a failed migration, +requires a specialized lock which expires after a given amount of inactivity. +We will refer to such expiring locks as a "lease". + +If a Kibana process stalls, it is possible that the process' lease has expired +but the process doesn't yet recognize this and continues the migration. To +prevent this from causing data loss each lease should be accompanied by a +"guard" that prevents all writes after the lease has expired. See +[how to do distributed +locking](https://martin.kleppmann.com/2016/02/08/how-to-do-distributed-locking.html) +for an in-depth discussion. + +Elasticsearch doesn't provide any building blocks for constructing such a guard. +
+ +However, we can implement a lock (that never expires) with strong +data-consistency guarantees. Because there’s no expiration, a failure between +obtaining the lock and releasing it will require manual intervention. Instead +of trying to accomplish the entire migration after obtaining a lock, we can +only perform the last step of the migration process, moving the aliases, with +a lock. A permanent failure in only this last step is not impossible, but very +unlikely. + +### 5.2.1 Migration algorithm +1. Obtain a document lock (see [5.2.2 Document lock + algorithm](#522-document-lock-algorithm)). Convert the lock into a "weak + lease" by expiring locks for nodes which aren't active (see [4.2.2.4 + Checking for lease expiry](#4324-checking-for-lease-expiry)). This "weak + lease" doesn't require strict guarantees since it's only used to prevent + multiple Kibana nodes from performing a migration in parallel to reduce the + load on Elasticsearch. +2. Migrate data into a new process specific index (we could use the process + UUID that’s used in the lease document like + `.kibana_3ef25ff1-090a-4335-83a0-307a47712b4e`). +3. Obtain a document lock (see [5.2.2 Document lock + algorithm](#522-document-lock-algorithm)). +4. Finish the migration by pointing `.kibana` → + `.kibana_3ef25ff1-090a-4335-83a0-307a47712b4e`. This automatically releases + the document lock (and any leases) because the new index will contain an + empty `kibana_cluster_state`. + +If a process crashes or is stopped after (3) but before (4) the lock will have +to be manually removed by deleting the `kibana_cluster_state` document from +`.kibana` or restoring from a snapshot. + +### 5.2.2 Document lock algorithm +To improve on the existing Saved Objects migrations lock, a locking algorithm +needs to satisfy the following requirements: +- Must guarantee that only a single node can obtain the lock. Since we can + only provide strong data-consistency guarantees on the document level in + Elasticsearch our locking mechanism needs to be based on a document. +- Manually removing the lock + - shouldn't have any risk of accidentally causing data loss. + - can be done with a single command that's always the same (shouldn’t + require trying to find `n` for removing the correct `.kibana_n` index). +- Must be easy to retrieve the lock/cluster state to aid in debugging or to + provide visibility. + +Algorithm: +1. Node reads `kibana_cluster_state` lease document from `.kibana` +2. It sends a heartbeat every `heartbeat_interval` seconds by sending an + update operation that adds it’s UUID to the `nodes` array and sets the + `lastSeen` value to the current local node time. If the update fails due to + a version conflict the update operation is retried after a random delay by + fetching the document again and attempting the update operation once more. +3. To obtain a lease, a node: + 1. Fetches the `kibana_cluster_state` document + 2. If all the nodes’ `hasLock === false` it sets it’s own `hasLock` to + true and attempts to write the document. If the update fails + (presumably because of another node’s heartbeat update) it restarts the + process to obtain a lease from step (3). + 3. If another nodes’ `hasLock === true` the node failed to acquire a + lock and waits until the active lock has expired before attempting to + obtain a lock again. +4. Once a node is done with its lock, it releases it by fetching and then + updating `hasLock = false`. The fetch + update operations are retried until + this node’s `hasLock === false`. + +Each machine writes a `UUID` to a file, so a single machine may have multiple +processes with the same Kibana `UUID`, so we should rather generate a new UUID +just for the lifetime of this process. + +`KibanaClusterState` document format: +```js + nodes: { + "852bd94e-5121-47f3-a321-e09d9db8d16e": { + version: "7.6.0", + lastSeen: [ 1114793, 555149266 ], // hrtime() big int timestamp + hasLease: true, + hasLock: false, + }, + "8d975c5b-cbf6-4418-9afb-7aa3ea34ac90": { + version: "7.6.0", + lastSeen: [ 1114862, 841295591 ], + hasLease: false, + hasLock: false, + }, + "3ef25ff1-090a-4335-83a0-307a47712b4e": { + version: "7.6.0", + lastSeen: [ 1114877, 611368546 ], + hasLease: false, + hasLock: false, + }, + }, + oplog: [ + {op: 'ACQUIRE_LOCK', node: '852bd94e...', timestamp: '2020-04-20T11:58:56.176Z'} + ] +} +``` + +### 5.2.3 Checking for "weak lease" expiry +The simplest way to check for lease expiry is to inspect the `lastSeen` value. +If `lastSeen + expiry_timeout > now` the lock is considered expired. If there +are clock drift or daylight savings time adjustments, there’s a risk that a +node loses it’s lease before `expiry_timeout` has occurred. Since losing a +lock prematurely will not lead to data loss it’s not critical that the +expiry time is observed under all conditions. + +A slightly safer approach is to use a monotonically increasing clock +(`process.hrtime()`) and relative time to determine expiry. Using a +monotonically increasing clock guarantees that the clock will always increase +even if the system time changes due to daylight savings time, NTP clock syncs, +or manually setting the time. To check for expiry, other nodes poll the +cluster state document. Once they see that the `lastSeen` value has increased, +they capture the current hr time `current_hr_time` and starts waiting until +`process.hrtime() - current_hr_time > expiry_timeout` if at that point +`lastSeen` hasn’t been updated the lease is considered to have expired. This +means other nodes can take up to `2*expiry_timeout` to recognize an expired +lease, but a lease will never expire prematurely. + +Any node that detects an expired lease can release that lease by setting the +expired node’s `hasLease = false`. It can then attempt to acquire its lease. + +## 5.3 Minimize data loss with mixed Kibana versions during 7.x +When multiple versions of Kibana are running at the same time, writes from the +outdated node can end up either in the outdated Kibana index, the newly +migrated index, or both. New documents added (and some updates) into the old +index while a migration is in-progress will be lost. Writes that end up in the +new index will be in an outdated format. This could cause queries on the data +to only return a subset of the results which leads to incorrect results or +silent data loss. + +Minimizing data loss from mixed 7.x versions, introduces two additional steps +to rollback to a previous version without a snapshot: +1. (existing) Point the `.kibana` alias to the previous Kibana index `.kibana_n-1` +2. (existing) Delete `.kibana_n` +3. (new) Enable writes on `.kibana_n-1` +4. (new) Delete the dummy "version lock" document from `.kibana_n-1` + +Since our documentation and server logs have implicitly encouraged users to +rollback without using snapshots, many users might have to rely on these +additional migration steps to perform a rollback. Since even the existing +steps are error prone, introducing more steps will likely introduce more +problems than what it solves. + +1. All future versions of Kibana 7.x will use the `.kibana_saved_objects` + alias to locate the current index. If `.kibana_saved_objects` doesn't + exist, newer versions will fallback to reading `.kibana`. +2. All future versions of Kibana will locate the index that + `.kibana_saved_objects` points to and then read and write directly from + the _index_ instead of the alias. +3. Before starting a migration: + 1. Write a new dummy "version lock" document to the `.kibana` index with a + `migrationVersion` set to the current version of Kibana. If an outdated + node is started up after a migration was started it will detect that + newer documents are present in the index and refuse to start up. + 2. Set the outdated index to read-only. Since `.kibana` is never advanced, + it will be pointing to a read-only index which prevent writes from + 6.8+ releases which are already online. + +## 5.4 In-place migrations that re-use the same index (8.0) +> We considered an algorithm that re-uses the same index for migrations and an approach to minimize data-loss if our upgrade procedures aren't followed. This is no longer our preferred approach because of several downsides: +> - It requires taking snapshots to prevent data loss so we can only release this in 8.x +> - Minimizing data loss with unsupported upgrade configurations adds significant complexity and still doesn't guarantee that data isn't lost. + +### 5.4.1 Migration algorithm (8.0): +1. Exit Kibana with a fatal error if a newer node has started a migration by + checking for: + 1. Documents with a newer `migrationVersion` numbers. +2. If the mappings are out of date, update the mappings to the combination of + the index's current mappings and the expected mappings. +3. If there are outdated documents, migrate these in batches: + 1. Read a batch of outdated documents from the index. + 2. Transform documents by applying the migration transformation functions. + 3. Update the document batch in the same index using optimistic concurrency + control. If a batch fails due to an update version mismatch continue + migrating the other batches. + 4. If a batch fails due other reasons repeat the entire migration process. +4. If any of the batches in step (3.3) failed, repeat the entire migration + process. This ensures that in-progress bulk update operations from an + outdated node won't lead to unmigrated documents still being present after + the migration. +5. Once all documents are up to date, the migration is complete and Kibana can + start serving traffic. + +Advantages: +- Not duplicating all documents into a new index will speed up migrations and + reduce the downtime window. This will be especially important for the future + requirement to support > 10k or > 100k documents. +- We can check the health of an existing index before starting the migration, + but we cannot detect what kind of failures might occur while creating a new + index. Whereas retrying migrations will eventually recover from the errors + in (3.3), re-using an index allows us to detect these problems before trying + and avoid errors like (3.3.1) altogether. +- Single index to backup instead of “index pattern” that matches any + `.kibana_n`. +- Simplifies Kibana system index Elasticsearch plugin since it needs to work + on one index per "tenant". +- By leveraging optimistic concurrency control we can further minimize data + loss for unsupported upgrade configurations in the future. + +Drawbacks: +- Cannot make breaking mapping changes (even though it was possible, we have not + introduced a breaking mapping change during 7.x). +- Rollback is only possible by restoring a snapshot which requires educating + users to ensure that they don't rely on `.kibana_n` indices as backups. + (Apart from the need to educate users, snapshot restores provide many + benefits). +- It narrows the second restriction under (4.2.1) even further: migrations + cannot rely on any state that could change as part of a migration because we + can no longer use the previous index as a snapshot of unmigrated state. +- We can’t automatically perform a rollback from a half-way done migration. +- It’s impossible to provide read-only functionality for outdated nodes which + means we can't achieve goal (2.7). + +### 5.4.2 Minimizing data loss with unsupported upgrade configurations (8.0) +> This alternative can reduce some data loss when our upgrade procedure isn't +> followed with the algorithm in (5.4.1). + +Even if (4.5.2) is the only supported upgrade procedure, we should try to +prevent data loss when these instructions aren't followed. + +To prevent data loss we need to prevent any writes from older nodes. We use +a version-specific alias for this purpose. Each time a migration is started, +all other aliases are removed. However, aliases are stored inside +Elasticsearch's ClusterState and this state could remain inconsistent between +nodes for an unbounded amount of time. In addition, bulk operations that were +accepted before the alias was removed will continue to run even after removing +the alias. + +As a result, Kibana cannot guarantee that there would be no data loss but +instead, aims to minimize it as much as possible by adding the bold sections +to the migration algorithm from (5.4.1) + +1. **Disable `action.auto_create_index` for the Kibana system indices.** +2. Exit Kibana with a fatal error if a newer node has started a migration by + checking for: + 1. **Version-specific aliases on the `.kibana` index with a newer version.** + 2. Documents with newer `migrationVersion` numbers. +3. **Remove all other aliases and create a new version-specific alias for + reading and writing to the `.kibana` index .e.g `.kibana_8.0.1`. During and + after the migration, all saved object reads and writes use this alias + instead of reading or writing directly to the index. By using the atomic + `POST /_aliases` API we minimize the chance that an outdated node creating + new outdated documents can cause data loss.** +4. **Wait for the default bulk operation timeout of 30s. This ensures that any + bulk operations accepted before the removal of the alias have either + completed or returned a timeout error to it's initiator.** +5. If the mappings are out of date, update the mappings **through the alias** + to the combination of the index's current mappings and the expected + mappings. **If this operation fails due to an index missing exception (most + likely because another node removed our version-specific alias) repeat the + entire migration process.** +6. If there are outdated documents, migrate these in batches: + 1. Read a batch of outdated documents from `.kibana_n`. + 2. Transform documents by applying the migration functions. + 3. Update the document batch in the same index using optimistic concurrency + control. If a batch fails due to an update version mismatch continue + migrating the other batches. + 4. If a batch fails due other reasons repeat the entire migration process. +7. If any of the batches in step (6.3) failed, repeat the entire migration + process. This ensures that in-progress bulk update operations from an + outdated node won't lead to unmigrated documents still being present after + the migration. +8. Once all documents are up to date, the migration is complete and Kibana can + start serving traffic. + +Steps (2) and (3) from the migration algorithm in minimize the chances of the +following scenarios occuring but cannot guarantee it. It is therefore useful +to enumarate some scenarios and their worst case impact: +1. An outdated node issued a bulk create to it's version-specific alias. + Because a user doesn't wait for all traffic to drain a newer node starts + it's migration before the bulk create was complete. Since this bulk create + was accepted before the newer node deleted the previous version-specific + aliases, it is possible that the index now contains some outdated documents + that the new node is unaware of and doesn't migrate. Although these outdated + documents can lead to inconsistent query results and data loss, step (4) + ensures that an error will be returned to the node that created these + objects. +2. A 8.1.0 node and a 8.2.0 node starts migrating a 8.0.0 index in parallel. + Even though the 8.2.0 node will remove the 8.1.0 version-specific aliases, + the 8.1.0 node could have sent an bulk update operation that got accepted + before its alias was removed. When the 8.2.0 node tries to migrate these + 8.1.0 documents it gets a version conflict but cannot be sure if this was + because another node of the same version migrated this document (which can + safely be ignored) or interference from a different Kibana version. The + 8.1.0 node will hit the error in step (6.3) and restart the migration but + then ultimately fail at step (2). The 8.2.0 node will repeat the entire + migration process from step (7) thus ensuring that all documents are up to + date. +3. A race condition with another Kibana node on the same version, but with + different enabled plugins caused this node's required mappings to be + overwritten. If this causes a mapper parsing exception in step (6.3) we can + restart the migration. Because updating the mappings is additive and saved + object types are unique to a plugin, restarting the migration will allow + the node to update the mappings to be compatible with node's plugins. Both + nodes will be able to successfully complete the migration of their plugins' + registered saved object types. However, if the migration doesn't trigger a + mapper parsing exception the incompatible mappings would go undetected + which can cause future problems like write failures or inconsistent query + results. + +## 5.5 Tag objects as “invalid” if their transformation fails +> This alternative prevents a failed migration when there's a migration transform function bug or a document with invalid data. Although it seems preferable to not fail the entire migration because of a single saved object type's migration transform bug or a single invalid document this has several pitfalls: +> 1. When an object fails to migrate the data for that saved object type becomes inconsistent. This could load to a critical feature being unavailable to a user leaving them with no choice but to downgrade. +> 2. Because Kibana starts accepting traffic after encountering invalid objects a rollback will lead to data loss leaving users with no clean way to recover. +> As a result we prefer to let an upgrade fail and making it easy for users to rollback until they can resolve the root cause. + +> Achieves goals: (2.2) +> Mitigates Errors (3.1), (3.2) + +1. Tag objects as “invalid” if they cause an exception when being transformed, + but don’t fail the entire migration. +2. Log an error message informing administrators that there are invalid + objects which require inspection. For each invalid object, provide an error + stack trace to aid in debugging. +3. Administrators should be able to generate a migration report (similar to + the one dry run migrations create) which is an NDJSON export of all objects + tagged as “invalid”. + 1. Expose this as an HTTP API first + 2. (later) Notify administrators and allow them to export invalid objects + from the Kibana UI. +4. When an invalid object is read, the Saved Objects repository will throw an + invalid object exception which should include a link to the documentation + to help administrators resolve migration bugs. +5. Educate Kibana developers to no longer simply write back an unmigrated + document if an exception occurred. A migration function should either + successfully transform the object or throw. + +# 6. How we teach this +1. Update documentation and server logs to start educating users to depend on + snapshots for Kibana rollbacks. +2. Update developer documentation and educate developers with best practices + for writing migration functions. + +# 7. Unresolved questions +1. When cloning an index we can only ever add new fields to the mappings. When + a saved object type or specific field is removed, the mappings will remain + until we re-index. Is it sufficient to only re-index every major? How do we + track the field count as it grows over every upgrade? +2. More generally, how do we deal with the growing field count approaching the + default limit of 1000? diff --git a/scripts/build_plugin_list_docs.js b/scripts/build_plugin_list_docs.js index 54821a1b10ee8..6f184ca7b14c6 100644 --- a/scripts/build_plugin_list_docs.js +++ b/scripts/build_plugin_list_docs.js @@ -17,5 +17,5 @@ * under the License. */ -require('../src/setup_node_env/prebuilt_dev_only_entry'); +require('../src/setup_node_env/no_transpilation'); require('@kbn/dev-utils').runPluginListCli(); diff --git a/scripts/es.js b/scripts/es.js index 93f1d69350bac..53b01d8cb4414 100644 --- a/scripts/es.js +++ b/scripts/es.js @@ -17,7 +17,7 @@ * under the License. */ -require('../src/setup_node_env'); +require('../src/setup_node_env/no_transpilation'); var resolve = require('path').resolve; var pkg = require('../package.json'); diff --git a/scripts/generate_plugin.js b/scripts/generate_plugin.js index f695eabb30f21..af3d31048ecfc 100644 --- a/scripts/generate_plugin.js +++ b/scripts/generate_plugin.js @@ -17,5 +17,5 @@ * under the License. */ -require('../src/setup_node_env/prebuilt_dev_only_entry'); +require('../src/setup_node_env/no_transpilation'); require('@kbn/plugin-generator').runCli(); diff --git a/scripts/generate_team_assignments.js b/scripts/generate_team_assignments.js new file mode 100644 index 0000000000000..9dcb9bb90e0fd --- /dev/null +++ b/scripts/generate_team_assignments.js @@ -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. + */ + +require('../src/setup_node_env'); +require('../src/dev/code_coverage/ingest_coverage/team_assignment').generateTeamAssignments(); diff --git a/scripts/kibana.js b/scripts/kibana.js index f5a63e6c07dd6..2767e555f2736 100644 --- a/scripts/kibana.js +++ b/scripts/kibana.js @@ -17,6 +17,4 @@ * under the License. */ -require('../src/apm')(process.env.ELASTIC_APM_PROXY_SERVICE_NAME || 'kibana-proxy'); -require('../src/setup_node_env'); -require('../src/cli/cli'); +require('../src/cli/dev'); diff --git a/scripts/load_team_assignment.js b/scripts/load_team_assignment.js deleted file mode 100644 index b8f5edc833634..0000000000000 --- a/scripts/load_team_assignment.js +++ /dev/null @@ -1,21 +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. - */ - -require('../src/setup_node_env'); -require('../src/dev/code_coverage/ingest_coverage/team_assignment').uploadTeamAssignmentJson(); diff --git a/scripts/plugin_helpers.js b/scripts/plugin_helpers.js index a07ba7a9185f8..f28bf8fcfff90 100644 --- a/scripts/plugin_helpers.js +++ b/scripts/plugin_helpers.js @@ -17,5 +17,5 @@ * under the License. */ -require('../src/setup_node_env/prebuilt_dev_only_entry'); +require('../src/setup_node_env/no_transpilation'); require('@kbn/plugin-helpers').runCli(); diff --git a/scripts/precommit_hook.js b/scripts/precommit_hook.js index 7b9647cb7a911..7749fab6d371f 100644 --- a/scripts/precommit_hook.js +++ b/scripts/precommit_hook.js @@ -17,5 +17,5 @@ * under the License. */ -require('../src/setup_node_env/babel_register'); +require('@kbn/optimizer').registerNodeAutoTranspilation(); require('../src/dev/run_precommit_hook'); diff --git a/scripts/register_git_hook.js b/scripts/register_git_hook.js index af3f54619bcec..50dfeaf46109f 100644 --- a/scripts/register_git_hook.js +++ b/scripts/register_git_hook.js @@ -17,5 +17,5 @@ * under the License. */ -require('../src/setup_node_env/prebuilt_dev_only_entry'); +require('../src/setup_node_env/no_transpilation'); require('@kbn/dev-utils/target/precommit_hook/cli'); diff --git a/scripts/release_notes.js b/scripts/release_notes.js index f46ee5823d70d..ee9275194ae94 100644 --- a/scripts/release_notes.js +++ b/scripts/release_notes.js @@ -17,5 +17,5 @@ * under the License. */ -require('../src/setup_node_env/prebuilt_dev_only_entry'); +require('../src/setup_node_env/no_transpilation'); require('@kbn/release-notes').runReleaseNotesCli(); diff --git a/scripts/telemetry_check.js b/scripts/telemetry_check.js index 06b3ed46bdba6..22a22b401cb15 100644 --- a/scripts/telemetry_check.js +++ b/scripts/telemetry_check.js @@ -17,5 +17,5 @@ * under the License. */ -require('../src/setup_node_env/prebuilt_dev_only_entry'); +require('../src/setup_node_env/no_transpilation'); require('@kbn/telemetry-tools').runTelemetryCheck(); diff --git a/scripts/telemetry_extract.js b/scripts/telemetry_extract.js index 051bee26537b9..e2fbb64c26719 100644 --- a/scripts/telemetry_extract.js +++ b/scripts/telemetry_extract.js @@ -17,5 +17,5 @@ * under the License. */ -require('../src/setup_node_env/prebuilt_dev_only_entry'); +require('../src/setup_node_env/no_transpilation'); require('@kbn/telemetry-tools').runTelemetryExtract(); diff --git a/src/cli/cluster/cluster_manager.ts b/src/cli/cluster/cluster_manager.ts index 78472bb3f517d..3d81185e8a313 100644 --- a/src/cli/cluster/cluster_manager.ts +++ b/src/cli/cluster/cluster_manager.ts @@ -19,6 +19,7 @@ import { resolve } from 'path'; import { format as formatUrl } from 'url'; +import Fs from 'fs'; import opn from 'opn'; import { REPO_ROOT } from '@kbn/utils'; @@ -227,22 +228,26 @@ export class ClusterManager { fromRoot('src/legacy/server'), fromRoot('src/legacy/ui'), fromRoot('src/legacy/utils'), - fromRoot('x-pack/legacy/common'), - fromRoot('x-pack/legacy/plugins'), - fromRoot('x-pack/legacy/server'), fromRoot('config'), ...extraPaths, ].map((path) => resolve(path)) ) ); + for (const watchPath of watchPaths) { + if (!Fs.existsSync(fromRoot(watchPath))) { + throw new Error( + `A watch directory [${watchPath}] does not exist, which will cause chokidar to fail. Either make sure the directory exists or remove it as a watch source in the ClusterManger` + ); + } + } + const ignorePaths = [ /[\\\/](\..*|node_modules|bower_components|target|public|__[a-z0-9_]+__|coverage)([\\\/]|$)/, /\.test\.(js|tsx?)$/, /\.md$/, /debug\.log$/, ...pluginInternalDirsIgnore, - fromRoot('src/legacy/server/sass/__tmp__'), fromRoot('x-pack/plugins/reporting/chromium'), fromRoot('x-pack/plugins/security_solution/cypress'), fromRoot('x-pack/plugins/apm/e2e'), @@ -253,7 +258,6 @@ export class ClusterManager { fromRoot('x-pack/plugins/lists/server/scripts'), fromRoot('x-pack/plugins/security_solution/scripts'), fromRoot('x-pack/plugins/security_solution/server/lib/detection_engine/scripts'), - 'plugins/java_languageserver', ]; this.watcher = chokidar.watch(watchPaths, { diff --git a/src/cli/cluster/worker.ts b/src/cli/cluster/worker.ts index c8a8a067d30bf..f6205b41ac5a5 100644 --- a/src/cli/cluster/worker.ts +++ b/src/cli/cluster/worker.ts @@ -24,7 +24,7 @@ import { EventEmitter } from 'events'; import { BinderFor } from './binder_for'; import { fromRoot } from '../../core/server/utils'; -const cliPath = fromRoot('src/cli'); +const cliPath = fromRoot('src/cli/dev'); const baseArgs = _.difference(process.argv.slice(2), ['--no-watch']); const baseArgv = [process.execPath, cliPath].concat(baseArgs); diff --git a/src/cli/dev.js b/src/cli/dev.js new file mode 100644 index 0000000000000..9d0cb35c3d730 --- /dev/null +++ b/src/cli/dev.js @@ -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. + */ + +require('../apm')(process.env.ELASTIC_APM_PROXY_SERVICE_NAME || 'kibana-proxy'); +require('../setup_node_env'); +require('./cli'); diff --git a/src/cli/dist.js b/src/cli/dist.js new file mode 100644 index 0000000000000..2e26eaf52e836 --- /dev/null +++ b/src/cli/dist.js @@ -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. + */ + +require('../apm')(); +require('../setup_node_env/no_transpilation'); +require('core-js/stable'); +require('./cli'); diff --git a/src/cli/index.js b/src/cli/index.js deleted file mode 100644 index 45f88eaf82a5b..0000000000000 --- a/src/cli/index.js +++ /dev/null @@ -1,22 +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. - */ - -require('../apm')(); -require('../setup_node_env'); -require('./cli'); diff --git a/src/cli/serve/integration_tests/invalid_config.test.ts b/src/cli/serve/integration_tests/invalid_config.test.ts index fd6fa1bf192fc..a72142faa22fe 100644 --- a/src/cli/serve/integration_tests/invalid_config.test.ts +++ b/src/cli/serve/integration_tests/invalid_config.test.ts @@ -18,10 +18,10 @@ */ import { spawnSync } from 'child_process'; -import { resolve } from 'path'; -const ROOT_DIR = resolve(__dirname, '../../../../'); -const INVALID_CONFIG_PATH = resolve(__dirname, '__fixtures__/invalid_config.yml'); +import { REPO_ROOT } from '@kbn/dev-utils'; + +const INVALID_CONFIG_PATH = require.resolve('./__fixtures__/invalid_config.yml'); interface LogEntry { message: string; @@ -35,11 +35,11 @@ describe('cli invalid config support', function () { function () { // Unused keys only throw once LegacyService starts, so disable migrations so that Core // will finish the start lifecycle without a running Elasticsearch instance. - const { error, status, stdout } = spawnSync( + const { error, status, stdout, stderr } = spawnSync( process.execPath, - ['src/cli', '--config', INVALID_CONFIG_PATH, '--migrations.skip=true'], + ['scripts/kibana', '--config', INVALID_CONFIG_PATH, '--migrations.skip=true'], { - cwd: ROOT_DIR, + cwd: REPO_ROOT, } ); @@ -57,13 +57,21 @@ describe('cli invalid config support', function () { })); expect(error).toBe(undefined); - expect(status).toBe(64); + + if (!fatalLogLine) { + throw new Error( + `cli did not log the expected fatal error message:\n\nstdout: \n${stdout}\n\nstderr:\n${stderr}` + ); + } + expect(fatalLogLine.message).toContain( 'Error: Unknown configuration key(s): "unknown.key", "other.unknown.key", "other.third", "some.flat.key", ' + '"some.array". Check for spelling errors and ensure that expected plugins are installed.' ); expect(fatalLogLine.tags).toEqual(['fatal', 'root']); expect(fatalLogLine.type).toEqual('log'); + + expect(status).toBe(64); }, 20 * 1000 ); diff --git a/src/core/public/apm_system.ts b/src/core/public/apm_system.ts new file mode 100644 index 0000000000000..0a18f02c97293 --- /dev/null +++ b/src/core/public/apm_system.ts @@ -0,0 +1,75 @@ +/* + * 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. + */ + +/** + * This is the entry point used to boot the frontend when serving a application + * that lives in the Kibana Platform. + * + * Any changes to this file should be kept in sync with + * src/legacy/ui/ui_bundles/app_entry_template.js + */ +import type { InternalApplicationStart } from './application'; + +interface ApmConfig { + // AgentConfigOptions is not exported from @elastic/apm-rum + globalLabels?: Record; +} + +interface StartDeps { + application: InternalApplicationStart; +} + +export class ApmSystem { + private readonly enabled: boolean; + /** + * `apmConfig` would be populated with relevant APM RUM agent + * configuration if server is started with `ELASTIC_APM_ACTIVE=true` + */ + constructor(private readonly apmConfig?: ApmConfig) { + this.enabled = process.env.IS_KIBANA_DISTRIBUTABLE !== 'true' && apmConfig != null; + } + + async setup() { + if (!this.enabled) return; + const { init, apm } = await import('@elastic/apm-rum'); + const { globalLabels, ...apmConfig } = this.apmConfig!; + if (globalLabels) { + apm.addLabels(globalLabels); + } + + init(apmConfig); + } + + async start(start?: StartDeps) { + if (!this.enabled || !start) return; + /** + * Register listeners for navigation changes and capture them as + * route-change transactions after Kibana app is bootstrapped + */ + start.application.currentAppId$.subscribe((appId) => { + const apmInstance = (window as any).elasticApm; + if (appId && apmInstance && typeof apmInstance.startTransaction === 'function') { + apmInstance.startTransaction(`/app/${appId}`, 'route-change', { + managed: true, + canReuse: true, + }); + } + }); + } +} diff --git a/src/core/public/application/integration_tests/router.test.tsx b/src/core/public/application/integration_tests/router.test.tsx index e3f992990f9f9..d982136422268 100644 --- a/src/core/public/application/integration_tests/router.test.tsx +++ b/src/core/public/application/integration_tests/router.test.tsx @@ -107,7 +107,7 @@ describe('AppRouter', () => { expect(app1.mounter.mount).toHaveBeenCalled(); expect(dom?.html()).toMatchInlineSnapshot(` - "
+ "
basename: /app/app1 html: App 1
" @@ -119,7 +119,7 @@ describe('AppRouter', () => { expect(app1Unmount).toHaveBeenCalled(); expect(app2.mounter.mount).toHaveBeenCalled(); expect(dom?.html()).toMatchInlineSnapshot(` - "
+ "
basename: /app/app2 html:
App 2
" @@ -133,7 +133,7 @@ describe('AppRouter', () => { expect(standardApp.mounter.mount).toHaveBeenCalled(); expect(dom?.html()).toMatchInlineSnapshot(` - "
+ "
basename: /app/app1 html: App 1
" @@ -145,7 +145,7 @@ describe('AppRouter', () => { expect(standardAppUnmount).toHaveBeenCalled(); expect(chromelessApp.mounter.mount).toHaveBeenCalled(); expect(dom?.html()).toMatchInlineSnapshot(` - "
+ "
basename: /chromeless-a/path html:
Chromeless A
" @@ -157,7 +157,7 @@ describe('AppRouter', () => { expect(chromelessAppUnmount).toHaveBeenCalled(); expect(standardApp.mounter.mount).toHaveBeenCalledTimes(2); expect(dom?.html()).toMatchInlineSnapshot(` - "
+ "
basename: /app/app1 html: App 1
" @@ -171,7 +171,7 @@ describe('AppRouter', () => { expect(chromelessAppA.mounter.mount).toHaveBeenCalled(); expect(dom?.html()).toMatchInlineSnapshot(` - "
+ "
basename: /chromeless-a/path html:
Chromeless A
" @@ -183,7 +183,7 @@ describe('AppRouter', () => { expect(chromelessAppAUnmount).toHaveBeenCalled(); expect(chromelessAppB.mounter.mount).toHaveBeenCalled(); expect(dom?.html()).toMatchInlineSnapshot(` - "
+ "
basename: /chromeless-b/path html:
Chromeless B
" @@ -195,7 +195,7 @@ describe('AppRouter', () => { expect(chromelessAppBUnmount).toHaveBeenCalled(); expect(chromelessAppA.mounter.mount).toHaveBeenCalledTimes(2); expect(dom?.html()).toMatchInlineSnapshot(` - "
+ "
basename: /chromeless-a/path html:
Chromeless A
" diff --git a/src/core/public/application/types.ts b/src/core/public/application/types.ts index df83b6e932aad..02d2d3a52a01a 100644 --- a/src/core/public/application/types.ts +++ b/src/core/public/application/types.ts @@ -710,11 +710,17 @@ export interface ApplicationStart { navigateToApp(appId: string, options?: NavigateToAppOptions): Promise; /** - * Navigate to given url, which can either be an absolute url or a relative path, in a SPA friendly way when possible. + * Navigate to given URL in a SPA friendly way when possible (when the URL will redirect to a valid application + * within the current basePath). * - * If all these criteria are true for the given url: + * The method resolves pathnames the same way browsers do when resolving a `` value. The provided `url` can be: + * - an absolute URL + * - an absolute path + * - a path relative to the current URL (window.location.href) + * + * If all these criteria are true for the given URL: * - (only for absolute URLs) The origin of the URL matches the origin of the browser's current location - * - The pathname of the URL starts with the current basePath (eg. /mybasepath/s/my-space) + * - The resolved pathname of the provided URL/path starts with the current basePath (eg. /mybasepath/s/my-space) * - The pathname segment after the basePath matches any known application route (eg. /app// or any application's `appRoute` configuration) * * Then a SPA navigation will be performed using `navigateToApp` using the corresponding application and path. @@ -727,23 +733,27 @@ export interface ApplicationStart { * // will call `application.navigateToApp('discover', { path: '/some-path?foo=bar'})` * application.navigateToUrl('https://kibana:8080/base-path/s/my-space/app/discover/some-path?foo=bar') * application.navigateToUrl('/base-path/s/my-space/app/discover/some-path?foo=bar') + * application.navigateToUrl('./discover/some-path?foo=bar') * * // will perform a full page reload using `window.location.assign` * application.navigateToUrl('https://elsewhere:8080/base-path/s/my-space/app/discover/some-path') // origin does not match * application.navigateToUrl('/app/discover/some-path') // does not include the current basePath * application.navigateToUrl('/base-path/s/my-space/app/unknown-app/some-path') // unknown application + * application.navigateToUrl('../discover') // resolve to `/base-path/s/my-space/discover` which is not a path of a known app. + * application.navigateToUrl('../../other-space/discover') // resolve to `/base-path/s/other-space/discover` which is not within the current basePath. * ``` * - * @param url - an absolute url, or a relative path, to navigate to. + * @param url - an absolute URL, an absolute path or a relative path, to navigate to. */ navigateToUrl(url: string): Promise; /** - * Returns an URL to a given app, including the global base path. - * By default, the URL is relative (/basePath/app/my-app). - * Use the `absolute` option to generate an absolute url (http://host:port/basePath/app/my-app) + * Returns the absolute path (or URL) to a given app, including the global base path. + * + * By default, it returns the absolute path of the application (e.g `/basePath/app/my-app`). + * Use the `absolute` option to generate an absolute url instead (e.g `http://host:port/basePath/app/my-app`) * - * Note that when generating absolute urls, the origin (protocol, host and port) are determined from the browser's location. + * Note that when generating absolute urls, the origin (protocol, host and port) are determined from the browser's current location. * * @param appId * @param options.path - optional path inside application to deep link to diff --git a/src/core/public/application/ui/app_container.tsx b/src/core/public/application/ui/app_container.tsx index 089d1cf3f3ced..9821db5ba2666 100644 --- a/src/core/public/application/ui/app_container.tsx +++ b/src/core/public/application/ui/app_container.tsx @@ -25,7 +25,7 @@ import React, { useState, MutableRefObject, } from 'react'; -import { EuiLoadingSpinner } from '@elastic/eui'; +import { EuiLoadingElastic } from '@elastic/eui'; import type { MountPoint } from '../../types'; import { AppLeaveHandler, AppStatus, AppUnmount, Mounter } from '../types'; @@ -120,7 +120,7 @@ export const AppContainer: FunctionComponent = ({ {appNotFound && } {showSpinner && (
- +
)}
diff --git a/src/core/public/application/utils.test.ts b/src/core/public/application/utils.test.ts deleted file mode 100644 index ee1d82a7a872e..0000000000000 --- a/src/core/public/application/utils.test.ts +++ /dev/null @@ -1,440 +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 { of } from 'rxjs'; -import { App, AppNavLinkStatus, AppStatus } from './types'; -import { BasePath } from '../http/base_path'; -import { appendAppPath, getAppInfo, parseAppUrl, relativeToAbsolute, removeSlashes } from './utils'; - -describe('removeSlashes', () => { - it('only removes duplicates by default', () => { - expect(removeSlashes('/some//url//to//')).toEqual('/some/url/to/'); - expect(removeSlashes('some/////other//url')).toEqual('some/other/url'); - }); - - it('remove trailing slash when `trailing` is true', () => { - expect(removeSlashes('/some//url//to//', { trailing: true })).toEqual('/some/url/to'); - }); - - it('remove leading slash when `leading` is true', () => { - expect(removeSlashes('/some//url//to//', { leading: true })).toEqual('some/url/to/'); - }); - - it('does not removes duplicates when `duplicates` is false', () => { - expect(removeSlashes('/some//url//to/', { leading: true, duplicates: false })).toEqual( - 'some//url//to/' - ); - expect(removeSlashes('/some//url//to/', { trailing: true, duplicates: false })).toEqual( - '/some//url//to' - ); - }); - - it('accept mixed options', () => { - expect( - removeSlashes('/some//url//to/', { leading: true, duplicates: false, trailing: true }) - ).toEqual('some//url//to'); - expect( - removeSlashes('/some//url//to/', { leading: true, duplicates: true, trailing: true }) - ).toEqual('some/url/to'); - }); -}); - -describe('appendAppPath', () => { - it('appends the appBasePath with given path', () => { - expect(appendAppPath('/app/my-app', '/some-path')).toEqual('/app/my-app/some-path'); - expect(appendAppPath('/app/my-app/', 'some-path')).toEqual('/app/my-app/some-path'); - expect(appendAppPath('/app/my-app', 'some-path')).toEqual('/app/my-app/some-path'); - expect(appendAppPath('/app/my-app', '')).toEqual('/app/my-app'); - }); - - it('preserves the trailing slash only if included in the hash or appPath', () => { - expect(appendAppPath('/app/my-app', '/some-path/')).toEqual('/app/my-app/some-path'); - expect(appendAppPath('/app/my-app', '/some-path#/')).toEqual('/app/my-app/some-path#/'); - expect(appendAppPath('/app/my-app#/', '')).toEqual('/app/my-app#/'); - expect(appendAppPath('/app/my-app#', '/')).toEqual('/app/my-app#/'); - expect(appendAppPath('/app/my-app', '/some-path#/hash/')).toEqual( - '/app/my-app/some-path#/hash/' - ); - expect(appendAppPath('/app/my-app', '/some-path#/hash')).toEqual('/app/my-app/some-path#/hash'); - }); -}); - -describe('relativeToAbsolute', () => { - it('converts a relative path to an absolute url', () => { - const origin = window.location.origin; - expect(relativeToAbsolute('path')).toEqual(`${origin}/path`); - expect(relativeToAbsolute('/path#hash')).toEqual(`${origin}/path#hash`); - expect(relativeToAbsolute('/path?query=foo')).toEqual(`${origin}/path?query=foo`); - }); -}); - -describe('parseAppUrl', () => { - let apps: Map>; - let basePath: BasePath; - - const getOrigin = () => 'https://kibana.local:8080'; - - const createApp = (props: Partial): App => { - const app: App = { - id: 'some-id', - title: 'some-title', - mount: () => () => undefined, - ...props, - }; - apps.set(app.id, app); - return app; - }; - - beforeEach(() => { - apps = new Map(); - basePath = new BasePath('/base-path'); - - createApp({ - id: 'foo', - }); - createApp({ - id: 'bar', - appRoute: '/custom-bar', - }); - }); - - describe('with relative paths', () => { - it('parses the app id', () => { - expect(parseAppUrl('/base-path/app/foo', basePath, apps, getOrigin)).toEqual({ - app: 'foo', - path: undefined, - }); - expect(parseAppUrl('/base-path/custom-bar', basePath, apps, getOrigin)).toEqual({ - app: 'bar', - path: undefined, - }); - }); - it('parses the path', () => { - expect(parseAppUrl('/base-path/app/foo/some/path', basePath, apps, getOrigin)).toEqual({ - app: 'foo', - path: '/some/path', - }); - expect(parseAppUrl('/base-path/custom-bar/another/path/', basePath, apps, getOrigin)).toEqual( - { - app: 'bar', - path: '/another/path/', - } - ); - }); - it('includes query and hash in the path for default app route', () => { - expect(parseAppUrl('/base-path/app/foo#hash/bang', basePath, apps, getOrigin)).toEqual({ - app: 'foo', - path: '#hash/bang', - }); - expect(parseAppUrl('/base-path/app/foo?hello=dolly', basePath, apps, getOrigin)).toEqual({ - app: 'foo', - path: '?hello=dolly', - }); - expect(parseAppUrl('/base-path/app/foo/path?hello=dolly', basePath, apps, getOrigin)).toEqual( - { - app: 'foo', - path: '/path?hello=dolly', - } - ); - expect(parseAppUrl('/base-path/app/foo/path#hash/bang', basePath, apps, getOrigin)).toEqual({ - app: 'foo', - path: '/path#hash/bang', - }); - expect( - parseAppUrl('/base-path/app/foo/path#hash/bang?hello=dolly', basePath, apps, getOrigin) - ).toEqual({ - app: 'foo', - path: '/path#hash/bang?hello=dolly', - }); - }); - it('includes query and hash in the path for custom app route', () => { - expect(parseAppUrl('/base-path/custom-bar#hash/bang', basePath, apps, getOrigin)).toEqual({ - app: 'bar', - path: '#hash/bang', - }); - expect(parseAppUrl('/base-path/custom-bar?hello=dolly', basePath, apps, getOrigin)).toEqual({ - app: 'bar', - path: '?hello=dolly', - }); - expect( - parseAppUrl('/base-path/custom-bar/path?hello=dolly', basePath, apps, getOrigin) - ).toEqual({ - app: 'bar', - path: '/path?hello=dolly', - }); - expect( - parseAppUrl('/base-path/custom-bar/path#hash/bang', basePath, apps, getOrigin) - ).toEqual({ - app: 'bar', - path: '/path#hash/bang', - }); - expect( - parseAppUrl('/base-path/custom-bar/path#hash/bang?hello=dolly', basePath, apps, getOrigin) - ).toEqual({ - app: 'bar', - path: '/path#hash/bang?hello=dolly', - }); - }); - it('returns undefined when the app is not known', () => { - expect(parseAppUrl('/base-path/app/non-registered', basePath, apps, getOrigin)).toEqual( - undefined - ); - expect(parseAppUrl('/base-path/unknown-path', basePath, apps, getOrigin)).toEqual(undefined); - }); - }); - - describe('with absolute urls', () => { - it('parses the app id', () => { - expect( - parseAppUrl('https://kibana.local:8080/base-path/app/foo', basePath, apps, getOrigin) - ).toEqual({ - app: 'foo', - path: undefined, - }); - expect( - parseAppUrl('https://kibana.local:8080/base-path/custom-bar', basePath, apps, getOrigin) - ).toEqual({ - app: 'bar', - path: undefined, - }); - }); - it('parses the path', () => { - expect( - parseAppUrl( - 'https://kibana.local:8080/base-path/app/foo/some/path', - basePath, - apps, - getOrigin - ) - ).toEqual({ - app: 'foo', - path: '/some/path', - }); - expect( - parseAppUrl( - 'https://kibana.local:8080/base-path/custom-bar/another/path/', - basePath, - apps, - getOrigin - ) - ).toEqual({ - app: 'bar', - path: '/another/path/', - }); - }); - it('includes query and hash in the path for default app routes', () => { - expect( - parseAppUrl( - 'https://kibana.local:8080/base-path/app/foo#hash/bang', - basePath, - apps, - getOrigin - ) - ).toEqual({ - app: 'foo', - path: '#hash/bang', - }); - expect( - parseAppUrl( - 'https://kibana.local:8080/base-path/app/foo?hello=dolly', - basePath, - apps, - getOrigin - ) - ).toEqual({ - app: 'foo', - path: '?hello=dolly', - }); - expect( - parseAppUrl( - 'https://kibana.local:8080/base-path/app/foo/path?hello=dolly', - basePath, - apps, - getOrigin - ) - ).toEqual({ - app: 'foo', - path: '/path?hello=dolly', - }); - expect( - parseAppUrl( - 'https://kibana.local:8080/base-path/app/foo/path#hash/bang', - basePath, - apps, - getOrigin - ) - ).toEqual({ - app: 'foo', - path: '/path#hash/bang', - }); - expect( - parseAppUrl( - 'https://kibana.local:8080/base-path/app/foo/path#hash/bang?hello=dolly', - basePath, - apps, - getOrigin - ) - ).toEqual({ - app: 'foo', - path: '/path#hash/bang?hello=dolly', - }); - }); - it('includes query and hash in the path for custom app route', () => { - expect( - parseAppUrl( - 'https://kibana.local:8080/base-path/custom-bar#hash/bang', - basePath, - apps, - getOrigin - ) - ).toEqual({ - app: 'bar', - path: '#hash/bang', - }); - expect( - parseAppUrl( - 'https://kibana.local:8080/base-path/custom-bar?hello=dolly', - basePath, - apps, - getOrigin - ) - ).toEqual({ - app: 'bar', - path: '?hello=dolly', - }); - expect( - parseAppUrl( - 'https://kibana.local:8080/base-path/custom-bar/path?hello=dolly', - basePath, - apps, - getOrigin - ) - ).toEqual({ - app: 'bar', - path: '/path?hello=dolly', - }); - expect( - parseAppUrl( - 'https://kibana.local:8080/base-path/custom-bar/path#hash/bang', - basePath, - apps, - getOrigin - ) - ).toEqual({ - app: 'bar', - path: '/path#hash/bang', - }); - expect( - parseAppUrl( - 'https://kibana.local:8080/base-path/custom-bar/path#hash/bang?hello=dolly', - basePath, - apps, - getOrigin - ) - ).toEqual({ - app: 'bar', - path: '/path#hash/bang?hello=dolly', - }); - }); - it('returns undefined when the app is not known', () => { - expect( - parseAppUrl( - 'https://kibana.local:8080/base-path/app/non-registered', - basePath, - apps, - getOrigin - ) - ).toEqual(undefined); - expect( - parseAppUrl('https://kibana.local:8080/base-path/unknown-path', basePath, apps, getOrigin) - ).toEqual(undefined); - }); - it('returns undefined when origin does not match', () => { - expect( - parseAppUrl( - 'https://other-kibana.external:8080/base-path/app/foo', - basePath, - apps, - getOrigin - ) - ).toEqual(undefined); - expect( - parseAppUrl( - 'https://other-kibana.external:8080/base-path/custom-bar', - basePath, - apps, - getOrigin - ) - ).toEqual(undefined); - }); - }); -}); - -describe('getAppInfo', () => { - const createApp = (props: Partial = {}): App => ({ - mount: () => () => undefined, - updater$: of(() => undefined), - id: 'some-id', - title: 'some-title', - status: AppStatus.accessible, - navLinkStatus: AppNavLinkStatus.default, - appRoute: `/app/some-id`, - ...props, - }); - - it('converts an application and remove sensitive properties', () => { - const app = createApp(); - const info = getAppInfo(app); - - expect(info).toEqual({ - id: 'some-id', - title: 'some-title', - status: AppStatus.accessible, - navLinkStatus: AppNavLinkStatus.visible, - appRoute: `/app/some-id`, - }); - }); - - it('computes the navLinkStatus depending on the app status', () => { - expect( - getAppInfo( - createApp({ - navLinkStatus: AppNavLinkStatus.default, - status: AppStatus.inaccessible, - }) - ) - ).toEqual( - expect.objectContaining({ - navLinkStatus: AppNavLinkStatus.hidden, - }) - ); - expect( - getAppInfo( - createApp({ - navLinkStatus: AppNavLinkStatus.default, - status: AppStatus.accessible, - }) - ) - ).toEqual( - expect.objectContaining({ - navLinkStatus: AppNavLinkStatus.visible, - }) - ); - }); -}); diff --git a/src/core/public/application/utils.ts b/src/core/public/application/utils.ts deleted file mode 100644 index 85760526bf544..0000000000000 --- a/src/core/public/application/utils.ts +++ /dev/null @@ -1,128 +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 { IBasePath } from '../http'; -import { App, AppNavLinkStatus, AppStatus, ParsedAppUrl, PublicAppInfo } from './types'; - -/** - * Utility to remove trailing, leading or duplicate slashes. - * By default will only remove duplicates. - */ -export const removeSlashes = ( - url: string, - { - trailing = false, - leading = false, - duplicates = true, - }: { trailing?: boolean; leading?: boolean; duplicates?: boolean } = {} -): string => { - if (duplicates) { - url = url.replace(/\/{2,}/g, '/'); - } - if (trailing) { - url = url.replace(/\/$/, ''); - } - if (leading) { - url = url.replace(/^\//, ''); - } - return url; -}; - -export const appendAppPath = (appBasePath: string, path: string = '') => { - // Only prepend slash if not a hash or query path - path = path === '' || path.startsWith('#') || path.startsWith('?') ? path : `/${path}`; - // Do not remove trailing slash when in hashbang or basePath - const removeTrailing = path.indexOf('#') === -1 && appBasePath.indexOf('#') === -1; - return removeSlashes(`${appBasePath}${path}`, { - trailing: removeTrailing, - duplicates: true, - leading: false, - }); -}; - -/** - * Converts a relative path to an absolute url. - * Implementation is based on a specified behavior of the browser to automatically convert - * a relative url to an absolute one when setting the `href` attribute of a `` html element. - * - * @example - * ```ts - * // current url: `https://kibana:8000/base-path/app/my-app` - * relativeToAbsolute('/base-path/app/another-app') => `https://kibana:8000/base-path/app/another-app` - * ``` - */ -export const relativeToAbsolute = (url: string): string => { - const a = document.createElement('a'); - a.setAttribute('href', url); - return a.href; -}; - -/** - * Parse given url and return the associated app id and path if any app matches. - * Input can either be: - * - a path containing the basePath, ie `/base-path/app/my-app/some-path` - * - an absolute url matching the `origin` of the kibana instance (as seen by the browser), - * i.e `https://kibana:8080/base-path/app/my-app/some-path` - */ -export const parseAppUrl = ( - url: string, - basePath: IBasePath, - apps: Map>, - getOrigin: () => string = () => window.location.origin -): ParsedAppUrl | undefined => { - url = removeBasePath(url, basePath, getOrigin()); - if (!url.startsWith('/')) { - return undefined; - } - - for (const app of apps.values()) { - const appPath = app.appRoute || `/app/${app.id}`; - - if (url.startsWith(appPath)) { - const path = url.substr(appPath.length); - return { - app: app.id, - path: path.length ? path : undefined, - }; - } - } -}; - -const removeBasePath = (url: string, basePath: IBasePath, origin: string): string => { - if (url.startsWith(origin)) { - url = url.substring(origin.length); - } - return basePath.remove(url); -}; - -export function getAppInfo(app: App): PublicAppInfo { - const navLinkStatus = - app.navLinkStatus === AppNavLinkStatus.default - ? app.status === AppStatus.inaccessible - ? AppNavLinkStatus.hidden - : AppNavLinkStatus.visible - : app.navLinkStatus!; - const { updater$, mount, ...infos } = app; - return { - ...infos, - status: app.status!, - navLinkStatus, - appRoute: app.appRoute!, - }; -} diff --git a/src/core/public/application/utils/append_app_path.test.ts b/src/core/public/application/utils/append_app_path.test.ts new file mode 100644 index 0000000000000..a153b5753bbe2 --- /dev/null +++ b/src/core/public/application/utils/append_app_path.test.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 { appendAppPath } from './append_app_path'; + +describe('appendAppPath', () => { + it('appends the appBasePath with given path', () => { + expect(appendAppPath('/app/my-app', '/some-path')).toEqual('/app/my-app/some-path'); + expect(appendAppPath('/app/my-app/', 'some-path')).toEqual('/app/my-app/some-path'); + expect(appendAppPath('/app/my-app', 'some-path')).toEqual('/app/my-app/some-path'); + expect(appendAppPath('/app/my-app', '')).toEqual('/app/my-app'); + }); + + it('preserves the trailing slash only if included in the hash or appPath', () => { + expect(appendAppPath('/app/my-app', '/some-path/')).toEqual('/app/my-app/some-path'); + expect(appendAppPath('/app/my-app', '/some-path#/')).toEqual('/app/my-app/some-path#/'); + expect(appendAppPath('/app/my-app#/', '')).toEqual('/app/my-app#/'); + expect(appendAppPath('/app/my-app#', '/')).toEqual('/app/my-app#/'); + expect(appendAppPath('/app/my-app', '/some-path#/hash/')).toEqual( + '/app/my-app/some-path#/hash/' + ); + expect(appendAppPath('/app/my-app', '/some-path#/hash')).toEqual('/app/my-app/some-path#/hash'); + }); +}); diff --git a/src/core/public/application/utils/append_app_path.ts b/src/core/public/application/utils/append_app_path.ts new file mode 100644 index 0000000000000..70cb4a44c648e --- /dev/null +++ b/src/core/public/application/utils/append_app_path.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. + */ + +import { removeSlashes } from './remove_slashes'; + +export const appendAppPath = (appBasePath: string, path: string = '') => { + // Only prepend slash if not a hash or query path + path = path === '' || path.startsWith('#') || path.startsWith('?') ? path : `/${path}`; + // Do not remove trailing slash when in hashbang or basePath + const removeTrailing = path.indexOf('#') === -1 && appBasePath.indexOf('#') === -1; + return removeSlashes(`${appBasePath}${path}`, { + trailing: removeTrailing, + duplicates: true, + leading: false, + }); +}; diff --git a/src/core/public/application/utils/get_app_info.test.ts b/src/core/public/application/utils/get_app_info.test.ts new file mode 100644 index 0000000000000..055f7d1a5ada9 --- /dev/null +++ b/src/core/public/application/utils/get_app_info.test.ts @@ -0,0 +1,75 @@ +/* + * 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 { of } from 'rxjs'; +import { App, AppNavLinkStatus, AppStatus } from '../types'; +import { getAppInfo } from './get_app_info'; + +describe('getAppInfo', () => { + const createApp = (props: Partial = {}): App => ({ + mount: () => () => undefined, + updater$: of(() => undefined), + id: 'some-id', + title: 'some-title', + status: AppStatus.accessible, + navLinkStatus: AppNavLinkStatus.default, + appRoute: `/app/some-id`, + ...props, + }); + + it('converts an application and remove sensitive properties', () => { + const app = createApp(); + const info = getAppInfo(app); + + expect(info).toEqual({ + id: 'some-id', + title: 'some-title', + status: AppStatus.accessible, + navLinkStatus: AppNavLinkStatus.visible, + appRoute: `/app/some-id`, + }); + }); + + it('computes the navLinkStatus depending on the app status', () => { + expect( + getAppInfo( + createApp({ + navLinkStatus: AppNavLinkStatus.default, + status: AppStatus.inaccessible, + }) + ) + ).toEqual( + expect.objectContaining({ + navLinkStatus: AppNavLinkStatus.hidden, + }) + ); + expect( + getAppInfo( + createApp({ + navLinkStatus: AppNavLinkStatus.default, + status: AppStatus.accessible, + }) + ) + ).toEqual( + expect.objectContaining({ + navLinkStatus: AppNavLinkStatus.visible, + }) + ); + }); +}); diff --git a/src/core/public/application/utils/get_app_info.ts b/src/core/public/application/utils/get_app_info.ts new file mode 100644 index 0000000000000..71cd8a3e14929 --- /dev/null +++ b/src/core/public/application/utils/get_app_info.ts @@ -0,0 +1,36 @@ +/* + * 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 { App, AppNavLinkStatus, AppStatus, PublicAppInfo } from '../types'; + +export function getAppInfo(app: App): PublicAppInfo { + const navLinkStatus = + app.navLinkStatus === AppNavLinkStatus.default + ? app.status === AppStatus.inaccessible + ? AppNavLinkStatus.hidden + : AppNavLinkStatus.visible + : app.navLinkStatus!; + const { updater$, mount, ...infos } = app; + return { + ...infos, + status: app.status!, + navLinkStatus, + appRoute: app.appRoute!, + }; +} diff --git a/src/core/public/application/utils/index.ts b/src/core/public/application/utils/index.ts new file mode 100644 index 0000000000000..3b8a34df8c50d --- /dev/null +++ b/src/core/public/application/utils/index.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 { appendAppPath } from './append_app_path'; +export { getAppInfo } from './get_app_info'; +export { parseAppUrl } from './parse_app_url'; +export { relativeToAbsolute } from './relative_to_absolute'; +export { removeSlashes } from './remove_slashes'; diff --git a/src/core/public/application/utils/parse_app_url.test.ts b/src/core/public/application/utils/parse_app_url.test.ts new file mode 100644 index 0000000000000..bf7e0a88a0742 --- /dev/null +++ b/src/core/public/application/utils/parse_app_url.test.ts @@ -0,0 +1,407 @@ +/* + * 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 { App } from '../types'; +import { BasePath } from '../../http/base_path'; +import { parseAppUrl } from './parse_app_url'; + +describe('parseAppUrl', () => { + let apps: Map>; + let basePath: BasePath; + + const currentUrl = + 'https://kibana.local:8080/base-path/app/current/current-path?current-query=true'; + + const createApp = (props: Partial): App => { + const app: App = { + id: 'some-id', + title: 'some-title', + mount: () => () => undefined, + ...props, + }; + apps.set(app.id, app); + return app; + }; + + beforeEach(() => { + apps = new Map(); + basePath = new BasePath('/base-path'); + + createApp({ + id: 'foo', + }); + createApp({ + id: 'bar', + appRoute: '/custom-bar', + }); + }); + + describe('with absolute paths', () => { + it('parses the app id', () => { + expect(parseAppUrl('/base-path/app/foo', basePath, apps, currentUrl)).toEqual({ + app: 'foo', + path: undefined, + }); + expect(parseAppUrl('/base-path/custom-bar', basePath, apps, currentUrl)).toEqual({ + app: 'bar', + path: undefined, + }); + }); + it('parses the path', () => { + expect(parseAppUrl('/base-path/app/foo/some/path', basePath, apps, currentUrl)).toEqual({ + app: 'foo', + path: '/some/path', + }); + expect( + parseAppUrl('/base-path/custom-bar/another/path/', basePath, apps, currentUrl) + ).toEqual({ + app: 'bar', + path: '/another/path/', + }); + }); + it('includes query and hash in the path for default app route', () => { + expect(parseAppUrl('/base-path/app/foo#hash/bang', basePath, apps, currentUrl)).toEqual({ + app: 'foo', + path: '#hash/bang', + }); + expect(parseAppUrl('/base-path/app/foo?hello=dolly', basePath, apps, currentUrl)).toEqual({ + app: 'foo', + path: '?hello=dolly', + }); + expect( + parseAppUrl('/base-path/app/foo/path?hello=dolly', basePath, apps, currentUrl) + ).toEqual({ + app: 'foo', + path: '/path?hello=dolly', + }); + expect(parseAppUrl('/base-path/app/foo/path#hash/bang', basePath, apps, currentUrl)).toEqual({ + app: 'foo', + path: '/path#hash/bang', + }); + expect( + parseAppUrl('/base-path/app/foo/path#hash/bang?hello=dolly', basePath, apps, currentUrl) + ).toEqual({ + app: 'foo', + path: '/path#hash/bang?hello=dolly', + }); + }); + it('includes query and hash in the path for custom app route', () => { + expect(parseAppUrl('/base-path/custom-bar#hash/bang', basePath, apps, currentUrl)).toEqual({ + app: 'bar', + path: '#hash/bang', + }); + expect(parseAppUrl('/base-path/custom-bar?hello=dolly', basePath, apps, currentUrl)).toEqual({ + app: 'bar', + path: '?hello=dolly', + }); + expect( + parseAppUrl('/base-path/custom-bar/path?hello=dolly', basePath, apps, currentUrl) + ).toEqual({ + app: 'bar', + path: '/path?hello=dolly', + }); + expect( + parseAppUrl('/base-path/custom-bar/path#hash/bang', basePath, apps, currentUrl) + ).toEqual({ + app: 'bar', + path: '/path#hash/bang', + }); + expect( + parseAppUrl('/base-path/custom-bar/path#hash/bang?hello=dolly', basePath, apps, currentUrl) + ).toEqual({ + app: 'bar', + path: '/path#hash/bang?hello=dolly', + }); + }); + it('returns undefined when the app is not known', () => { + expect(parseAppUrl('/base-path/app/non-registered', basePath, apps, currentUrl)).toEqual( + undefined + ); + expect(parseAppUrl('/base-path/unknown-path', basePath, apps, currentUrl)).toEqual(undefined); + }); + it('returns undefined when the path does not start with the base path', () => { + expect(parseAppUrl('/app/foo', basePath, apps, currentUrl)).toBeUndefined(); + }); + }); + + describe('with relative paths', () => { + it('works with sibling relative urls', () => { + expect( + parseAppUrl('./foo', basePath, apps, 'https://kibana.local:8080/base-path/app/current') + ).toEqual({ + app: 'foo', + path: undefined, + }); + }); + it('works with parent relative urls', () => { + expect( + parseAppUrl( + '../custom-bar', + basePath, + apps, + 'https://kibana.local:8080/base-path/app/current' + ) + ).toEqual({ + app: 'bar', + path: undefined, + }); + }); + it('works with nested parents', () => { + expect( + parseAppUrl( + '../../custom-bar', + basePath, + apps, + 'https://kibana.local:8080/base-path/app/current/some-path' + ) + ).toEqual({ + app: 'bar', + path: undefined, + }); + }); + it('parses the path', () => { + expect( + parseAppUrl( + './foo/path?hello=dolly', + basePath, + apps, + 'https://kibana.local:8080/base-path/app/current' + ) + ).toEqual({ + app: 'foo', + path: '/path?hello=dolly', + }); + }); + it('parses the path with query and hash', () => { + expect( + parseAppUrl( + '../custom-bar/path#hash?hello=dolly', + basePath, + apps, + 'https://kibana.local:8080/base-path/app/current' + ) + ).toEqual({ + app: 'bar', + path: '/path#hash?hello=dolly', + }); + }); + + it('returns undefined if the relative path redirect outside of the basePath', () => { + expect( + parseAppUrl( + '../../custom-bar', + basePath, + apps, + 'https://kibana.local:8080/base-path/app/current' + ) + ).toBeUndefined(); + }); + }); + + describe('with absolute urls', () => { + it('parses the app id', () => { + expect( + parseAppUrl('https://kibana.local:8080/base-path/app/foo', basePath, apps, currentUrl) + ).toEqual({ + app: 'foo', + path: undefined, + }); + expect( + parseAppUrl('https://kibana.local:8080/base-path/custom-bar', basePath, apps, currentUrl) + ).toEqual({ + app: 'bar', + path: undefined, + }); + }); + it('parses the path', () => { + expect( + parseAppUrl( + 'https://kibana.local:8080/base-path/app/foo/some/path', + basePath, + apps, + currentUrl + ) + ).toEqual({ + app: 'foo', + path: '/some/path', + }); + expect( + parseAppUrl( + 'https://kibana.local:8080/base-path/custom-bar/another/path/', + basePath, + apps, + currentUrl + ) + ).toEqual({ + app: 'bar', + path: '/another/path/', + }); + }); + it('includes query and hash in the path for default app routes', () => { + expect( + parseAppUrl( + 'https://kibana.local:8080/base-path/app/foo#hash/bang', + basePath, + apps, + currentUrl + ) + ).toEqual({ + app: 'foo', + path: '#hash/bang', + }); + expect( + parseAppUrl( + 'https://kibana.local:8080/base-path/app/foo?hello=dolly', + basePath, + apps, + currentUrl + ) + ).toEqual({ + app: 'foo', + path: '?hello=dolly', + }); + expect( + parseAppUrl( + 'https://kibana.local:8080/base-path/app/foo/path?hello=dolly', + basePath, + apps, + currentUrl + ) + ).toEqual({ + app: 'foo', + path: '/path?hello=dolly', + }); + expect( + parseAppUrl( + 'https://kibana.local:8080/base-path/app/foo/path#hash/bang', + basePath, + apps, + currentUrl + ) + ).toEqual({ + app: 'foo', + path: '/path#hash/bang', + }); + expect( + parseAppUrl( + 'https://kibana.local:8080/base-path/app/foo/path#hash/bang?hello=dolly', + basePath, + apps, + currentUrl + ) + ).toEqual({ + app: 'foo', + path: '/path#hash/bang?hello=dolly', + }); + }); + it('includes query and hash in the path for custom app route', () => { + expect( + parseAppUrl( + 'https://kibana.local:8080/base-path/custom-bar#hash/bang', + basePath, + apps, + currentUrl + ) + ).toEqual({ + app: 'bar', + path: '#hash/bang', + }); + expect( + parseAppUrl( + 'https://kibana.local:8080/base-path/custom-bar?hello=dolly', + basePath, + apps, + currentUrl + ) + ).toEqual({ + app: 'bar', + path: '?hello=dolly', + }); + expect( + parseAppUrl( + 'https://kibana.local:8080/base-path/custom-bar/path?hello=dolly', + basePath, + apps, + currentUrl + ) + ).toEqual({ + app: 'bar', + path: '/path?hello=dolly', + }); + expect( + parseAppUrl( + 'https://kibana.local:8080/base-path/custom-bar/path#hash/bang', + basePath, + apps, + currentUrl + ) + ).toEqual({ + app: 'bar', + path: '/path#hash/bang', + }); + expect( + parseAppUrl( + 'https://kibana.local:8080/base-path/custom-bar/path#hash/bang?hello=dolly', + basePath, + apps, + currentUrl + ) + ).toEqual({ + app: 'bar', + path: '/path#hash/bang?hello=dolly', + }); + }); + it('returns undefined when the app is not known', () => { + expect( + parseAppUrl( + 'https://kibana.local:8080/base-path/app/non-registered', + basePath, + apps, + currentUrl + ) + ).toEqual(undefined); + expect( + parseAppUrl('https://kibana.local:8080/base-path/unknown-path', basePath, apps, currentUrl) + ).toEqual(undefined); + }); + it('returns undefined when origin does not match', () => { + expect( + parseAppUrl( + 'https://other-kibana.external:8080/base-path/app/foo', + basePath, + apps, + currentUrl + ) + ).toEqual(undefined); + expect( + parseAppUrl( + 'https://other-kibana.external:8080/base-path/custom-bar', + basePath, + apps, + currentUrl + ) + ).toEqual(undefined); + }); + it('returns undefined when the path does not contain the base path', () => { + expect(parseAppUrl('https://kibana.local:8080/app/foo', basePath, apps, currentUrl)).toEqual( + undefined + ); + }); + }); +}); diff --git a/src/core/public/application/utils/parse_app_url.ts b/src/core/public/application/utils/parse_app_url.ts new file mode 100644 index 0000000000000..d253129a63ae4 --- /dev/null +++ b/src/core/public/application/utils/parse_app_url.ts @@ -0,0 +1,83 @@ +/* + * 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 { getUrlOrigin } from '@kbn/std'; +import { resolve } from 'url'; +import { IBasePath } from '../../http'; +import { App, ParsedAppUrl } from '../types'; + +/** + * Parse given URL and return the associated app id and path if any app matches, or undefined if none do. + * Input can either be: + * + * - an absolute path containing the basePath, + * e.g `/base-path/app/my-app/some-path` + * + * - an absolute URL matching the `origin` of the Kibana instance (as seen by the browser), + * e.g `https://kibana:8080/base-path/app/my-app/some-path` + * + * - a path relative to the provided `currentUrl`. + * e.g with `currentUrl` being `https://kibana:8080/base-path/app/current-app/some-path` + * `../other-app/other-path` will be converted to `/base-path/app/other-app/other-path` + */ +export const parseAppUrl = ( + url: string, + basePath: IBasePath, + apps: Map>, + currentUrl: string = window.location.href +): ParsedAppUrl | undefined => { + const currentOrigin = getUrlOrigin(currentUrl); + if (!currentOrigin) { + throw new Error('when manually provided, currentUrl must be valid url with an origin'); + } + const currentPath = currentUrl.substring(currentOrigin.length); + + // remove the origin from the given url + if (url.startsWith(currentOrigin)) { + url = url.substring(currentOrigin.length); + } + + // if the path is relative (i.e `../../to/somewhere`), we convert it to absolute + if (!url.startsWith('/')) { + url = resolve(currentPath, url); + } + + // if using a basePath and the absolute path does not starts with it, it can't be a match + const basePathValue = basePath.get(); + if (basePathValue && !url.startsWith(basePathValue)) { + return undefined; + } + + url = basePath.remove(url); + if (!url.startsWith('/')) { + return undefined; + } + + for (const app of apps.values()) { + const appPath = app.appRoute || `/app/${app.id}`; + + if (url.startsWith(appPath)) { + const path = url.substr(appPath.length); + return { + app: app.id, + path: path.length ? path : undefined, + }; + } + } +}; diff --git a/src/core/public/application/utils/relative_to_absolute.test.ts b/src/core/public/application/utils/relative_to_absolute.test.ts new file mode 100644 index 0000000000000..56a33450ce902 --- /dev/null +++ b/src/core/public/application/utils/relative_to_absolute.test.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. + */ + +import { relativeToAbsolute } from './relative_to_absolute'; + +describe('relativeToAbsolute', () => { + it('converts a relative path to an absolute url', () => { + const origin = window.location.origin; + expect(relativeToAbsolute('path')).toEqual(`${origin}/path`); + expect(relativeToAbsolute('/path#hash')).toEqual(`${origin}/path#hash`); + expect(relativeToAbsolute('/path?query=foo')).toEqual(`${origin}/path?query=foo`); + }); +}); diff --git a/src/core/public/application/utils/relative_to_absolute.ts b/src/core/public/application/utils/relative_to_absolute.ts new file mode 100644 index 0000000000000..0f24f754f56cd --- /dev/null +++ b/src/core/public/application/utils/relative_to_absolute.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. + */ + +/** + * Converts a relative path to an absolute url. + * Implementation is based on a specified behavior of the browser to automatically convert + * a relative url to an absolute one when setting the `href` attribute of a `` html element. + * + * @example + * ```ts + * // current url: `https://kibana:8000/base-path/app/my-app` + * relativeToAbsolute('/base-path/app/another-app') => `https://kibana:8000/base-path/app/another-app` + * ``` + */ +export const relativeToAbsolute = (url: string): string => { + const a = document.createElement('a'); + a.setAttribute('href', url); + return a.href; +}; diff --git a/src/core/public/application/utils/remove_slashes.test.ts b/src/core/public/application/utils/remove_slashes.test.ts new file mode 100644 index 0000000000000..719e1ea08d109 --- /dev/null +++ b/src/core/public/application/utils/remove_slashes.test.ts @@ -0,0 +1,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. + */ + +import { removeSlashes } from './remove_slashes'; + +describe('removeSlashes', () => { + it('only removes duplicates by default', () => { + expect(removeSlashes('/some//url//to//')).toEqual('/some/url/to/'); + expect(removeSlashes('some/////other//url')).toEqual('some/other/url'); + }); + + it('remove trailing slash when `trailing` is true', () => { + expect(removeSlashes('/some//url//to//', { trailing: true })).toEqual('/some/url/to'); + }); + + it('remove leading slash when `leading` is true', () => { + expect(removeSlashes('/some//url//to//', { leading: true })).toEqual('some/url/to/'); + }); + + it('does not removes duplicates when `duplicates` is false', () => { + expect(removeSlashes('/some//url//to/', { leading: true, duplicates: false })).toEqual( + 'some//url//to/' + ); + expect(removeSlashes('/some//url//to/', { trailing: true, duplicates: false })).toEqual( + '/some//url//to' + ); + }); + + it('accept mixed options', () => { + expect( + removeSlashes('/some//url//to/', { leading: true, duplicates: false, trailing: true }) + ).toEqual('some//url//to'); + expect( + removeSlashes('/some//url//to/', { leading: true, duplicates: true, trailing: true }) + ).toEqual('some/url/to'); + }); +}); diff --git a/src/core/public/application/utils/remove_slashes.ts b/src/core/public/application/utils/remove_slashes.ts new file mode 100644 index 0000000000000..641d7bc4164f4 --- /dev/null +++ b/src/core/public/application/utils/remove_slashes.ts @@ -0,0 +1,42 @@ +/* + * 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. + */ + +/** + * Utility to remove trailing, leading or duplicate slashes. + * By default will only remove duplicates. + */ +export const removeSlashes = ( + url: string, + { + trailing = false, + leading = false, + duplicates = true, + }: { trailing?: boolean; leading?: boolean; duplicates?: boolean } = {} +): string => { + if (duplicates) { + url = url.replace(/\/{2,}/g, '/'); + } + if (trailing) { + url = url.replace(/\/$/, ''); + } + if (leading) { + url = url.replace(/^\//, ''); + } + return url; +}; diff --git a/src/core/public/chrome/ui/__snapshots__/loading_indicator.test.tsx.snap b/src/core/public/chrome/ui/__snapshots__/loading_indicator.test.tsx.snap index 3007be1e5dfe0..e6bf7e898d8c4 100644 --- a/src/core/public/chrome/ui/__snapshots__/loading_indicator.test.tsx.snap +++ b/src/core/public/chrome/ui/__snapshots__/loading_indicator.test.tsx.snap @@ -1,23 +1,19 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`kbnLoadingIndicator is hidden by default 1`] = ` -
-
-
+/> `; exports[`kbnLoadingIndicator is visible when loadingCount is > 0 1`] = ` -
-
-
+/> `; diff --git a/src/core/public/chrome/ui/_loading_indicator.scss b/src/core/public/chrome/ui/_loading_indicator.scss index ad934717b4b76..ccf1ecc873fc5 100644 --- a/src/core/public/chrome/ui/_loading_indicator.scss +++ b/src/core/public/chrome/ui/_loading_indicator.scss @@ -1,55 +1,4 @@ -$kbnLoadingIndicatorBackgroundSize: $euiSizeXXL * 10; -$kbnLoadingIndicatorColor1: tint($euiColorAccent, 15%); -$kbnLoadingIndicatorColor2: tint($euiColorAccent, 60%); - -/** - * 1. Position this loader on top of the content. - * 2. Make sure indicator isn't wider than the screen. - */ -.kbnLoadingIndicator { - position: fixed; // 1 - top: 0; // 1 - left: 0; // 1 - right: 0; // 1 - z-index: $euiZLevel2; // 1 - overflow: hidden; // 2 - height: $euiSizeXS / 2; - - &.hidden { - visibility: hidden; - opacity: 0; - transition-delay: 0.25s; - } -} - -.kbnLoadingIndicator__bar { - top: 0; - left: 0; - right: 0; - bottom: 0; - position: absolute; - z-index: $euiZLevel2 + 1; - visibility: visible; - display: block; - animation: kbn-animate-loading-indicator 2s linear infinite; - background-color: $kbnLoadingIndicatorColor2; - background-image: linear-gradient( - to right, - $kbnLoadingIndicatorColor1 0%, - $kbnLoadingIndicatorColor1 50%, - $kbnLoadingIndicatorColor2 50%, - $kbnLoadingIndicatorColor2 100% - ); - background-repeat: repeat-x; - background-size: $kbnLoadingIndicatorBackgroundSize $kbnLoadingIndicatorBackgroundSize; - width: 200%; -} - -@keyframes kbn-animate-loading-indicator { - from { - transform: translateX(0); - } - to { - transform: translateX(-$kbnLoadingIndicatorBackgroundSize); - } +.kbnLoadingIndicator-hidden { + visibility: hidden; + animation-play-state: paused; } diff --git a/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap b/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap index 1a4d93aee9516..e733c7fda5d5a 100644 --- a/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap +++ b/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap @@ -477,17 +477,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 1, - "outerValue": BehaviorSubject { - "_isScalar": false, - "_value": "", - "closed": false, - "hasError": false, - "isStopped": false, - "observers": Array [ - [Circular], - ], - "thrownError": null, - }, + "outerValue": undefined, "parent": [Circular], "syncErrorThrowable": false, "syncErrorThrown": false, @@ -558,7 +548,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 1, - "outerValue": [Circular], + "outerValue": undefined, "parent": [Circular], "syncErrorThrowable": false, "syncErrorThrown": false, @@ -568,7 +558,7 @@ exports[`Header renders 1`] = ` "thrownError": null, }, ], - "resultSelector": null, + "resultSelector": undefined, "syncErrorThrowable": true, "syncErrorThrown": false, "syncErrorValue": null, @@ -597,7 +587,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 0, - "outerValue": [Circular], + "outerValue": undefined, "parent": CombineLatestSubscriber { "_parentOrParents": Subscriber { "_parentOrParents": null, @@ -663,17 +653,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 1, - "outerValue": BehaviorSubject { - "_isScalar": false, - "_value": "", - "closed": false, - "hasError": false, - "isStopped": false, - "observers": Array [ - [Circular], - ], - "thrownError": null, - }, + "outerValue": undefined, "parent": [Circular], "syncErrorThrowable": false, "syncErrorThrown": false, @@ -744,7 +724,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 1, - "outerValue": [Circular], + "outerValue": undefined, "parent": [Circular], "syncErrorThrowable": false, "syncErrorThrown": false, @@ -754,7 +734,7 @@ exports[`Header renders 1`] = ` "thrownError": null, }, ], - "resultSelector": null, + "resultSelector": undefined, "syncErrorThrowable": true, "syncErrorThrown": false, "syncErrorValue": null, @@ -845,17 +825,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 0, - "outerValue": BehaviorSubject { - "_isScalar": false, - "_value": undefined, - "closed": false, - "hasError": false, - "isStopped": false, - "observers": Array [ - [Circular], - ], - "thrownError": null, - }, + "outerValue": undefined, "parent": [Circular], "syncErrorThrowable": false, "syncErrorThrown": false, @@ -926,7 +896,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 0, - "outerValue": [Circular], + "outerValue": undefined, "parent": [Circular], "syncErrorThrowable": false, "syncErrorThrown": false, @@ -937,7 +907,7 @@ exports[`Header renders 1`] = ` }, [Circular], ], - "resultSelector": null, + "resultSelector": undefined, "syncErrorThrowable": true, "syncErrorThrown": false, "syncErrorValue": null, @@ -966,7 +936,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 1, - "outerValue": [Circular], + "outerValue": undefined, "parent": CombineLatestSubscriber { "_parentOrParents": Subscriber { "_parentOrParents": null, @@ -1031,17 +1001,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 0, - "outerValue": BehaviorSubject { - "_isScalar": false, - "_value": undefined, - "closed": false, - "hasError": false, - "isStopped": false, - "observers": Array [ - [Circular], - ], - "thrownError": null, - }, + "outerValue": undefined, "parent": [Circular], "syncErrorThrowable": false, "syncErrorThrown": false, @@ -1112,7 +1072,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 0, - "outerValue": [Circular], + "outerValue": undefined, "parent": [Circular], "syncErrorThrowable": false, "syncErrorThrown": false, @@ -1123,7 +1083,7 @@ exports[`Header renders 1`] = ` }, [Circular], ], - "resultSelector": null, + "resultSelector": undefined, "syncErrorThrowable": true, "syncErrorThrown": false, "syncErrorValue": null, @@ -1690,66 +1650,6 @@ exports[`Header renders 1`] = ` } } > - -
-
-
-
, - ], - }, - Object { - "borders": "none", - "items": Array [ - , ], }, Object { "borders": "none", "items": Array [ + + + , + ], + }, + Object { + "borders": "none", + "items": Array [ + + + ,
-
- - -
- + showAsBar={false} + > + + + + +
+
+
+
+ +
+ +
+ + +
@@ -3050,6 +3118,24 @@ exports[`Header renders 1`] = ` +
+ +
+
+
- -
- ; + return ; } const toggleCollapsibleNavRef = createRef(); @@ -97,7 +99,6 @@ export function Header({ return ( <> -
, + , ], borders: 'none', }, { ...(observables.navControlsCenter$ && { - items: [], + items: [ + + + , + ], }), borders: 'none', }, { items: [ + + + , - - diff --git a/src/core/public/chrome/ui/header/header_breadcrumbs.tsx b/src/core/public/chrome/ui/header/header_breadcrumbs.tsx index 174c46981db53..52412f8990c7a 100644 --- a/src/core/public/chrome/ui/header/header_breadcrumbs.tsx +++ b/src/core/public/chrome/ui/header/header_breadcrumbs.tsx @@ -20,7 +20,7 @@ import { EuiHeaderBreadcrumbs } from '@elastic/eui'; import classNames from 'classnames'; import React from 'react'; -import { useObservable } from 'react-use'; +import useObservable from 'react-use/lib/useObservable'; import { Observable } from 'rxjs'; import { ChromeBreadcrumb } from '../../chrome_service'; diff --git a/src/core/public/chrome/ui/header/header_logo.tsx b/src/core/public/chrome/ui/header/header_logo.tsx index dee93ecb1a804..83e0c52ab3f3a 100644 --- a/src/core/public/chrome/ui/header/header_logo.tsx +++ b/src/core/public/chrome/ui/header/header_logo.tsx @@ -20,7 +20,7 @@ import { EuiHeaderLogo } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; -import { useObservable } from 'react-use'; +import useObservable from 'react-use/lib/useObservable'; import { Observable } from 'rxjs'; import Url from 'url'; import { ChromeNavLink } from '../..'; diff --git a/src/core/public/chrome/ui/header/header_nav_controls.tsx b/src/core/public/chrome/ui/header/header_nav_controls.tsx index 8d9d8097fd8e3..69b0e3bd8afe3 100644 --- a/src/core/public/chrome/ui/header/header_nav_controls.tsx +++ b/src/core/public/chrome/ui/header/header_nav_controls.tsx @@ -19,7 +19,7 @@ import { EuiHeaderSectionItem } from '@elastic/eui'; import React from 'react'; -import { useObservable } from 'react-use'; +import useObservable from 'react-use/lib/useObservable'; import { Observable } from 'rxjs'; import { ChromeNavControl } from '../../nav_controls'; import { HeaderExtension } from './header_extension'; diff --git a/src/core/public/chrome/ui/loading_indicator.tsx b/src/core/public/chrome/ui/loading_indicator.tsx index 0209612eae08c..ca3e95f722ec5 100644 --- a/src/core/public/chrome/ui/loading_indicator.tsx +++ b/src/core/public/chrome/ui/loading_indicator.tsx @@ -17,6 +17,8 @@ * under the License. */ +import { EuiLoadingSpinner, EuiProgress } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; import React from 'react'; import classNames from 'classnames'; import { Subscription } from 'rxjs'; @@ -25,9 +27,12 @@ import { HttpStart } from '../../http'; export interface LoadingIndicatorProps { loadingCount$: ReturnType; + showAsBar?: boolean; } export class LoadingIndicator extends React.Component { + public static defaultProps = { showAsBar: false }; + private loadingCountSubscription?: Subscription; state = { @@ -50,16 +55,35 @@ export class LoadingIndicator extends React.Component -
-
+ const ariaHidden = this.state.visible ? false : true; + + const ariaLabel = i18n.translate('core.ui.loadingIndicatorAriaLabel', { + defaultMessage: 'Loading content', + }); + + return !this.props.showAsBar ? ( + + ) : ( + ); } } diff --git a/src/core/public/doc_links/doc_links_service.ts b/src/core/public/doc_links/doc_links_service.ts index 47f58a3a9fcbf..629bf97c24887 100644 --- a/src/core/public/doc_links/doc_links_service.ts +++ b/src/core/public/doc_links/doc_links_service.ts @@ -119,6 +119,7 @@ export class DocLinksService { gettingStarted: `${ELASTIC_WEBSITE_URL}guide/en/security/${DOC_LINK_VERSION}/index.html`, }, query: { + eql: `${ELASTICSEARCH_DOCS}eql.html`, luceneQuerySyntax: `${ELASTICSEARCH_DOCS}query-dsl-query-string-query.html#query-string-syntax`, queryDsl: `${ELASTICSEARCH_DOCS}query-dsl.html`, kueryQuerySyntax: `${ELASTIC_WEBSITE_URL}guide/en/kibana/${DOC_LINK_VERSION}/kuery-query.html`, @@ -227,6 +228,7 @@ export interface DocLinksStart { readonly gettingStarted: string; }; readonly query: { + readonly eql: string; readonly luceneQuerySyntax: string; readonly queryDsl: string; readonly kueryQuerySyntax: string; diff --git a/src/core/public/http/base_path.ts b/src/core/public/http/base_path.ts index 5d9eb51023b78..78e9cf75ff806 100644 --- a/src/core/public/http/base_path.ts +++ b/src/core/public/http/base_path.ts @@ -16,24 +16,6 @@ * specific language governing permissions and limitations * under the License. */ -/* - * 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 { modifyUrl } from '@kbn/std'; diff --git a/src/core/public/i18n/i18n_eui_mapping.tsx b/src/core/public/i18n/i18n_eui_mapping.tsx index 4c7cdd18d03f6..3bb8fa39d4ff8 100644 --- a/src/core/public/i18n/i18n_eui_mapping.tsx +++ b/src/core/public/i18n/i18n_eui_mapping.tsx @@ -25,550 +25,564 @@ interface EuiValues { [key: string]: any; } -export const euiContextMapping = { - 'euiBasicTable.selectAllRows': i18n.translate('core.euiBasicTable.selectAllRows', { - defaultMessage: 'Select all rows', - description: 'ARIA and displayed label on a checkbox to select all table rows', - }), - 'euiBasicTable.selectThisRow': i18n.translate('core.euiBasicTable.selectThisRow', { - defaultMessage: 'Select this row', - description: 'ARIA and displayed label on a checkbox to select a single table row', - }), - 'euiBasicTable.tableDescription': ({ itemCount }: EuiValues) => - i18n.translate('core.euiBasicTable.tableDescription', { - defaultMessage: 'Below is a table of {itemCount} items.', - values: { itemCount }, - description: 'Screen reader text to describe the size of a table', - }), - 'euiBottomBar.screenReaderAnnouncement': i18n.translate( - 'core.euiBottomBar.screenReaderAnnouncement', - { - defaultMessage: - 'There is a new menu opening with page level controls at the end of the document.', - description: - 'Screen reader announcement that functionality is available in the page document', - } - ), - 'euiBreadcrumbs.collapsedBadge.ariaLabel': i18n.translate( - 'core.euiBreadcrumbs.collapsedBadge.ariaLabel', - { - defaultMessage: 'Show all breadcrumbs', - description: 'Displayed when one or more breadcrumbs are hidden.', - } - ), - 'euiCardSelect.select': i18n.translate('core.euiCardSelect.select', { - defaultMessage: 'Select', - description: 'Displayed button text when a card option can be selected.', - }), - 'euiCardSelect.selected': i18n.translate('core.euiCardSelect.selected', { - defaultMessage: 'Selected', - description: 'Displayed button text when a card option is selected.', - }), - 'euiCardSelect.unavailable': i18n.translate('core.euiCardSelect.unavailable', { - defaultMessage: 'Unavailable', - description: 'Displayed button text when a card option is unavailable.', - }), - 'euiCodeBlock.copyButton': i18n.translate('core.euiCodeBlock.copyButton', { - defaultMessage: 'Copy', - description: 'ARIA label for a button that copies source code text to the clipboard', - }), - 'euiCodeEditor.startEditing': i18n.translate('core.euiCodeEditor.startEditing', { - defaultMessage: 'Press Enter to start editing.', - }), - 'euiCodeEditor.startInteracting': i18n.translate('core.euiCodeEditor.startInteracting', { - defaultMessage: 'Press Enter to start interacting with the code.', - }), - 'euiCodeEditor.stopEditing': i18n.translate('core.euiCodeEditor.stopEditing', { - defaultMessage: "When you're done, press Escape to stop editing.", - }), - 'euiCodeEditor.stopInteracting': i18n.translate('core.euiCodeEditor.stopInteracting', { - defaultMessage: "When you're done, press Escape to stop interacting with the code.", - }), - 'euiCollapsedItemActions.allActions': i18n.translate('core.euiCollapsedItemActions.allActions', { - defaultMessage: 'All actions', - description: 'ARIA label and tooltip content describing a button that expands an actions menu', - }), - 'euiColorPicker.screenReaderAnnouncement': i18n.translate( - 'core.euiColorPicker.screenReaderAnnouncement', - { - defaultMessage: - 'A popup with a range of selectable colors opened. Tab forward to cycle through colors choices or press escape to close this popup.', - description: - 'Message when the color picker popover is opened. Describes the interaction with the elements in the popover.', - } - ), - 'euiColorPicker.swatchAriaLabel': ({ swatch }: EuiValues) => - i18n.translate('core.euiColorPicker.swatchAriaLabel', { - defaultMessage: 'Select {swatch} as the color', - values: { swatch }, - description: - 'Screen reader text to describe the action and hex value of the selectable option', - }), - 'euiColorStopThumb.removeLabel': i18n.translate('core.euiColorStopThumb.removeLabel', { - defaultMessage: 'Remove this stop', - description: 'Label accompanying a button whose action will remove the color stop', - }), - 'euiColorStopThumb.screenReaderAnnouncement': i18n.translate( - 'core.euiColorStopThumb.screenReaderAnnouncement', - { - defaultMessage: - 'A popup with a color stop edit form opened. Tab forward to cycle through form controls or press escape to close this popup.', - description: - 'Message when the color picker popover has opened for an individual color stop thumb.', - } - ), - 'euiColorStops.screenReaderAnnouncement': ({ label, readOnly, disabled }: EuiValues) => - i18n.translate('core.euiColorStops.screenReaderAnnouncement', { - defaultMessage: - '{label}: {readOnly} {disabled} Color stop picker. Each stop consists of a number and corresponding color value. Use the Down and Up arrow keys to select individual stops. Press the Enter key to create a new stop.', - values: { label, readOnly, disabled }, - description: - 'Screen reader text to describe the composite behavior of the color stops component.', - }), - 'euiColumnSelector.hideAll': i18n.translate('core.euiColumnSelector.hideAll', { - defaultMessage: 'Hide all', - }), - 'euiColumnSelector.selectAll': i18n.translate('core.euiColumnSelector.selectAll', { - defaultMessage: 'Show all', - }), - 'euiColumnSorting.clearAll': i18n.translate('core.euiColumnSorting.clearAll', { - defaultMessage: 'Clear sorting', - }), - 'euiColumnSorting.emptySorting': i18n.translate('core.euiColumnSorting.emptySorting', { - defaultMessage: 'Currently no fields are sorted', - }), - 'euiColumnSorting.pickFields': i18n.translate('core.euiColumnSorting.pickFields', { - defaultMessage: 'Pick fields to sort by', - }), - 'euiColumnSorting.sortFieldAriaLabel': i18n.translate( - 'core.euiColumnSorting.sortFieldAriaLabel', - { - defaultMessage: 'Sort by:', - } - ), - 'euiColumnSortingDraggable.activeSortLabel': i18n.translate( - 'core.euiColumnSortingDraggable.activeSortLabel', - { - defaultMessage: 'is sorting this data grid', - } - ), - 'euiColumnSortingDraggable.defaultSortAsc': i18n.translate( - 'core.euiColumnSortingDraggable.defaultSortAsc', - { - defaultMessage: 'A-Z', - description: 'Ascending sort label', - } - ), - 'euiColumnSortingDraggable.defaultSortDesc': i18n.translate( - 'core.euiColumnSortingDraggable.defaultSortDesc', - { - defaultMessage: 'Z-A', - description: 'Descending sort label', - } - ), - 'euiColumnSortingDraggable.removeSortLabel': i18n.translate( - 'core.euiColumnSortingDraggable.removeSortLabel', - { - defaultMessage: 'Remove from data grid sort:', - } - ), - 'euiColumnSortingDraggable.toggleLegend': i18n.translate( - 'core.euiColumnSortingDraggable.toggleLegend', - { - defaultMessage: 'Select sorting method for field:', - } - ), - 'euiComboBoxOptionsList.allOptionsSelected': i18n.translate( - 'core.euiComboBoxOptionsList.allOptionsSelected', - { - defaultMessage: "You've selected all available options", - } - ), - 'euiComboBoxOptionsList.alreadyAdded': ({ label }: EuiValues) => ( - - ), - 'euiComboBoxOptionsList.createCustomOption': ({ key, searchValue }: EuiValues) => ( - - ), - 'euiComboBoxOptionsList.loadingOptions': i18n.translate( - 'core.euiComboBoxOptionsList.loadingOptions', - { +export const getEuiContextMapping = () => { + const euiContextMapping = { + 'euiBasicTable.selectAllRows': i18n.translate('core.euiBasicTable.selectAllRows', { + defaultMessage: 'Select all rows', + description: 'ARIA and displayed label on a checkbox to select all table rows', + }), + 'euiBasicTable.selectThisRow': i18n.translate('core.euiBasicTable.selectThisRow', { + defaultMessage: 'Select this row', + description: 'ARIA and displayed label on a checkbox to select a single table row', + }), + 'euiBasicTable.tableDescription': ({ itemCount }: EuiValues) => + i18n.translate('core.euiBasicTable.tableDescription', { + defaultMessage: 'Below is a table of {itemCount} items.', + values: { itemCount }, + description: 'Screen reader text to describe the size of a table', + }), + 'euiBottomBar.screenReaderAnnouncement': i18n.translate( + 'core.euiBottomBar.screenReaderAnnouncement', + { + defaultMessage: + 'There is a new menu opening with page level controls at the end of the document.', + description: + 'Screen reader announcement that functionality is available in the page document', + } + ), + 'euiBreadcrumbs.collapsedBadge.ariaLabel': i18n.translate( + 'core.euiBreadcrumbs.collapsedBadge.ariaLabel', + { + defaultMessage: 'Show all breadcrumbs', + description: 'Displayed when one or more breadcrumbs are hidden.', + } + ), + 'euiCardSelect.select': i18n.translate('core.euiCardSelect.select', { + defaultMessage: 'Select', + description: 'Displayed button text when a card option can be selected.', + }), + 'euiCardSelect.selected': i18n.translate('core.euiCardSelect.selected', { + defaultMessage: 'Selected', + description: 'Displayed button text when a card option is selected.', + }), + 'euiCardSelect.unavailable': i18n.translate('core.euiCardSelect.unavailable', { + defaultMessage: 'Unavailable', + description: 'Displayed button text when a card option is unavailable.', + }), + 'euiCodeBlock.copyButton': i18n.translate('core.euiCodeBlock.copyButton', { + defaultMessage: 'Copy', + description: 'ARIA label for a button that copies source code text to the clipboard', + }), + 'euiCodeEditor.startEditing': i18n.translate('core.euiCodeEditor.startEditing', { + defaultMessage: 'Press Enter to start editing.', + }), + 'euiCodeEditor.startInteracting': i18n.translate('core.euiCodeEditor.startInteracting', { + defaultMessage: 'Press Enter to start interacting with the code.', + }), + 'euiCodeEditor.stopEditing': i18n.translate('core.euiCodeEditor.stopEditing', { + defaultMessage: "When you're done, press Escape to stop editing.", + }), + 'euiCodeEditor.stopInteracting': i18n.translate('core.euiCodeEditor.stopInteracting', { + defaultMessage: "When you're done, press Escape to stop interacting with the code.", + }), + 'euiCollapsedItemActions.allActions': i18n.translate( + 'core.euiCollapsedItemActions.allActions', + { + defaultMessage: 'All actions', + description: + 'ARIA label and tooltip content describing a button that expands an actions menu', + } + ), + 'euiColorPicker.screenReaderAnnouncement': i18n.translate( + 'core.euiColorPicker.screenReaderAnnouncement', + { + defaultMessage: + 'A popup with a range of selectable colors opened. Tab forward to cycle through colors choices or press escape to close this popup.', + description: + 'Message when the color picker popover is opened. Describes the interaction with the elements in the popover.', + } + ), + 'euiColorPicker.swatchAriaLabel': ({ swatch }: EuiValues) => + i18n.translate('core.euiColorPicker.swatchAriaLabel', { + defaultMessage: 'Select {swatch} as the color', + values: { swatch }, + description: + 'Screen reader text to describe the action and hex value of the selectable option', + }), + 'euiColorStopThumb.removeLabel': i18n.translate('core.euiColorStopThumb.removeLabel', { + defaultMessage: 'Remove this stop', + description: 'Label accompanying a button whose action will remove the color stop', + }), + 'euiColorStopThumb.screenReaderAnnouncement': i18n.translate( + 'core.euiColorStopThumb.screenReaderAnnouncement', + { + defaultMessage: + 'A popup with a color stop edit form opened. Tab forward to cycle through form controls or press escape to close this popup.', + description: + 'Message when the color picker popover has opened for an individual color stop thumb.', + } + ), + 'euiColorStops.screenReaderAnnouncement': ({ label, readOnly, disabled }: EuiValues) => + i18n.translate('core.euiColorStops.screenReaderAnnouncement', { + defaultMessage: + '{label}: {readOnly} {disabled} Color stop picker. Each stop consists of a number and corresponding color value. Use the Down and Up arrow keys to select individual stops. Press the Enter key to create a new stop.', + values: { label, readOnly, disabled }, + description: + 'Screen reader text to describe the composite behavior of the color stops component.', + }), + 'euiColumnSelector.hideAll': i18n.translate('core.euiColumnSelector.hideAll', { + defaultMessage: 'Hide all', + }), + 'euiColumnSelector.selectAll': i18n.translate('core.euiColumnSelector.selectAll', { + defaultMessage: 'Show all', + }), + 'euiColumnSorting.clearAll': i18n.translate('core.euiColumnSorting.clearAll', { + defaultMessage: 'Clear sorting', + }), + 'euiColumnSorting.emptySorting': i18n.translate('core.euiColumnSorting.emptySorting', { + defaultMessage: 'Currently no fields are sorted', + }), + 'euiColumnSorting.pickFields': i18n.translate('core.euiColumnSorting.pickFields', { + defaultMessage: 'Pick fields to sort by', + }), + 'euiColumnSorting.sortFieldAriaLabel': i18n.translate( + 'core.euiColumnSorting.sortFieldAriaLabel', + { + defaultMessage: 'Sort by:', + } + ), + 'euiColumnSortingDraggable.activeSortLabel': i18n.translate( + 'core.euiColumnSortingDraggable.activeSortLabel', + { + defaultMessage: 'is sorting this data grid', + } + ), + 'euiColumnSortingDraggable.defaultSortAsc': i18n.translate( + 'core.euiColumnSortingDraggable.defaultSortAsc', + { + defaultMessage: 'A-Z', + description: 'Ascending sort label', + } + ), + 'euiColumnSortingDraggable.defaultSortDesc': i18n.translate( + 'core.euiColumnSortingDraggable.defaultSortDesc', + { + defaultMessage: 'Z-A', + description: 'Descending sort label', + } + ), + 'euiColumnSortingDraggable.removeSortLabel': i18n.translate( + 'core.euiColumnSortingDraggable.removeSortLabel', + { + defaultMessage: 'Remove from data grid sort:', + } + ), + 'euiColumnSortingDraggable.toggleLegend': i18n.translate( + 'core.euiColumnSortingDraggable.toggleLegend', + { + defaultMessage: 'Select sorting method for field:', + } + ), + 'euiComboBoxOptionsList.allOptionsSelected': i18n.translate( + 'core.euiComboBoxOptionsList.allOptionsSelected', + { + defaultMessage: "You've selected all available options", + } + ), + 'euiComboBoxOptionsList.alreadyAdded': ({ label }: EuiValues) => ( + + ), + 'euiComboBoxOptionsList.createCustomOption': ({ key, searchValue }: EuiValues) => ( + + ), + 'euiComboBoxOptionsList.loadingOptions': i18n.translate( + 'core.euiComboBoxOptionsList.loadingOptions', + { + defaultMessage: 'Loading options', + description: 'Placeholder message while data is asynchronously loaded', + } + ), + 'euiComboBoxOptionsList.noAvailableOptions': i18n.translate( + 'core.euiComboBoxOptionsList.noAvailableOptions', + { + defaultMessage: "There aren't any options available", + } + ), + 'euiComboBoxOptionsList.noMatchingOptions': ({ searchValue }: EuiValues) => ( + + ), + 'euiComboBoxPill.removeSelection': ({ children }: EuiValues) => + i18n.translate('core.euiComboBoxPill.removeSelection', { + defaultMessage: 'Remove {children} from selection in this group', + values: { children }, + description: 'ARIA label, `children` is the human-friendly value of an option', + }), + 'euiCommonlyUsedTimeRanges.legend': i18n.translate('core.euiCommonlyUsedTimeRanges.legend', { + defaultMessage: 'Commonly used', + }), + 'euiDataGrid.screenReaderNotice': i18n.translate('core.euiDataGrid.screenReaderNotice', { + defaultMessage: 'Cell contains interactive content.', + }), + 'euiDataGridCell.expandButtonTitle': i18n.translate('core.euiDataGridCell.expandButtonTitle', { + defaultMessage: 'Click or hit enter to interact with cell content', + }), + 'euiDataGridSchema.booleanSortTextAsc': i18n.translate( + 'core.euiDataGridSchema.booleanSortTextAsc', + { + defaultMessage: 'True-False', + description: 'Ascending boolean label', + } + ), + 'euiDataGridSchema.booleanSortTextDesc': i18n.translate( + 'core.euiDataGridSchema.booleanSortTextDesc', + { + defaultMessage: 'False-True', + description: 'Descending boolean label', + } + ), + 'euiDataGridSchema.currencySortTextAsc': i18n.translate( + 'core.euiDataGridSchema.currencySortTextAsc', + { + defaultMessage: 'Low-High', + description: 'Ascending currency label', + } + ), + 'euiDataGridSchema.currencySortTextDesc': i18n.translate( + 'core.euiDataGridSchema.currencySortTextDesc', + { + defaultMessage: 'High-Low', + description: 'Descending currency label', + } + ), + 'euiDataGridSchema.dateSortTextAsc': i18n.translate('core.euiDataGridSchema.dateSortTextAsc', { + defaultMessage: 'New-Old', + description: 'Ascending date label', + }), + 'euiDataGridSchema.dateSortTextDesc': i18n.translate( + 'core.euiDataGridSchema.dateSortTextDesc', + { + defaultMessage: 'Old-New', + description: 'Descending date label', + } + ), + 'euiDataGridSchema.numberSortTextAsc': i18n.translate( + 'core.euiDataGridSchema.numberSortTextAsc', + { + defaultMessage: 'Low-High', + description: 'Ascending number label', + } + ), + 'euiDataGridSchema.numberSortTextDesc': i18n.translate( + 'core.euiDataGridSchema.numberSortTextDesc', + { + defaultMessage: 'High-Low', + description: 'Descending number label', + } + ), + 'euiDataGridSchema.jsonSortTextAsc': i18n.translate('core.euiDataGridSchema.jsonSortTextAsc', { + defaultMessage: 'Small-Large', + description: 'Ascending size label', + }), + 'euiDataGridSchema.jsonSortTextDesc': i18n.translate( + 'core.euiDataGridSchema.jsonSortTextDesc', + { + defaultMessage: 'Large-Small', + description: 'Descending size label', + } + ), + 'euiFilterButton.filterBadge': ({ count, hasActiveFilters }: EuiValues) => + i18n.translate('core.euiFilterButton.filterBadge', { + defaultMessage: '${count} ${filterCountLabel} filters', + values: { count, filterCountLabel: hasActiveFilters ? 'active' : 'available' }, + }), + 'euiForm.addressFormErrors': i18n.translate('core.euiForm.addressFormErrors', { + defaultMessage: 'Please address the errors in your form.', + }), + 'euiFormControlLayoutClearButton.label': i18n.translate( + 'core.euiFormControlLayoutClearButton.label', + { + defaultMessage: 'Clear input', + description: 'ARIA label on a button that removes any entry in a form field', + } + ), + 'euiHeaderAlert.dismiss': i18n.translate('core.euiHeaderAlert.dismiss', { + defaultMessage: 'Dismiss', + description: 'ARIA label on a button that dismisses/removes a notification', + }), + 'euiHeaderLinks.appNavigation': i18n.translate('core.euiHeaderLinks.appNavigation', { + defaultMessage: 'App navigation', + description: 'ARIA label on a `nav` element', + }), + 'euiHeaderLinks.openNavigationMenu': i18n.translate('core.euiHeaderLinks.openNavigationMenu', { + defaultMessage: 'Open navigation menu', + }), + 'euiHue.label': i18n.translate('core.euiHue.label', { + defaultMessage: 'Select the HSV color mode "hue" value', + }), + 'euiImage.closeImage': ({ alt }: EuiValues) => + i18n.translate('core.euiImage.closeImage', { + defaultMessage: 'Close full screen {alt} image', + values: { alt }, + }), + 'euiImage.openImage': ({ alt }: EuiValues) => + i18n.translate('core.euiImage.openImage', { + defaultMessage: 'Open full screen {alt} image', + values: { alt }, + }), + 'euiLink.external.ariaLabel': i18n.translate('core.euiLink.external.ariaLabel', { + defaultMessage: 'External link', + }), + 'euiModal.closeModal': i18n.translate('core.euiModal.closeModal', { + defaultMessage: 'Closes this modal window', + }), + 'euiPagination.jumpToLastPage': ({ pageCount }: EuiValues) => + i18n.translate('core.euiPagination.jumpToLastPage', { + defaultMessage: 'Jump to the last page, number {pageCount}', + values: { pageCount }, + }), + 'euiPagination.nextPage': i18n.translate('core.euiPagination.nextPage', { + defaultMessage: 'Next page', + }), + 'euiPagination.pageOfTotal': ({ page, total }: EuiValues) => + i18n.translate('core.euiPagination.pageOfTotal', { + defaultMessage: 'Page {page} of {total}', + values: { page, total }, + }), + 'euiPagination.previousPage': i18n.translate('core.euiPagination.previousPage', { + defaultMessage: 'Previous page', + }), + 'euiPopover.screenReaderAnnouncement': i18n.translate( + 'core.euiPopover.screenReaderAnnouncement', + { + defaultMessage: 'You are in a dialog. To close this dialog, hit escape.', + } + ), + 'euiQuickSelect.applyButton': i18n.translate('core.euiQuickSelect.applyButton', { + defaultMessage: 'Apply', + }), + 'euiQuickSelect.fullDescription': ({ timeTense, timeValue, timeUnit }: EuiValues) => + i18n.translate('core.euiQuickSelect.fullDescription', { + defaultMessage: 'Currently set to {timeTense} {timeValue} {timeUnit}.', + values: { timeTense, timeValue, timeUnit }, + }), + 'euiQuickSelect.legendText': i18n.translate('core.euiQuickSelect.legendText', { + defaultMessage: 'Quick select a time range', + }), + 'euiQuickSelect.nextLabel': i18n.translate('core.euiQuickSelect.nextLabel', { + defaultMessage: 'Next time window', + }), + 'euiQuickSelect.previousLabel': i18n.translate('core.euiQuickSelect.previousLabel', { + defaultMessage: 'Previous time window', + }), + 'euiQuickSelect.quickSelectTitle': i18n.translate('core.euiQuickSelect.quickSelectTitle', { + defaultMessage: 'Quick select', + }), + 'euiQuickSelect.tenseLabel': i18n.translate('core.euiQuickSelect.tenseLabel', { + defaultMessage: 'Time tense', + }), + 'euiQuickSelect.unitLabel': i18n.translate('core.euiQuickSelect.unitLabel', { + defaultMessage: 'Time unit', + }), + 'euiQuickSelect.valueLabel': i18n.translate('core.euiQuickSelect.valueLabel', { + defaultMessage: 'Time value', + }), + 'euiRefreshInterval.fullDescription': ({ optionValue, optionText }: EuiValues) => + i18n.translate('core.euiRefreshInterval.fullDescription', { + defaultMessage: 'Currently set to {optionValue} {optionText}.', + values: { optionValue, optionText }, + }), + 'euiRefreshInterval.legend': i18n.translate('core.euiRefreshInterval.legend', { + defaultMessage: 'Refresh every', + }), + 'euiRefreshInterval.start': i18n.translate('core.euiRefreshInterval.start', { + defaultMessage: 'Start', + }), + 'euiRefreshInterval.stop': i18n.translate('core.euiRefreshInterval.stop', { + defaultMessage: 'Stop', + }), + 'euiRelativeTab.fullDescription': ({ unit }: EuiValues) => + i18n.translate('core.euiRelativeTab.fullDescription', { + defaultMessage: 'The unit is changeable. Currently set to {unit}.', + values: { unit }, + }), + 'euiRelativeTab.relativeDate': ({ position }: EuiValues) => + i18n.translate('core.euiRelativeTab.relativeDate', { + defaultMessage: '{position} date', + values: { position }, + }), + 'euiRelativeTab.roundingLabel': ({ unit }: EuiValues) => + i18n.translate('core.euiRelativeTab.roundingLabel', { + defaultMessage: 'Round to the {unit}', + values: { unit }, + }), + 'euiRelativeTab.unitInputLabel': i18n.translate('core.euiRelativeTab.unitInputLabel', { + defaultMessage: 'Relative time span', + }), + 'euiSaturation.roleDescription': i18n.translate('core.euiSaturation.roleDescription', { + defaultMessage: 'HSV color mode saturation and value selection', + }), + 'euiSaturation.screenReaderAnnouncement': i18n.translate( + 'core.euiSaturation.screenReaderAnnouncement', + { + defaultMessage: + 'Use the arrow keys to navigate the square color gradient. The coordinates resulting from each key press will be used to calculate HSV color mode "saturation" and "value" numbers, in the range of 0 to 1. Left and right decrease and increase (respectively) the "saturation" value. Up and down decrease and increase (respectively) the "value" value.', + } + ), + 'euiSelectable.loadingOptions': i18n.translate('core.euiSelectable.loadingOptions', { defaultMessage: 'Loading options', description: 'Placeholder message while data is asynchronously loaded', - } - ), - 'euiComboBoxOptionsList.noAvailableOptions': i18n.translate( - 'core.euiComboBoxOptionsList.noAvailableOptions', - { + }), + 'euiSelectable.noAvailableOptions': i18n.translate('core.euiSelectable.noAvailableOptions', { defaultMessage: "There aren't any options available", - } - ), - 'euiComboBoxOptionsList.noMatchingOptions': ({ searchValue }: EuiValues) => ( - - ), - 'euiComboBoxPill.removeSelection': ({ children }: EuiValues) => - i18n.translate('core.euiComboBoxPill.removeSelection', { - defaultMessage: 'Remove {children} from selection in this group', - values: { children }, - description: 'ARIA label, `children` is the human-friendly value of an option', - }), - 'euiCommonlyUsedTimeRanges.legend': i18n.translate('core.euiCommonlyUsedTimeRanges.legend', { - defaultMessage: 'Commonly used', - }), - 'euiDataGrid.screenReaderNotice': i18n.translate('core.euiDataGrid.screenReaderNotice', { - defaultMessage: 'Cell contains interactive content.', - }), - 'euiDataGridCell.expandButtonTitle': i18n.translate('core.euiDataGridCell.expandButtonTitle', { - defaultMessage: 'Click or hit enter to interact with cell content', - }), - 'euiDataGridSchema.booleanSortTextAsc': i18n.translate( - 'core.euiDataGridSchema.booleanSortTextAsc', - { - defaultMessage: 'True-False', - description: 'Ascending boolean label', - } - ), - 'euiDataGridSchema.booleanSortTextDesc': i18n.translate( - 'core.euiDataGridSchema.booleanSortTextDesc', - { - defaultMessage: 'False-True', - description: 'Descending boolean label', - } - ), - 'euiDataGridSchema.currencySortTextAsc': i18n.translate( - 'core.euiDataGridSchema.currencySortTextAsc', - { - defaultMessage: 'Low-High', - description: 'Ascending currency label', - } - ), - 'euiDataGridSchema.currencySortTextDesc': i18n.translate( - 'core.euiDataGridSchema.currencySortTextDesc', - { - defaultMessage: 'High-Low', - description: 'Descending currency label', - } - ), - 'euiDataGridSchema.dateSortTextAsc': i18n.translate('core.euiDataGridSchema.dateSortTextAsc', { - defaultMessage: 'New-Old', - description: 'Ascending date label', - }), - 'euiDataGridSchema.dateSortTextDesc': i18n.translate('core.euiDataGridSchema.dateSortTextDesc', { - defaultMessage: 'Old-New', - description: 'Descending date label', - }), - 'euiDataGridSchema.numberSortTextAsc': i18n.translate( - 'core.euiDataGridSchema.numberSortTextAsc', - { - defaultMessage: 'Low-High', - description: 'Ascending number label', - } - ), - 'euiDataGridSchema.numberSortTextDesc': i18n.translate( - 'core.euiDataGridSchema.numberSortTextDesc', - { - defaultMessage: 'High-Low', - description: 'Descending number label', - } - ), - 'euiDataGridSchema.jsonSortTextAsc': i18n.translate('core.euiDataGridSchema.jsonSortTextAsc', { - defaultMessage: 'Small-Large', - description: 'Ascending size label', - }), - 'euiDataGridSchema.jsonSortTextDesc': i18n.translate('core.euiDataGridSchema.jsonSortTextDesc', { - defaultMessage: 'Large-Small', - description: 'Descending size label', - }), - 'euiFilterButton.filterBadge': ({ count, hasActiveFilters }: EuiValues) => - i18n.translate('core.euiFilterButton.filterBadge', { - defaultMessage: '${count} ${filterCountLabel} filters', - values: { count, filterCountLabel: hasActiveFilters ? 'active' : 'available' }, - }), - 'euiForm.addressFormErrors': i18n.translate('core.euiForm.addressFormErrors', { - defaultMessage: 'Please address the errors in your form.', - }), - 'euiFormControlLayoutClearButton.label': i18n.translate( - 'core.euiFormControlLayoutClearButton.label', - { - defaultMessage: 'Clear input', - description: 'ARIA label on a button that removes any entry in a form field', - } - ), - 'euiHeaderAlert.dismiss': i18n.translate('core.euiHeaderAlert.dismiss', { - defaultMessage: 'Dismiss', - description: 'ARIA label on a button that dismisses/removes a notification', - }), - 'euiHeaderLinks.appNavigation': i18n.translate('core.euiHeaderLinks.appNavigation', { - defaultMessage: 'App navigation', - description: 'ARIA label on a `nav` element', - }), - 'euiHeaderLinks.openNavigationMenu': i18n.translate('core.euiHeaderLinks.openNavigationMenu', { - defaultMessage: 'Open navigation menu', - }), - 'euiHue.label': i18n.translate('core.euiHue.label', { - defaultMessage: 'Select the HSV color mode "hue" value', - }), - 'euiImage.closeImage': ({ alt }: EuiValues) => - i18n.translate('core.euiImage.closeImage', { - defaultMessage: 'Close full screen {alt} image', - values: { alt }, - }), - 'euiImage.openImage': ({ alt }: EuiValues) => - i18n.translate('core.euiImage.openImage', { - defaultMessage: 'Open full screen {alt} image', - values: { alt }, - }), - 'euiLink.external.ariaLabel': i18n.translate('core.euiLink.external.ariaLabel', { - defaultMessage: 'External link', - }), - 'euiModal.closeModal': i18n.translate('core.euiModal.closeModal', { - defaultMessage: 'Closes this modal window', - }), - 'euiPagination.jumpToLastPage': ({ pageCount }: EuiValues) => - i18n.translate('core.euiPagination.jumpToLastPage', { - defaultMessage: 'Jump to the last page, number {pageCount}', - values: { pageCount }, - }), - 'euiPagination.nextPage': i18n.translate('core.euiPagination.nextPage', { - defaultMessage: 'Next page', - }), - 'euiPagination.pageOfTotal': ({ page, total }: EuiValues) => - i18n.translate('core.euiPagination.pageOfTotal', { - defaultMessage: 'Page {page} of {total}', - values: { page, total }, - }), - 'euiPagination.previousPage': i18n.translate('core.euiPagination.previousPage', { - defaultMessage: 'Previous page', - }), - 'euiPopover.screenReaderAnnouncement': i18n.translate( - 'core.euiPopover.screenReaderAnnouncement', - { - defaultMessage: 'You are in a dialog. To close this dialog, hit escape.', - } - ), - 'euiQuickSelect.applyButton': i18n.translate('core.euiQuickSelect.applyButton', { - defaultMessage: 'Apply', - }), - 'euiQuickSelect.fullDescription': ({ timeTense, timeValue, timeUnit }: EuiValues) => - i18n.translate('core.euiQuickSelect.fullDescription', { - defaultMessage: 'Currently set to {timeTense} {timeValue} {timeUnit}.', - values: { timeTense, timeValue, timeUnit }, - }), - 'euiQuickSelect.legendText': i18n.translate('core.euiQuickSelect.legendText', { - defaultMessage: 'Quick select a time range', - }), - 'euiQuickSelect.nextLabel': i18n.translate('core.euiQuickSelect.nextLabel', { - defaultMessage: 'Next time window', - }), - 'euiQuickSelect.previousLabel': i18n.translate('core.euiQuickSelect.previousLabel', { - defaultMessage: 'Previous time window', - }), - 'euiQuickSelect.quickSelectTitle': i18n.translate('core.euiQuickSelect.quickSelectTitle', { - defaultMessage: 'Quick select', - }), - 'euiQuickSelect.tenseLabel': i18n.translate('core.euiQuickSelect.tenseLabel', { - defaultMessage: 'Time tense', - }), - 'euiQuickSelect.unitLabel': i18n.translate('core.euiQuickSelect.unitLabel', { - defaultMessage: 'Time unit', - }), - 'euiQuickSelect.valueLabel': i18n.translate('core.euiQuickSelect.valueLabel', { - defaultMessage: 'Time value', - }), - 'euiRefreshInterval.fullDescription': ({ optionValue, optionText }: EuiValues) => - i18n.translate('core.euiRefreshInterval.fullDescription', { - defaultMessage: 'Currently set to {optionValue} {optionText}.', - values: { optionValue, optionText }, - }), - 'euiRefreshInterval.legend': i18n.translate('core.euiRefreshInterval.legend', { - defaultMessage: 'Refresh every', - }), - 'euiRefreshInterval.start': i18n.translate('core.euiRefreshInterval.start', { - defaultMessage: 'Start', - }), - 'euiRefreshInterval.stop': i18n.translate('core.euiRefreshInterval.stop', { - defaultMessage: 'Stop', - }), - 'euiRelativeTab.fullDescription': ({ unit }: EuiValues) => - i18n.translate('core.euiRelativeTab.fullDescription', { - defaultMessage: 'The unit is changeable. Currently set to {unit}.', - values: { unit }, - }), - 'euiRelativeTab.relativeDate': ({ position }: EuiValues) => - i18n.translate('core.euiRelativeTab.relativeDate', { - defaultMessage: '{position} date', - values: { position }, - }), - 'euiRelativeTab.roundingLabel': ({ unit }: EuiValues) => - i18n.translate('core.euiRelativeTab.roundingLabel', { - defaultMessage: 'Round to the {unit}', - values: { unit }, - }), - 'euiRelativeTab.unitInputLabel': i18n.translate('core.euiRelativeTab.unitInputLabel', { - defaultMessage: 'Relative time span', - }), - 'euiSaturation.roleDescription': i18n.translate('core.euiSaturation.roleDescription', { - defaultMessage: 'HSV color mode saturation and value selection', - }), - 'euiSaturation.screenReaderAnnouncement': i18n.translate( - 'core.euiSaturation.screenReaderAnnouncement', - { - defaultMessage: - 'Use the arrow keys to navigate the square color gradient. The coordinates resulting from each key press will be used to calculate HSV color mode "saturation" and "value" numbers, in the range of 0 to 1. Left and right decrease and increase (respectively) the "saturation" value. Up and down decrease and increase (respectively) the "value" value.', - } - ), - 'euiSelectable.loadingOptions': i18n.translate('core.euiSelectable.loadingOptions', { - defaultMessage: 'Loading options', - description: 'Placeholder message while data is asynchronously loaded', - }), - 'euiSelectable.noAvailableOptions': i18n.translate('core.euiSelectable.noAvailableOptions', { - defaultMessage: "There aren't any options available", - }), - 'euiSelectable.noMatchingOptions': ({ searchValue }: EuiValues) => ( - - ), - 'euiStat.loadingText': i18n.translate('core.euiStat.loadingText', { - defaultMessage: 'Statistic is loading', - }), - 'euiStep.ariaLabel': ({ status }: EuiValues) => - i18n.translate('core.euiStep.ariaLabel', { - defaultMessage: '{stepStatus}', - values: { stepStatus: status === 'incomplete' ? 'Incomplete Step' : 'Step' }, - }), - 'euiStepHorizontal.buttonTitle': ({ step, title, disabled, isComplete }: EuiValues) => { - return i18n.translate('core.euiStepHorizontal.buttonTitle', { - defaultMessage: 'Step {step}: {title}{titleAppendix}', - values: { - step, - title, - titleAppendix: disabled ? ' is disabled' : isComplete ? ' is complete' : '', - }, - }); - }, - 'euiStepHorizontal.step': i18n.translate('core.euiStepHorizontal.step', { - defaultMessage: 'Step', - description: 'Screen reader text announcing information about a step in some process', - }), - 'euiStepNumber.hasErrors': i18n.translate('core.euiStepNumber.hasErrors', { - defaultMessage: 'has errors', - description: - 'Used as the title attribute on an image or svg icon to indicate a given process step has errors', - }), - 'euiStepNumber.hasWarnings': i18n.translate('core.euiStepNumber.hasWarnings', { - defaultMessage: 'has warnings', - description: - 'Used as the title attribute on an image or svg icon to indicate a given process step has warnings', - }), - 'euiStepNumber.isComplete': i18n.translate('core.euiStepNumber.isComplete', { - defaultMessage: 'complete', - description: - 'Used as the title attribute on an image or svg icon to indicate a given process step is complete', - }), - 'euiStyleSelector.buttonText': i18n.translate('core.euiStyleSelector.buttonText', { - defaultMessage: 'Density', - }), - 'euiSuperDatePicker.showDatesButtonLabel': i18n.translate( - 'core.euiSuperDatePicker.showDatesButtonLabel', - { - defaultMessage: 'Show dates', - description: 'Displayed in a button that shows date picker', - } - ), - 'euiSuperSelect.screenReaderAnnouncement': ({ optionsCount }: EuiValues) => - i18n.translate('core.euiSuperSelect.screenReaderAnnouncement', { - defaultMessage: - 'You are in a form selector of {optionsCount} items and must select a single option. Use the Up and Down keys to navigate or Escape to close.', - values: { optionsCount }, - }), - 'euiSuperSelectControl.selectAnOption': ({ selectedValue }: EuiValues) => - i18n.translate('core.euiSuperSelectControl.selectAnOption', { - defaultMessage: 'Select an option: {selectedValue}, is selected', - values: { selectedValue }, - }), - 'euiSuperUpdateButton.cannotUpdateTooltip': i18n.translate( - 'core.euiSuperUpdateButton.cannotUpdateTooltip', - { - defaultMessage: 'Cannot update', - description: "Displayed in a tooltip when updates can't happen", - } - ), - 'euiSuperUpdateButton.clickToApplyTooltip': i18n.translate( - 'core.euiSuperUpdateButton.clickToApplyTooltip', - { - defaultMessage: 'Click to apply', - description: "Displayed in a tooltip when there are changes that haven't been applied", - } - ), - 'euiSuperUpdateButton.refreshButtonLabel': i18n.translate( - 'core.euiSuperUpdateButton.refreshButtonLabel', - { - defaultMessage: 'Refresh', - description: 'Displayed in a button that refreshes based on date picked', - } - ), - 'euiSuperUpdateButton.updatingButtonLabel': i18n.translate( - 'core.euiSuperUpdateButton.updatingButtonLabel', - { - defaultMessage: 'Updating', - description: 'Displayed in a button that refreshes when updates are happening', - } - ), - 'euiSuperUpdateButton.updateButtonLabel': i18n.translate( - 'core.euiSuperUpdateButton.updateButtonLabel', - { - defaultMessage: 'Update', - description: 'Displayed in a button that updates based on date picked', - } - ), - 'euiTablePagination.rowsPerPage': i18n.translate('core.euiTablePagination.rowsPerPage', { - defaultMessage: 'Rows per page', - description: 'Displayed in a button that toggles a table pagination menu', - }), - 'euiTablePagination.rowsPerPageOption': ({ rowsPerPage }: EuiValues) => - i18n.translate('core.euiTablePagination.rowsPerPageOption', { - defaultMessage: '{rowsPerPage} rows', - description: 'Displayed in a button that toggles the number of visible rows', - values: { rowsPerPage }, - }), - 'euiTableSortMobile.sorting': i18n.translate('core.euiTableSortMobile.sorting', { - defaultMessage: 'Sorting', - description: 'Displayed in a button that toggles a table sorting menu', - }), - 'euiToast.dismissToast': i18n.translate('core.euiToast.dismissToast', { - defaultMessage: 'Dismiss toast', - }), - 'euiToast.newNotification': i18n.translate('core.euiToast.newNotification', { - defaultMessage: 'A new notification appears', - }), - 'euiToast.notification': i18n.translate('core.euiToast.notification', { - defaultMessage: 'Notification', - description: 'ARIA label on an element containing a notification', - }), - 'euiTreeView.ariaLabel': ({ nodeLabel, ariaLabel }: EuiValues) => - i18n.translate('core.euiTreeView.ariaLabel', { - defaultMessage: '{nodeLabel} child of {ariaLabel}', - values: { nodeLabel, ariaLabel }, - }), - 'euiTreeView.listNavigationInstructions': i18n.translate( - 'core.euiTreeView.listNavigationInstructions', - { - defaultMessage: 'You can quickly navigate this list using arrow keys.', - } - ), + }), + 'euiSelectable.noMatchingOptions': ({ searchValue }: EuiValues) => ( + + ), + 'euiStat.loadingText': i18n.translate('core.euiStat.loadingText', { + defaultMessage: 'Statistic is loading', + }), + 'euiStep.ariaLabel': ({ status }: EuiValues) => + i18n.translate('core.euiStep.ariaLabel', { + defaultMessage: '{stepStatus}', + values: { stepStatus: status === 'incomplete' ? 'Incomplete Step' : 'Step' }, + }), + 'euiStepHorizontal.buttonTitle': ({ step, title, disabled, isComplete }: EuiValues) => { + return i18n.translate('core.euiStepHorizontal.buttonTitle', { + defaultMessage: 'Step {step}: {title}{titleAppendix}', + values: { + step, + title, + titleAppendix: disabled ? ' is disabled' : isComplete ? ' is complete' : '', + }, + }); + }, + 'euiStepHorizontal.step': i18n.translate('core.euiStepHorizontal.step', { + defaultMessage: 'Step', + description: 'Screen reader text announcing information about a step in some process', + }), + 'euiStepNumber.hasErrors': i18n.translate('core.euiStepNumber.hasErrors', { + defaultMessage: 'has errors', + description: + 'Used as the title attribute on an image or svg icon to indicate a given process step has errors', + }), + 'euiStepNumber.hasWarnings': i18n.translate('core.euiStepNumber.hasWarnings', { + defaultMessage: 'has warnings', + description: + 'Used as the title attribute on an image or svg icon to indicate a given process step has warnings', + }), + 'euiStepNumber.isComplete': i18n.translate('core.euiStepNumber.isComplete', { + defaultMessage: 'complete', + description: + 'Used as the title attribute on an image or svg icon to indicate a given process step is complete', + }), + 'euiStyleSelector.buttonText': i18n.translate('core.euiStyleSelector.buttonText', { + defaultMessage: 'Density', + }), + 'euiSuperDatePicker.showDatesButtonLabel': i18n.translate( + 'core.euiSuperDatePicker.showDatesButtonLabel', + { + defaultMessage: 'Show dates', + description: 'Displayed in a button that shows date picker', + } + ), + 'euiSuperSelect.screenReaderAnnouncement': ({ optionsCount }: EuiValues) => + i18n.translate('core.euiSuperSelect.screenReaderAnnouncement', { + defaultMessage: + 'You are in a form selector of {optionsCount} items and must select a single option. Use the Up and Down keys to navigate or Escape to close.', + values: { optionsCount }, + }), + 'euiSuperSelectControl.selectAnOption': ({ selectedValue }: EuiValues) => + i18n.translate('core.euiSuperSelectControl.selectAnOption', { + defaultMessage: 'Select an option: {selectedValue}, is selected', + values: { selectedValue }, + }), + 'euiSuperUpdateButton.cannotUpdateTooltip': i18n.translate( + 'core.euiSuperUpdateButton.cannotUpdateTooltip', + { + defaultMessage: 'Cannot update', + description: "Displayed in a tooltip when updates can't happen", + } + ), + 'euiSuperUpdateButton.clickToApplyTooltip': i18n.translate( + 'core.euiSuperUpdateButton.clickToApplyTooltip', + { + defaultMessage: 'Click to apply', + description: "Displayed in a tooltip when there are changes that haven't been applied", + } + ), + 'euiSuperUpdateButton.refreshButtonLabel': i18n.translate( + 'core.euiSuperUpdateButton.refreshButtonLabel', + { + defaultMessage: 'Refresh', + description: 'Displayed in a button that refreshes based on date picked', + } + ), + 'euiSuperUpdateButton.updatingButtonLabel': i18n.translate( + 'core.euiSuperUpdateButton.updatingButtonLabel', + { + defaultMessage: 'Updating', + description: 'Displayed in a button that refreshes when updates are happening', + } + ), + 'euiSuperUpdateButton.updateButtonLabel': i18n.translate( + 'core.euiSuperUpdateButton.updateButtonLabel', + { + defaultMessage: 'Update', + description: 'Displayed in a button that updates based on date picked', + } + ), + 'euiTablePagination.rowsPerPage': i18n.translate('core.euiTablePagination.rowsPerPage', { + defaultMessage: 'Rows per page', + description: 'Displayed in a button that toggles a table pagination menu', + }), + 'euiTablePagination.rowsPerPageOption': ({ rowsPerPage }: EuiValues) => + i18n.translate('core.euiTablePagination.rowsPerPageOption', { + defaultMessage: '{rowsPerPage} rows', + description: 'Displayed in a button that toggles the number of visible rows', + values: { rowsPerPage }, + }), + 'euiTableSortMobile.sorting': i18n.translate('core.euiTableSortMobile.sorting', { + defaultMessage: 'Sorting', + description: 'Displayed in a button that toggles a table sorting menu', + }), + 'euiToast.dismissToast': i18n.translate('core.euiToast.dismissToast', { + defaultMessage: 'Dismiss toast', + }), + 'euiToast.newNotification': i18n.translate('core.euiToast.newNotification', { + defaultMessage: 'A new notification appears', + }), + 'euiToast.notification': i18n.translate('core.euiToast.notification', { + defaultMessage: 'Notification', + description: 'ARIA label on an element containing a notification', + }), + 'euiTreeView.ariaLabel': ({ nodeLabel, ariaLabel }: EuiValues) => + i18n.translate('core.euiTreeView.ariaLabel', { + defaultMessage: '{nodeLabel} child of {ariaLabel}', + values: { nodeLabel, ariaLabel }, + }), + 'euiTreeView.listNavigationInstructions': i18n.translate( + 'core.euiTreeView.listNavigationInstructions', + { + defaultMessage: 'You can quickly navigate this list using arrow keys.', + } + ), + }; + + return euiContextMapping; }; diff --git a/src/core/public/i18n/i18n_service.tsx b/src/core/public/i18n/i18n_service.tsx index 501d83e36b1b9..37af6127346c1 100644 --- a/src/core/public/i18n/i18n_service.tsx +++ b/src/core/public/i18n/i18n_service.tsx @@ -21,7 +21,7 @@ import React from 'react'; import { EuiContext } from '@elastic/eui'; import { I18nProvider } from '@kbn/i18n/react'; -import { euiContextMapping } from './i18n_eui_mapping'; +import { getEuiContextMapping } from './i18n_eui_mapping'; /** * Service that is responsible for i18n capabilities. @@ -37,6 +37,8 @@ export class I18nService { * @internal */ public getContext(): I18nStart { + const euiContextMapping = getEuiContextMapping(); + const mapping = { ...euiContextMapping, }; diff --git a/src/core/public/kbn_bootstrap.test.mocks.ts b/src/core/public/kbn_bootstrap.test.mocks.ts new file mode 100644 index 0000000000000..30f292280a135 --- /dev/null +++ b/src/core/public/kbn_bootstrap.test.mocks.ts @@ -0,0 +1,50 @@ +/* + * 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 { applicationServiceMock } from './application/application_service.mock'; +import { fatalErrorsServiceMock } from './fatal_errors/fatal_errors_service.mock'; +export const fatalErrorMock = fatalErrorsServiceMock.createSetupContract(); +export const coreSystemMock = { + setup: jest.fn().mockResolvedValue({ + fatalErrors: fatalErrorMock, + }), + start: jest.fn().mockResolvedValue({ + application: applicationServiceMock.createInternalStartContract(), + }), +}; +jest.doMock('./core_system', () => ({ + CoreSystem: jest.fn().mockImplementation(() => coreSystemMock), +})); + +export const apmSystem = { + setup: jest.fn().mockResolvedValue(undefined), + start: jest.fn().mockResolvedValue(undefined), +}; +export const ApmSystemConstructor = jest.fn().mockImplementation(() => apmSystem); +jest.doMock('./apm_system', () => ({ + ApmSystem: ApmSystemConstructor, +})); + +export const i18nLoad = jest.fn().mockResolvedValue(undefined); +jest.doMock('@kbn/i18n', () => ({ + i18n: { + ...jest.requireActual('@kbn/i18n').i18n, + load: i18nLoad, + }, +})); diff --git a/src/core/public/kbn_bootstrap.test.ts b/src/core/public/kbn_bootstrap.test.ts new file mode 100644 index 0000000000000..9cd16dd6ab9df --- /dev/null +++ b/src/core/public/kbn_bootstrap.test.ts @@ -0,0 +1,54 @@ +/* + * 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 { apmSystem, fatalErrorMock, i18nLoad } from './kbn_bootstrap.test.mocks'; +import { __kbnBootstrap__ } from './'; + +describe('kbn_bootstrap', () => { + beforeAll(() => { + const metadata = { + i18n: { translationsUrl: 'http://localhost' }, + vars: { apmConfig: null }, + }; + // eslint-disable-next-line no-unsanitized/property + document.body.innerHTML = ` +`; + }); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('does not report a fatal error if apm load fails', async () => { + apmSystem.setup.mockRejectedValueOnce(new Error('reason')); + const consoleSpy = jest.spyOn(console, 'warn').mockImplementationOnce(() => undefined); + + await __kbnBootstrap__(); + + expect(fatalErrorMock.add).toHaveBeenCalledTimes(0); + expect(consoleSpy).toHaveBeenCalledTimes(1); + }); + + it('reports a fatal error if i18n load fails', async () => { + i18nLoad.mockRejectedValueOnce(new Error('reason')); + + await __kbnBootstrap__(); + + expect(fatalErrorMock.add).toHaveBeenCalledTimes(1); + }); +}); diff --git a/src/core/public/kbn_bootstrap.ts b/src/core/public/kbn_bootstrap.ts index a108b5aaa47ec..a083196004cf4 100644 --- a/src/core/public/kbn_bootstrap.ts +++ b/src/core/public/kbn_bootstrap.ts @@ -17,70 +17,38 @@ * under the License. */ -/** - * This is the entry point used to boot the frontend when serving a application - * that lives in the Kibana Platform. - * - * Any changes to this file should be kept in sync with - * src/legacy/ui/ui_bundles/app_entry_template.js - */ - import { i18n } from '@kbn/i18n'; import { CoreSystem } from './core_system'; +import { ApmSystem } from './apm_system'; /** @internal */ -export function __kbnBootstrap__() { +export async function __kbnBootstrap__() { const injectedMetadata = JSON.parse( document.querySelector('kbn-injected-metadata')!.getAttribute('data')! ); - /** - * `apmConfig` would be populated with relavant APM RUM agent - * configuration if server is started with `ELASTIC_APM_ACTIVE=true` - */ - const apmConfig = injectedMetadata.vars.apmConfig; - const APM_ENABLED = process.env.IS_KIBANA_DISTRIBUTABLE !== 'true' && apmConfig != null; - - if (APM_ENABLED) { - // eslint-disable-next-line @typescript-eslint/no-var-requires - const { init, apm } = require('@elastic/apm-rum'); - if (apmConfig.globalLabels) { - apm.addLabels(apmConfig.globalLabels); - } - init(apmConfig); + let i18nError: Error | undefined; + const apmSystem = new ApmSystem(injectedMetadata.vars.apmConfig); + + await Promise.all([ + // eslint-disable-next-line no-console + apmSystem.setup().catch(console.warn), + i18n.load(injectedMetadata.i18n.translationsUrl).catch((error) => { + i18nError = error; + }), + ]); + + const coreSystem = new CoreSystem({ + injectedMetadata, + rootDomElement: document.body, + browserSupportsCsp: !(window as any).__kbnCspNotEnforced__, + }); + + const setup = await coreSystem.setup(); + if (i18nError && setup) { + setup.fatalErrors.add(i18nError); } - i18n - .load(injectedMetadata.i18n.translationsUrl) - .catch((e) => e) - .then(async (i18nError) => { - const coreSystem = new CoreSystem({ - injectedMetadata, - rootDomElement: document.body, - browserSupportsCsp: !(window as any).__kbnCspNotEnforced__, - }); - - const setup = await coreSystem.setup(); - if (i18nError && setup) { - setup.fatalErrors.add(i18nError); - } - - const start = await coreSystem.start(); - - if (APM_ENABLED && start) { - /** - * Register listeners for navigation changes and capture them as - * route-change transactions after Kibana app is bootstrapped - */ - start.application.currentAppId$.subscribe((appId) => { - const apmInstance = (window as any).elasticApm; - if (appId && apmInstance && typeof apmInstance.startTransaction === 'function') { - apmInstance.startTransaction(`/app/${appId}`, 'route-change', { - managed: true, - canReuse: true, - }); - } - }); - } - }); + const start = await coreSystem.start(); + await apmSystem.start(start); } diff --git a/src/core/public/notifications/toasts/__snapshots__/global_toast_list.test.tsx.snap b/src/core/public/notifications/toasts/__snapshots__/global_toast_list.test.tsx.snap index 2b3bdb65708a3..0ed32a1dbccb2 100644 --- a/src/core/public/notifications/toasts/__snapshots__/global_toast_list.test.tsx.snap +++ b/src/core/public/notifications/toasts/__snapshots__/global_toast_list.test.tsx.snap @@ -2,6 +2,7 @@ exports[`renders matching snapshot 1`] = ` { public render() { return ( this.props.dismissToast(id)} diff --git a/src/core/public/overlays/banners/user_banner_service.tsx b/src/core/public/overlays/banners/user_banner_service.tsx index 643d95a1e3bb4..2b93c3e4b6c21 100644 --- a/src/core/public/overlays/banners/user_banner_service.tsx +++ b/src/core/public/overlays/banners/user_banner_service.tsx @@ -19,12 +19,11 @@ import React, { Fragment } from 'react'; import ReactDOM from 'react-dom'; -import ReactMarkdown from 'react-markdown'; import { filter } from 'rxjs/operators'; import { Subscription } from 'rxjs'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiCallOut, EuiButton } from '@elastic/eui'; +import { EuiCallOut, EuiButton, EuiLoadingSpinner } from '@elastic/eui'; import { I18nStart } from '../../i18n'; import { IUiSettingsClient } from '../../ui_settings'; @@ -36,6 +35,8 @@ interface StartDeps { uiSettings: IUiSettingsClient; } +const ReactMarkdownLazy = React.lazy(() => import('react-markdown')); + /** * Sets up the custom banner that can be specified in advanced settings. * @internal @@ -75,7 +76,15 @@ export class UserBannerService { } iconType="help" > - {content.trim()} + + +
+ } + > + + banners.remove(id!)}> ; // @public (undocumented) export interface App { @@ -539,6 +539,7 @@ export interface DocLinksStart { readonly gettingStarted: string; }; readonly query: { + readonly eql: string; readonly luceneQuerySyntax: string; readonly queryDsl: string; readonly kueryQuerySyntax: string; @@ -1029,8 +1030,9 @@ export class SavedObjectsClient { }>) => Promise>; bulkUpdate(objects?: SavedObjectsBulkUpdateObject[]): Promise>; create: (type: string, attributes: T, options?: SavedObjectsCreateOptions) => Promise>; + // Warning: (ae-forgotten-export) The symbol "SavedObjectsDeleteOptions" needs to be exported by the entry point index.d.ts // Warning: (ae-forgotten-export) The symbol "SavedObjectsClientContract" needs to be exported by the entry point index.d.ts - delete: (type: string, id: string) => ReturnType; + delete: (type: string, id: string, options?: SavedObjectsDeleteOptions | undefined) => ReturnType; // Warning: (ae-forgotten-export) The symbol "SavedObjectsFindOptions" needs to be exported by the entry point index.d.ts find: (options: SavedObjectsFindOptions_2) => Promise>; get: (type: string, id: string) => Promise>; diff --git a/src/core/public/saved_objects/saved_objects_client.test.ts b/src/core/public/saved_objects/saved_objects_client.test.ts index 20824af38af0f..fab651379ea6a 100644 --- a/src/core/public/saved_objects/saved_objects_client.test.ts +++ b/src/core/public/saved_objects/saved_objects_client.test.ts @@ -132,7 +132,9 @@ describe('SavedObjectsClient', () => { Object { "body": undefined, "method": "DELETE", - "query": undefined, + "query": Object { + "force": false, + }, }, ] `); diff --git a/src/core/public/saved_objects/saved_objects_client.ts b/src/core/public/saved_objects/saved_objects_client.ts index 6a10eb44d9ca4..beed3e6fe0a18 100644 --- a/src/core/public/saved_objects/saved_objects_client.ts +++ b/src/core/public/saved_objects/saved_objects_client.ts @@ -96,6 +96,12 @@ export interface SavedObjectsBatchResponse { savedObjects: Array>; } +/** @public */ +export interface SavedObjectsDeleteOptions { + /** Force deletion of an object that exists in multiple namespaces */ + force?: boolean; +} + /** * Return type of the Saved Objects `find()` method. * @@ -261,12 +267,20 @@ export class SavedObjectsClient { * @param id * @returns */ - public delete = (type: string, id: string): ReturnType => { + public delete = ( + type: string, + id: string, + options?: SavedObjectsDeleteOptions + ): ReturnType => { if (!type || !id) { return Promise.reject(new Error('requires type and id')); } - return this.savedObjectsFetch(this.getPath([type, id]), { method: 'DELETE' }); + const query = { + force: !!options?.force, + }; + + return this.savedObjectsFetch(this.getPath([type, id]), { method: 'DELETE', query }); }; /** diff --git a/src/core/server/config/deprecation/core_deprecations.ts b/src/core/server/config/deprecation/core_deprecations.ts index 2701edcf44e03..6c85cfbed8e82 100644 --- a/src/core/server/config/deprecation/core_deprecations.ts +++ b/src/core/server/config/deprecation/core_deprecations.ts @@ -136,6 +136,8 @@ export const coreDeprecationProvider: ConfigDeprecationProvider = ({ rename, unu unusedFromRoot('optimize.workers'), unusedFromRoot('optimize.profile'), unusedFromRoot('optimize.validateSyntaxOfNodeModules'), + unusedFromRoot('elasticsearch.preserveHost'), + unusedFromRoot('elasticsearch.startupTimeout'), rename('cpu.cgroup.path.override', 'ops.cGroupOverrides.cpuPath'), rename('cpuacct.cgroup.path.override', 'ops.cGroupOverrides.cpuAcctPath'), configPathDeprecation, diff --git a/src/core/server/core_route_handler_context.test.ts b/src/core/server/core_route_handler_context.test.ts new file mode 100644 index 0000000000000..563e337e6c7e0 --- /dev/null +++ b/src/core/server/core_route_handler_context.test.ts @@ -0,0 +1,239 @@ +/* + * 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 { CoreRouteHandlerContext } from './core_route_handler_context'; +import { coreMock, httpServerMock } from './mocks'; + +describe('#auditor', () => { + test('returns the results of coreStart.audiTrail.asScoped', () => { + const request = httpServerMock.createKibanaRequest(); + const coreStart = coreMock.createInternalStart(); + const context = new CoreRouteHandlerContext(coreStart, request); + + const auditor = context.auditor; + expect(auditor).toBe(coreStart.auditTrail.asScoped.mock.results[0].value); + }); + + test('lazily created', () => { + const request = httpServerMock.createKibanaRequest(); + const coreStart = coreMock.createInternalStart(); + const context = new CoreRouteHandlerContext(coreStart, request); + + expect(coreStart.auditTrail.asScoped).not.toHaveBeenCalled(); + const auditor = context.auditor; + expect(coreStart.auditTrail.asScoped).toHaveBeenCalled(); + expect(auditor).toBeDefined(); + }); + + test('only creates one instance', () => { + const request = httpServerMock.createKibanaRequest(); + const coreStart = coreMock.createInternalStart(); + const context = new CoreRouteHandlerContext(coreStart, request); + + const auditor1 = context.auditor; + const auditor2 = context.auditor; + expect(coreStart.auditTrail.asScoped.mock.calls.length).toBe(1); + const mockResult = coreStart.auditTrail.asScoped.mock.results[0].value; + expect(auditor1).toBe(mockResult); + expect(auditor2).toBe(mockResult); + }); +}); + +describe('#elasticsearch', () => { + describe('#client', () => { + test('returns the results of coreStart.elasticsearch.client.asScoped', () => { + const request = httpServerMock.createKibanaRequest(); + const coreStart = coreMock.createInternalStart(); + const context = new CoreRouteHandlerContext(coreStart, request); + + const client = context.elasticsearch.client; + expect(client).toBe(coreStart.elasticsearch.client.asScoped.mock.results[0].value); + }); + + test('lazily created', () => { + const request = httpServerMock.createKibanaRequest(); + const coreStart = coreMock.createInternalStart(); + const context = new CoreRouteHandlerContext(coreStart, request); + + expect(coreStart.elasticsearch.client.asScoped).not.toHaveBeenCalled(); + const client = context.elasticsearch.client; + expect(coreStart.elasticsearch.client.asScoped).toHaveBeenCalled(); + expect(client).toBeDefined(); + }); + + test('only creates one instance', () => { + const request = httpServerMock.createKibanaRequest(); + const coreStart = coreMock.createInternalStart(); + const context = new CoreRouteHandlerContext(coreStart, request); + + const client1 = context.elasticsearch.client; + const client2 = context.elasticsearch.client; + expect(coreStart.elasticsearch.client.asScoped.mock.calls.length).toBe(1); + const mockResult = coreStart.elasticsearch.client.asScoped.mock.results[0].value; + expect(client1).toBe(mockResult); + expect(client2).toBe(mockResult); + }); + }); + + describe('#legacy', () => { + describe('#client', () => { + test('returns the results of coreStart.elasticsearch.legacy.client.asScoped', () => { + const request = httpServerMock.createKibanaRequest(); + const coreStart = coreMock.createInternalStart(); + const context = new CoreRouteHandlerContext(coreStart, request); + + const client = context.elasticsearch.legacy.client; + expect(client).toBe(coreStart.elasticsearch.legacy.client.asScoped.mock.results[0].value); + }); + + test('lazily created', () => { + const request = httpServerMock.createKibanaRequest(); + const coreStart = coreMock.createInternalStart(); + const context = new CoreRouteHandlerContext(coreStart, request); + + expect(coreStart.elasticsearch.legacy.client.asScoped).not.toHaveBeenCalled(); + const client = context.elasticsearch.legacy.client; + expect(coreStart.elasticsearch.legacy.client.asScoped).toHaveBeenCalled(); + expect(client).toBeDefined(); + }); + + test('only creates one instance', () => { + const request = httpServerMock.createKibanaRequest(); + const coreStart = coreMock.createInternalStart(); + const context = new CoreRouteHandlerContext(coreStart, request); + + const client1 = context.elasticsearch.legacy.client; + const client2 = context.elasticsearch.legacy.client; + expect(coreStart.elasticsearch.legacy.client.asScoped.mock.calls.length).toBe(1); + const mockResult = coreStart.elasticsearch.legacy.client.asScoped.mock.results[0].value; + expect(client1).toBe(mockResult); + expect(client2).toBe(mockResult); + }); + }); + }); +}); + +describe('#savedObjects', () => { + describe('#client', () => { + test('returns the results of coreStart.savedObjects.getScopedClient', () => { + const request = httpServerMock.createKibanaRequest(); + const coreStart = coreMock.createInternalStart(); + const context = new CoreRouteHandlerContext(coreStart, request); + + const client = context.savedObjects.client; + expect(client).toBe(coreStart.savedObjects.getScopedClient.mock.results[0].value); + }); + + test('lazily created', () => { + const request = httpServerMock.createKibanaRequest(); + const coreStart = coreMock.createInternalStart(); + const context = new CoreRouteHandlerContext(coreStart, request); + + const savedObjects = context.savedObjects; + expect(coreStart.savedObjects.getScopedClient).not.toHaveBeenCalled(); + const client = savedObjects.client; + expect(coreStart.savedObjects.getScopedClient).toHaveBeenCalled(); + expect(client).toBeDefined(); + }); + + test('only creates one instance', () => { + const request = httpServerMock.createKibanaRequest(); + const coreStart = coreMock.createInternalStart(); + const context = new CoreRouteHandlerContext(coreStart, request); + + const client1 = context.savedObjects.client; + const client2 = context.savedObjects.client; + expect(coreStart.savedObjects.getScopedClient.mock.calls.length).toBe(1); + const mockResult = coreStart.savedObjects.getScopedClient.mock.results[0].value; + expect(client1).toBe(mockResult); + expect(client2).toBe(mockResult); + }); + }); + + describe('#typeRegistry', () => { + test('returns the results of coreStart.savedObjects.getTypeRegistry', () => { + const request = httpServerMock.createKibanaRequest(); + const coreStart = coreMock.createInternalStart(); + const context = new CoreRouteHandlerContext(coreStart, request); + + const typeRegistry = context.savedObjects.typeRegistry; + expect(typeRegistry).toBe(coreStart.savedObjects.getTypeRegistry.mock.results[0].value); + }); + + test('lazily created', () => { + const request = httpServerMock.createKibanaRequest(); + const coreStart = coreMock.createInternalStart(); + const context = new CoreRouteHandlerContext(coreStart, request); + + expect(coreStart.savedObjects.getTypeRegistry).not.toHaveBeenCalled(); + const typeRegistry = context.savedObjects.typeRegistry; + expect(coreStart.savedObjects.getTypeRegistry).toHaveBeenCalled(); + expect(typeRegistry).toBeDefined(); + }); + + test('only creates one instance', () => { + const request = httpServerMock.createKibanaRequest(); + const coreStart = coreMock.createInternalStart(); + const context = new CoreRouteHandlerContext(coreStart, request); + + const typeRegistry1 = context.savedObjects.typeRegistry; + const typeRegistry2 = context.savedObjects.typeRegistry; + expect(coreStart.savedObjects.getTypeRegistry.mock.calls.length).toBe(1); + const mockResult = coreStart.savedObjects.getTypeRegistry.mock.results[0].value; + expect(typeRegistry1).toBe(mockResult); + expect(typeRegistry2).toBe(mockResult); + }); + }); +}); + +describe('#uiSettings', () => { + describe('#client', () => { + test('returns the results of coreStart.uiSettings.asScopedToClient', () => { + const request = httpServerMock.createKibanaRequest(); + const coreStart = coreMock.createInternalStart(); + const context = new CoreRouteHandlerContext(coreStart, request); + + const client = context.uiSettings.client; + expect(client).toBe(coreStart.uiSettings.asScopedToClient.mock.results[0].value); + }); + + test('lazily created', () => { + const request = httpServerMock.createKibanaRequest(); + const coreStart = coreMock.createInternalStart(); + const context = new CoreRouteHandlerContext(coreStart, request); + + expect(coreStart.uiSettings.asScopedToClient).not.toHaveBeenCalled(); + const client = context.uiSettings.client; + expect(coreStart.uiSettings.asScopedToClient).toHaveBeenCalled(); + expect(client).toBeDefined(); + }); + + test('only creates one instance', () => { + const request = httpServerMock.createKibanaRequest(); + const coreStart = coreMock.createInternalStart(); + const context = new CoreRouteHandlerContext(coreStart, request); + + const client1 = context.uiSettings.client; + const client2 = context.uiSettings.client; + expect(coreStart.uiSettings.asScopedToClient.mock.calls.length).toBe(1); + const mockResult = coreStart.uiSettings.asScopedToClient.mock.results[0].value; + expect(client1).toBe(mockResult); + expect(client2).toBe(mockResult); + }); + }); +}); diff --git a/src/core/server/core_route_handler_context.ts b/src/core/server/core_route_handler_context.ts new file mode 100644 index 0000000000000..8a182a523f52c --- /dev/null +++ b/src/core/server/core_route_handler_context.ts @@ -0,0 +1,132 @@ +/* + * 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 max-classes-per-file +import { InternalCoreStart } from './internal_types'; +import { KibanaRequest } from './http/router'; +import { SavedObjectsClientContract } from './saved_objects/types'; +import { InternalSavedObjectsServiceStart, ISavedObjectTypeRegistry } from './saved_objects'; +import { + InternalElasticsearchServiceStart, + IScopedClusterClient, + LegacyScopedClusterClient, +} from './elasticsearch'; +import { Auditor } from './audit_trail'; +import { InternalUiSettingsServiceStart, IUiSettingsClient } from './ui_settings'; + +class CoreElasticsearchRouteHandlerContext { + #client?: IScopedClusterClient; + #legacy?: { + client: Pick; + }; + + constructor( + private readonly elasticsearchStart: InternalElasticsearchServiceStart, + private readonly request: KibanaRequest + ) {} + + public get client() { + if (this.#client == null) { + this.#client = this.elasticsearchStart.client.asScoped(this.request); + } + return this.#client; + } + + public get legacy() { + if (this.#legacy == null) { + this.#legacy = { + client: this.elasticsearchStart.legacy.client.asScoped(this.request), + }; + } + return this.#legacy; + } +} + +class CoreSavedObjectsRouteHandlerContext { + constructor( + private readonly savedObjectsStart: InternalSavedObjectsServiceStart, + private readonly request: KibanaRequest + ) {} + #scopedSavedObjectsClient?: SavedObjectsClientContract; + #typeRegistry?: ISavedObjectTypeRegistry; + + public get client() { + if (this.#scopedSavedObjectsClient == null) { + this.#scopedSavedObjectsClient = this.savedObjectsStart.getScopedClient(this.request); + } + return this.#scopedSavedObjectsClient; + } + + public get typeRegistry() { + if (this.#typeRegistry == null) { + this.#typeRegistry = this.savedObjectsStart.getTypeRegistry(); + } + return this.#typeRegistry; + } +} + +class CoreUiSettingsRouteHandlerContext { + #client?: IUiSettingsClient; + constructor( + private readonly uiSettingsStart: InternalUiSettingsServiceStart, + private readonly savedObjectsRouterHandlerContext: CoreSavedObjectsRouteHandlerContext + ) {} + + public get client() { + if (this.#client == null) { + this.#client = this.uiSettingsStart.asScopedToClient( + this.savedObjectsRouterHandlerContext.client + ); + } + return this.#client; + } +} + +export class CoreRouteHandlerContext { + #auditor?: Auditor; + + readonly elasticsearch: CoreElasticsearchRouteHandlerContext; + readonly savedObjects: CoreSavedObjectsRouteHandlerContext; + readonly uiSettings: CoreUiSettingsRouteHandlerContext; + + constructor( + private readonly coreStart: InternalCoreStart, + private readonly request: KibanaRequest + ) { + this.elasticsearch = new CoreElasticsearchRouteHandlerContext( + this.coreStart.elasticsearch, + this.request + ); + this.savedObjects = new CoreSavedObjectsRouteHandlerContext( + this.coreStart.savedObjects, + this.request + ); + this.uiSettings = new CoreUiSettingsRouteHandlerContext( + this.coreStart.uiSettings, + this.savedObjects + ); + } + + public get auditor() { + if (this.#auditor == null) { + this.#auditor = this.coreStart.auditTrail.asScoped(this.request); + } + return this.#auditor; + } +} diff --git a/src/core/server/elasticsearch/elasticsearch_config.ts b/src/core/server/elasticsearch/elasticsearch_config.ts index cac8c75a04486..cfc1edfbd318e 100644 --- a/src/core/server/elasticsearch/elasticsearch_config.ts +++ b/src/core/server/elasticsearch/elasticsearch_config.ts @@ -45,7 +45,6 @@ export const configSchema = schema.object({ hosts: schema.oneOf([hostURISchema, schema.arrayOf(hostURISchema, { minSize: 1 })], { defaultValue: 'http://localhost:9200', }), - preserveHost: schema.boolean({ defaultValue: true }), username: schema.maybe( schema.conditional( schema.contextRef('dist'), @@ -71,7 +70,6 @@ export const configSchema = schema.object({ shardTimeout: schema.duration({ defaultValue: '30s' }), requestTimeout: schema.duration({ defaultValue: '30s' }), pingTimeout: schema.duration({ defaultValue: schema.siblingRef('requestTimeout') }), - startupTimeout: schema.duration({ defaultValue: '5s' }), logQueries: schema.boolean({ defaultValue: false }), ssl: schema.object( { diff --git a/src/core/server/mocks.ts b/src/core/server/mocks.ts index e9b345317e999..3030cd9f4e0cb 100644 --- a/src/core/server/mocks.ts +++ b/src/core/server/mocks.ts @@ -67,7 +67,6 @@ export function pluginInitializerContextConfigMock(config: T) { shardTimeout: duration('30s'), requestTimeout: duration('30s'), pingTimeout: duration('30s'), - startupTimeout: duration('30s'), }, path: { data: '/tmp' }, savedObjects: { diff --git a/src/core/server/plugins/plugin_context.test.ts b/src/core/server/plugins/plugin_context.test.ts index cb4e8f20be982..7b2a5cd3b35f8 100644 --- a/src/core/server/plugins/plugin_context.test.ts +++ b/src/core/server/plugins/plugin_context.test.ts @@ -91,7 +91,6 @@ describe('createPluginInitializerContext', () => { shardTimeout: duration(30, 's'), requestTimeout: duration(30, 's'), pingTimeout: duration(30, 's'), - startupTimeout: duration(5, 's'), }, path: { data: fromRoot('data') }, savedObjects: { maxImportPayloadBytes: new ByteSizeValue(10485760) }, diff --git a/src/core/server/plugins/plugins_service.test.ts b/src/core/server/plugins/plugins_service.test.ts index d36fd2251176a..64a382e539fb0 100644 --- a/src/core/server/plugins/plugins_service.test.ts +++ b/src/core/server/plugins/plugins_service.test.ts @@ -102,35 +102,42 @@ const createPlugin = ( }); }; -describe('PluginsService', () => { - beforeEach(async () => { - mockPackage.raw = { - branch: 'feature-v1', - version: 'v1', - build: { - distributable: true, - number: 100, - sha: 'feature-v1-build-sha', - }, - }; +async function testSetup(options: { isDevClusterMaster?: boolean } = {}) { + mockPackage.raw = { + branch: 'feature-v1', + version: 'v1', + build: { + distributable: true, + number: 100, + sha: 'feature-v1-build-sha', + }, + }; - coreId = Symbol('core'); - env = Env.createDefault(REPO_ROOT, getEnvOptions()); + coreId = Symbol('core'); + env = Env.createDefault(REPO_ROOT, { + ...getEnvOptions(), + isDevClusterMaster: options.isDevClusterMaster ?? false, + }); - config$ = new BehaviorSubject>({ plugins: { initialize: true } }); - const rawConfigService = rawConfigServiceMock.create({ rawConfig$: config$ }); - configService = new ConfigService(rawConfigService, env, logger); - await configService.setSchema(config.path, config.schema); - pluginsService = new PluginsService({ coreId, env, logger, configService }); + config$ = new BehaviorSubject>({ plugins: { initialize: true } }); + const rawConfigService = rawConfigServiceMock.create({ rawConfig$: config$ }); + configService = new ConfigService(rawConfigService, env, logger); + await configService.setSchema(config.path, config.schema); + pluginsService = new PluginsService({ coreId, env, logger, configService }); - [mockPluginSystem] = MockPluginsSystem.mock.instances as any; - mockPluginSystem.uiPlugins.mockReturnValue(new Map()); + [mockPluginSystem] = MockPluginsSystem.mock.instances as any; + mockPluginSystem.uiPlugins.mockReturnValue(new Map()); - environmentSetup = environmentServiceMock.createSetupContract(); - }); + environmentSetup = environmentServiceMock.createSetupContract(); +} - afterEach(() => { - jest.clearAllMocks(); +afterEach(() => { + jest.clearAllMocks(); +}); + +describe('PluginsService', () => { + beforeEach(async () => { + await testSetup(); }); describe('#discover()', () => { @@ -613,3 +620,29 @@ describe('PluginsService', () => { }); }); }); + +describe('PluginService when isDevClusterMaster is true', () => { + beforeEach(async () => { + await testSetup({ + isDevClusterMaster: true, + }); + }); + + describe('#discover()', () => { + it('does not try to run discovery', async () => { + await expect(pluginsService.discover({ environment: environmentSetup })).resolves + .toMatchInlineSnapshot(` + Object { + "pluginTree": undefined, + "uiPlugins": Object { + "browserConfigs": Map {}, + "internal": Map {}, + "public": Map {}, + }, + } + `); + + expect(mockDiscover).not.toHaveBeenCalled(); + }); + }); +}); diff --git a/src/core/server/plugins/plugins_service.ts b/src/core/server/plugins/plugins_service.ts index e8fe42ee491ca..a1062bde7765f 100644 --- a/src/core/server/plugins/plugins_service.ts +++ b/src/core/server/plugins/plugins_service.ts @@ -18,7 +18,7 @@ */ import Path from 'path'; -import { Observable } from 'rxjs'; +import { Observable, EMPTY } from 'rxjs'; import { filter, first, map, mergeMap, tap, toArray } from 'rxjs/operators'; import { pick } from '@kbn/std'; @@ -86,9 +86,11 @@ export class PluginsService implements CoreService; private readonly pluginConfigDescriptors = new Map(); private readonly uiPluginInternalInfo = new Map(); + private readonly discoveryDisabled: boolean; constructor(private readonly coreContext: CoreContext) { this.log = coreContext.logger.get('plugins-service'); + this.discoveryDisabled = coreContext.env.isDevClusterMaster; this.pluginsSystem = new PluginsSystem(coreContext); this.configService = coreContext.configService; this.config$ = coreContext.configService @@ -97,13 +99,17 @@ export class PluginsService implements CoreService { }) ) ), + namespaces: schema.maybe(schema.arrayOf(schema.string(), { minSize: 1 })), }) ), }, diff --git a/src/core/server/saved_objects/routes/create.ts b/src/core/server/saved_objects/routes/create.ts index 6cf906a3b2895..191dbfaa0dbf1 100644 --- a/src/core/server/saved_objects/routes/create.ts +++ b/src/core/server/saved_objects/routes/create.ts @@ -44,15 +44,16 @@ export const registerCreateRoute = (router: IRouter) => { }) ) ), + namespaces: schema.maybe(schema.arrayOf(schema.string(), { minSize: 1 })), }), }, }, router.handleLegacyErrors(async (context, req, res) => { const { type, id } = req.params; const { overwrite } = req.query; - const { attributes, migrationVersion, references } = req.body; + const { attributes, migrationVersion, references, namespaces } = req.body; - const options = { id, overwrite, migrationVersion, references }; + const options = { id, overwrite, migrationVersion, references, namespaces }; const result = await context.core.savedObjects.client.create(type, attributes, options); return res.ok({ body: result }); }) diff --git a/src/core/server/saved_objects/routes/delete.ts b/src/core/server/saved_objects/routes/delete.ts index d119455336212..d99397d2a050c 100644 --- a/src/core/server/saved_objects/routes/delete.ts +++ b/src/core/server/saved_objects/routes/delete.ts @@ -29,11 +29,15 @@ export const registerDeleteRoute = (router: IRouter) => { type: schema.string(), id: schema.string(), }), + query: schema.object({ + force: schema.maybe(schema.boolean()), + }), }, }, router.handleLegacyErrors(async (context, req, res) => { const { type, id } = req.params; - const result = await context.core.savedObjects.client.delete(type, id); + const { force } = req.query; + const result = await context.core.savedObjects.client.delete(type, id, { force }); return res.ok({ body: result }); }) ); diff --git a/src/core/server/saved_objects/routes/integration_tests/delete.test.ts b/src/core/server/saved_objects/routes/integration_tests/delete.test.ts index a58f400ec3e1d..ff8642a34929f 100644 --- a/src/core/server/saved_objects/routes/integration_tests/delete.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/delete.test.ts @@ -58,6 +58,19 @@ describe('DELETE /api/saved_objects/{type}/{id}', () => { .delete('/api/saved_objects/index-pattern/logstash-*') .expect(200); - expect(savedObjectsClient.delete).toHaveBeenCalledWith('index-pattern', 'logstash-*'); + expect(savedObjectsClient.delete).toHaveBeenCalledWith('index-pattern', 'logstash-*', { + force: undefined, + }); + }); + + it('can specify `force` option', async () => { + await supertest(httpSetup.server.listener) + .delete('/api/saved_objects/index-pattern/logstash-*') + .query({ force: true }) + .expect(200); + + expect(savedObjectsClient.delete).toHaveBeenCalledWith('index-pattern', 'logstash-*', { + force: true, + }); }); }); diff --git a/src/core/server/saved_objects/service/lib/repository.test.js b/src/core/server/saved_objects/service/lib/repository.test.js index 0e72ad2fec06c..10c7f143e52b9 100644 --- a/src/core/server/saved_objects/service/lib/repository.test.js +++ b/src/core/server/saved_objects/service/lib/repository.test.js @@ -20,6 +20,7 @@ import { SavedObjectsRepository } from './repository'; import * as getSearchDslNS from './search_dsl/search_dsl'; import { SavedObjectsErrorHelpers } from './errors'; +import { ALL_NAMESPACES_STRING } from './utils'; import { SavedObjectsSerializer } from '../../serialization'; import { encodeHitVersion } from '../../version'; import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry'; @@ -634,6 +635,32 @@ describe('SavedObjectsRepository', () => { await test(namespace); }); + it(`adds namespaces instead of namespace`, async () => { + const test = async (namespace) => { + const ns2 = 'bar-namespace'; + const ns3 = 'baz-namespace'; + const objects = [ + { ...obj1, type: MULTI_NAMESPACE_TYPE, namespaces: [ns2] }, + { ...obj2, type: MULTI_NAMESPACE_TYPE, namespaces: [ns3] }, + ]; + await bulkCreateSuccess(objects, { namespace, overwrite: true }); + const body = [ + expect.any(Object), + expect.objectContaining({ namespaces: [ns2] }), + expect.any(Object), + expect.objectContaining({ namespaces: [ns3] }), + ]; + expect(client.bulk).toHaveBeenCalledWith( + expect.objectContaining({ body }), + expect.anything() + ); + client.bulk.mockClear(); + client.mget.mockClear(); + }; + await test(undefined); + await test(namespace); + }); + it(`doesn't add namespaces to request body for any types that are not multi-namespace`, async () => { const test = async (namespace) => { const objects = [obj1, { ...obj2, type: NAMESPACE_AGNOSTIC_TYPE }]; @@ -725,6 +752,40 @@ describe('SavedObjectsRepository', () => { }); }; + it(`throws when options.namespace is '*'`, async () => { + await expect( + savedObjectsRepository.bulkCreate([obj3], { namespace: ALL_NAMESPACES_STRING }) + ).rejects.toThrowError(createBadRequestError('"options.namespace" cannot be "*"')); + }); + + it(`returns error when namespaces is used with a non-multi-namespace object`, async () => { + const test = async (objType) => { + const obj = { ...obj3, type: objType, namespaces: [] }; + await bulkCreateError( + obj, + undefined, + expectErrorResult( + obj, + createBadRequestError('"namespaces" can only be used on multi-namespace types') + ) + ); + }; + await test('dashboard'); + await test(NAMESPACE_AGNOSTIC_TYPE); + }); + + it(`throws when options.namespaces is used with a multi-namespace type and is empty`, async () => { + const obj = { ...obj3, type: MULTI_NAMESPACE_TYPE, namespaces: [] }; + await bulkCreateError( + obj, + undefined, + expectErrorResult( + obj, + createBadRequestError('"namespaces" must be a non-empty array of strings') + ) + ); + }); + it(`returns error when type is invalid`, async () => { const obj = { ...obj3, type: 'unknownType' }; await bulkCreateError(obj, undefined, expectErrorInvalidType(obj)); @@ -1042,6 +1103,13 @@ describe('SavedObjectsRepository', () => { }); }; + it(`throws when options.namespace is '*'`, async () => { + const obj = { type: 'dashboard', id: 'three' }; + await expect( + savedObjectsRepository.bulkGet([obj], { namespace: ALL_NAMESPACES_STRING }) + ).rejects.toThrowError(createBadRequestError('"options.namespace" cannot be "*"')); + }); + it(`returns error when type is invalid`, async () => { const obj = { type: 'unknownType', id: 'three' }; await bulkGetErrorInvalidType([obj1, obj, obj2]); @@ -1467,6 +1535,12 @@ describe('SavedObjectsRepository', () => { }); }; + it(`throws when options.namespace is '*'`, async () => { + await expect( + savedObjectsRepository.bulkUpdate([obj], { namespace: ALL_NAMESPACES_STRING }) + ).rejects.toThrowError(createBadRequestError('"options.namespace" cannot be "*"')); + }); + it(`returns error when type is invalid`, async () => { const _obj = { ...obj, type: 'unknownType' }; await bulkUpdateError(_obj, undefined, expectErrorNotFound(_obj)); @@ -1477,6 +1551,15 @@ describe('SavedObjectsRepository', () => { await bulkUpdateError(_obj, undefined, expectErrorNotFound(_obj)); }); + it(`returns error when object namespace is '*'`, async () => { + const _obj = { ...obj, namespace: '*' }; + await bulkUpdateError( + _obj, + undefined, + expectErrorResult(obj, createBadRequestError('"namespace" cannot be "*"')) + ); + }); + it(`returns error when ES is unable to find the document (mget)`, async () => { const _obj = { ...obj, type: MULTI_NAMESPACE_TYPE, found: false }; const mgetResponse = getMockMgetResponse([_obj]); @@ -1630,7 +1713,7 @@ describe('SavedObjectsRepository', () => { ); }; - describe('cluster calls', () => { + describe('client calls', () => { it(`doesn't make a cluster call if the objects array is empty`, async () => { await checkConflicts([]); expect(client.mget).not.toHaveBeenCalled(); @@ -1662,6 +1745,14 @@ describe('SavedObjectsRepository', () => { }); }); + describe('errors', () => { + it(`throws when options.namespace is '*'`, async () => { + await expect( + savedObjectsRepository.checkConflicts([obj1], { namespace: ALL_NAMESPACES_STRING }) + ).rejects.toThrowError(createBadRequestError('"options.namespace" cannot be "*"')); + }); + }); + describe('returns', () => { it(`expected results`, async () => { const unknownTypeObj = { type: 'unknownType', id: 'three' }; @@ -1858,21 +1949,23 @@ describe('SavedObjectsRepository', () => { ); }); - it(`prepends namespace to the id when providing namespace for single-namespace type`, async () => { + it(`prepends namespace to the id and adds namespace to the body when providing namespace for single-namespace type`, async () => { await createSuccess(type, attributes, { id, namespace }); expect(client.create).toHaveBeenCalledWith( expect.objectContaining({ id: `${namespace}:${type}:${id}`, + body: expect.objectContaining({ namespace }), }), expect.anything() ); }); - it(`doesn't prepend namespace to the id when providing no namespace for single-namespace type`, async () => { + it(`doesn't prepend namespace to the id or add namespace to the body when providing no namespace for single-namespace type`, async () => { await createSuccess(type, attributes, { id }); expect(client.create).toHaveBeenCalledWith( expect.objectContaining({ id: `${type}:${id}`, + body: expect.not.objectContaining({ namespace: expect.anything() }), }), expect.anything() ); @@ -1883,25 +1976,44 @@ describe('SavedObjectsRepository', () => { expect(client.create).toHaveBeenCalledWith( expect.objectContaining({ id: `${type}:${id}`, + body: expect.not.objectContaining({ namespace: expect.anything() }), }), expect.anything() ); }); - it(`doesn't prepend namespace to the id when not using single-namespace type`, async () => { - await createSuccess(NAMESPACE_AGNOSTIC_TYPE, attributes, { id, namespace }); + it(`doesn't prepend namespace to the id and adds namespaces to body when using multi-namespace type`, async () => { + await createSuccess(MULTI_NAMESPACE_TYPE, attributes, { id, namespace }); expect(client.create).toHaveBeenCalledWith( expect.objectContaining({ - id: `${NAMESPACE_AGNOSTIC_TYPE}:${id}`, + id: `${MULTI_NAMESPACE_TYPE}:${id}`, + body: expect.objectContaining({ namespaces: [namespace] }), }), expect.anything() ); - client.create.mockClear(); + }); - await createSuccess(MULTI_NAMESPACE_TYPE, attributes, { id, namespace }); + it(`adds namespaces instead of namespace`, async () => { + const options = { id, namespace, namespaces: ['bar-namespace', 'baz-namespace'] }; + await createSuccess(MULTI_NAMESPACE_TYPE, attributes, options); expect(client.create).toHaveBeenCalledWith( expect.objectContaining({ id: `${MULTI_NAMESPACE_TYPE}:${id}`, + body: expect.objectContaining({ namespaces: options.namespaces }), + }), + expect.anything() + ); + }); + + it(`doesn't prepend namespace to the id or add namespace or namespaces fields when using namespace-agnostic type`, async () => { + await createSuccess(NAMESPACE_AGNOSTIC_TYPE, attributes, { id, namespace }); + expect(client.create).toHaveBeenCalledWith( + expect.objectContaining({ + id: `${NAMESPACE_AGNOSTIC_TYPE}:${id}`, + body: expect.not.objectContaining({ + namespace: expect.anything(), + namespaces: expect.anything(), + }), }), expect.anything() ); @@ -1909,6 +2021,32 @@ describe('SavedObjectsRepository', () => { }); describe('errors', () => { + it(`throws when options.namespaces is used with a non-multi-namespace object`, async () => { + const test = async (objType) => { + await expect( + savedObjectsRepository.create(objType, attributes, { namespaces: [namespace] }) + ).rejects.toThrowError( + createBadRequestError('"options.namespaces" can only be used on multi-namespace types') + ); + }; + await test('dashboard'); + await test(NAMESPACE_AGNOSTIC_TYPE); + }); + + it(`throws when options.namespaces is used with a multi-namespace type and is empty`, async () => { + await expect( + savedObjectsRepository.create(MULTI_NAMESPACE_TYPE, attributes, { namespaces: [] }) + ).rejects.toThrowError( + createBadRequestError('"options.namespaces" must be a non-empty array of strings') + ); + }); + + it(`throws when options.namespace is '*'`, async () => { + await expect( + savedObjectsRepository.create(type, attributes, { namespace: ALL_NAMESPACES_STRING }) + ).rejects.toThrowError(createBadRequestError('"options.namespace" cannot be "*"')); + }); + it(`throws when type is invalid`, async () => { await expect(savedObjectsRepository.create('unknownType', attributes)).rejects.toThrowError( createUnsupportedTypeError('unknownType') @@ -2043,31 +2181,17 @@ describe('SavedObjectsRepository', () => { describe('client calls', () => { it(`should use the ES delete action when not using a multi-namespace type`, async () => { await deleteSuccess(type, id); + expect(client.get).not.toHaveBeenCalled(); expect(client.delete).toHaveBeenCalledTimes(1); }); - it(`should use ES get action then delete action when using a multi-namespace type with no namespaces remaining`, async () => { + it(`should use ES get action then delete action when using a multi-namespace type`, async () => { await deleteSuccess(MULTI_NAMESPACE_TYPE, id); expect(client.get).toHaveBeenCalledTimes(1); expect(client.delete).toHaveBeenCalledTimes(1); }); - it(`should use ES get action then update action when using a multi-namespace type with one or more namespaces remaining`, async () => { - const mockResponse = getMockGetResponse({ type: MULTI_NAMESPACE_TYPE, id }); - mockResponse._source.namespaces = ['default', 'some-other-nameespace']; - client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(mockResponse) - ); - client.update.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({ result: 'updated' }) - ); - - await savedObjectsRepository.delete(MULTI_NAMESPACE_TYPE, id); - expect(client.get).toHaveBeenCalledTimes(1); - expect(client.update).toHaveBeenCalledTimes(1); - }); - - it(`includes the version of the existing document when type is multi-namespace`, async () => { + it(`includes the version of the existing document when using a multi-namespace type`, async () => { await deleteSuccess(MULTI_NAMESPACE_TYPE, id); const versionProperties = { if_seq_no: mockVersionProps._seq_no, @@ -2134,6 +2258,12 @@ describe('SavedObjectsRepository', () => { ); }; + it(`throws when options.namespace is '*'`, async () => { + await expect( + savedObjectsRepository.delete(type, id, { namespace: ALL_NAMESPACES_STRING }) + ).rejects.toThrowError(createBadRequestError('"options.namespace" cannot be "*"')); + }); + it(`throws when type is invalid`, async () => { await expectNotFoundError('unknownType', id); expect(client.delete).not.toHaveBeenCalled(); @@ -2169,19 +2299,32 @@ describe('SavedObjectsRepository', () => { expect(client.get).toHaveBeenCalledTimes(1); }); - it(`throws when ES is unable to find the document during update`, async () => { - const mockResponse = getMockGetResponse({ type: MULTI_NAMESPACE_TYPE, id }); - mockResponse._source.namespaces = ['default', 'some-other-nameespace']; + it(`throws when the type is multi-namespace and the document has multiple namespaces and the force option is not enabled`, async () => { + const response = getMockGetResponse({ type: MULTI_NAMESPACE_TYPE, id, namespace }); + response._source.namespaces = [namespace, 'bar-namespace']; client.get.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise(mockResponse) + elasticsearchClientMock.createSuccessTransportRequestPromise(response) ); - client.update.mockResolvedValueOnce( - elasticsearchClientMock.createSuccessTransportRequestPromise({}, { statusCode: 404 }) + await expect( + savedObjectsRepository.delete(MULTI_NAMESPACE_TYPE, id, { namespace }) + ).rejects.toThrowError( + 'Unable to delete saved object that exists in multiple namespaces, use the `force` option to delete it anyway' ); + expect(client.get).toHaveBeenCalledTimes(1); + }); - await expectNotFoundError(MULTI_NAMESPACE_TYPE, id); + it(`throws when the type is multi-namespace and the document has all namespaces and the force option is not enabled`, async () => { + const response = getMockGetResponse({ type: MULTI_NAMESPACE_TYPE, id, namespace }); + response._source.namespaces = ['*']; + client.get.mockResolvedValueOnce( + elasticsearchClientMock.createSuccessTransportRequestPromise(response) + ); + await expect( + savedObjectsRepository.delete(MULTI_NAMESPACE_TYPE, id, { namespace }) + ).rejects.toThrowError( + 'Unable to delete saved object that exists in multiple namespaces, use the `force` option to delete it anyway' + ); expect(client.get).toHaveBeenCalledTimes(1); - expect(client.update).toHaveBeenCalledTimes(1); }); it(`throws when ES is unable to find the document during delete`, async () => { @@ -2267,7 +2410,7 @@ describe('SavedObjectsRepository', () => { }); describe('errors', () => { - it(`throws when namespace is not a string`, async () => { + it(`throws when namespace is not a string or is '*'`, async () => { const test = async (namespace) => { await expect(savedObjectsRepository.deleteByNamespace(namespace)).rejects.toThrowError( `namespace is required, and must be a string` @@ -2278,6 +2421,7 @@ describe('SavedObjectsRepository', () => { await test(['namespace']); await test(123); await test(true); + await test(ALL_NAMESPACES_STRING); }); }); @@ -2876,6 +3020,12 @@ describe('SavedObjectsRepository', () => { ); }; + it(`throws when options.namespace is '*'`, async () => { + await expect( + savedObjectsRepository.get(type, id, { namespace: ALL_NAMESPACES_STRING }) + ).rejects.toThrowError(createBadRequestError('"options.namespace" cannot be "*"')); + }); + it(`throws when type is invalid`, async () => { await expectNotFoundError('unknownType', id); expect(client.get).not.toHaveBeenCalled(); @@ -3067,6 +3217,14 @@ describe('SavedObjectsRepository', () => { ); }; + it(`throws when options.namespace is '*'`, async () => { + await expect( + savedObjectsRepository.incrementCounter(type, id, field, { + namespace: ALL_NAMESPACES_STRING, + }) + ).rejects.toThrowError(createBadRequestError('"options.namespace" cannot be "*"')); + }); + it(`throws when type is not a string`, async () => { const test = async (type) => { await expect( @@ -3723,6 +3881,12 @@ describe('SavedObjectsRepository', () => { ); }; + it(`throws when options.namespace is '*'`, async () => { + await expect( + savedObjectsRepository.update(type, id, attributes, { namespace: ALL_NAMESPACES_STRING }) + ).rejects.toThrowError(createBadRequestError('"options.namespace" cannot be "*"')); + }); + it(`throws when type is invalid`, async () => { await expectNotFoundError('unknownType', id); expect(client.update).not.toHaveBeenCalled(); diff --git a/src/core/server/saved_objects/service/lib/repository.ts b/src/core/server/saved_objects/service/lib/repository.ts index a83c86e585628..bae96ceec2783 100644 --- a/src/core/server/saved_objects/service/lib/repository.ts +++ b/src/core/server/saved_objects/service/lib/repository.ts @@ -67,7 +67,12 @@ import { } from '../../types'; import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry'; import { validateConvertFilterToKueryNode } from './filter_utils'; -import { FIND_DEFAULT_PAGE, FIND_DEFAULT_PER_PAGE, SavedObjectsUtils } from './utils'; +import { + ALL_NAMESPACES_STRING, + FIND_DEFAULT_PAGE, + FIND_DEFAULT_PER_PAGE, + SavedObjectsUtils, +} from './utils'; // BEWARE: The SavedObjectClient depends on the implementation details of the SavedObjectsRepository // so any breaking changes to this repository are considered breaking changes to the SavedObjectsClient. @@ -225,10 +230,23 @@ export class SavedObjectsRepository { references = [], refresh = DEFAULT_REFRESH_SETTING, originId, + namespaces, version, } = options; const namespace = normalizeNamespace(options.namespace); + if (namespaces) { + if (!this._registry.isMultiNamespace(type)) { + throw SavedObjectsErrorHelpers.createBadRequestError( + '"options.namespaces" can only be used on multi-namespace types' + ); + } else if (!namespaces.length) { + throw SavedObjectsErrorHelpers.createBadRequestError( + '"options.namespaces" must be a non-empty array of strings' + ); + } + } + if (!this._allowedTypes.includes(type)) { throw SavedObjectsErrorHelpers.createUnsupportedTypeError(type); } @@ -242,9 +260,11 @@ export class SavedObjectsRepository { } else if (this._registry.isMultiNamespace(type)) { if (id && overwrite) { // we will overwrite a multi-namespace saved object if it exists; if that happens, ensure we preserve its included namespaces - savedObjectNamespaces = await this.preflightGetNamespaces(type, id, namespace); + // note: this check throws an error if the object is found but does not exist in this namespace + const existingNamespaces = await this.preflightGetNamespaces(type, id, namespace); + savedObjectNamespaces = namespaces || existingNamespaces; } else { - savedObjectNamespaces = getSavedObjectNamespaces(namespace); + savedObjectNamespaces = namespaces || getSavedObjectNamespaces(namespace); } } @@ -300,14 +320,25 @@ export class SavedObjectsRepository { let bulkGetRequestIndexCounter = 0; const expectedResults: Either[] = objects.map((object) => { + let error: DecoratedError | undefined; if (!this._allowedTypes.includes(object.type)) { + error = SavedObjectsErrorHelpers.createUnsupportedTypeError(object.type); + } else if (object.namespaces) { + if (!this._registry.isMultiNamespace(object.type)) { + error = SavedObjectsErrorHelpers.createBadRequestError( + '"namespaces" can only be used on multi-namespace types' + ); + } else if (!object.namespaces.length) { + error = SavedObjectsErrorHelpers.createBadRequestError( + '"namespaces" must be a non-empty array of strings' + ); + } + } + + if (error) { return { tag: 'Left' as 'Left', - error: { - id: object.id, - type: object.type, - error: errorContent(SavedObjectsErrorHelpers.createUnsupportedTypeError(object.type)), - }, + error: { id: object.id, type: object.type, error: errorContent(error) }, }; } @@ -357,7 +388,7 @@ export class SavedObjectsRepository { let versionProperties; const { esRequestIndex, - object: { version, ...object }, + object: { namespaces, version, ...object }, method, } = expectedBulkGetResult.value; if (esRequestIndex !== undefined) { @@ -378,13 +409,14 @@ export class SavedObjectsRepository { }, }; } - savedObjectNamespaces = getSavedObjectNamespaces(namespace, docFound && actualResult); + savedObjectNamespaces = + namespaces || getSavedObjectNamespaces(namespace, docFound && actualResult); versionProperties = getExpectedVersionProperties(version, actualResult); } else { if (this._registry.isSingleNamespace(object.type)) { savedObjectNamespace = namespace; } else if (this._registry.isMultiNamespace(object.type)) { - savedObjectNamespaces = getSavedObjectNamespaces(namespace); + savedObjectNamespaces = namespaces || getSavedObjectNamespaces(namespace); } versionProperties = getExpectedVersionProperties(version); } @@ -553,7 +585,7 @@ export class SavedObjectsRepository { throw SavedObjectsErrorHelpers.createGenericNotFoundError(type, id); } - const { refresh = DEFAULT_REFRESH_SETTING } = options; + const { refresh = DEFAULT_REFRESH_SETTING, force } = options; const namespace = normalizeNamespace(options.namespace); const rawId = this._serializer.generateRawId(namespace, type, id); @@ -561,38 +593,14 @@ export class SavedObjectsRepository { if (this._registry.isMultiNamespace(type)) { preflightResult = await this.preflightCheckIncludesNamespace(type, id, namespace); - const existingNamespaces = getSavedObjectNamespaces(undefined, preflightResult); - const remainingNamespaces = existingNamespaces?.filter( - (x) => x !== SavedObjectsUtils.namespaceIdToString(namespace) - ); - - if (remainingNamespaces?.length) { - // if there is 1 or more namespace remaining, update the saved object - const time = this._getCurrentTime(); - - const doc = { - updated_at: time, - namespaces: remainingNamespaces, - }; - - const { statusCode } = await this.client.update( - { - id: rawId, - index: this.getIndexForType(type), - ...getExpectedVersionProperties(undefined, preflightResult), - refresh, - body: { - doc, - }, - }, - { ignore: [404] } + const existingNamespaces = getSavedObjectNamespaces(undefined, preflightResult) ?? []; + if ( + !force && + (existingNamespaces.length > 1 || existingNamespaces.includes(ALL_NAMESPACES_STRING)) + ) { + throw SavedObjectsErrorHelpers.createBadRequestError( + 'Unable to delete saved object that exists in multiple namespaces, use the `force` option to delete it anyway' ); - - if (statusCode === 404) { - // see "404s from missing index" above - throw SavedObjectsErrorHelpers.createGenericNotFoundError(type, id); - } - return {}; } } @@ -637,8 +645,8 @@ export class SavedObjectsRepository { namespace: string, options: SavedObjectsDeleteByNamespaceOptions = {} ): Promise { - if (!namespace || typeof namespace !== 'string') { - throw new TypeError(`namespace is required, and must be a string`); + if (!namespace || typeof namespace !== 'string' || namespace === '*') { + throw new TypeError(`namespace is required, and must be a string that is not equal to '*'`); } const allTypes = Object.keys(getRootPropertiesObjects(this._mappings)); @@ -1253,6 +1261,19 @@ export class SavedObjectsRepository { } const { attributes, references, version, namespace: objectNamespace } = object; + + if (objectNamespace === ALL_NAMESPACES_STRING) { + return { + tag: 'Left' as 'Left', + error: { + id, + type, + error: errorContent( + SavedObjectsErrorHelpers.createBadRequestError('"namespace" cannot be "*"') + ), + }, + }; + } // `objectNamespace` is a namespace string, while `namespace` is a namespace ID. // The object namespace string, if defined, will supersede the operation's namespace ID. @@ -1568,7 +1589,10 @@ export class SavedObjectsRepository { } const namespaces = raw._source.namespaces; - return namespaces?.includes(SavedObjectsUtils.namespaceIdToString(namespace)) ?? false; + const existsInNamespace = + namespaces?.includes(SavedObjectsUtils.namespaceIdToString(namespace)) || + namespaces?.includes('*'); + return existsInNamespace ?? false; } /** @@ -1695,8 +1719,15 @@ function getSavedObjectNamespaces( * Ensure that a namespace is always in its namespace ID representation. * This allows `'default'` to be used interchangeably with `undefined`. */ -const normalizeNamespace = (namespace?: string) => - namespace === undefined ? namespace : SavedObjectsUtils.namespaceStringToId(namespace); +const normalizeNamespace = (namespace?: string) => { + if (namespace === ALL_NAMESPACES_STRING) { + throw SavedObjectsErrorHelpers.createBadRequestError('"options.namespace" cannot be "*"'); + } else if (namespace === undefined) { + return namespace; + } else { + return SavedObjectsUtils.namespaceStringToId(namespace); + } +}; /** * Extracts the contents of a decorated error to return the attributes for bulk operations. diff --git a/src/core/server/saved_objects/service/lib/search_dsl/query_params.test.ts b/src/core/server/saved_objects/service/lib/search_dsl/query_params.test.ts index e13c67a720400..330fa5066051f 100644 --- a/src/core/server/saved_objects/service/lib/search_dsl/query_params.test.ts +++ b/src/core/server/saved_objects/service/lib/search_dsl/query_params.test.ts @@ -22,6 +22,7 @@ import { esKuery } from '../../../es_query'; type KueryNode = any; import { typeRegistryMock } from '../../../saved_objects_type_registry.mock'; +import { ALL_NAMESPACES_STRING } from '../utils'; import { getQueryParams } from './query_params'; const registry = typeRegistryMock.create(); @@ -52,9 +53,10 @@ const ALL_TYPE_SUBSETS = ALL_TYPES.reduce( const createTypeClause = (type: string, namespaces?: string[]) => { if (registry.isMultiNamespace(type)) { + const array = [...(namespaces ?? ['default']), ALL_NAMESPACES_STRING]; return { bool: { - must: expect.arrayContaining([{ terms: { namespaces: namespaces ?? ['default'] } }]), + must: expect.arrayContaining([{ terms: { namespaces: array } }]), must_not: [{ exists: { field: 'namespace' } }], }, }; diff --git a/src/core/server/saved_objects/service/lib/search_dsl/query_params.ts b/src/core/server/saved_objects/service/lib/search_dsl/query_params.ts index eaddc05fa921c..8bd9c7d8312ee 100644 --- a/src/core/server/saved_objects/service/lib/search_dsl/query_params.ts +++ b/src/core/server/saved_objects/service/lib/search_dsl/query_params.ts @@ -22,7 +22,7 @@ type KueryNode = any; import { getRootPropertiesObjects, IndexMapping } from '../../../mappings'; import { ISavedObjectTypeRegistry } from '../../../saved_objects_type_registry'; -import { DEFAULT_NAMESPACE_STRING } from '../utils'; +import { ALL_NAMESPACES_STRING, DEFAULT_NAMESPACE_STRING } from '../utils'; /** * Gets the types based on the type. Uses mappings to support @@ -84,7 +84,10 @@ function getClauseForType( if (registry.isMultiNamespace(type)) { return { bool: { - must: [{ term: { type } }, { terms: { namespaces } }], + must: [ + { term: { type } }, + { terms: { namespaces: [...namespaces, ALL_NAMESPACES_STRING] } }, + ], must_not: [{ exists: { field: 'namespace' } }], }, }; diff --git a/src/core/server/saved_objects/service/lib/utils.ts b/src/core/server/saved_objects/service/lib/utils.ts index 3efe8614da1d7..69abc37089218 100644 --- a/src/core/server/saved_objects/service/lib/utils.ts +++ b/src/core/server/saved_objects/service/lib/utils.ts @@ -21,6 +21,7 @@ import { SavedObjectsFindOptions } from '../../types'; import { SavedObjectsFindResponse } from '..'; export const DEFAULT_NAMESPACE_STRING = 'default'; +export const ALL_NAMESPACES_STRING = '*'; export const FIND_DEFAULT_PAGE = 1; export const FIND_DEFAULT_PER_PAGE = 20; diff --git a/src/core/server/saved_objects/service/saved_objects_client.ts b/src/core/server/saved_objects/service/saved_objects_client.ts index 8c96116de49cb..d2b3b89b928c7 100644 --- a/src/core/server/saved_objects/service/saved_objects_client.ts +++ b/src/core/server/saved_objects/service/saved_objects_client.ts @@ -50,6 +50,13 @@ export interface SavedObjectsCreateOptions extends SavedObjectsBaseOptions { refresh?: MutatingOperationRefreshSetting; /** Optional ID of the original saved object, if this object's `id` was regenerated */ originId?: string; + /** + * Optional initial namespaces for the object to be created in. If this is defined, it will supersede the namespace ID that is in + * {@link SavedObjectsCreateOptions}. + * + * Note: this can only be used for multi-namespace object types. + */ + namespaces?: string[]; } /** @@ -66,6 +73,13 @@ export interface SavedObjectsBulkCreateObject { migrationVersion?: SavedObjectsMigrationVersion; /** Optional ID of the original saved object, if this object's `id` was regenerated */ originId?: string; + /** + * Optional initial namespaces for the object to be created in. If this is defined, it will supersede the namespace ID that is in + * {@link SavedObjectsCreateOptions}. + * + * Note: this can only be used for multi-namespace object types. + */ + namespaces?: string[]; } /** @@ -211,6 +225,8 @@ export interface SavedObjectsBulkUpdateOptions extends SavedObjectsBaseOptions { export interface SavedObjectsDeleteOptions extends SavedObjectsBaseOptions { /** The Elasticsearch Refresh setting for this operation */ refresh?: MutatingOperationRefreshSetting; + /** Force deletion of an object that exists in multiple namespaces */ + force?: boolean; } /** diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index cc51d27589ce7..7742dad150cfa 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -348,7 +348,6 @@ export const config: { sniffInterval: Type; sniffOnConnectionFault: Type; hosts: Type; - preserveHost: Type; username: Type; password: Type; requestHeadersWhitelist: Type; @@ -356,7 +355,6 @@ export const config: { shardTimeout: Type; requestTimeout: Type; pingTimeout: Type; - startupTimeout: Type; logQueries: Type; ssl: import("@kbn/config-schema").ObjectType<{ verificationMode: Type<"none" | "certificate" | "full">; @@ -1822,6 +1820,7 @@ export interface SavedObjectsBulkCreateObject { // (undocumented) id?: string; migrationVersion?: SavedObjectsMigrationVersion; + namespaces?: string[]; originId?: string; // (undocumented) references?: SavedObjectReference[]; @@ -1979,6 +1978,7 @@ export interface SavedObjectsCoreFieldMapping { export interface SavedObjectsCreateOptions extends SavedObjectsBaseOptions { id?: string; migrationVersion?: SavedObjectsMigrationVersion; + namespaces?: string[]; originId?: string; overwrite?: boolean; // (undocumented) @@ -2004,6 +2004,7 @@ export interface SavedObjectsDeleteFromNamespacesResponse { // @public (undocumented) export interface SavedObjectsDeleteOptions extends SavedObjectsBaseOptions { + force?: boolean; refresh?: MutatingOperationRefreshSetting; } diff --git a/src/core/server/server.test.ts b/src/core/server/server.test.ts index 3258840d09df2..51defb7d0392e 100644 --- a/src/core/server/server.test.ts +++ b/src/core/server/server.test.ts @@ -215,3 +215,20 @@ test(`doesn't setup core services if legacy config validation fails`, async () = expect(mockStatusService.setup).not.toHaveBeenCalled(); expect(mockLoggingService.setup).not.toHaveBeenCalled(); }); + +test(`doesn't validate config if env.isDevClusterMaster is true`, async () => { + const devParentEnv = Env.createDefault(REPO_ROOT, { + ...getEnvOptions(), + isDevClusterMaster: true, + }); + + const server = new Server(rawConfigService, devParentEnv, logger); + await server.setup(); + + expect(mockEnsureValidConfiguration).not.toHaveBeenCalled(); + expect(mockContextService.setup).toHaveBeenCalled(); + expect(mockAuditTrailService.setup).toHaveBeenCalled(); + expect(mockHttpService.setup).toHaveBeenCalled(); + expect(mockElasticsearchService.setup).toHaveBeenCalled(); + expect(mockSavedObjectsService.setup).toHaveBeenCalled(); +}); diff --git a/src/core/server/server.ts b/src/core/server/server.ts index 5935636d54f9d..600f45e0b50da 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ - +import apm from 'elastic-apm-node'; import { config as pathConfig } from '@kbn/utils'; import { mapToObject } from '@kbn/std'; import { ConfigService, Env, RawConfigurationProvider, coreDeprecationProvider } from './config'; @@ -48,6 +48,7 @@ import { config as statusConfig } from './status'; import { ContextService } from './context'; import { RequestHandlerContext } from '.'; import { InternalCoreSetup, InternalCoreStart, ServiceConfigDescriptor } from './internal_types'; +import { CoreRouteHandlerContext } from './core_route_handler_context'; const coreId = Symbol('core'); const rootConfigPath = ''; @@ -106,6 +107,7 @@ export class Server { public async setup() { this.log.debug('setting up server'); + const setupTransaction = apm.startTransaction('server_setup', 'kibana_platform'); const environmentSetup = await this.environment.setup(); @@ -115,10 +117,13 @@ export class Server { }); const legacyConfigSetup = await this.legacy.setupLegacyConfig(); - // Immediately terminate in case of invalid configuration - // This needs to be done after plugin discovery - await this.configService.validate(); - await ensureValidConfiguration(this.configService, legacyConfigSetup); + // rely on dev server to validate config, don't validate in the parent process + if (!this.env.isDevClusterMaster) { + // Immediately terminate in case of invalid configuration + // This needs to be done after plugin discovery + await this.configService.validate(); + await ensureValidConfiguration(this.configService, legacyConfigSetup); + } const contextServiceSetup = this.context.setup({ // We inject a fake "legacy plugin" with dependencies on every plugin so that legacy plugins: @@ -207,20 +212,25 @@ export class Server { this.registerCoreContext(coreSetup); this.coreApp.setup(coreSetup); + setupTransaction?.end(); return coreSetup; } public async start() { this.log.debug('starting server'); + const startTransaction = apm.startTransaction('server_start', 'kibana_platform'); + const auditTrailStart = this.auditTrail.start(); const elasticsearchStart = await this.elasticsearch.start({ auditTrail: auditTrailStart, }); + const soStartSpan = startTransaction?.startSpan('saved_objects.migration', 'migration'); const savedObjectsStart = await this.savedObjects.start({ elasticsearch: elasticsearchStart, pluginsInitialized: this.#pluginsInitialized, }); + soStartSpan?.end(); const capabilitiesStart = this.capabilities.start(); const uiSettingsStart = await this.uiSettings.start(); const metricsStart = await this.metrics.start(); @@ -248,6 +258,7 @@ export class Server { await this.http.start(); + startTransaction?.end(); return this.coreStart; } @@ -272,25 +283,7 @@ export class Server { coreId, 'core', async (context, req, res): Promise => { - const coreStart = this.coreStart!; - const savedObjectsClient = coreStart.savedObjects.getScopedClient(req); - - return { - savedObjects: { - client: savedObjectsClient, - typeRegistry: coreStart.savedObjects.getTypeRegistry(), - }, - elasticsearch: { - client: coreStart.elasticsearch.client.asScoped(req), - legacy: { - client: coreStart.elasticsearch.legacy.client.asScoped(req), - }, - }, - uiSettings: { - client: coreStart.uiSettings.asScopedToClient(savedObjectsClient), - }, - auditor: coreStart.auditTrail.asScoped(req), - }; + return new CoreRouteHandlerContext(this.coreStart!, req); } ); } diff --git a/src/dev/build/tasks/bin/scripts/kibana b/src/dev/build/tasks/bin/scripts/kibana index 3283e17008e7c..c606436c7b83f 100755 --- a/src/dev/build/tasks/bin/scripts/kibana +++ b/src/dev/build/tasks/bin/scripts/kibana @@ -26,4 +26,4 @@ if [ -f "${CONFIG_DIR}/node.options" ]; then KBN_NODE_OPTS="$(grep -v ^# < ${CONFIG_DIR}/node.options | xargs)" fi -NODE_OPTIONS="--no-warnings --max-http-header-size=65536 $KBN_NODE_OPTS $NODE_OPTIONS" NODE_ENV=production exec "${NODE}" "${DIR}/src/cli" ${@} +NODE_OPTIONS="--no-warnings --max-http-header-size=65536 $KBN_NODE_OPTS $NODE_OPTIONS" NODE_ENV=production exec "${NODE}" "${DIR}/src/cli/dist" ${@} diff --git a/src/dev/build/tasks/copy_source_task.ts b/src/dev/build/tasks/copy_source_task.ts index 948e2357effb0..a5039717760ae 100644 --- a/src/dev/build/tasks/copy_source_task.ts +++ b/src/dev/build/tasks/copy_source_task.ts @@ -35,8 +35,11 @@ export const CopySource: Task = { '!src/fixtures/**', '!src/cli/cluster/**', '!src/cli/repl/**', + '!src/cli/dev.js', '!src/functional_test_runner/**', '!src/dev/**', + '!src/setup_node_env/babel_register/index.js', + '!src/setup_node_env/babel_register/register.js', '!**/public/**', 'typings/**', 'config/kibana.yml', diff --git a/src/dev/build/tasks/create_empty_dirs_and_files_task.ts b/src/dev/build/tasks/create_empty_dirs_and_files_task.ts index a72c6a4598338..48745572def78 100644 --- a/src/dev/build/tasks/create_empty_dirs_and_files_task.ts +++ b/src/dev/build/tasks/create_empty_dirs_and_files_task.ts @@ -17,7 +17,7 @@ * under the License. */ -import { mkdirp, write, Task } from '../lib'; +import { mkdirp, Task } from '../lib'; export const CreateEmptyDirsAndFiles: Task = { description: 'Creating some empty directories and files to prevent file-permission issues', @@ -26,7 +26,6 @@ export const CreateEmptyDirsAndFiles: Task = { await Promise.all([ mkdirp(build.resolvePath('plugins')), mkdirp(build.resolvePath('data/optimize')), - write(build.resolvePath('data/optimize/.babel_register_cache.json'), '{}'), ]); }, }; diff --git a/src/dev/build/tasks/os_packages/docker_generator/resources/bin/kibana-docker b/src/dev/build/tasks/os_packages/docker_generator/resources/bin/kibana-docker index 884e7e38494cc..959e1f8dc3e72 100755 --- a/src/dev/build/tasks/os_packages/docker_generator/resources/bin/kibana-docker +++ b/src/dev/build/tasks/os_packages/docker_generator/resources/bin/kibana-docker @@ -8,11 +8,11 @@ # # eg. Setting the environment variable: # -# ELASTICSEARCH_STARTUPTIMEOUT=60 +# ELASTICSEARCH_LOGQUERIES=true # # will cause Kibana to be invoked with: # -# --elasticsearch.startupTimeout=60 +# --elasticsearch.logQueries=true kibana_vars=( console.enabled @@ -30,7 +30,6 @@ kibana_vars=( elasticsearch.logQueries elasticsearch.password elasticsearch.pingTimeout - elasticsearch.preserveHost elasticsearch.requestHeadersWhitelist elasticsearch.requestTimeout elasticsearch.shardTimeout @@ -47,7 +46,6 @@ kibana_vars=( elasticsearch.ssl.truststore.path elasticsearch.ssl.truststore.password elasticsearch.ssl.verificationMode - elasticsearch.startupTimeout elasticsearch.username i18n.locale interpreter.enableInVisualize @@ -161,6 +159,7 @@ kibana_vars=( xpack.code.security.gitHostWhitelist xpack.code.security.gitProtocolWhitelist xpack.encryptedSavedObjects.encryptionKey + xpack.encryptedSavedObjects.keyRotation.decryptionOnlyKeys xpack.graph.enabled xpack.graph.canEditDrillDownUrls xpack.graph.savePolicy diff --git a/src/dev/build/tasks/os_packages/service_templates/sysv/etc/default/kibana b/src/dev/build/tasks/os_packages/service_templates/sysv/etc/default/kibana index ee019d348ed97..9c9f58ded350b 100644 --- a/src/dev/build/tasks/os_packages/service_templates/sysv/etc/default/kibana +++ b/src/dev/build/tasks/os_packages/service_templates/sysv/etc/default/kibana @@ -10,6 +10,4 @@ nice="" # The default behavior is to simply log a message "program stop failed; still running" KILL_ON_STOP_TIMEOUT=0 -BABEL_CACHE_PATH="/var/lib/kibana/optimize/.babel_register_cache.json" - KBN_PATH_CONF="/etc/kibana" diff --git a/src/dev/ci_setup/setup_env.sh b/src/dev/ci_setup/setup_env.sh index 72ec73ad810e6..8ec80ac295c73 100644 --- a/src/dev/ci_setup/setup_env.sh +++ b/src/dev/ci_setup/setup_env.sh @@ -24,15 +24,6 @@ export NODE_OPTIONS="$NODE_OPTIONS --max-old-space-size=4096" ### export FORCE_COLOR=1 -### -### The @babel/register cache collects the build output from each file in -### a map, in memory, and then when the process exits it writes that to the -### babel cache file as a JSON encoded object. Stringifying that object -### causes OOMs on CI regularly enough that we need to find another solution, -### and until we do we need to disable the cache -### -export BABEL_DISABLE_CACHE=true - ### ### check that we seem to be in a kibana project ### diff --git a/src/dev/code_coverage/docs/team_assignment/README.md b/src/dev/code_coverage/docs/team_assignment/README.md index 3509fb5c2a4fc..f2884fb42b8d7 100644 --- a/src/dev/code_coverage/docs/team_assignment/README.md +++ b/src/dev/code_coverage/docs/team_assignment/README.md @@ -1,8 +1,41 @@ -# Team Assignment Ingestion Pipeline +# Code Coverage Team Assignments -Team assignment will occur once per ci run. -Team assignment uses an ingest pipeline. +Team assignment occurs once per ci run. -The coverage user has the coverage admin role. +The "orchestration" entry point is a [Jenkinsfile Scripted Pipeline](https://github.com/elastic/kibana/blob/f73bc48b3bbbb5ad2042c1aa267aea2150b7b742/.ci/Jenkinsfile_coverage#L21) +This Jenkinsfile runs a [shell script](https://github.com/elastic/kibana/blob/master/src/dev/code_coverage/shell_scripts/generate_team_assignments_and_ingest_coverage.sh#L33) that kicks everything off. +The end result is the data is ingested to our [Kibana Stats Cluster](https://kibana-stats.elastic.dev/app/dashboards#/view/58b8db70-62f9-11ea-8312-7f2d69b79843?_g=(filters%3A!()%2CrefreshInterval%3A(pause%3A!t%2Cvalue%3A0)%2Ctime%3A(from%3Anow-7d%2Cto%3Anow))) -This role must have the rights depicted below ![Cluster Rights](./security_privleges.png) +## Team Assignment Parsing (from .github/CODEOWNERS) +We add additional metadata to the CODEOWNERS file. +This metadata allows users to assign teams to paths, in a friendly location. +Example CODEOWNERS Block: +_notice the coverage delimiter `#CC# ...`_ +``` +/x-pack/test/functional/es_archives/endpoint/ @elastic/endpoint-app-team @elastic/siem +/x-pack/test/plugin_functional/plugins/resolver_test/ @elastic/endpoint-app-team @elastic/siem +/x-pack/test/plugin_functional/test_suites/resolver/ @elastic/endpoint-app-team @elastic/siem +#CC# /x-pack/legacy/plugins/siem/ @elastic/siem +#CC# /x-pack/plugins/siem/ @elastic/siem +#CC# /x-pack/plugins/security_solution/ @elastic/siem +``` +The first 3 lines above fill the usual purpose of the CODEOWNERS file and cause PRs modifying files in these paths to require approval by the listed team(s). +They also attribute files in those paths for purpose of code coverage reporting. +The last 3 lines above ONLY attribute files in those paths for purpose of code coverage reporting. + +## Team Assignment Data File Creation (Before Ingestion) +We create a data file containing all paths in the repo, with a team assigned. +Example Team Assignments Block: +``` +x-pack/plugins/security_solution/common/constants.ts siem +x-pack/plugins/security_solution/common/detection_engine/build_exceptions_query.test.ts siem +x-pack/plugins/security_solution/common/detection_engine/build_exceptions_query.ts siem +... +``` + +## Team Assignment Data File Usage (During Code Coverage Ingestion) +Subsequently, we use the data file during ingestion. +We search the data file, for any given "coveredFilePath" + - Given the above assignments block, and lets say the "coveredFilePath" during ingestion is + - `x-pack/plugins/security_solution/common/constants.ts` + - The team assignment would be `siem` in our [Kibana Stats Cluster](https://kibana-stats.elastic.dev/app/dashboards#/view/58b8db70-62f9-11ea-8312-7f2d69b79843?_g=(filters%3A!()%2CrefreshInterval%3A(pause%3A!t%2Cvalue%3A0)%2Ctime%3A(from%3Anow-7d%2Cto%3Anow))) diff --git a/src/dev/code_coverage/docs/team_assignment/security_privleges.png b/src/dev/code_coverage/docs/team_assignment/security_privleges.png deleted file mode 100644 index 002774f3ecefa..0000000000000 Binary files a/src/dev/code_coverage/docs/team_assignment/security_privleges.png and /dev/null differ diff --git a/src/dev/code_coverage/ingest_coverage/__tests__/either.test.js b/src/dev/code_coverage/ingest_coverage/__tests__/either.test.js index 3a493539f6743..0ae55508e8434 100644 --- a/src/dev/code_coverage/ingest_coverage/__tests__/either.test.js +++ b/src/dev/code_coverage/ingest_coverage/__tests__/either.test.js @@ -53,7 +53,7 @@ describe(`either datatype functions`, () => { expect(sut.inspect()).to.be('Right(undefined)'); }); }); - describe(`'fromNullable`, () => { + describe(`fromNullable`, () => { it(`should continue processing if a truthy is calculated`, () => { attempt({ detail: 'x' }).fold( () => {}, @@ -64,4 +64,18 @@ describe(`either datatype functions`, () => { attempt(false).fold(expectNull, () => {}); }); }); + describe(`predicate fns`, () => { + it(`right.isRight() is true`, () => { + expect(Either.right('a').isRight()).to.be(true); + }); + it(`right.isLeft() is false`, () => { + expect(Either.right('a').isLeft()).to.be(false); + }); + it(`left.isLeft() is true`, () => { + expect(Either.left().isLeft()).to.be(true); + }); + it(`left.isRight() is true`, () => { + expect(Either.left().isRight()).to.be(false); + }); + }); }); diff --git a/src/dev/code_coverage/ingest_coverage/__tests__/enumerate_patterns.test.js b/src/dev/code_coverage/ingest_coverage/__tests__/enumerate_patterns.test.js new file mode 100644 index 0000000000000..371695337ed56 --- /dev/null +++ b/src/dev/code_coverage/ingest_coverage/__tests__/enumerate_patterns.test.js @@ -0,0 +1,60 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import expect from '@kbn/expect'; +import { enumeratePatterns } from '../team_assignment/enumerate_patterns'; +import { ToolingLog, REPO_ROOT } from '@kbn/dev-utils'; + +const log = new ToolingLog({ + level: 'info', + writeTo: process.stdout, +}); + +describe(`enumeratePatterns`, () => { + it(`should resolve x-pack/plugins/reporting/server/browsers/extract/unzip.js to kibana-reporting`, () => { + const actual = enumeratePatterns(REPO_ROOT)(log)( + new Map([['x-pack/plugins/reporting', ['kibana-reporting']]]) + ); + + expect( + actual[0].includes( + 'x-pack/plugins/reporting/server/browsers/extract/unzip.js kibana-reporting' + ) + ).to.be(true); + }); + it(`should resolve src/plugins/charts/public/static/color_maps/color_maps.ts to kibana-app`, () => { + const actual = enumeratePatterns(REPO_ROOT)(log)( + new Map([['src/plugins/charts/public/static/color_maps', ['kibana-app']]]) + ); + + expect(actual[0][0]).to.be( + 'src/plugins/charts/public/static/color_maps/color_maps.ts kibana-app' + ); + }); + it(`should resolve x-pack/plugins/security_solution/public/common/components/exceptions/builder/translations.ts to kibana-security`, () => { + const short = 'x-pack/plugins/security_solution'; + const actual = enumeratePatterns(REPO_ROOT)(log)(new Map([[short, ['kibana-security']]])); + + expect( + actual[0].includes( + `${short}/public/common/components/exceptions/builder/translations.ts kibana-security` + ) + ).to.be(true); + }); +}); diff --git a/src/dev/code_coverage/ingest_coverage/__tests__/enumeration_helpers.test.js b/src/dev/code_coverage/ingest_coverage/__tests__/enumeration_helpers.test.js new file mode 100644 index 0000000000000..f480135b45ac6 --- /dev/null +++ b/src/dev/code_coverage/ingest_coverage/__tests__/enumeration_helpers.test.js @@ -0,0 +1,50 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import expect from '@kbn/expect'; +import { tryPath } from '../team_assignment/enumeration_helpers'; + +describe(`enumeration helper fns`, () => { + describe(`tryPath`, () => { + describe(`w/o glob file paths`, () => { + it(`should return a right on an existing path`, () => { + const aPath = 'src/dev/code_coverage/ingest_coverage/ingest.js'; + const actual = tryPath(aPath); + expect(actual.isRight()).to.be(true); + }); + it(`should return a left on a non existing path`, () => { + const aPath = 'src/dev/code_coverage/ingest_coverage/does_not_exist.js'; + const actual = tryPath(aPath); + expect(actual.isLeft()).to.be(true); + }); + }); + describe(`with glob file paths`, () => { + it(`should not error when the glob expands to nothing, but instead return a Left`, () => { + const aPath = 'src/legacy/core_plugins/kibana/public/home/*.ts'; + const actual = tryPath(aPath); + expect(actual.isLeft()).to.be(true); + }); + it(`should return a right on a glob that does indeed expand`, () => { + const aPath = 'src/dev/code_coverage/ingest_coverage/*.js'; + const actual = tryPath(aPath); + expect(actual.isRight()).to.be(true); + }); + }); + }); +}); diff --git a/src/dev/code_coverage/ingest_coverage/__tests__/ingest_helpers.test.js b/src/dev/code_coverage/ingest_coverage/__tests__/ingest_helpers.test.js index 7ca7279e0d64c..f668c1f86f5b0 100644 --- a/src/dev/code_coverage/ingest_coverage/__tests__/ingest_helpers.test.js +++ b/src/dev/code_coverage/ingest_coverage/__tests__/ingest_helpers.test.js @@ -18,13 +18,8 @@ */ import expect from '@kbn/expect'; -import { maybeTeamAssign, whichIndex } from '../ingest_helpers'; -import { - TOTALS_INDEX, - RESEARCH_TOTALS_INDEX, - RESEARCH_COVERAGE_INDEX, - // COVERAGE_INDEX, -} from '../constants'; +import { whichIndex } from '../ingest_helpers'; +import { TOTALS_INDEX, RESEARCH_TOTALS_INDEX, RESEARCH_COVERAGE_INDEX } from '../constants'; describe(`Ingest Helper fns`, () => { describe(`whichIndex`, () => { @@ -56,20 +51,4 @@ describe(`Ingest Helper fns`, () => { }); }); }); - describe(`maybeTeamAssign`, () => { - describe(`against a coverage index`, () => { - it(`should have the pipeline prop`, () => { - const actual = maybeTeamAssign(true, { a: 'blah' }); - expect(actual).to.have.property('pipeline'); - }); - }); - describe(`against a totals index`, () => { - describe(`for "prod"`, () => { - it(`should not have the pipeline prop`, () => { - const actual = maybeTeamAssign(false, { b: 'blah' }); - expect(actual).not.to.have.property('pipeline'); - }); - }); - }); - }); }); diff --git a/src/dev/code_coverage/ingest_coverage/__tests__/mocks/team_assign_mock.json b/src/dev/code_coverage/ingest_coverage/__tests__/mocks/team_assign_mock.json deleted file mode 100644 index 355c484a84fa3..0000000000000 --- a/src/dev/code_coverage/ingest_coverage/__tests__/mocks/team_assign_mock.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "abc": "123" -} diff --git a/src/dev/code_coverage/ingest_coverage/__tests__/mocks/team_assign_mock.txt b/src/dev/code_coverage/ingest_coverage/__tests__/mocks/team_assign_mock.txt new file mode 100644 index 0000000000000..d8924bd563f30 --- /dev/null +++ b/src/dev/code_coverage/ingest_coverage/__tests__/mocks/team_assign_mock.txt @@ -0,0 +1,194 @@ +x-pack/plugins/dashboard_enhanced/public/index.ts kibana-app +x-pack/plugins/dashboard_enhanced/public/mocks.ts kibana-app +x-pack/plugins/dashboard_enhanced/public/plugin.ts kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/drilldown_shared.ts kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_create_drilldown/flyout_create_drilldown.test.tsx kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_create_drilldown/flyout_create_drilldown.tsx kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_create_drilldown/index.ts kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.test.tsx kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/flyout_edit_drilldown.tsx kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/i18n.ts kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/index.tsx kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/menu_item.test.tsx kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/menu_item.tsx kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/index.ts kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/test_helpers.ts kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_drilldowns_services.ts kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/components/collect_config_container.tsx kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/components/dashboard_drilldown_config/dashboard_drilldown_config.story.tsx kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/components/dashboard_drilldown_config/dashboard_drilldown_config.test.tsx kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/components/dashboard_drilldown_config/dashboard_drilldown_config.tsx kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/components/dashboard_drilldown_config/i18n.ts kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/components/dashboard_drilldown_config/index.ts kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/components/i18n.ts kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/components/index.ts kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/constants.ts kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/drilldown.test.tsx kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/drilldown.tsx kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/i18n.ts kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/index.ts kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/types.ts kibana-app +x-pack/plugins/dashboard_enhanced/public/services/drilldowns/index.ts kibana-app +x-pack/plugins/dashboard_enhanced/public/services/index.ts kibana-app +x-pack/plugins/dashboard_enhanced/scripts/storybook.js kibana-app +x-pack/plugins/discover_enhanced/common/config.ts kibana-app +x-pack/plugins/discover_enhanced/common/index.ts kibana-app +x-pack/plugins/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts kibana-app +x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.test.ts kibana-app +x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_chart_action.ts kibana-app +x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.test.ts kibana-app +x-pack/plugins/discover_enhanced/public/actions/explore_data/explore_data_context_menu_action.ts kibana-app +x-pack/plugins/discover_enhanced/public/actions/explore_data/index.ts kibana-app +x-pack/plugins/discover_enhanced/public/actions/explore_data/kibana_url.ts kibana-app +x-pack/plugins/discover_enhanced/public/actions/explore_data/shared.ts kibana-app +x-pack/plugins/discover_enhanced/public/actions/index.ts kibana-app +x-pack/plugins/discover_enhanced/public/index.ts kibana-app +x-pack/plugins/discover_enhanced/public/plugin.ts kibana-app +x-pack/plugins/discover_enhanced/server/config.ts kibana-app +x-pack/plugins/discover_enhanced/server/index.ts kibana-app +x-pack/plugins/discover_enhanced/server/plugin.ts kibana-app +x-pack/plugins/lens/common/api.ts kibana-app +x-pack/plugins/lens/common/constants.ts kibana-app +x-pack/plugins/lens/common/index.ts kibana-app +x-pack/plugins/lens/common/types.ts kibana-app +x-pack/plugins/lens/config.ts kibana-app +x-pack/plugins/lens/public/app_plugin/app.test.tsx kibana-app +x-pack/plugins/lens/public/app_plugin/app.tsx kibana-app +x-pack/plugins/lens/public/app_plugin/index.ts kibana-app +x-pack/plugins/lens/public/app_plugin/mounter.tsx kibana-app +x-pack/plugins/lens/public/datatable_visualization/expression.test.tsx kibana-app +x-pack/plugins/lens/public/datatable_visualization/expression.tsx kibana-app +x-pack/plugins/lens/public/datatable_visualization/index.ts kibana-app +x-pack/plugins/lens/public/datatable_visualization/visualization.test.tsx kibana-app +x-pack/plugins/lens/public/datatable_visualization/visualization.tsx kibana-app +x-pack/plugins/lens/public/debounced_component/debounced_component.test.tsx kibana-app +x-pack/plugins/lens/public/debounced_component/debounced_component.tsx kibana-app +x-pack/plugins/lens/public/debounced_component/index.ts kibana-app +x-pack/plugins/lens/public/drag_drop/drag_drop.test.tsx kibana-app +x-pack/plugins/lens/public/drag_drop/drag_drop.tsx kibana-app +x-pack/plugins/lens/public/drag_drop/index.ts kibana-app +x-pack/plugins/lens/public/drag_drop/providers.test.tsx kibana-app +x-pack/plugins/lens/public/drag_drop/providers.tsx kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/__mocks__/expression_helpers.ts kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/__mocks__/suggestion_helpers.ts kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/dimension_popover.tsx kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/index.ts kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_actions.test.ts kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_actions.ts kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.test.tsx kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_settings.tsx kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/types.ts kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.tsx kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.test.tsx kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/editor_frame.tsx kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/expression_helpers.ts kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/frame_layout.tsx kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/index.ts kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/save.test.ts kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/save.ts kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_helpers.ts kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_management.test.ts kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_management.ts kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.test.ts kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.ts kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.test.tsx kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.test.tsx kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/chart_switch.tsx kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/index.ts kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.test.tsx kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.test.tsx kibana-app +x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx kibana-app +x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.test.tsx kibana-app +x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx kibana-app +x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable_factory.ts kibana-app +x-pack/plugins/lens/public/editor_frame_service/embeddable/expression_wrapper.tsx kibana-app +x-pack/plugins/lens/public/editor_frame_service/format_column.ts kibana-app +x-pack/plugins/lens/public/editor_frame_service/index.ts kibana-app +x-pack/plugins/lens/public/editor_frame_service/merge_tables.test.ts kibana-app +x-pack/plugins/lens/public/editor_frame_service/merge_tables.ts kibana-app +x-pack/plugins/lens/public/editor_frame_service/mocks.tsx kibana-app +x-pack/plugins/lens/public/editor_frame_service/service.test.tsx kibana-app +x-pack/plugins/lens/public/editor_frame_service/service.tsx kibana-app +x-pack/plugins/lens/public/help_menu_util.tsx kibana-app +x-pack/plugins/lens/public/id_generator/id_generator.test.ts kibana-app +x-pack/plugins/lens/public/id_generator/id_generator.ts kibana-app +x-pack/plugins/lens/public/id_generator/index.ts kibana-app +x-pack/plugins/lens/public/index.ts kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/__mocks__/loader.ts kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/__mocks__/state_helpers.ts kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/change_indexpattern.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/datapanel.test.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/bucket_nesting_editor.test.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/bucket_nesting_editor.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.test.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/format_selector.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/index.ts kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/popover_editor.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/document_field.ts kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/field_item.test.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/fields_accordion.test.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/fields_accordion.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/index.ts kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.test.ts kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/layerpanel.test.tsx kibana-app +x-pack/plugins/reporting/server/browsers/download/clean.ts kibana-reporting +x-pack/plugins/reporting/server/browsers/download/download.test.ts kibana-reporting +x-pack/plugins/reporting/server/browsers/download/download.ts kibana-reporting +x-pack/plugins/reporting/server/browsers/download/ensure_downloaded.ts kibana-reporting +x-pack/plugins/reporting/server/browsers/download/index.ts kibana-reporting +x-pack/plugins/reporting/server/browsers/download/util.ts kibana-reporting +x-pack/plugins/reporting/server/browsers/extract/extract.js kibana-reporting +x-pack/plugins/reporting/server/browsers/extract/extract_error.js kibana-reporting +x-pack/plugins/reporting/server/browsers/extract/index.js kibana-reporting +x-pack/plugins/reporting/server/browsers/extract/unzip.js kibana-reporting +x-pack/plugins/reporting/server/browsers/index.ts kibana-reporting +x-pack/plugins/reporting/server/browsers/install.ts kibana-reporting +x-pack/plugins/reporting/server/browsers/network_policy.test.ts kibana-reporting +x-pack/plugins/reporting/server/browsers/network_policy.ts kibana-reporting +x-pack/plugins/reporting/server/browsers/safe_child_process.ts kibana-reporting +x-pack/plugins/reporting/server/config/config.ts kibana-reporting +x-pack/plugins/reporting/server/config/create_config.test.ts kibana-reporting +x-pack/plugins/reporting/server/config/create_config.ts kibana-reporting +x-pack/plugins/reporting/server/config/default_chromium_sandbox_disabled.test.ts kibana-reporting +x-pack/plugins/lens/public/indexpattern_datasource/layerpanel.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/lens_field_icon.test.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/lens_field_icon.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/loader.ts kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/mocks.ts kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/no_fields_callout.test.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/no_fields_callout.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/operations/__mocks__/index.ts kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/cardinality.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/column_types.ts kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/count.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.test.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/date_histogram.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/index.ts kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/metrics.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.test.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.tsx kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/operations/index.ts kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.test.ts kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.ts kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/pure_helpers.test.ts kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/pure_helpers.ts kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/rename_columns.test.ts kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/rename_columns.ts kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/state_helpers.test.ts kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/state_helpers.ts kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/to_expression.ts kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/types.ts kibana-app +x-pack/plugins/lens/public/indexpattern_datasource/utils.ts kibana-app +x-pack/plugins/lens/public/lens_ui_telemetry/factory.test.ts kibana-app diff --git a/src/dev/code_coverage/ingest_coverage/__tests__/team_assignment.test.js b/src/dev/code_coverage/ingest_coverage/__tests__/team_assignment.test.js deleted file mode 100644 index e597ffb5d2f4b..0000000000000 --- a/src/dev/code_coverage/ingest_coverage/__tests__/team_assignment.test.js +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import expect from '@kbn/expect'; -import { fetch } from '../team_assignment/get_data'; -import { noop } from '../utils'; - -describe(`Team Assignment`, () => { - const mockPath = 'src/dev/code_coverage/ingest_coverage/__tests__/mocks/team_assign_mock.json'; - describe(`fetch fn`, () => { - it(`should be a fn`, () => { - expect(typeof fetch).to.be('function'); - }); - describe(`applied to a path that exists`, () => { - it(`should return the contents of the path`, () => { - const sut = fetch(mockPath); - expect(sut.chain(JSON.parse)).to.have.property('abc'); - }); - }); - describe(`applied to an non-existing path`, () => { - it(`should return a Left with the error message within`, () => { - const expectLeft = (err) => - expect(err.message).to.contain('ENOENT: no such file or directory'); - - fetch('fake_path.json').fold(expectLeft, noop); - }); - }); - }); -}); diff --git a/src/dev/code_coverage/ingest_coverage/__tests__/transforms.test.js b/src/dev/code_coverage/ingest_coverage/__tests__/transforms.test.js index 746bccc3d718a..b6d17f83e327e 100644 --- a/src/dev/code_coverage/ingest_coverage/__tests__/transforms.test.js +++ b/src/dev/code_coverage/ingest_coverage/__tests__/transforms.test.js @@ -18,9 +18,17 @@ */ import expect from '@kbn/expect'; -import { ciRunUrl, coveredFilePath, itemizeVcs, prokPrevious } from '../transforms'; +import { + ciRunUrl, + coveredFilePath, + itemizeVcs, + prokPrevious, + teamAssignment, + last, +} from '../transforms'; +import { ToolingLog } from '@kbn/dev-utils'; -describe(`Transform fn`, () => { +describe(`Transform fns`, () => { describe(`ciRunUrl`, () => { it(`should add the url when present in the environment`, () => { process.env.CI_RUN_URL = 'blah'; @@ -83,4 +91,59 @@ describe(`Transform fn`, () => { ); }); }); + describe(`teamAssignment`, () => { + const teamAssignmentsPathMOCK = + 'src/dev/code_coverage/ingest_coverage/__tests__/mocks/team_assign_mock.txt'; + const coveredFilePath = 'x-pack/plugins/reporting/server/browsers/extract/unzip.js'; + const obj = { coveredFilePath }; + const log = new ToolingLog({ + level: 'info', + writeTo: process.stdout, + }); + + describe(`with a coveredFilePath of ${coveredFilePath}`, () => { + const expected = 'kibana-reporting'; + it(`should resolve to ${expected}`, async () => { + const actual = await teamAssignment(teamAssignmentsPathMOCK)(log)(obj); + const { team } = actual; + expect(team).to.eql(expected); + }); + }); + + describe(`with a coveredFilePath of src/plugins/charts/public/static/color_maps/color_maps.ts`, () => { + const expected = 'kibana-reporting'; + it(`should resolve to ${expected}`, async () => { + const actual = await teamAssignment(teamAssignmentsPathMOCK)(log)(obj); + const { team } = actual; + expect(team).to.eql(expected); + }); + }); + + describe(`last fn`, () => { + describe(`applied to n results`, () => { + it(`should pick the last one`, () => { + const nteams = `src/plugins/charts/public/static/color_maps/color_maps.ts kibana-app +src/plugins/charts/public/static/color_maps/color_maps.ts kibana-app-arch`; + + const actual = last(nteams); + + expect(actual).to.be( + 'src/plugins/charts/public/static/color_maps/color_maps.ts kibana-app-arch' + ); + }); + }); + describe(`applied to 1 result`, () => { + it(`should pick that 1 result`, () => { + const nteams = + 'src/plugins/charts/public/static/color_maps/color_maps.ts kibana-app-arch'; + + const actual = last(nteams); + + expect(actual).to.be( + 'src/plugins/charts/public/static/color_maps/color_maps.ts kibana-app-arch' + ); + }); + }); + }); + }); }); diff --git a/src/dev/code_coverage/ingest_coverage/constants.js b/src/dev/code_coverage/ingest_coverage/constants.js index f2f467e461ae5..8f850ac2f1f12 100644 --- a/src/dev/code_coverage/ingest_coverage/constants.js +++ b/src/dev/code_coverage/ingest_coverage/constants.js @@ -27,8 +27,6 @@ export const RESEARCH_COVERAGE_INDEX = export const RESEARCH_TOTALS_INDEX = process.env.RESEARCH_TOTALS_INDEX || `qa_research_total_code_coverage`; -export const TEAM_ASSIGNMENT_PIPELINE_NAME = process.env.PIPELINE_NAME || 'team_assignment'; - export const CODE_COVERAGE_CI_JOB_NAME = 'elastic+kibana+code-coverage'; export const RESEARCH_CI_JOB_NAME = 'elastic+kibana+qa-research'; export const CI_JOB_NAME = process.env.COVERAGE_JOB_NAME || RESEARCH_CI_JOB_NAME; diff --git a/src/dev/code_coverage/ingest_coverage/either.js b/src/dev/code_coverage/ingest_coverage/either.js index eeb48893f18d8..326f238074e30 100644 --- a/src/dev/code_coverage/ingest_coverage/either.js +++ b/src/dev/code_coverage/ingest_coverage/either.js @@ -20,11 +20,15 @@ /* eslint new-cap: 0 */ /* eslint no-unused-vars: 0 */ +import { always } from './utils'; + export const Right = (x) => ({ chain: (f) => f(x), map: (f) => Right(f(x)), fold: (leftFn, rightFn) => rightFn(x), inspect: () => `Right(${x})`, + isLeft: always(false), + isRight: always(true), }); Right.of = function of(x) { @@ -40,6 +44,8 @@ export const Left = (x) => ({ map: (f) => Left(x), fold: (leftFn, rightFn) => leftFn(x), inspect: () => `Left(${x})`, + isLeft: always(true), + isRight: always(false), }); Left.of = function of(x) { diff --git a/src/dev/code_coverage/ingest_coverage/index.js b/src/dev/code_coverage/ingest_coverage/index.js index 4047ee78ee6ec..f29739c4cf29c 100644 --- a/src/dev/code_coverage/ingest_coverage/index.js +++ b/src/dev/code_coverage/ingest_coverage/index.js @@ -20,13 +20,16 @@ import { resolve } from 'path'; import { prok } from './process'; import { run, createFlagError } from '@kbn/dev-utils'; +import { pathExists } from './team_assignment/enumeration_helpers'; +import { id, reThrow } from './utils'; const ROOT = resolve(__dirname, '../../../..'); const flags = { - string: ['path', 'verbose', 'vcsInfoPath'], + string: ['path', 'verbose', 'vcsInfoPath', 'teamAssignmentsPath'], help: ` --path Required, path to the file to extract coverage data --vcsInfoPath Required, path to the git info file (branch, sha, author, & commit msg) +--teamAssignmentsPath Required, path to the team assignments data file `, }; @@ -36,12 +39,18 @@ export function runCoverageIngestionCli() { if (flags.path === '') throw createFlagError('please provide a single --path flag'); if (flags.vcsInfoPath === '') throw createFlagError('please provide a single --vcsInfoPath flag'); + if (flags.teamAssignmentsPath === '') + throw createFlagError('please provide a single --teamAssignments flag'); if (flags.verbose) log.verbose(`Verbose logging enabled`); const resolveRoot = resolve.bind(null, ROOT); const jsonSummaryPath = resolveRoot(flags.path); const vcsInfoFilePath = resolveRoot(flags.vcsInfoPath); - prok({ jsonSummaryPath, vcsInfoFilePath }, log); + const { teamAssignmentsPath } = flags; + + pathExists(teamAssignmentsPath).fold(reThrow, id); + + prok({ jsonSummaryPath, vcsInfoFilePath, teamAssignmentsPath }, log); }, { description: ` diff --git a/src/dev/code_coverage/ingest_coverage/ingest.js b/src/dev/code_coverage/ingest_coverage/ingest.js index 31a94d161a3cc..24da7a9338a46 100644 --- a/src/dev/code_coverage/ingest_coverage/ingest.js +++ b/src/dev/code_coverage/ingest_coverage/ingest.js @@ -19,7 +19,7 @@ const { Client } = require('@elastic/elasticsearch'); import { createFailError } from '@kbn/dev-utils'; -import { RESEARCH_CI_JOB_NAME, TEAM_ASSIGNMENT_PIPELINE_NAME } from './constants'; +import { RESEARCH_CI_JOB_NAME } from './constants'; import { errMsg, redact, whichIndex } from './ingest_helpers'; import { pretty, green } from './utils'; import { right, left } from './either'; @@ -34,14 +34,10 @@ const isResearchJob = process.env.COVERAGE_JOB_NAME === RESEARCH_CI_JOB_NAME ? t export const ingest = (log) => async (body) => { const isTotal = !!body.isTotal; const index = whichIndex(isResearchJob)(isTotal); - const isACoverageIndex = isTotal ? false : true; const stringified = pretty(body); - const pipeline = TEAM_ASSIGNMENT_PIPELINE_NAME; - const finalPayload = isACoverageIndex - ? { index, body: stringified, pipeline } - : { index, body: stringified }; + const finalPayload = { index, body: stringified }; const justLog = dontSendButLog(log); const doSendToIndex = doSend(index); @@ -77,11 +73,11 @@ async function send(logF, idx, redactedEsHostUrl, client, requestBody) { const sendMsg = (actuallySent, redactedEsHostUrl, payload) => { const { index, body } = payload; return `### ${actuallySent ? 'Sent' : 'Fake Sent'}: -${payload.pipeline ? `\t### Team Assignment Pipeline: ${green(payload.pipeline)}` : ''} ${redactedEsHostUrl ? `\t### ES Host: ${redactedEsHostUrl}` : ''} + \t### Index: ${green(index)} + \t### payload.body: ${body} -${process.env.NODE_ENV === 'integration_test' ? `ingest-pipe=>${payload.pipeline}` : ''} `; }; diff --git a/src/dev/code_coverage/ingest_coverage/ingest_helpers.js b/src/dev/code_coverage/ingest_coverage/ingest_helpers.js index 86bcf03977082..a7822a671887b 100644 --- a/src/dev/code_coverage/ingest_coverage/ingest_helpers.js +++ b/src/dev/code_coverage/ingest_coverage/ingest_helpers.js @@ -24,7 +24,6 @@ import { COVERAGE_INDEX, RESEARCH_COVERAGE_INDEX, RESEARCH_TOTALS_INDEX, - TEAM_ASSIGNMENT_PIPELINE_NAME, TOTALS_INDEX, } from './constants'; @@ -70,12 +69,6 @@ function color(whichColor) { }; } -export function maybeTeamAssign(isACoverageIndex, body) { - const doAddTeam = isACoverageIndex ? true : false; - const payload = doAddTeam ? { ...body, pipeline: TEAM_ASSIGNMENT_PIPELINE_NAME } : body; - return payload; -} - export function whichIndex(isResearchJob) { return (isTotal) => isTotal ? whichTotalsIndex(isResearchJob) : whichCoverageIndex(isResearchJob); diff --git a/src/dev/code_coverage/ingest_coverage/integration_tests/ingest_coverage.test.js b/src/dev/code_coverage/ingest_coverage/integration_tests/ingest_coverage.test.js index ba73922ec508a..a4d07215efec1 100644 --- a/src/dev/code_coverage/ingest_coverage/integration_tests/ingest_coverage.test.js +++ b/src/dev/code_coverage/ingest_coverage/integration_tests/ingest_coverage.test.js @@ -20,6 +20,7 @@ import { resolve } from 'path'; import execa from 'execa'; import expect from '@kbn/expect'; +import shell from 'shelljs'; const ROOT_DIR = resolve(__dirname, '../../../../..'); const MOCKS_DIR = resolve(__dirname, './mocks'); @@ -35,9 +36,14 @@ const env = { }; describe('Ingesting coverage', () => { + const teamAssignmentsPath = + 'src/dev/code_coverage/ingest_coverage/team_assignment/team_assignments.txt'; + const verboseArgs = [ 'scripts/ingest_coverage.js', '--verbose', + '--teamAssignmentsPath', + teamAssignmentsPath, '--vcsInfoPath', 'src/dev/code_coverage/ingest_coverage/integration_tests/mocks/VCS_INFO.txt', '--path', @@ -46,6 +52,21 @@ describe('Ingesting coverage', () => { const summaryPath = 'jest-combined/coverage-summary-manual-mix.json'; const resolved = resolve(MOCKS_DIR, summaryPath); + beforeAll(async () => { + const params = [ + 'scripts/generate_team_assignments.js', + '--src', + '.github/CODEOWNERS', + '--dest', + teamAssignmentsPath, + ]; + await execa(process.execPath, params, { cwd: ROOT_DIR, env }); + }); + + afterAll(() => { + shell.rm(teamAssignmentsPath); + }); + describe(`staticSiteUrl`, () => { let actualUrl = ''; const siteUrlRegex = /"staticSiteUrl":\s*(.+,)/; diff --git a/src/dev/code_coverage/ingest_coverage/integration_tests/mocks/CODEOWNERS b/src/dev/code_coverage/ingest_coverage/integration_tests/mocks/CODEOWNERS new file mode 100644 index 0000000000000..1822c3fd95e34 --- /dev/null +++ b/src/dev/code_coverage/ingest_coverage/integration_tests/mocks/CODEOWNERS @@ -0,0 +1,6 @@ +# GitHub CODEOWNERS definition +# Identify which groups will be pinged by changes to different parts of the codebase. +# For more info, see https://help.github.com/articles/about-codeowners/ + +# App +/x-pack/plugins/code/ @elastic/kibana-tre diff --git a/src/dev/code_coverage/ingest_coverage/integration_tests/mocks/jest-combined/coverage-summary-possibly-n-teams.json b/src/dev/code_coverage/ingest_coverage/integration_tests/mocks/jest-combined/coverage-summary-possibly-n-teams.json new file mode 100644 index 0000000000000..9e66d8f5cb101 --- /dev/null +++ b/src/dev/code_coverage/ingest_coverage/integration_tests/mocks/jest-combined/coverage-summary-possibly-n-teams.json @@ -0,0 +1,28 @@ +{ + "/var/lib/jenkins/workspace/elastic+kibana+code-coverage/kibana/src/plugins/charts/public/static/color_maps/color_maps.ts": { + "lines": { + "total": 4, + "covered": 4, + "skipped": 0, + "pct": 100 + }, + "functions": { + "total": 1, + "covered": 1, + "skipped": 0, + "pct": 100 + }, + "statements": { + "total": 4, + "covered": 4, + "skipped": 0, + "pct": 100 + }, + "branches": { + "total": 0, + "covered": 0, + "skipped": 0, + "pct": 100 + } + } +} diff --git a/src/dev/code_coverage/ingest_coverage/integration_tests/mocks/jest-combined/coverage-summary-qa-research-job.json b/src/dev/code_coverage/ingest_coverage/integration_tests/mocks/jest-combined/coverage-summary-qa-research-job.json new file mode 100644 index 0000000000000..6e4d8ea954c2c --- /dev/null +++ b/src/dev/code_coverage/ingest_coverage/integration_tests/mocks/jest-combined/coverage-summary-qa-research-job.json @@ -0,0 +1,28 @@ +{ + "/var/lib/jenkins/workspace/elastic+kibana+qa-research/kibana/x-pack/plugins/reporting/server/browsers/extract/unzip.js": { + "lines": { + "total": 4, + "covered": 4, + "skipped": 0, + "pct": 100 + }, + "functions": { + "total": 1, + "covered": 1, + "skipped": 0, + "pct": 100 + }, + "statements": { + "total": 4, + "covered": 4, + "skipped": 0, + "pct": 100 + }, + "branches": { + "total": 0, + "covered": 0, + "skipped": 0, + "pct": 100 + } + } +} diff --git a/src/dev/code_coverage/ingest_coverage/integration_tests/team_assignment.test.js b/src/dev/code_coverage/ingest_coverage/integration_tests/team_assignment.test.js new file mode 100644 index 0000000000000..c666581ddb08c --- /dev/null +++ b/src/dev/code_coverage/ingest_coverage/integration_tests/team_assignment.test.js @@ -0,0 +1,58 @@ +/* + * 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 { resolve } from 'path'; +import execa from 'execa'; +import expect from '@kbn/expect'; +import shell from 'shelljs'; + +const ROOT_DIR = resolve(__dirname, '../../../../..'); +const MOCKS_DIR = resolve(__dirname, './mocks'); + +describe('Team Assignment', () => { + const teamAssignmentsPath = + 'src/dev/code_coverage/ingest_coverage/team_assignment/team_assignments.txt'; + const mockCodeOwners = 'CODEOWNERS'; + const resolved = resolve(MOCKS_DIR, mockCodeOwners); + + beforeAll(async () => { + const params = [ + 'scripts/generate_team_assignments.js', + '--src', + resolved, + '--dest', + teamAssignmentsPath, + ]; + await execa(process.execPath, params, { cwd: ROOT_DIR }); + }); + + afterAll(() => { + shell.rm(teamAssignmentsPath); + }); + + describe(`when the codeowners file contains #CC#`, () => { + it(`should strip the prefix and still drill down through the fs`, async () => { + const { stdout } = await execa('grep', ['tre', teamAssignmentsPath], { cwd: ROOT_DIR }); + expect(stdout).to.be(`x-pack/plugins/code/server/config.ts kibana-tre +x-pack/plugins/code/server/index.ts kibana-tre +x-pack/plugins/code/server/plugin.test.ts kibana-tre +x-pack/plugins/code/server/plugin.ts kibana-tre`); + }); + }); +}); diff --git a/src/dev/code_coverage/ingest_coverage/process.js b/src/dev/code_coverage/ingest_coverage/process.js index 85a42cfffa6e2..28a7c9ccd41b0 100644 --- a/src/dev/code_coverage/ingest_coverage/process.js +++ b/src/dev/code_coverage/ingest_coverage/process.js @@ -18,7 +18,7 @@ */ import { fromEventPattern, of, fromEvent } from 'rxjs'; -import { concatMap, delay, map, takeUntil } from 'rxjs/operators'; +import { concatMap, delay, map, mergeMap, takeUntil } from 'rxjs/operators'; import jsonStream from './json_stream'; import { pipe, noop, green, always } from './utils'; import { ingest } from './ingest'; @@ -32,6 +32,7 @@ import { coveredFilePath, ciRunUrl, itemizeVcs, + teamAssignment, } from './transforms'; import { resolve } from 'path'; import { createReadStream } from 'fs'; @@ -50,9 +51,10 @@ const addPrePopulatedTimeStamp = addTimeStamp(process.env.TIME_STAMP || formatte const preamble = pipe(statsAndstaticSiteUrl, rootDirAndOrigPath, buildId, addPrePopulatedTimeStamp); const addTestRunnerAndStaticSiteUrl = pipe(testRunner, staticSite(staticSiteUrlBase)); -const transform = (jsonSummaryPath) => (log) => (vcsInfo) => { +const transform = (jsonSummaryPath) => (log) => (vcsInfo) => (teamAssignmentsPath) => { const objStream = jsonStream(jsonSummaryPath).on('done', noop); const itemizeVcsInfo = itemizeVcs(vcsInfo); + const assignTeams = teamAssignment(teamAssignmentsPath)(log); const jsonSummary$ = (_) => objStream.on('node', '!.*', _); @@ -64,6 +66,7 @@ const transform = (jsonSummaryPath) => (log) => (vcsInfo) => { map(ciRunUrl), map(addJsonSummaryPath(jsonSummaryPath)), map(addTestRunnerAndStaticSiteUrl), + mergeMap(assignTeams), concatMap((x) => of(x).pipe(delay(ms))) ) .subscribe(ingest(log)); @@ -83,7 +86,7 @@ const vcsInfoLines$ = (vcsInfoFilePath) => { return fromEvent(rl, 'line').pipe(takeUntil(fromEvent(rl, 'close'))); }; -export const prok = ({ jsonSummaryPath, vcsInfoFilePath }, log) => { +export const prok = ({ jsonSummaryPath, vcsInfoFilePath, teamAssignmentsPath }, log) => { validateRoot(COVERAGE_INGESTION_KIBANA_ROOT, log); logAll(jsonSummaryPath, log); @@ -93,7 +96,7 @@ export const prok = ({ jsonSummaryPath, vcsInfoFilePath }, log) => { vcsInfoLines$(vcsInfoFilePath).subscribe( mutateVcsInfo(vcsInfo), (err) => log.error(err), - always(xformWithPath(vcsInfo)) + always(xformWithPath(vcsInfo)(teamAssignmentsPath)) ); }; diff --git a/src/dev/code_coverage/ingest_coverage/team_assignment/enumerate_patterns.js b/src/dev/code_coverage/ingest_coverage/team_assignment/enumerate_patterns.js new file mode 100644 index 0000000000000..dcdb32c91b8f8 --- /dev/null +++ b/src/dev/code_coverage/ingest_coverage/team_assignment/enumerate_patterns.js @@ -0,0 +1,78 @@ +/* + * 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 { readdirSync, statSync } from 'fs'; +import { join } from 'path'; +import { + push, + prokGlob, + trim, + isRejectedDir, + isFileAllowed, + isDir, + tryPath, + dropEmpty, + notFound, +} from './enumeration_helpers'; +import { stripLeading } from '../transforms'; + +export const enumeratePatterns = (rootPath) => (log) => (patterns) => { + const res = []; + const resPush = push(res); + const logNotFound = notFound(log); + + for (const entry of patterns) { + const [pathPattern, team] = entry; + const cleaned = stripLeading(pathPattern); + const existsWithOwner = pathExists(team); + + const collect = (x) => existsWithOwner(x).forEach(resPush); + tryPath(cleaned).fold(logNotFound, collect); + } + + return res; + + function pathExists(owner) { + const creeper = (x) => creepFsSync(x, [], rootPath, owner); + return function creepAllAsGlobs(pathPattern) { + return prokGlob(pathPattern).map(creeper).filter(dropEmpty); + }; + } +}; + +function creepFsSync(aPath, xs, rootPath, owner) { + xs = xs || []; + + const joinRoot = join.bind(null, rootPath); + const trimRoot = trim(rootPath); + const joined = joinRoot(aPath); + const isADir = isDir(joined); + + (isADir ? readdirSync(joined) : [aPath]).forEach(maybeRecurse); + + return xs; + + function maybeRecurse(entry) { + const full = isADir ? join(aPath, entry) : entry; + const fullIsDir = statSync(full).isDirectory(); + + if (fullIsDir && !isRejectedDir(full)) xs = creepFsSync(full, xs, rootPath, owner); + else if (isFileAllowed(full)) xs.push(`${trimRoot(full)} ${owner}`); + } +} diff --git a/src/dev/code_coverage/ingest_coverage/team_assignment/enumeration_helpers.js b/src/dev/code_coverage/ingest_coverage/team_assignment/enumeration_helpers.js new file mode 100644 index 0000000000000..b06141965d2b6 --- /dev/null +++ b/src/dev/code_coverage/ingest_coverage/team_assignment/enumeration_helpers.js @@ -0,0 +1,46 @@ +/* + * 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 { statSync } from 'fs'; +import isGlob from 'is-glob'; +import glob from 'glob'; +import { left, right, tryCatch } from '../either'; + +export const push = (xs) => (x) => xs.push(x); +export const pathExists = (x) => tryCatch(() => statSync(x)).fold(left, right); +export const isDir = (x) => statSync(x).isDirectory(); +export const prokGlob = (x) => glob.sync(x, { nonull: true }); +export const trim = (ROOT) => (x) => x.replace(`${ROOT}/`, ''); +export const isFileAllowed = (x) => { + const isJsOrTsOrTsxOrJsx = /.(j|t)(s|sx)$/gm; + return isJsOrTsOrTsxOrJsx.test(x); +}; +export const isRejectedDir = (x) => + /node_modules|__tests__|__fixture__|__fixtures__|build\//gm.test(x); +const isGlobFound = (x) => (xs) => (x === xs[0] ? false : true); +export const globExpands = (x) => isGlobFound(x)(prokGlob(x)); +export const tryPath = (x) => { + const isAGlob = isGlob(x); + + if (isAGlob) return globExpands(x) ? right(x) : left(x); + + if (!isAGlob) return pathExists(x).isRight() ? right(x) : left(x); +}; +export const dropEmpty = (x) => x.length > 0; +export const notFound = (log) => (err) => log.error(`\n!!! Not Found: \n${err}`); diff --git a/src/dev/code_coverage/ingest_coverage/team_assignment/flush.js b/src/dev/code_coverage/ingest_coverage/team_assignment/flush.js new file mode 100644 index 0000000000000..5150ac2e655f2 --- /dev/null +++ b/src/dev/code_coverage/ingest_coverage/team_assignment/flush.js @@ -0,0 +1,44 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { writeFileSync } from 'fs'; +import shell from 'shelljs'; +import { tryCatch } from '../either'; +import { id } from '../utils'; + +const encoding = 'utf8'; +const appendUtf8 = { flag: 'a', encoding }; + +export const flush = (dest) => (log) => (assignments) => { + log.verbose(`\n### Flushing assignments to: \n\t${dest}`); + + const writeToFile = writeFileSync.bind(null, dest); + + writeToFile('', { encoding }); + + for (const xs of assignments) xs.forEach((x) => writeToFile(`${x}\n`, appendUtf8)); + + tryCatch(() => maybeShowSize(dest)).fold(id, (x) => { + log.verbose(`\n### Flushed [${x}] lines`); + }); +}; +function maybeShowSize(x) { + const { output } = shell.exec(`wc -l ${x}`, { silent: true }); + return output.match(/\s*\d*\s*/)[0].trim(); +} diff --git a/src/dev/code_coverage/ingest_coverage/team_assignment/get_data.js b/src/dev/code_coverage/ingest_coverage/team_assignment/get_data.js deleted file mode 100644 index 34526a2f79302..0000000000000 --- a/src/dev/code_coverage/ingest_coverage/team_assignment/get_data.js +++ /dev/null @@ -1,33 +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 { readFileSync } from 'fs'; -import { resolve } from 'path'; -import { tryCatch as tc } from '../either'; - -const ROOT = resolve(__dirname, '../../../../..'); - -const resolveFromRoot = resolve.bind(null, ROOT); - -const resolved = (path) => () => resolveFromRoot(path); - -const getContents = (path) => tc(() => readFileSync(path, 'utf8')); - -// fetch :: String -> Left | Right -export const fetch = (path) => tc(resolved(path)).chain(getContents); diff --git a/src/dev/code_coverage/ingest_coverage/team_assignment/index.js b/src/dev/code_coverage/ingest_coverage/team_assignment/index.js index 11f9748708283..30112df3b6ba4 100644 --- a/src/dev/code_coverage/ingest_coverage/team_assignment/index.js +++ b/src/dev/code_coverage/ingest_coverage/team_assignment/index.js @@ -17,42 +17,55 @@ * under the License. */ -import { run } from '@kbn/dev-utils'; -import { TEAM_ASSIGNMENT_PIPELINE_NAME } from '../constants'; -import { fetch } from './get_data'; -import { update } from './update_ingest_pipeline'; +import { run, createFlagError, REPO_ROOT } from '@kbn/dev-utils'; +import { parse } from './parse_owners'; +import { flush } from './flush'; +import { enumeratePatterns } from './enumerate_patterns'; +import { pipe } from '../utils'; +import { reduce } from 'rxjs/operators'; -const updatePipeline = update(TEAM_ASSIGNMENT_PIPELINE_NAME); - -const execute = ({ flags, log }) => { - if (flags.verbose) log.verbose(`### Verbose logging enabled`); - - const logLeft = handleErr(log); - const updateAndLog = updatePipeline(log); - - const { path } = flags; - - fetch(path).fold(logLeft, updateAndLog); +const flags = { + string: ['src', 'dest'], + help: ` +--src Required, path to CODEOWNERS file. +--dest Required, destination path of the assignments. + `, }; -function handleErr(log) { - return (msg) => log.error(msg); -} +export const generateTeamAssignments = () => { + run( + ({ flags, log }) => { + if (flags.src === '') throw createFlagError('please provide a single --src flag'); + if (flags.dest === '') throw createFlagError('please provide a single --dest flag'); -const description = ` + const logCreepAndFlush = pipe( + logSuccess(flags.src, log), + enumeratePatterns(REPO_ROOT)(log), + flush(flags.dest)(log) + ); -Upload the latest team assignment pipeline def from src, -to the cluster. + parse(flags.src).pipe(reduce(toMap, new Map())).subscribe(logCreepAndFlush); + }, + { + description: ` - `; +Create a file defining the team assignments, + parsed from .github/CODEOWNERS -const flags = { - string: ['path', 'verbose'], - help: ` ---path Required, path to painless definition for team assignment. - `, + `, + flags, + } + ); }; -const usage = 'node scripts/load_team_assignment.js --verbose --path PATH_TO_PAINLESS_SCRIPT.json'; +function toMap(acc, x) { + acc.set(x[0], x[1][0]); + return acc; +} -export const uploadTeamAssignmentJson = () => run(execute, { description, flags, usage }); +function logSuccess(src, log) { + return (dataObj) => { + log.verbose(`\n### Parsing [${src}] Complete`); + return dataObj; + }; +} diff --git a/src/dev/code_coverage/ingest_coverage/team_assignment/ingestion_pipeline_painless.json b/src/dev/code_coverage/ingest_coverage/team_assignment/ingestion_pipeline_painless.json deleted file mode 100644 index 017d208133cdc..0000000000000 --- a/src/dev/code_coverage/ingest_coverage/team_assignment/ingestion_pipeline_painless.json +++ /dev/null @@ -1 +0,0 @@ -{"description":"Kibana code coverage team assignments","processors":[{"script":{"lang":"painless","source":"\n String path = ctx.coveredFilePath; \n if (path.indexOf('src/legacy/core_plugins/kibana/') == 0) {\n\n if (path.indexOf('src/legacy/core_plugins/kibana/common/utils') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('src/legacy/core_plugins/kibana/migrations') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('src/legacy/core_plugins/kibana/public') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('src/legacy/core_plugins/kibana/public/dashboard/') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('src/legacy/core_plugins/kibana/public/dev_tools/') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('src/legacy/core_plugins/kibana/public/discover/') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('src/legacy/core_plugins/kibana/public/home') == 0) ctx.team = 'kibana-core-ui';\n else if (path.indexOf('src/legacy/core_plugins/kibana/public/home/np_ready/') == 0) ctx.team = 'kibana-core-ui';\n else if (path.indexOf('src/legacy/core_plugins/kibana/public/local_application_service/') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('src/legacy/core_plugins/kibana/public/management/') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/legacy/core_plugins/kibana/server/lib') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('src/legacy/core_plugins/kibana/server/lib/management/saved_objects') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('src/legacy/core_plugins/kibana/server/routes/api/management/') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/legacy/core_plugins/kibana/server/routes/api/import/') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('src/legacy/core_plugins/kibana/server/routes/api/export/') == 0) ctx.team = 'kibana-platform';\n else ctx.team = 'unknown';\n\n } else if (path.indexOf('src/legacy/core_plugins/') == 0) {\n\n if (path.indexOf('src/legacy/core_plugins/apm_oss/') == 0) ctx.team = 'apm-ui';\n else if (path.indexOf('src/legacy/core_plugins/console_legacy') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('src/legacy/core_plugins/elasticsearch') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('src/legacy/core_plugins/embeddable_api/') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/legacy/core_plugins/input_control_vis') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('src/legacy/core_plugins/interpreter/') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/legacy/core_plugins/kibana_react/') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/legacy/core_plugins/newsfeed') == 0) ctx.team = 'kibana-core-ui';\n else if (path.indexOf('src/legacy/core_plugins/region_map') == 0) ctx.team = 'maps';\n else if (path.indexOf('src/legacy/core_plugins/status_page/public') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/legacy/core_plugins/testbed') == 0) ctx.team = 'kibana-platform';\n // else if (path.indexOf('src/legacy/core_plugins/tests_bundle/') == 0) ctx.team = 'kibana-platform';\n \n else if (path.indexOf('src/legacy/core_plugins/tile_map') == 0) ctx.team = 'maps';\n else if (path.indexOf('src/legacy/core_plugins/timelion') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('src/legacy/core_plugins/ui_metric/') == 0) ctx.team = 'pulse';\n else if (path.indexOf('src/legacy/core_plugins/vis_type_tagcloud') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('src/legacy/core_plugins/vis_type_vega') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('src/legacy/core_plugins/vis_type_vislib/') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('src/legacy/core_plugins/visualizations/') == 0) ctx.team = 'kibana-app-arch';\n else ctx.team = 'unknown';\n\n } else if (path.indexOf('src/legacy/server/') == 0) {\n\n if (path.indexOf('src/legacy/server/config/') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('src/legacy/server/http/') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('src/legacy/server/i18n/') == 0) ctx.team = 'kibana-localization';\n else if (path.indexOf('src/legacy/server/index_patterns/') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/legacy/server/keystore/') == 0) ctx.team = 'kibana-operations';\n else if (path.indexOf('src/legacy/server/logging/') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('src/legacy/server/pid/') == 0) ctx.team = 'kibana-operations';\n else if (path.indexOf('src/legacy/server/sample_data/') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('src/legacy/server/sass/') == 0) ctx.team = 'kibana-operations';\n else if (path.indexOf('src/legacy/server/saved_objects/') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('src/legacy/server/status/') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('src/legacy/server/url_shortening/') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('src/legacy/server/utils/') == 0) ctx.team = 'kibana-operations';\n else if (path.indexOf('src/legacy/server/warnings/') == 0) ctx.team = 'kibana-operations';\n else ctx.team = 'unknown';\n\n } else if (path.indexOf('src/legacy/ui') == 0) {\n\n if (path.indexOf('src/legacy/ui/public/field_editor') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/legacy/ui/public/timefilter') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/legacy/ui/public/management') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/legacy/ui/public/state_management') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('src/legacy/ui/public/new_platform') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('src/legacy/ui/public/plugin_discovery') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('src/legacy/ui/public/chrome') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('src/legacy/ui/public/notify') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('src/legacy/ui/public/documentation_links') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('src/legacy/ui/public/autoload') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('src/legacy/ui/public/capabilities') == 0) ctx.team = 'kibana-security';\n else if (path.indexOf('src/legacy/ui/public/apm') == 0) ctx.team = 'apm-ui';\n\n } else if (path.indexOf('src/plugins/') == 0) {\n\n if (path.indexOf('src/plugins/advanced_settings/') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/plugins/apm_oss/') == 0) ctx.team = 'apm-ui';\n else if (path.indexOf('src/plugins/bfetch/') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/plugins/charts/') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/plugins/charts/public/static/color_maps') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('src/plugins/console/') == 0) ctx.team = 'es-ui';\n else if (path.indexOf('src/plugins/dashboard/') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('src/plugins/data/') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/plugins/dev_tools/') == 0) ctx.team = 'es-ui';\n else if (path.indexOf('src/plugins/discover/') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('src/plugins/embeddable/') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/plugins/es_ui_shared/') == 0) ctx.team = 'es-ui';\n else if (path.indexOf('src/plugins/expressions/') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/plugins/home/public') == 0) ctx.team = 'kibana-core-ui';\n else if (path.indexOf('src/plugins/home/server/tutorials') == 0) ctx.team = 'observability';\n else if (path.indexOf('src/plugins/home/server/services/') == 0) ctx.team = 'kibana-core-ui';\n else if (path.indexOf('src/plugins/home/') == 0) ctx.team = 'kibana-core-ui';\n else if (path.indexOf('src/plugins/index_pattern_management/public/service') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/plugins/index_pattern_management/public') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('src/plugins/input_control_vis/') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('src/plugins/inspector/') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/plugins/kibana_legacy/') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('src/plugins/kibana_react/public/code_editor') == 0) ctx.team = 'kibana-canvas';\n else if (path.indexOf('src/plugins/kibana_react/') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/plugins/kibana_utils/') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/plugins/management/') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/plugins/kibana_usage_collection/') == 0) ctx.team = 'pulse';\n else if (path.indexOf('src/plugins/legacy_export/') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('src/plugins/maps_legacy/') == 0) ctx.team = 'maps';\n else if (path.indexOf('src/plugins/region_map/') == 0) ctx.team = 'maps';\n else if (path.indexOf('src/plugins/tile_map/') == 0) ctx.team = 'maps';\n else if (path.indexOf('src/plugins/timelion') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('src/plugins/navigation/') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/plugins/newsfeed') == 0) ctx.team = 'kibana-core-ui';\n else if (path.indexOf('src/plugins/saved_objects_management/') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('src/plugins/saved_objects/') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/plugins/share/') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/plugins/status_page/') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('src/plugins/telemetry') == 0) ctx.team = 'pulse';\n else if (path.indexOf('src/plugins/testbed/server/') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('src/plugins/ui_actions/') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/plugins/usage_collection/') == 0) ctx.team = 'pulse';\n else if (path.indexOf('src/plugins/vis_default_editor') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/plugins/vis_type') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('src/plugins/visualizations/') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('src/plugins/visualize/') == 0) ctx.team = 'kibana-app';\n else ctx.team = 'unknown';\n\n } else if (path.indexOf('x-pack/legacy/') == 0) {\n\n if (path.indexOf('x-pack/legacy/plugins/actions/') == 0) ctx.team = 'kibana-alerting-services';\n else if (path.indexOf('x-pack/legacy/plugins/alerting/') == 0) ctx.team = 'kibana-alerting-services';\n else if (path.indexOf('x-pack/legacy/plugins/apm/') == 0) ctx.team = 'apm-ui';\n else if (path.indexOf('x-pack/legacy/plugins/beats_management/') == 0) ctx.team = 'beats';\n else if (path.indexOf('x-pack/legacy/plugins/canvas/') == 0) ctx.team = 'kibana-canvas';\n else if (path.indexOf('x-pack/legacy/plugins/cross_cluster_replication/') == 0) ctx.team = 'es-ui';\n else if (path.indexOf('x-pack/legacy/plugins/dashboard_mode/') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('x-pack/legacy/plugins/encrypted_saved_objects/') == 0) ctx.team = 'kibana-security';\n else if (path.indexOf('x-pack/legacy/plugins/index_management/') == 0) ctx.team = 'es-ui';\n else if (path.indexOf('x-pack/legacy/plugins/infra/') == 0) ctx.team = 'logs-metrics-ui';\n else if (path.indexOf('x-pack/legacy/plugins/ingest_manager/') == 0) ctx.team = 'ingest-management';\n else if (path.indexOf('x-pack/legacy/plugins/license_management/') == 0) ctx.team = 'es-ui';\n else if (path.indexOf('x-pack/legacy/plugins/maps/') == 0) ctx.team = 'kibana-gis';\n else if (path.indexOf('x-pack/legacy/plugins/ml/') == 0) ctx.team = 'ml-ui';\n else if (path.indexOf('x-pack/legacy/plugins/monitoring/') == 0) ctx.team = 'stack-monitoring-ui';\n else if (path.indexOf('x-pack/legacy/plugins/reporting') == 0) ctx.team = 'kibana-reporting';\n else if (path.indexOf('x-pack/legacy/plugins/rollup/') == 0) ctx.team = 'es-ui';\n else if (path.indexOf('x-pack/legacy/plugins/security/') == 0) ctx.team = 'kibana-security';\n else if (path.indexOf('x-pack/legacy/plugins/siem/') == 0) ctx.team = 'siem';\n else if (path.indexOf('x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules') == 0) ctx.team = 'security-intelligence-analytics';\n else if (path.indexOf('x-pack/legacy/plugins/snapshot_restore/') == 0) ctx.team = 'es-ui';\n else if (path.indexOf('x-pack/legacy/plugins/task_manager') == 0) ctx.team = 'kibana-alerting-services';\n else if (path.indexOf('x-pack/legacy/plugins/triggers_actions_ui/') == 0) ctx.team = 'kibana-alerting-services';\n else if (path.indexOf('x-pack/legacy/plugins/upgrade_assistant/') == 0) ctx.team = 'es-ui';\n else if (path.indexOf('x-pack/legacy/plugins/uptime') == 0) ctx.team = 'uptime';\n else if (path.indexOf('x-pack/legacy/plugins/xpack_main/server/') == 0) ctx.team = 'kibana-platform';\n\n else if (path.indexOf('x-pack/legacy/server/lib/create_router/') == 0) ctx.team = 'es-ui';\n else if (path.indexOf('x-pack/legacy/server/lib/check_license/') == 0) ctx.team = 'es-ui'; \n else if (path.indexOf('x-pack/legacy/server/lib/') == 0) ctx.team = 'kibana-platform'; \n else ctx.team = 'unknown';\n\n } else if (path.indexOf('x-pack/plugins/') == 0) {\n\n if (path.indexOf('x-pack/plugins/actions/') == 0) ctx.team = 'kibana-alerting-services';\n else if (path.indexOf('x-pack/plugins/advanced_ui_actions/') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('x-pack/plugins/alerts') == 0) ctx.team = 'kibana-alerting-services';\n else if (path.indexOf('x-pack/plugins/alerting_builtins') == 0) ctx.team = 'kibana-alerting-services';\n else if (path.indexOf('x-pack/plugins/apm/') == 0) ctx.team = 'apm-ui';\n else if (path.indexOf('x-pack/plugins/beats_management/') == 0) ctx.team = 'beats';\n else if (path.indexOf('x-pack/plugins/canvas/') == 0) ctx.team = 'kibana-canvas';\n else if (path.indexOf('x-pack/plugins/case') == 0) ctx.team = 'siem';\n else if (path.indexOf('x-pack/plugins/cloud/') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('x-pack/plugins/code/') == 0) ctx.team = 'code';\n else if (path.indexOf('x-pack/plugins/console_extensions/') == 0) ctx.team = 'es-ui';\n else if (path.indexOf('x-pack/plugins/cross_cluster_replication/') == 0) ctx.team = 'es-ui';\n else if (path.indexOf('x-pack/plugins/dashboard_enhanced') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('x-pack/plugins/dashboard_mode') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('x-pack/plugins/discover_enhanced') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('x-pack/plugins/embeddable_enhanced') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('x-pack/plugins/data_enhanced/') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('x-pack/plugins/drilldowns/') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('x-pack/plugins/encrypted_saved_objects/') == 0) ctx.team = 'kibana-security';\n else if (path.indexOf('x-pack/plugins/endpoint/') == 0) ctx.team = 'endpoint-app-team';\n else if (path.indexOf('x-pack/plugins/es_ui_shared/') == 0) ctx.team = 'es-ui';\n else if (path.indexOf('x-pack/plugins/event_log/') == 0) ctx.team = 'kibana-alerting-services';\n else if (path.indexOf('x-pack/plugins/features/') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('x-pack/plugins/file_upload') == 0) ctx.team = 'kibana-gis';\n else if (path.indexOf('x-pack/plugins/global_search') == 0) ctx.team = 'kibana-platform';\n \n else if (path.indexOf('x-pack/plugins/graph/') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('x-pack/plugins/grokdebugger/') == 0) ctx.team = 'es-ui';\n else if (path.indexOf('x-pack/plugins/index_lifecycle_management/') == 0) ctx.team = 'es-ui';\n else if (path.indexOf('x-pack/plugins/index_management/') == 0) ctx.team = 'es-ui';\n else if (path.indexOf('x-pack/plugins/infra/') == 0) ctx.team = 'logs-metrics-ui';\n else if (path.indexOf('x-pack/plugins/ingest_manager/') == 0) ctx.team = 'ingest-management';\n else if (path.indexOf('x-pack/plugins/ingest_pipelines/') == 0) ctx.team = 'es-ui';\n \n else if (path.indexOf('x-pack/plugins/lens/') == 0) ctx.team = 'kibana-app';\n else if (path.indexOf('x-pack/plugins/license_management/') == 0) ctx.team = 'es-ui';\n else if (path.indexOf('x-pack/plugins/licensing/') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('x-pack/plugins/lists/') == 0) ctx.team = 'siem';\n else if (path.indexOf('x-pack/plugins/logstash') == 0) ctx.team = 'logstash';\n else if (path.indexOf('x-pack/plugins/maps/') == 0) ctx.team = 'kibana-gis';\n else if (path.indexOf('x-pack/plugins/maps_legacy_licensing') == 0) ctx.team = 'maps';\n else if (path.indexOf('x-pack/plugins/ml/') == 0) ctx.team = 'ml-ui';\n else if (path.indexOf('x-pack/plugins/monitoring') == 0) ctx.team = 'stack-monitoring-ui';\n else if (path.indexOf('x-pack/plugins/observability/') == 0) ctx.team = 'apm-ui';\n else if (path.indexOf('x-pack/plugins/oss_telemetry/') == 0) ctx.team = 'pulse';\n else if (path.indexOf('x-pack/plugins/painless_lab/') == 0) ctx.team = 'es-ui';\n else if (path.indexOf('x-pack/plugins/remote_clusters/') == 0) ctx.team = 'es-ui';\n else if (path.indexOf('x-pack/plugins/reporting') == 0) ctx.team = 'kibana-reporting';\n else if (path.indexOf('x-pack/plugins/rollup/') == 0) ctx.team = 'es-ui';\n else if (path.indexOf('x-pack/plugins/searchprofiler/') == 0) ctx.team = 'es-ui';\n else if (path.indexOf('x-pack/plugins/security/') == 0) ctx.team = 'kibana-security';\n else if (path.indexOf('x-pack/plugins/security_solution/') == 0) ctx.team = 'siem';\n \n else if (path.indexOf('x-pack/plugins/siem/server/lib/detection_engine/rules/prepackaged_rules') == 0) ctx.team = 'security-intelligence-analytics';\n else if (path.indexOf('x-pack/plugins/siem/') == 0) ctx.team = 'siem';\n else if (path.indexOf('x-pack/plugins/snapshot_restore/') == 0) ctx.team = 'es-ui';\n else if (path.indexOf('x-pack/plugins/spaces/') == 0) ctx.team = 'kibana-security';\n else if (path.indexOf('x-pack/plugins/task_manager/') == 0) ctx.team = 'kibana-alerting-services';\n else if (path.indexOf('x-pack/plugins/telemetry_collection_xpack/') == 0) ctx.team = 'pulse';\n else if (path.indexOf('x-pack/plugins/transform/') == 0) ctx.team = 'ml-ui';\n else if (path.indexOf('x-pack/plugins/translations/') == 0) ctx.team = 'kibana-localization';\n else if (path.indexOf('x-pack/plugins/triggers_actions_ui/') == 0) ctx.team = 'kibana-alerting-services';\n else if (path.indexOf('x-pack/plugins/upgrade_assistant/') == 0) ctx.team = 'es-ui';\n else if (path.indexOf('x-pack/plugins/ui_actions_enhanced') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('x-pack/plugins/uptime') == 0) ctx.team = 'uptime';\n \n else if (path.indexOf('x-pack/plugins/watcher/') == 0) ctx.team = 'es-ui';\n else ctx.team = 'unknown';\n\n } else if (path.indexOf('packages') == 0) {\n\n if (path.indexOf('packages/kbn-analytics/') == 0) ctx.team = 'pulse';\n else if (path.indexOf('packages/kbn-babel') == 0) ctx.team = 'kibana-operations';\n else if (path.indexOf('packages/kbn-config-schema/') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('packages/elastic-datemath') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('packages/kbn-dev-utils') == 0) ctx.team = 'kibana-operations';\n else if (path.indexOf('packages/kbn-es/') == 0) ctx.team = 'kibana-operations';\n else if (path.indexOf('packages/kbn-eslint') == 0) ctx.team = 'kibana-operations';\n else if (path.indexOf('packages/kbn-expect') == 0) ctx.team = 'kibana-operations';\n else if (path.indexOf('packages/kbn-i18n/') == 0) ctx.team = 'kibana-localization';\n else if (path.indexOf('packages/kbn-interpreter/') == 0) ctx.team = 'kibana-app-arch';\n else if (path.indexOf('packages/kbn-optimizer/') == 0) ctx.team = 'kibana-operations';\n else if (path.indexOf('packages/kbn-pm/') == 0) ctx.team = 'kibana-operations';\n else if (path.indexOf('packages/kbn-test/') == 0) ctx.team = 'kibana-operations';\n else if (path.indexOf('packages/kbn-test-subj-selector/') == 0) ctx.team = 'kibana-operations';\n else if (path.indexOf('packages/kbn-ui-framework/') == 0) ctx.team = 'kibana-design';\n else if (path.indexOf('packages/kbn-ui-shared-deps/') == 0) ctx.team = 'kibana-operations';\n else ctx.team = 'unknown';\n\n } else {\n\n if (path.indexOf('config/kibana.yml') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('src/apm.js') == 0) ctx.team = 'apm-ui';\n else if (path.indexOf('src/core/') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('src/core/public/i18n/') == 0) ctx.team = 'kibana-localization';\n else if (path.indexOf('src/core/server/csp/') == 0) ctx.team = 'kibana-security';\n else if (path.indexOf('src/dev/') == 0) ctx.team = 'kibana-operations';\n else if (path.indexOf('src/dev/i18n/') == 0) ctx.team = 'kibana-localization';\n else if (path.indexOf('src/dev/run_check_published_api_changes.ts') == 0) ctx.team = 'kibana-platform';\n else if (path.indexOf('packages/kbn-es-archiver/') == 0) ctx.team = 'kibana-operations';\n else if (path.indexOf('src/optimize/') == 0) ctx.team = 'kibana-operations';\n else if (path.indexOf('src/setup_node_env/') == 0) ctx.team = 'kibana-operations';\n else if (path.indexOf('src/test_utils/') == 0) ctx.team = 'kibana-operations'; \n else ctx.team = 'unknown';\n }"}}]} diff --git a/src/dev/code_coverage/ingest_coverage/team_assignment/parse_owners.js b/src/dev/code_coverage/ingest_coverage/team_assignment/parse_owners.js new file mode 100644 index 0000000000000..a07d556c9b403 --- /dev/null +++ b/src/dev/code_coverage/ingest_coverage/team_assignment/parse_owners.js @@ -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. + */ + +import { fromEvent } from 'rxjs'; +import { map, filter, takeUntil } from 'rxjs/operators'; +import { lineRead, pathAndTeams, empties, comments, dropCCDelim } from './parse_owners_helpers'; +import { pipe } from '../utils'; + +const cleanAndParse = pipe(dropCCDelim, pathAndTeams); + +const allLines$ = (lineReader) => + fromEvent(lineReader, 'line').pipe( + filter(empties), + filter(comments), + map(cleanAndParse), + takeUntil(fromEvent(lineReader, 'close')) + ); + +export const parse = (codeOwnersPath) => allLines$(lineRead(codeOwnersPath)); diff --git a/src/dev/code_coverage/ingest_coverage/team_assignment/parse_owners_helpers.js b/src/dev/code_coverage/ingest_coverage/team_assignment/parse_owners_helpers.js new file mode 100644 index 0000000000000..454accb00a7b6 --- /dev/null +++ b/src/dev/code_coverage/ingest_coverage/team_assignment/parse_owners_helpers.js @@ -0,0 +1,48 @@ +/* + * 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 { always, id, pipe } from '../utils'; +import * as Either from '../either'; +import readline from 'readline'; +import { createReadStream } from 'fs'; +import { pluckIndex } from '../transforms'; + +const coverageDelimRe = /^#CC#\s/; + +export const empties = (x) => x !== ''; +export const comments = (x) => !/^#\s{1,3}/.test(x); +const dropDelim = (x) => () => x.replace(coverageDelimRe, ''); + +export const dropCCDelim = (x) => + Either.fromNullable(coverageDelimRe.test(x)).fold(always(x), id(dropDelim(x))); + +const splitFilter = (splitter) => (x) => x.split(splitter).filter(empties); +const spaceSplit = splitFilter(' '); +const esSplit = splitFilter('@elastic/'); +const getFirst = pluckIndex(0); +const trimEsGrabFirst = pipe(esSplit, getFirst); + +export const pathAndTeams = (x) => { + const [path, ...teamEntries] = spaceSplit(x); + const teams = teamEntries.map(trimEsGrabFirst); + + return [path, teams]; +}; + +export const lineRead = (x) => readline.createInterface({ input: createReadStream(x) }); diff --git a/src/dev/code_coverage/ingest_coverage/team_assignment/parsing_helpers.js b/src/dev/code_coverage/ingest_coverage/team_assignment/parsing_helpers.js new file mode 100644 index 0000000000000..50dd6f719f34e --- /dev/null +++ b/src/dev/code_coverage/ingest_coverage/team_assignment/parsing_helpers.js @@ -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. + */ + +import { always } from '../utils'; +import * as Either from '../either'; + +const coverageDelimRe = /^#CC#\s/; + +export const empties = (x) => x !== ''; +export const comments = (x) => !/^#\s{1,3}/.test(x); +const dropDelim = (x) => x.replace(coverageDelimRe, ''); + +export const dropCCDelim = (x) => + Either.fromNullable(coverageDelimRe.test(x)).fold(always(x), always(dropDelim(x))); diff --git a/src/dev/code_coverage/ingest_coverage/team_assignment/update_ingest_pipeline.js b/src/dev/code_coverage/ingest_coverage/team_assignment/update_ingest_pipeline.js deleted file mode 100644 index 22a9d0a461ebf..0000000000000 --- a/src/dev/code_coverage/ingest_coverage/team_assignment/update_ingest_pipeline.js +++ /dev/null @@ -1,37 +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 { createFailError } from '@kbn/dev-utils'; -import { ES_HOST } from '../constants'; -import { pretty, green } from '../utils'; - -const { Client } = require('@elastic/elasticsearch'); - -const node = ES_HOST; -const client = new Client({ node }); - -export const update = (id) => (log) => async (body) => { - try { - await client.ingest.putPipeline({ id, body }); - log.verbose(`### Ingestion Pipeline ID: ${green(id)}`); - log.verbose(`### Payload Partial: \n${body.slice(0, 600)}...`); - } catch (e) { - throw createFailError(`${pretty(e.meta)}`); - } -}; diff --git a/src/dev/code_coverage/ingest_coverage/transforms.js b/src/dev/code_coverage/ingest_coverage/transforms.js index b8c9acd6fc49d..ff6ffd46462ed 100644 --- a/src/dev/code_coverage/ingest_coverage/transforms.js +++ b/src/dev/code_coverage/ingest_coverage/transforms.js @@ -18,8 +18,12 @@ */ import * as Either from './either'; -import { fromNullable } from './maybe'; -import { always, id, noop } from './utils'; +import * as Maybe from './maybe'; +import { always, id, noop, pink } from './utils'; +import execa from 'execa'; +import { resolve } from 'path'; + +const ROOT_DIR = resolve(__dirname, '../../../..'); const maybeTotal = (x) => (x === 'total' ? Either.left(x) : Either.right(x)); @@ -83,20 +87,60 @@ export const staticSite = (urlBase) => (obj) => { return { ...obj, staticSiteUrl: prokForBoth() }; }; +const leadingSlashRe = /^\//; +export const maybeDropLeadingSlash = (x) => + leadingSlashRe.test(x) ? Either.right(x) : Either.left(x); +export const dropLeadingSlash = (x) => x.replace(leadingSlashRe, ''); +export const stripLeading = (x) => maybeDropLeadingSlash(x).fold(id, dropLeadingSlash); + export const coveredFilePath = (obj) => { const { staticSiteUrl, COVERAGE_INGESTION_KIBANA_ROOT } = obj; const withoutCoveredFilePath = always(obj); - const leadingSlashRe = /^\//; - const maybeDropLeadingSlash = (x) => (leadingSlashRe.test(x) ? Either.right(x) : Either.left(x)); - const dropLeadingSlash = (x) => x.replace(leadingSlashRe, ''); - const dropRoot = (root) => (x) => - maybeDropLeadingSlash(x.replace(root, '')).fold(id, dropLeadingSlash); + const dropRoot = (root) => (x) => stripLeading(x.replace(root, '')); return maybeTotal(staticSiteUrl) .map(dropRoot(COVERAGE_INGESTION_KIBANA_ROOT)) .fold(withoutCoveredFilePath, (coveredFilePath) => ({ ...obj, coveredFilePath })); }; +const findTeam = (x) => x.match(/.+\s{1,3}(.+)$/, 'gm'); +export const pluckIndex = (idx) => (xs) => xs[idx]; +const pluckTeam = pluckIndex(1); + +export const teamAssignment = (teamAssignmentsPath) => (log) => async (obj) => { + const { coveredFilePath } = obj; + const isTotal = Either.fromNullable(obj.isTotal); + + return isTotal.isRight() ? obj : await assignTeam(teamAssignmentsPath, coveredFilePath, log, obj); +}; +export const last = (x) => { + const xs = x.split('\n'); + const len = xs.length; + + return len === 1 ? xs[0] : xs[len - 1]; +}; +async function assignTeam(teamAssignmentsPath, coveredFilePath, log, obj) { + const params = [coveredFilePath, teamAssignmentsPath]; + + let grepResponse; + + try { + const { stdout } = await execa('grep', params, { cwd: ROOT_DIR }); + grepResponse = stdout; + } catch (e) { + log.error(`\n!!! Unknown Team for path: \n\t\t${pink(coveredFilePath)}\n`); + } + + return Either.fromNullable(grepResponse) + .map(last) + .map(findTeam) + .map(pluckTeam) + .fold( + () => ({ team: 'unknown', ...obj }), + (team) => ({ team, ...obj }) + ); +} + export const ciRunUrl = (obj) => Either.fromNullable(process.env.CI_RUN_URL).fold(always(obj), (ciRunUrl) => ({ ...obj, @@ -126,13 +170,12 @@ export const itemizeVcs = (vcsInfo) => (obj) => { }; const mutateVcs = (x) => (vcs.commitMsg = truncateMsg(x)); - fromNullable(commitMsg).map(mutateVcs); + Maybe.fromNullable(commitMsg).map(mutateVcs); const vcsCompareUrl = process.env.FETCHED_PREVIOUS ? `${comparePrefix()}/${process.env.FETCHED_PREVIOUS}...${sha}` : 'PREVIOUS SHA NOT PROVIDED'; - // const withoutPreviousL = always({ ...obj, vcs }); const withPreviousR = () => ({ ...obj, vcs: { diff --git a/src/dev/code_coverage/ingest_coverage/utils.js b/src/dev/code_coverage/ingest_coverage/utils.js index 7d817bdf7a6f3..e854e3d3b7248 100644 --- a/src/dev/code_coverage/ingest_coverage/utils.js +++ b/src/dev/code_coverage/ingest_coverage/utils.js @@ -22,6 +22,10 @@ import chalk from 'chalk'; export const pipe = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args))); export const noop = () => {}; export const green = (x) => chalk.greenBright.bold(x); +export const pink = (x) => chalk.bgMagenta.bold.cyan.bold(x); export const id = (x) => x; -export const always = (x) => () => x; +export const always = (x) => () => x; // Wraps a value in a fn. Eager evaluation if passed a fn. export const pretty = (x) => JSON.stringify(x, null, 2); +export const reThrow = (e) => { + throw e; +}; diff --git a/src/dev/code_coverage/shell_scripts/assign_teams.sh b/src/dev/code_coverage/shell_scripts/assign_teams.sh deleted file mode 100644 index aaa14655a9a26..0000000000000 --- a/src/dev/code_coverage/shell_scripts/assign_teams.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -echo "### Code Coverage Team Assignment" -echo "" - -PIPELINE_NAME=$1 -export PIPELINE_NAME - -ES_HOST="https://${USER_FROM_VAULT}:${PASS_FROM_VAULT}@${HOST_FROM_VAULT}" -export ES_HOST - -node scripts/load_team_assignment.js --verbose --path src/dev/code_coverage/ingest_coverage/team_assignment/ingestion_pipeline_painless.json - -echo "### Code Coverage Team Assignment - Complete" -echo "" diff --git a/src/dev/code_coverage/shell_scripts/generate_team_assignments_and_ingest_coverage.sh b/src/dev/code_coverage/shell_scripts/generate_team_assignments_and_ingest_coverage.sh new file mode 100644 index 0000000000000..62b81929ae79b --- /dev/null +++ b/src/dev/code_coverage/shell_scripts/generate_team_assignments_and_ingest_coverage.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +echo "### Ingesting Code Coverage" +echo "" + +COVERAGE_JOB_NAME=$1 +export COVERAGE_JOB_NAME +echo "### debug COVERAGE_JOB_NAME: ${COVERAGE_JOB_NAME}" + +BUILD_ID=$2 +export BUILD_ID + +CI_RUN_URL=$3 +export CI_RUN_URL +echo "### debug CI_RUN_URL: ${CI_RUN_URL}" + +FETCHED_PREVIOUS=$4 +export FETCHED_PREVIOUS +echo "### debug FETCHED_PREVIOUS: ${FETCHED_PREVIOUS}" + +ES_HOST="https://${USER_FROM_VAULT}:${PASS_FROM_VAULT}@${HOST_FROM_VAULT}" +export ES_HOST + +STATIC_SITE_URL_BASE='https://kibana-coverage.elastic.dev' +export STATIC_SITE_URL_BASE + +DELAY=100 +export DELAY + +TEAM_ASSIGN_PATH=$5 + +# Build team assignments dat file +node scripts/generate_team_assignments.js --verbose --src .github/CODEOWNERS --dest $TEAM_ASSIGN_PATH + +for x in jest functional; do + echo "### Ingesting coverage for ${x}" + + COVERAGE_SUMMARY_FILE=target/kibana-coverage/${x}-combined/coverage-summary.json + + node scripts/ingest_coverage.js --verbose --path ${COVERAGE_SUMMARY_FILE} --vcsInfoPath ./VCS_INFO.txt --teamAssignmentsPath $TEAM_ASSIGN_PATH +done + +# Need to override COVERAGE_INGESTION_KIBANA_ROOT since mocha json file has original intake worker path +COVERAGE_SUMMARY_FILE=target/kibana-coverage/mocha-combined/coverage-summary.json +export COVERAGE_INGESTION_KIBANA_ROOT=/dev/shm/workspace/kibana + +node scripts/ingest_coverage.js --verbose --path ${COVERAGE_SUMMARY_FILE} --vcsInfoPath ./VCS_INFO.txt --teamAssignmentsPath $TEAM_ASSIGN_PATH + +echo "### Ingesting Code Coverage - Complete" +echo "" diff --git a/src/dev/code_coverage/shell_scripts/ingest_coverage.sh b/src/dev/code_coverage/shell_scripts/ingest_coverage.sh deleted file mode 100644 index 0b67dac307473..0000000000000 --- a/src/dev/code_coverage/shell_scripts/ingest_coverage.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/bash - -echo "### Ingesting Code Coverage" -echo "" - -COVERAGE_JOB_NAME=$1 -export COVERAGE_JOB_NAME -echo "### debug COVERAGE_JOB_NAME: ${COVERAGE_JOB_NAME}" - -BUILD_ID=$2 -export BUILD_ID - -CI_RUN_URL=$3 -export CI_RUN_URL -echo "### debug CI_RUN_URL: ${CI_RUN_URL}" - -FETCHED_PREVIOUS=$4 -export FETCHED_PREVIOUS -echo "### debug FETCHED_PREVIOUS: ${FETCHED_PREVIOUS}" - -ES_HOST="https://${USER_FROM_VAULT}:${PASS_FROM_VAULT}@${HOST_FROM_VAULT}" -export ES_HOST - -STATIC_SITE_URL_BASE='https://kibana-coverage.elastic.dev' -export STATIC_SITE_URL_BASE - -DELAY=100 -export DELAY - -for x in jest functional; do - echo "### Ingesting coverage for ${x}" - - COVERAGE_SUMMARY_FILE=target/kibana-coverage/${x}-combined/coverage-summary.json - - node scripts/ingest_coverage.js --verbose --path ${COVERAGE_SUMMARY_FILE} --vcsInfoPath ./VCS_INFO.txt -done - -# Need to override COVERAGE_INGESTION_KIBANA_ROOT since mocha json file has original intake worker path -COVERAGE_SUMMARY_FILE=target/kibana-coverage/mocha-combined/coverage-summary.json -export COVERAGE_INGESTION_KIBANA_ROOT=/dev/shm/workspace/kibana - -node scripts/ingest_coverage.js --verbose --path ${COVERAGE_SUMMARY_FILE} --vcsInfoPath ./VCS_INFO.txt - -echo "### Ingesting Code Coverage - Complete" -echo "" diff --git a/src/dev/jest/setup/babel_polyfill.js b/src/dev/jest/setup/babel_polyfill.js index 58325c1a67f94..085c8e2a25eef 100644 --- a/src/dev/jest/setup/babel_polyfill.js +++ b/src/dev/jest/setup/babel_polyfill.js @@ -20,4 +20,4 @@ // 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 // reason it did not work. See https://github.com/elastic/kibana/issues/14506 -import '../../../setup_node_env/babel_register/polyfill'; +import '@kbn/optimizer/src/node/polyfill'; diff --git a/src/dev/jest/setup/react_testing_library.js b/src/dev/jest/setup/react_testing_library.js index 84b5b6096e79b..90f73b04dc210 100644 --- a/src/dev/jest/setup/react_testing_library.js +++ b/src/dev/jest/setup/react_testing_library.js @@ -19,14 +19,13 @@ import '@testing-library/jest-dom'; /** - * Have to import "/pure" here to not register afterEach() hook clean up - * in the very beginning. There are couple tests which fail with clean up hook. - * On CI they run before first test which imports '@testing-library/react' - * and registers afterEach hook so the whole suite is passing. - * This have to be fixed as we depend on test order execution + * PLEASE NOTE: + * Importing '@testing-library/react' registers an `afterEach(cleanup)` side effect. + * It has tricky code that flushes pending promises, that previously led to unpredictable test failures * https://github.com/elastic/kibana/issues/59469 + * But since newer versions it has stabilised itself */ -import { configure } from '@testing-library/react/pure'; +import { configure } from '@testing-library/react'; // instead of default 'data-testid', use kibana's 'data-test-subj' configure({ testIdAttribute: 'data-test-subj', asyncUtilTimeout: 4500 }); diff --git a/src/dev/precommit_hook/casing_check_config.js b/src/dev/precommit_hook/casing_check_config.js index ba58dcdfa4d58..9cd6ca6801bc3 100644 --- a/src/dev/precommit_hook/casing_check_config.js +++ b/src/dev/precommit_hook/casing_check_config.js @@ -50,14 +50,12 @@ export const IGNORE_FILE_GLOBS = [ 'vars/*', '.ci/pipeline-library/**/*', - // Files in this directory must match a pre-determined name in some cases. - 'x-pack/plugins/canvas/storybook/*', - // filename must match language code which requires capital letters '**/translations/*.json', - // filename is required by storybook - 'packages/kbn-storybook/storybook_config/preview-head.html', + // Storybook has predetermined filesnames + '**/preview-body.html', + '**/preview-head.html', // filename required by api-extractor 'api-documenter.json', diff --git a/src/dev/run_check_published_api_changes.ts b/src/dev/run_check_published_api_changes.ts index 28e8570812915..984e013114c9e 100644 --- a/src/dev/run_check_published_api_changes.ts +++ b/src/dev/run_check_published_api_changes.ts @@ -230,6 +230,11 @@ async function run(folder: string, { opts }: { opts: Options }): Promise`, diff --git a/src/dev/typescript/build_refs.ts b/src/dev/typescript/build_refs.ts index cbb596c185f8b..de006bd674e87 100644 --- a/src/dev/typescript/build_refs.ts +++ b/src/dev/typescript/build_refs.ts @@ -18,12 +18,18 @@ */ import execa from 'execa'; +import Path from 'path'; import { run, ToolingLog } from '@kbn/dev-utils'; -export async function buildRefs(log: ToolingLog) { +export async function buildAllRefs(log: ToolingLog) { + await buildRefs(log, 'tsconfig.refs.json'); + await buildRefs(log, Path.join('x-pack', 'tsconfig.refs.json')); +} + +async function buildRefs(log: ToolingLog, projectPath: string) { try { - log.info('Building TypeScript projects refs...'); - await execa(require.resolve('typescript/bin/tsc'), ['-b', 'tsconfig.refs.json']); + log.debug(`Building TypeScript projects refs for ${projectPath}...`); + await execa(require.resolve('typescript/bin/tsc'), ['-b', projectPath]); } catch (e) { log.error(e); process.exit(1); @@ -31,7 +37,18 @@ export async function buildRefs(log: ToolingLog) { } export async function runBuildRefs() { - run(async ({ log }) => { - await buildRefs(log); - }); + run( + async ({ log, flags }) => { + await buildRefs(log, flags.project as string); + }, + { + description: 'Build TypeScript projects', + flags: { + string: ['project'], + help: ` +--project Required, path to the tsconfig.refs.file + `, + }, + } + ); } diff --git a/src/dev/typescript/projects.ts b/src/dev/typescript/projects.ts index 4d1e549e192b6..9891e9fa02c82 100644 --- a/src/dev/typescript/projects.ts +++ b/src/dev/typescript/projects.ts @@ -24,11 +24,11 @@ import { Project } from './project'; export const PROJECTS = [ new Project(resolve(REPO_ROOT, 'tsconfig.json')), - new Project(resolve(REPO_ROOT, 'src/test_utils/tsconfig.json')), - new Project(resolve(REPO_ROOT, 'src/core/tsconfig.json')), new Project(resolve(REPO_ROOT, 'test/tsconfig.json'), { name: 'kibana/test' }), new Project(resolve(REPO_ROOT, 'x-pack/tsconfig.json')), new Project(resolve(REPO_ROOT, 'x-pack/test/tsconfig.json'), { name: 'x-pack/test' }), + new Project(resolve(REPO_ROOT, 'src/test_utils/tsconfig.json')), + new Project(resolve(REPO_ROOT, 'src/core/tsconfig.json')), new Project(resolve(REPO_ROOT, 'x-pack/plugins/security_solution/cypress/tsconfig.json'), { name: 'security_solution/cypress', }), @@ -47,6 +47,12 @@ export const PROJECTS = [ ...glob .sync('packages/*/tsconfig.json', { cwd: REPO_ROOT }) .map((path) => new Project(resolve(REPO_ROOT, path))), + ...glob + .sync('src/plugins/*/tsconfig.json', { cwd: REPO_ROOT }) + .map((path) => new Project(resolve(REPO_ROOT, path))), + ...glob + .sync('x-pack/plugins/*/tsconfig.json', { cwd: REPO_ROOT }) + .map((path) => new Project(resolve(REPO_ROOT, path))), ...glob .sync('examples/*/tsconfig.json', { cwd: REPO_ROOT }) .map((path) => new Project(resolve(REPO_ROOT, path))), diff --git a/src/dev/typescript/run_type_check_cli.ts b/src/dev/typescript/run_type_check_cli.ts index 00968b7259a30..c52b9454c28be 100644 --- a/src/dev/typescript/run_type_check_cli.ts +++ b/src/dev/typescript/run_type_check_cli.ts @@ -24,7 +24,7 @@ import getopts from 'getopts'; import { execInProjects } from './exec_in_projects'; import { filterProjectsByFlag } from './projects'; -import { buildRefs } from './build_refs'; +import { buildAllRefs } from './build_refs'; export async function runTypeCheckCli() { const extraFlags: string[] = []; @@ -80,7 +80,7 @@ export async function runTypeCheckCli() { process.exit(); } - await buildRefs(log); + await buildAllRefs(log); const tscArgs = [ // composite project cannot be used with --noEmit diff --git a/src/fixtures/telemetry_collectors/constants.ts b/src/fixtures/telemetry_collectors/constants.ts index d4c9a1f85c4d7..8896c294676c4 100644 --- a/src/fixtures/telemetry_collectors/constants.ts +++ b/src/fixtures/telemetry_collectors/constants.ts @@ -55,3 +55,18 @@ export const externallyDefinedSchema: MakeSchemaFrom<{ locale: string }> = { export type TypeAliasWithUnion = Usage & WithUnion; export type TypeAliasWithRecord = Usage & Record; + +export type MappedTypeProps = 'prop1' | 'prop2'; + +export interface MappedTypes { + mappedTypeWithExternallyDefinedProps: { + [key in MappedTypeProps]: number; + }; + mappedTypeWithOneInlineProp: { + [key in 'prop3']: number; + }; +} + +export type RecordWithKnownProps = Record; + +export type IndexedAccessType = Pick; diff --git a/src/fixtures/telemetry_collectors/indexed_interface_with_not_matching_schema.ts b/src/fixtures/telemetry_collectors/indexed_interface_with_not_matching_schema.ts index 0ec8d2e15c34a..b925696c96563 100644 --- a/src/fixtures/telemetry_collectors/indexed_interface_with_not_matching_schema.ts +++ b/src/fixtures/telemetry_collectors/indexed_interface_with_not_matching_schema.ts @@ -41,8 +41,9 @@ export const myCollector = makeUsageCollector({ return { something: { count_2: 2 } }; }, schema: { + // @ts-expect-error Intentionally missing count_2 something: { - count_1: { type: 'long' }, // Intentionally missing count_2 + count_1: { type: 'long' }, }, }, }); diff --git a/src/fixtures/telemetry_collectors/schema_defined_with_spreads_collector.ts b/src/fixtures/telemetry_collectors/schema_defined_with_spreads_collector.ts new file mode 100644 index 0000000000000..af9fef0bbd297 --- /dev/null +++ b/src/fixtures/telemetry_collectors/schema_defined_with_spreads_collector.ts @@ -0,0 +1,77 @@ +/* + * 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 { CollectorSet, MakeSchemaFrom } from '../../plugins/usage_collection/server/collector'; +import { loggerMock } from '../../core/server/logging/logger.mock'; + +const { makeUsageCollector } = new CollectorSet({ + logger: loggerMock.create(), + maximumWaitTimeForAllCollectorsInS: 0, +}); + +interface MyObject { + total: number; + type: boolean; +} + +interface Usage { + flat?: string; + my_str?: string; + my_objects: MyObject; +} + +const SOME_NUMBER: number = 123; + +const someSchema: MakeSchemaFrom> = { + flat: { + type: 'keyword', + }, + my_str: { + type: 'text', + }, +}; + +const someOtherSchema: MakeSchemaFrom> = { + my_objects: { + total: { + type: 'number', + }, + type: { type: 'boolean' }, + }, +}; + +export const myCollector = makeUsageCollector({ + type: 'schema_defined_with_spreads', + isReady: () => true, + fetch() { + const testString = '123'; + + return { + flat: 'hello', + my_str: testString, + my_objects: { + total: SOME_NUMBER, + type: true, + }, + }; + }, + schema: { + ...someSchema, + ...someOtherSchema, + }, +}); diff --git a/src/legacy/server/logging/rotate/log_rotator.test.ts b/src/legacy/server/logging/rotate/log_rotator.test.ts index 70842d42f5e1f..8f67b47f6949e 100644 --- a/src/legacy/server/logging/rotate/log_rotator.test.ts +++ b/src/legacy/server/logging/rotate/log_rotator.test.ts @@ -22,6 +22,7 @@ import fs, { existsSync, mkdirSync, statSync, writeFileSync } from 'fs'; import { LogRotator } from './log_rotator'; import { tmpdir } from 'os'; import { dirname, join } from 'path'; +import lodash from 'lodash'; const mockOn = jest.fn(); jest.mock('chokidar', () => ({ @@ -31,10 +32,7 @@ jest.mock('chokidar', () => ({ })), })); -jest.mock('lodash', () => ({ - ...require.requireActual('lodash'), - throttle: (fn: any) => fn, -})); +lodash.throttle = (fn: any) => fn; const tempDir = join(tmpdir(), 'kbn_log_rotator_test'); const testFilePath = join(tempDir, 'log_rotator_test_log_file.log'); diff --git a/src/plugins/advanced_settings/public/index.ts b/src/plugins/advanced_settings/public/index.ts index db478fa1579e6..0e621e7cd7d1a 100644 --- a/src/plugins/advanced_settings/public/index.ts +++ b/src/plugins/advanced_settings/public/index.ts @@ -17,11 +17,19 @@ * under the License. */ +import React from 'react'; import { PluginInitializerContext } from 'kibana/public'; import { AdvancedSettingsPlugin } from './plugin'; export { AdvancedSettingsSetup, AdvancedSettingsStart } from './types'; export { ComponentRegistry } from './component_registry'; -export { Field } from './management_app/components/field'; + +/** + * Exports the field component as a React.lazy component. We're explicitly naming it lazy here + * so any plugin that would import that can clearly see it's lazy loaded and can only be used + * inside a suspense context. + */ +const LazyField = React.lazy(() => import('./management_app/components/field')); +export { LazyField }; export function plugin(initializerContext: PluginInitializerContext) { return new AdvancedSettingsPlugin(); diff --git a/src/plugins/advanced_settings/public/management_app/_advanced_settings.scss b/src/plugins/advanced_settings/public/management_app/_advanced_settings.scss index 66ae9cca3f83b..fd26677e93894 100644 --- a/src/plugins/advanced_settings/public/management_app/_advanced_settings.scss +++ b/src/plugins/advanced_settings/public/management_app/_advanced_settings.scss @@ -64,3 +64,7 @@ .mgtAdvancedSettingsForm__button { width: 100%; } + +.kbnBody--mgtAdvancedSettingsHasBottomBar .mgtPage__body { + padding-bottom: $euiSizeXL * 2; +} diff --git a/src/plugins/advanced_settings/public/management_app/components/advanced_settings_voice_announcement/__snapshots__/advanced_settings_voice_announcement.test.tsx.snap b/src/plugins/advanced_settings/public/management_app/components/advanced_settings_voice_announcement/__snapshots__/advanced_settings_voice_announcement.test.tsx.snap index 490e105c18a7d..82c8dcd7f7ea1 100644 --- a/src/plugins/advanced_settings/public/management_app/components/advanced_settings_voice_announcement/__snapshots__/advanced_settings_voice_announcement.test.tsx.snap +++ b/src/plugins/advanced_settings/public/management_app/components/advanced_settings_voice_announcement/__snapshots__/advanced_settings_voice_announcement.test.tsx.snap @@ -3,6 +3,7 @@ exports[`Advanced Settings: Voice Announcement should render announcement 1`] = `
@@ -28,6 +29,7 @@ exports[`Advanced Settings: Voice Announcement should render announcement 1`] = exports[`Advanced Settings: Voice Announcement should render nothing 1`] = `
@@ -35,12 +37,11 @@ exports[`Advanced Settings: Voice Announcement should render nothing 1`] = ` delay={500} > { const filteredOptions = [...filteredSections]; return ( -
+
- + {this.props.queryText ? ( + + ) : ( + + )}
diff --git a/src/plugins/advanced_settings/public/management_app/components/field/__snapshots__/field.test.tsx.snap b/src/plugins/advanced_settings/public/management_app/components/field/__snapshots__/field.test.tsx.snap index 2aabacb061667..19bf9e6d73757 100644 --- a/src/plugins/advanced_settings/public/management_app/components/field/__snapshots__/field.test.tsx.snap +++ b/src/plugins/advanced_settings/public/management_app/components/field/__snapshots__/field.test.tsx.snap @@ -15,7 +15,7 @@ exports[`Field for array setting should render as read only if saving is disable } fullWidth={true} - id="array:test:setting" + id="array:test:setting-group" title={

} fullWidth={true} - id="array:test:setting" + id="array:test:setting-group" title={

} fullWidth={true} - id="array:test:setting" + id="array:test:setting-group" title={

} fullWidth={true} - id="array:test:setting" + id="array:test:setting-group" title={

} fullWidth={true} - id="array:test:setting" + id="array:test:setting-group" title={

Setting is currently not saved.

@@ -364,7 +364,7 @@ exports[`Field for array setting should render user value if there is user value } fullWidth={true} - id="array:test:setting" + id="array:test:setting-group" title={

} fullWidth={true} - id="boolean:test:setting" + id="boolean:test:setting-group" title={

} fullWidth={true} - id="boolean:test:setting" + id="boolean:test:setting-group" title={

} fullWidth={true} - id="boolean:test:setting" + id="boolean:test:setting-group" title={

} fullWidth={true} - id="boolean:test:setting" + id="boolean:test:setting-group" title={

} fullWidth={true} - id="boolean:test:setting" + id="boolean:test:setting-group" title={

Setting is currently not saved.

@@ -807,7 +807,7 @@ exports[`Field for boolean setting should render user value if there is user val } fullWidth={true} - id="boolean:test:setting" + id="boolean:test:setting-group" title={

} fullWidth={true} - id="image:test:setting" + id="image:test:setting-group" title={

} fullWidth={true} - id="image:test:setting" + id="image:test:setting-group" title={

} fullWidth={true} - id="image:test:setting" + id="image:test:setting-group" title={

} fullWidth={true} - id="image:test:setting" + id="image:test:setting-group" title={

} fullWidth={true} - id="image:test:setting" + id="image:test:setting-group" title={

Setting is currently not saved.

@@ -1231,7 +1235,7 @@ exports[`Field for image setting should render user value if there is user value } fullWidth={true} - id="image:test:setting" + id="image:test:setting-group" title={

} fullWidth={true} - id="json:test:setting" + id="json:test:setting-group" title={

} fullWidth={true} - id="json:test:setting" + id="json:test:setting-group" title={

} fullWidth={true} - id="json:test:setting" + id="json:test:setting-group" title={

} fullWidth={true} - id="json:test:setting" + id="json:test:setting-group" title={

} fullWidth={true} - id="json:test:setting" + id="json:test:setting-group" title={

Setting is currently not saved.

@@ -1832,7 +1836,7 @@ exports[`Field for json setting should render user value if there is user value } fullWidth={true} - id="json:test:setting" + id="json:test:setting-group" title={

} fullWidth={true} - id="markdown:test:setting" + id="markdown:test:setting-group" title={

} fullWidth={true} - id="markdown:test:setting" + id="markdown:test:setting-group" title={

} fullWidth={true} - id="markdown:test:setting" + id="markdown:test:setting-group" title={

} fullWidth={true} - id="markdown:test:setting" + id="markdown:test:setting-group" title={

} fullWidth={true} - id="markdown:test:setting" + id="markdown:test:setting-group" title={

Setting is currently not saved.

@@ -2365,7 +2369,7 @@ exports[`Field for markdown setting should render user value if there is user va } fullWidth={true} - id="markdown:test:setting" + id="markdown:test:setting-group" title={

} fullWidth={true} - id="number:test:setting" + id="number:test:setting-group" title={

} fullWidth={true} - id="number:test:setting" + id="number:test:setting-group" title={

} fullWidth={true} - id="number:test:setting" + id="number:test:setting-group" title={

} fullWidth={true} - id="number:test:setting" + id="number:test:setting-group" title={

} fullWidth={true} - id="number:test:setting" + id="number:test:setting-group" title={

Setting is currently not saved.

@@ -2798,7 +2802,7 @@ exports[`Field for number setting should render user value if there is user valu } fullWidth={true} - id="number:test:setting" + id="number:test:setting-group" title={

} fullWidth={true} - id="select:test:setting" + id="select:test:setting-group" title={

} fullWidth={true} - id="select:test:setting" + id="select:test:setting-group" title={

} fullWidth={true} - id="select:test:setting" + id="select:test:setting-group" title={

} fullWidth={true} - id="select:test:setting" + id="select:test:setting-group" title={

} fullWidth={true} - id="select:test:setting" + id="select:test:setting-group" title={

Setting is currently not saved.

@@ -3291,7 +3295,7 @@ exports[`Field for select setting should render user value if there is user valu } fullWidth={true} - id="select:test:setting" + id="select:test:setting-group" title={

} fullWidth={true} - id="string:test:setting" + id="string:test:setting-group" title={

} fullWidth={true} - id="string:test:setting" + id="string:test:setting-group" title={

} fullWidth={true} - id="string:test:setting" + id="string:test:setting-group" title={

} fullWidth={true} - id="string:test:setting" + id="string:test:setting-group" title={

} fullWidth={true} - id="string:test:setting" + id="string:test:setting-group" title={

Setting is currently not saved.

@@ -3720,7 +3724,7 @@ exports[`Field for string setting should render user value if there is user valu } fullWidth={true} - id="string:test:setting" + id="string:test:setting-group" title={

} fullWidth={true} - id="string:test-validation:setting" + id="string:test-validation:setting-group" title={

} fullWidth={true} - id="string:test-validation:setting" + id="string:test-validation:setting-group" title={

} fullWidth={true} - id="string:test-validation:setting" + id="string:test-validation:setting-group" title={

} fullWidth={true} - id="string:test-validation:setting" + id="string:test-validation:setting-group" title={

} fullWidth={true} - id="string:test-validation:setting" + id="string:test-validation:setting-group" title={

Setting is currently not saved.

@@ -4133,7 +4137,7 @@ exports[`Field for stringWithValidation setting should render user value if ther } fullWidth={true} - id="string:test-validation:setting" + id="string:test-validation:setting-group" title={

{ } }; - renderField(id: string, setting: FieldSetting) { + renderField(setting: FieldSetting, ariaDescribedBy?: string) { const { enableSaving, unsavedChanges, loading } = this.props; const { name, @@ -301,10 +299,10 @@ export class Field extends PureComponent { defVal, ariaName, } = setting; - const a11yProps: { [key: string]: string } = unsavedChanges + const a11yProps: { [key: string]: string } = ariaDescribedBy ? { 'aria-label': ariaName, - 'aria-describedby': id, + 'aria-describedby': ariaDescribedBy, } : { 'aria-label': ariaName, @@ -370,6 +368,7 @@ export class Field extends PureComponent { ref={this.changeImageForm} fullWidth data-test-subj={`advancedSetting-editField-${name}`} + aria-label={name} /> ); } @@ -669,11 +668,12 @@ export class Field extends PureComponent { // eslint-disable-next-line @typescript-eslint/naming-convention 'mgtAdvancedSettings__field--invalid': isInvalid, }); - const id = setting.name; + const groupId = `${setting.name}-group`; + const unsavedId = `${setting.name}-unsaved`; return ( { fullWidth > <> - {this.renderField(id, setting)} + {this.renderField(setting, unsavedChanges ? `${groupId} ${unsavedId}` : undefined)} {unsavedChanges && ( -

+

{unsavedChanges.error ? unsavedChanges.error : i18n.translate('advancedSettings.field.settingIsUnsaved', { diff --git a/src/plugins/advanced_settings/public/management_app/components/field/index.ts b/src/plugins/advanced_settings/public/management_app/components/field/index.ts index d1b9b34515532..c486dc96bfc33 100644 --- a/src/plugins/advanced_settings/public/management_app/components/field/index.ts +++ b/src/plugins/advanced_settings/public/management_app/components/field/index.ts @@ -18,3 +18,6 @@ */ export { Field, getEditableValue } from './field'; + +// eslint-disable-next-line import/no-default-export +export { Field as default } from './field'; diff --git a/src/plugins/advanced_settings/public/management_app/components/form/__snapshots__/form.test.tsx.snap b/src/plugins/advanced_settings/public/management_app/components/form/__snapshots__/form.test.tsx.snap index e38ccb6866ab6..ebebf49c5213f 100644 --- a/src/plugins/advanced_settings/public/management_app/components/form/__snapshots__/form.test.tsx.snap +++ b/src/plugins/advanced_settings/public/management_app/components/form/__snapshots__/form.test.tsx.snap @@ -18,6 +18,32 @@ exports[`Form should not render no settings message when instructed not to 1`] = General

+ + + + + + + , + "settingsCount": -1, + } + } + /> + + + + + + + + + + , + "settingsCount": -1, + } + } + /> + + + + + + + + + + , + "settingsCount": -1, + } + } + /> + + + + + + + + + + , + "settingsCount": -1, + } + } + /> + + + { }) ); }); + + it('should save an array typed field when user provides an empty string correctly', async () => { + const wrapper = mountWithI18nProvider( +
+ ); + + (wrapper.instance() as Form).setState({ + unsavedChanges: { + 'general:test:array': { + value: '', + }, + }, + }); + + findTestSubject(wrapper.update(), `advancedSetting-saveButton`).simulate('click'); + expect(save).toHaveBeenCalledWith({ 'general:test:array': [] }); + }); + + it('should save an array typed field when user provides a comma separated string correctly', async () => { + const wrapper = mountWithI18nProvider( + + ); + + (wrapper.instance() as Form).setState({ + unsavedChanges: { + 'general:test:array': { + value: 'test1, test2', + }, + }, + }); + + findTestSubject(wrapper.update(), `advancedSetting-saveButton`).simulate('click'); + expect(save).toHaveBeenCalledWith({ 'general:test:array': ['test1', 'test2'] }); + }); }); diff --git a/src/plugins/advanced_settings/public/management_app/components/form/form.tsx b/src/plugins/advanced_settings/public/management_app/components/form/form.tsx index 0378d816fd2c3..d243d85e12a66 100644 --- a/src/plugins/advanced_settings/public/management_app/components/form/form.tsx +++ b/src/plugins/advanced_settings/public/management_app/components/form/form.tsx @@ -154,7 +154,9 @@ export class Form extends PureComponent { let equalsToDefault = false; switch (type) { case 'array': - valueToSave = valueToSave.split(',').map((val: string) => val.trim()); + valueToSave = valueToSave.trim(); + valueToSave = + valueToSave === '' ? [] : valueToSave.split(',').map((val: string) => val.trim()); equalsToDefault = valueToSave.join(',') === (defVal as string[]).join(','); break; case 'json': @@ -386,6 +388,13 @@ export class Form extends PureComponent { const { unsavedChanges } = this.state; const { visibleSettings, categories, categoryCounts, clearQuery } = this.props; const currentCategories: Category[] = []; + const hasUnsavedChanges = !isEmpty(unsavedChanges); + + if (hasUnsavedChanges) { + document.body.classList.add('kbnBody--mgtAdvancedSettingsHasBottomBar'); + } else { + document.body.classList.remove('kbnBody--mgtAdvancedSettingsHasBottomBar'); + } categories.forEach((category) => { if (visibleSettings[category] && visibleSettings[category].length) { @@ -406,7 +415,7 @@ export class Form extends PureComponent { }) : this.maybeRenderNoSettings(clearQuery)}

- {!isEmpty(unsavedChanges) && this.renderBottomBar()} + {hasUnsavedChanges && this.renderBottomBar()} ); } diff --git a/src/plugins/apm_oss/server/tutorial/index_pattern.json b/src/plugins/apm_oss/server/tutorial/index_pattern.json index bb42b223c85ed..dbceaacfb4a27 100644 --- a/src/plugins/apm_oss/server/tutorial/index_pattern.json +++ b/src/plugins/apm_oss/server/tutorial/index_pattern.json @@ -1,11 +1,11 @@ { "attributes": { - "fieldFormatMap": "{\"client.bytes\":{\"id\":\"bytes\"},\"client.nat.port\":{\"id\":\"string\"},\"client.port\":{\"id\":\"string\"},\"destination.bytes\":{\"id\":\"bytes\"},\"destination.nat.port\":{\"id\":\"string\"},\"destination.port\":{\"id\":\"string\"},\"event.duration\":{\"id\":\"duration\",\"params\":{\"inputFormat\":\"nanoseconds\",\"outputFormat\":\"asMilliseconds\",\"outputPrecision\":1}},\"event.sequence\":{\"id\":\"string\"},\"event.severity\":{\"id\":\"string\"},\"http.request.body.bytes\":{\"id\":\"bytes\"},\"http.request.bytes\":{\"id\":\"bytes\"},\"http.response.body.bytes\":{\"id\":\"bytes\"},\"http.response.bytes\":{\"id\":\"bytes\"},\"http.response.status_code\":{\"id\":\"string\"},\"log.syslog.facility.code\":{\"id\":\"string\"},\"log.syslog.priority\":{\"id\":\"string\"},\"network.bytes\":{\"id\":\"bytes\"},\"package.size\":{\"id\":\"string\"},\"process.parent.pgid\":{\"id\":\"string\"},\"process.parent.pid\":{\"id\":\"string\"},\"process.parent.ppid\":{\"id\":\"string\"},\"process.parent.thread.id\":{\"id\":\"string\"},\"process.pgid\":{\"id\":\"string\"},\"process.pid\":{\"id\":\"string\"},\"process.ppid\":{\"id\":\"string\"},\"process.thread.id\":{\"id\":\"string\"},\"server.bytes\":{\"id\":\"bytes\"},\"server.nat.port\":{\"id\":\"string\"},\"server.port\":{\"id\":\"string\"},\"source.bytes\":{\"id\":\"bytes\"},\"source.nat.port\":{\"id\":\"string\"},\"source.port\":{\"id\":\"string\"},\"system.cpu.total.norm.pct\":{\"id\":\"percent\"},\"system.memory.actual.free\":{\"id\":\"bytes\"},\"system.memory.total\":{\"id\":\"bytes\"},\"system.process.cgroup.memory.mem.limit.bytes\":{\"id\":\"bytes\"},\"system.process.cgroup.memory.mem.usage.bytes\":{\"id\":\"bytes\"},\"system.process.cgroup.memory.stats.inactive_file.bytes\":{\"id\":\"bytes\"},\"system.process.cpu.total.norm.pct\":{\"id\":\"percent\"},\"system.process.memory.rss.bytes\":{\"id\":\"bytes\"},\"system.process.memory.size\":{\"id\":\"bytes\"},\"url.port\":{\"id\":\"string\"},\"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\":\"as.number\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"as.organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"as.organization.name.text\",\"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.as.number\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.as.organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.as.organization.name.text\",\"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.nat.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.nat.port\",\"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.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.registered_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.top_level_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.full_name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.group.domain\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.name.text\",\"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\":\"code_signature.exists\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"code_signature.status\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"code_signature.subject_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"code_signature.trusted\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"code_signature.valid\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"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.as.number\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.as.organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.as.organization.name.text\",\"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.nat.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.nat.port\",\"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.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.registered_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.top_level_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.full_name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.group.domain\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.code_signature.exists\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.code_signature.status\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.code_signature.subject_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.code_signature.trusted\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.code_signature.valid\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.hash.md5\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.hash.sha1\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.hash.sha256\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.hash.sha512\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.pe.company\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.pe.description\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.pe.file_version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.pe.original_file_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.pe.product\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.answers\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.answers.class\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.answers.data\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.answers.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.answers.ttl\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.answers.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.header_flags\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.op_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.question.class\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.question.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.question.registered_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.question.subdomain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.question.top_level_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.question.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.resolved_ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.response_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.type\",\"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\":\"error.stack_trace\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"error.stack_trace.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"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\":\"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.code\",\"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.ingested\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"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.provider\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.reference\",\"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.sequence\",\"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\":\"event.url\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.accessed\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.attributes\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.code_signature.exists\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.code_signature.status\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.code_signature.subject_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.code_signature.trusted\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.code_signature.valid\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.created\",\"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\":\"file.device\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.directory\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.drive_letter\",\"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.hash.md5\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.hash.sha1\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.hash.sha256\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.hash.sha512\",\"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.mime_type\",\"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.name\",\"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.path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.path.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.pe.company\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.pe.description\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.pe.file_version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.pe.original_file_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.pe.product\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.target_path.text\",\"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.domain\",\"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\":\"hash.md5\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"hash.sha1\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"hash.sha256\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"hash.sha512\",\"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.domain\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.full.text\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.name.text\",\"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.uptime\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.domain\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.full_name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.group.domain\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.name.text\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.body.content.text\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.body.content.text\",\"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\":\"interface.alias\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"interface.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"interface.name\",\"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.logger\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.origin.file.line\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.origin.file.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.origin.function\",\"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\":\"log.syslog\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.syslog.facility.code\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.syslog.facility.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.syslog.priority\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.syslog.severity.code\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.syslog.severity.name\",\"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.inner\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.inner.vlan.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.inner.vlan.name\",\"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\":\"network.vlan.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.vlan.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.egress\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.egress.interface.alias\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.egress.interface.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.egress.interface.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.egress.vlan.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.egress.vlan.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.egress.zone\",\"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.ingress\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.ingress.interface.alias\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.ingress.interface.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.ingress.interface.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.ingress.vlan.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.ingress.vlan.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.ingress.zone\",\"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.name\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.full.text\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.name.text\",\"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.product\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"organization.name.text\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.full.text\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.name.text\",\"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\":\"package.architecture\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.build_version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.checksum\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.description\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.install_scope\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.installed\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.license\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.reference\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.size\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"pe.company\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"pe.description\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"pe.file_version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"pe.original_file_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"pe.product\",\"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.args_count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.code_signature.exists\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.code_signature.status\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.code_signature.subject_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.code_signature.trusted\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.code_signature.valid\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.command_line\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.command_line.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.entity_id\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.executable.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.exit_code\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.hash.md5\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.hash.sha1\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.hash.sha256\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.hash.sha512\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.args\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.args_count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.code_signature.exists\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.code_signature.status\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.code_signature.subject_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.code_signature.trusted\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.code_signature.valid\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.command_line\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.command_line.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.entity_id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.executable\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.executable.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.exit_code\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.hash.md5\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.hash.sha1\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.hash.sha256\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.hash.sha512\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.pgid\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.pid\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.ppid\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.start\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.thread.id\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.thread.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.title\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.title.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.uptime\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.working_directory\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.working_directory.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.pe.company\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.pe.description\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.pe.file_version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.pe.original_file_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.pe.product\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.pgid\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"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.thread.name\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.title.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.uptime\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.working_directory\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.working_directory.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"registry.data.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"registry.data.strings\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"registry.data.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"registry.hive\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"registry.key\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"registry.path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"registry.value\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"related.hash\",\"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\":\"related.user\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"rule.author\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"rule.category\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"rule.description\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"rule.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"rule.license\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"rule.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"rule.reference\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"rule.ruleset\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"rule.uuid\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"rule.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"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.as.number\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.as.organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.as.organization.name.text\",\"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.nat.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.nat.port\",\"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.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.registered_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.top_level_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.full_name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.group.domain\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.name.text\",\"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.node.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.as.number\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.as.organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.as.organization.name.text\",\"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.nat.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.nat.port\",\"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.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.registered_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.top_level_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.full_name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.group.domain\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.framework\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.tactic.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.tactic.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.tactic.reference\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.technique.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.technique.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.technique.name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.technique.reference\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.cipher\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.certificate\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.certificate_chain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.hash.md5\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.hash.sha1\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.hash.sha256\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.issuer\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.ja3\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.not_after\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.not_before\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.server_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.subject\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.supported_ciphers\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.curve\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.established\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.next_protocol\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.resumed\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.certificate\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.certificate_chain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.hash.md5\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.hash.sha1\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.hash.sha256\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.issuer\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.ja3s\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.not_after\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.not_before\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.subject\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.version_protocol\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tracing.trace.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tracing.transaction.id\",\"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.extension\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.full.text\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.original.text\",\"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.registered_domain\",\"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.top_level_domain\",\"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.domain\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.full_name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.group.domain\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.name.text\",\"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\":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\":\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.full.text\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.name.text\",\"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\":\"vlan.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vlan.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.category\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.classification\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.description\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.description.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.enumeration\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.reference\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.report_id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.scanner.vendor\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.score.base\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.score.environmental\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.score.temporal\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.score.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.severity\",\"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\":\"timeseries.instance\",\"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\":\"cloud.image.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\":\"host.os.codename\",\"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\":\"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.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.duration.sum.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.self_time.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.self_time.sum.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.breakdown.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"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\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.self_time.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.self_time.sum.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"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\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"experimental\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.account.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.project.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"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\":\"system.process.cgroup.memory.mem.limit.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.process.cgroup.memory.mem.usage.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.process.cgroup.memory.stats.inactive_file.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.root\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.duration\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.cpu.ns\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.samples.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.alloc_objects.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.alloc_space.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.inuse_objects.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.inuse_space.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.top.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.top.function\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.top.filename\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.top.line\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.stack.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.stack.function\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.stack.filename\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.stack.line\",\"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\":\"child.id\",\"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.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\":\"span.db.link\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.db.rows_affected\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.destination.service.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.destination.service.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.destination.service.resource\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.message.queue.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.message.age.ms\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"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.experience.cls\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.experience.fid\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.experience.tbt\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.span_count.dropped\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.message.queue.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.message.age.ms\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.duration.histogram\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"metricset.period\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.destination.service.response_time.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.destination.service.response_time.sum.us\",\"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\"},\"client.nat.port\":{\"id\":\"string\"},\"client.port\":{\"id\":\"string\"},\"destination.bytes\":{\"id\":\"bytes\"},\"destination.nat.port\":{\"id\":\"string\"},\"destination.port\":{\"id\":\"string\"},\"event.duration\":{\"id\":\"duration\",\"params\":{\"inputFormat\":\"nanoseconds\",\"outputFormat\":\"asMilliseconds\",\"outputPrecision\":1}},\"event.sequence\":{\"id\":\"string\"},\"event.severity\":{\"id\":\"string\"},\"http.request.body.bytes\":{\"id\":\"bytes\"},\"http.request.bytes\":{\"id\":\"bytes\"},\"http.response.body.bytes\":{\"id\":\"bytes\"},\"http.response.bytes\":{\"id\":\"bytes\"},\"http.response.status_code\":{\"id\":\"string\"},\"log.syslog.facility.code\":{\"id\":\"string\"},\"log.syslog.priority\":{\"id\":\"string\"},\"network.bytes\":{\"id\":\"bytes\"},\"package.size\":{\"id\":\"string\"},\"process.parent.pgid\":{\"id\":\"string\"},\"process.parent.pid\":{\"id\":\"string\"},\"process.parent.ppid\":{\"id\":\"string\"},\"process.parent.thread.id\":{\"id\":\"string\"},\"process.pgid\":{\"id\":\"string\"},\"process.pid\":{\"id\":\"string\"},\"process.ppid\":{\"id\":\"string\"},\"process.thread.id\":{\"id\":\"string\"},\"server.bytes\":{\"id\":\"bytes\"},\"server.nat.port\":{\"id\":\"string\"},\"server.port\":{\"id\":\"string\"},\"source.bytes\":{\"id\":\"bytes\"},\"source.nat.port\":{\"id\":\"string\"},\"source.port\":{\"id\":\"string\"},\"system.cpu.total.norm.pct\":{\"id\":\"percent\"},\"system.memory.actual.free\":{\"id\":\"bytes\"},\"system.memory.total\":{\"id\":\"bytes\"},\"system.process.cgroup.memory.mem.limit.bytes\":{\"id\":\"bytes\"},\"system.process.cgroup.memory.mem.usage.bytes\":{\"id\":\"bytes\"},\"system.process.cpu.total.norm.pct\":{\"id\":\"percent\"},\"system.process.memory.rss.bytes\":{\"id\":\"bytes\"},\"system.process.memory.size\":{\"id\":\"bytes\"},\"url.port\":{\"id\":\"string\"},\"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.build.original\",\"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\":\"as.number\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"as.organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"as.organization.name.text\",\"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.as.number\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.as.organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.as.organization.name.text\",\"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.nat.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.nat.port\",\"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.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.registered_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.top_level_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.full_name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.group.domain\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"client.user.roles\",\"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.account.name\",\"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.project.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.project.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.region\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"code_signature.exists\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"code_signature.status\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"code_signature.subject_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"code_signature.trusted\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"code_signature.valid\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"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.as.number\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.as.organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.as.organization.name.text\",\"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.nat.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.nat.port\",\"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.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.registered_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.top_level_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.full_name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.group.domain\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"destination.user.roles\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.code_signature.exists\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.code_signature.status\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.code_signature.subject_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.code_signature.trusted\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.code_signature.valid\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.hash.md5\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.hash.sha1\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.hash.sha256\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.hash.sha512\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.pe.architecture\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.pe.company\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.pe.description\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.pe.file_version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.pe.imphash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.pe.original_file_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dll.pe.product\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.answers\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.answers.class\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.answers.data\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.answers.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.answers.ttl\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.answers.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.header_flags\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.op_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.question.class\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.question.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.question.registered_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.question.subdomain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.question.top_level_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.question.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.resolved_ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.response_code\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"dns.type\",\"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\":false,\"name\":\"error.stack_trace\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":false,\"name\":\"error.stack_trace.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"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\":\"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.code\",\"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.ingested\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"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\":false,\"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.provider\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.reason\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"event.reference\",\"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.sequence\",\"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\":\"event.url\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.accessed\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.attributes\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.code_signature.exists\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.code_signature.status\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.code_signature.subject_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.code_signature.trusted\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.code_signature.valid\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.created\",\"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\":\"file.device\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.directory\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.drive_letter\",\"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.hash.md5\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.hash.sha1\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.hash.sha256\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.hash.sha512\",\"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.mime_type\",\"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.name\",\"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.path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.path.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.pe.architecture\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.pe.company\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.pe.description\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.pe.file_version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.pe.imphash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.pe.original_file_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.pe.product\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.target_path.text\",\"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\":\"file.x509.alternative_names\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.x509.issuer.common_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.x509.issuer.country\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.x509.issuer.distinguished_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.x509.issuer.locality\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.x509.issuer.organization\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.x509.issuer.organizational_unit\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.x509.issuer.state_or_province\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.x509.not_after\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.x509.not_before\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.x509.public_key_algorithm\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.x509.public_key_curve\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":false,\"name\":\"file.x509.public_key_exponent\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.x509.public_key_size\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.x509.serial_number\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.x509.signature_algorithm\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.x509.subject.common_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.x509.subject.country\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.x509.subject.distinguished_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.x509.subject.locality\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.x509.subject.organization\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.x509.subject.organizational_unit\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.x509.subject.state_or_province\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"file.x509.version_number\",\"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.domain\",\"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\":\"hash.md5\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"hash.sha1\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"hash.sha256\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"hash.sha512\",\"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.domain\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.full.text\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.os.name.text\",\"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.uptime\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.domain\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.full_name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.group.domain\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"host.user.roles\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.request.body.content.text\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"http.response.body.content.text\",\"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\":\"interface.alias\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"interface.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"interface.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.file.path\",\"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.logger\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.origin.file.line\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.origin.file.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.origin.function\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":false,\"name\":\"log.original\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.syslog\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.syslog.facility.code\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.syslog.facility.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.syslog.priority\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.syslog.severity.code\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"log.syslog.severity.name\",\"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.inner\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.inner.vlan.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.inner.vlan.name\",\"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\":\"network.vlan.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"network.vlan.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.egress\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.egress.interface.alias\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.egress.interface.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.egress.interface.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.egress.vlan.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.egress.vlan.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.egress.zone\",\"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.ingress\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.ingress.interface.alias\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.ingress.interface.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.ingress.interface.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.ingress.vlan.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.ingress.vlan.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.ingress.zone\",\"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.name\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.full.text\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"observer.os.name.text\",\"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.product\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"organization.name.text\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.full.text\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"os.name.text\",\"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\":\"package.architecture\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.build_version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.checksum\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.description\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.install_scope\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.installed\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.license\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.reference\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.size\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"package.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"pe.architecture\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"pe.company\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"pe.description\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"pe.file_version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"pe.imphash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"pe.original_file_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"pe.product\",\"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.args_count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.code_signature.exists\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.code_signature.status\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.code_signature.subject_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.code_signature.trusted\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.code_signature.valid\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.command_line\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.command_line.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.entity_id\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.executable.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.exit_code\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.hash.md5\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.hash.sha1\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.hash.sha256\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.hash.sha512\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.args\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.args_count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.code_signature.exists\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.code_signature.status\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.code_signature.subject_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.code_signature.trusted\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.code_signature.valid\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.command_line\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.command_line.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.entity_id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.executable\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.executable.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.exit_code\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.hash.md5\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.hash.sha1\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.hash.sha256\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.hash.sha512\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.pe.architecture\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.pe.company\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.pe.description\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.pe.file_version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.pe.imphash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.pe.original_file_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.pe.product\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.pgid\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.pid\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.ppid\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.start\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.thread.id\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.thread.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.title\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.title.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.uptime\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.working_directory\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.parent.working_directory.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.pe.architecture\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.pe.company\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.pe.description\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.pe.file_version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.pe.imphash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.pe.original_file_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.pe.product\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.pgid\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"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.thread.name\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.title.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.uptime\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.working_directory\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"process.working_directory.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"registry.data.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"registry.data.strings\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"registry.data.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"registry.hive\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"registry.key\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"registry.path\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"registry.value\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"related.hash\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"related.hosts\",\"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\":\"related.user\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"rule.author\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"rule.category\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"rule.description\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"rule.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"rule.license\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"rule.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"rule.reference\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"rule.ruleset\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"rule.uuid\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"rule.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"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.as.number\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.as.organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.as.organization.name.text\",\"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.nat.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.nat.port\",\"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.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.registered_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.top_level_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.full_name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.group.domain\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"server.user.roles\",\"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.node.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.as.number\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.as.organization.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.as.organization.name.text\",\"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.nat.ip\",\"scripted\":false,\"searchable\":true,\"type\":\"ip\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.nat.port\",\"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.port\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.registered_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.top_level_domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.domain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.full_name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.group.domain\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"source.user.roles\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.framework\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.tactic.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.tactic.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.tactic.reference\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.technique.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.technique.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.technique.name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"threat.technique.reference\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.cipher\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.certificate\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.certificate_chain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.hash.md5\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.hash.sha1\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.hash.sha256\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.issuer\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.ja3\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.not_after\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.not_before\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.server_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.subject\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.supported_ciphers\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.x509.alternative_names\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.x509.issuer.common_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.x509.issuer.country\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.x509.issuer.distinguished_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.x509.issuer.locality\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.x509.issuer.organization\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.x509.issuer.organizational_unit\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.x509.issuer.state_or_province\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.x509.not_after\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.x509.not_before\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.x509.public_key_algorithm\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.x509.public_key_curve\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":false,\"name\":\"tls.client.x509.public_key_exponent\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.x509.public_key_size\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.x509.serial_number\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.x509.signature_algorithm\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.x509.subject.common_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.x509.subject.country\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.x509.subject.distinguished_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.x509.subject.locality\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.x509.subject.organization\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.x509.subject.organizational_unit\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.x509.subject.state_or_province\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.client.x509.version_number\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.curve\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.established\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.next_protocol\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.resumed\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.certificate\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.certificate_chain\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.hash.md5\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.hash.sha1\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.hash.sha256\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.issuer\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.ja3s\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.not_after\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.not_before\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.subject\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.x509.alternative_names\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.x509.issuer.common_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.x509.issuer.country\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.x509.issuer.distinguished_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.x509.issuer.locality\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.x509.issuer.organization\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.x509.issuer.organizational_unit\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.x509.issuer.state_or_province\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.x509.not_after\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.x509.not_before\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.x509.public_key_algorithm\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.x509.public_key_curve\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":false,\"name\":\"tls.server.x509.public_key_exponent\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.x509.public_key_size\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.x509.serial_number\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.x509.signature_algorithm\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.x509.subject.common_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.x509.subject.country\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.x509.subject.distinguished_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.x509.subject.locality\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.x509.subject.organization\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.x509.subject.organizational_unit\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.x509.subject.state_or_province\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.server.x509.version_number\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tls.version_protocol\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tracing.span.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tracing.trace.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"tracing.transaction.id\",\"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.extension\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.full.text\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"url.original.text\",\"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.registered_domain\",\"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.top_level_domain\",\"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.domain\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.full_name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.group.domain\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.name.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user.roles\",\"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\":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\":\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.full.text\",\"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\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"user_agent.os.name.text\",\"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\":\"vlan.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vlan.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.category\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.classification\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.description\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":false,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.description.text\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.enumeration\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.reference\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.report_id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.scanner.vendor\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.score.base\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.score.environmental\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.score.temporal\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.score.version\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"vulnerability.severity\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"x509.alternative_names\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"x509.issuer.common_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"x509.issuer.country\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"x509.issuer.distinguished_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"x509.issuer.locality\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"x509.issuer.organization\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"x509.issuer.organizational_unit\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"x509.issuer.state_or_province\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"x509.not_after\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"x509.not_before\",\"scripted\":false,\"searchable\":true,\"type\":\"date\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"x509.public_key_algorithm\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"x509.public_key_curve\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":false,\"name\":\"x509.public_key_exponent\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"x509.public_key_size\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"x509.serial_number\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"x509.signature_algorithm\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"x509.subject.common_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"x509.subject.country\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"x509.subject.distinguished_name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"x509.subject.locality\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"x509.subject.organization\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"x509.subject.organizational_unit\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"x509.subject.state_or_province\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"x509.version_number\",\"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\":\"timeseries.instance\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"cloud.image.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\":\"host.os.codename\",\"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\":\"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.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.duration.sum.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.self_time.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.self_time.sum.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.breakdown.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"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\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.self_time.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.self_time.sum.us\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"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\":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\":\"system.process.cgroup.memory.mem.limit.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"system.process.cgroup.memory.mem.usage.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.root\",\"scripted\":false,\"searchable\":true,\"type\":\"boolean\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.duration\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.cpu.ns\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.samples.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.alloc_objects.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.alloc_space.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.inuse_objects.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.inuse_space.bytes\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.top.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.top.function\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.top.filename\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":1,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.top.line\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.stack.id\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.stack.function\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.stack.filename\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"profile.stack.line\",\"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\":\"child.id\",\"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.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\":\"span.db.link\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.db.rows_affected\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.destination.service.type\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.destination.service.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.destination.service.resource\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.message.queue.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.message.age.ms\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"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.experience.cls\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.experience.fid\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.experience.tbt\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.experience.longtask.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.experience.longtask.sum\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.experience.longtask.max\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.span_count.dropped\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.message.queue.name\",\"scripted\":false,\"searchable\":true,\"type\":\"string\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.message.age.ms\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"transaction.duration.histogram\",\"scripted\":false,\"searchable\":true},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"metricset.period\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.destination.service.response_time.count\",\"scripted\":false,\"searchable\":true,\"type\":\"number\"},{\"aggregatable\":true,\"analyzed\":false,\"count\":0,\"doc_values\":true,\"indexed\":true,\"name\":\"span.destination.service.response_time.sum.us\",\"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" }, "id": "apm-*", "type": "index-pattern", "version": "1" -} +} \ No newline at end of file diff --git a/src/plugins/charts/public/services/colors/color_palette.ts b/src/plugins/charts/public/services/colors/color_palette.ts index 464e9e3a66101..e1c32fe68da12 100644 --- a/src/plugins/charts/public/services/colors/color_palette.ts +++ b/src/plugins/charts/public/services/colors/color_palette.ts @@ -17,8 +17,8 @@ * under the License. */ -import d3 from 'd3'; import _ from 'lodash'; +import { hsl } from 'color'; import { seedColors } from './seed_colors'; @@ -49,7 +49,7 @@ const fraction = function (goal: number) { * If the number is greater than the length of seed colors available, * new colors are generated up to the value of the input number. */ -export function createColorPalette(num?: any): string[] { +export function createColorPalette(num: number): string[] { if (!_.isNumber(num)) { throw new TypeError('ColorPaletteUtilService expects a number'); } @@ -58,7 +58,7 @@ export function createColorPalette(num?: any): string[] { const seedLength = seedColors.length; _.times(num - seedLength, function (i) { - colors.push(d3.hsl((fraction(i + seedLength + 1) * 360 + offset) % 360, 0.5, 0.5).toString()); + colors.push(hsl((fraction(i + seedLength + 1) * 360 + offset) % 360, 0.5, 0.5).hex()); }); return colors; diff --git a/src/plugins/charts/public/services/colors/colors_palette.test.ts b/src/plugins/charts/public/services/colors/colors_palette.test.ts index 6612447cefe9e..02ff5a6056d54 100644 --- a/src/plugins/charts/public/services/colors/colors_palette.test.ts +++ b/src/plugins/charts/public/services/colors/colors_palette.test.ts @@ -37,26 +37,32 @@ describe('Color Palette', () => { it('should throw an error if input is not a number', () => { expect(() => { + // @ts-expect-error createColorPalette(string); }).toThrowError(); expect(() => { + // @ts-expect-error createColorPalette(bool); }).toThrowError(); expect(() => { + // @ts-expect-error createColorPalette(nullValue); }).toThrowError(); expect(() => { + // @ts-expect-error createColorPalette(emptyArr); }).toThrowError(); expect(() => { + // @ts-expect-error createColorPalette(emptyObject); }).toThrowError(); expect(() => { + // @ts-expect-error createColorPalette(); }).toThrowError(); }); diff --git a/src/plugins/charts/public/services/colors/mapped_colors.test.ts b/src/plugins/charts/public/services/colors/mapped_colors.test.ts index e97ca8ac257b4..9d00bf098de4c 100644 --- a/src/plugins/charts/public/services/colors/mapped_colors.test.ts +++ b/src/plugins/charts/public/services/colors/mapped_colors.test.ts @@ -18,7 +18,7 @@ */ import _ from 'lodash'; -import d3 from 'd3'; +import Color from 'color'; import { coreMock } from '../../../../../core/public/mocks'; import { COLOR_MAPPING_SETTING } from '../../../common'; @@ -61,7 +61,7 @@ describe('Mapped Colors', () => { mappedColors.mapKeys(arr); const colorValues = _(mappedColors.mapping).values(); - expect(colorValues.includes(seedColors[0])).toBe(false); + expect(colorValues).not.toContain(seedColors[0]); expect(colorValues.uniq().size()).toBe(arr.length); }); @@ -78,8 +78,8 @@ describe('Mapped Colors', () => { }); it('should treat different formats of colors as equal', () => { - const color = d3.rgb(seedColors[0]); - const rgb = `rgb(${color.r}, ${color.g}, ${color.b})`; + const color = new Color(seedColors[0]); + const rgb = `rgb(${color.red()}, ${color.green()}, ${color.blue()})`; const newConfig = { bar: rgb }; config.set(COLOR_MAPPING_SETTING, newConfig); diff --git a/src/plugins/charts/public/services/colors/mapped_colors.ts b/src/plugins/charts/public/services/colors/mapped_colors.ts index 3b9e1501d638d..15f9be32b829c 100644 --- a/src/plugins/charts/public/services/colors/mapped_colors.ts +++ b/src/plugins/charts/public/services/colors/mapped_colors.ts @@ -18,14 +18,14 @@ */ import _ from 'lodash'; -import d3 from 'd3'; +import Color from 'color'; import { CoreSetup } from 'kibana/public'; import { COLOR_MAPPING_SETTING } from '../../../common'; import { createColorPalette } from './color_palette'; -const standardizeColor = (color: string) => d3.rgb(color).toString(); +const standardizeColor = (color: string) => new Color(color).hex().toLowerCase(); /** * Maintains a lookup table that associates the value (key) with a hex color (value) diff --git a/src/plugins/dashboard/public/application/actions/expand_panel_action.tsx b/src/plugins/dashboard/public/application/actions/expand_panel_action.tsx index d0442fbc26073..933d2766d13f4 100644 --- a/src/plugins/dashboard/public/application/actions/expand_panel_action.tsx +++ b/src/plugins/dashboard/public/application/actions/expand_panel_action.tsx @@ -57,7 +57,7 @@ export class ExpandPanelAction implements ActionByType) { + const { doStart } = embeddablePluginMock.createInstance(); + const defaultInput: DashboardContainerInput = { + id: '123', + viewMode: ViewMode.EDIT, + filters: [] as DashboardContainerInput['filters'], + query: {} as DashboardContainerInput['query'], + timeRange: {} as DashboardContainerInput['timeRange'], + useMargins: true, + title: 'ultra awesome test dashboard', + isFullScreenMode: false, + panels: {} as DashboardContainerInput['panels'], + }; + const input = { ...defaultInput, ...(initialInput ?? {}) }; + return new DashboardContainer(input, { embeddable: doStart() } as DashboardContainerOptions); + } + describe('syncTimefilterWithDashboard', function () { test('syncs quick time', function () { savedDashboard.timeRestore = true; @@ -95,6 +115,43 @@ describe('DashboardState', function () { }); }); + describe('Dashboard Container Changes', () => { + beforeEach(() => { + initDashboardState(); + }); + + test('expanedPanelId in container input casues state update', () => { + dashboardState.setExpandedPanelId = jest.fn(); + + const dashboardContainer = initDashboardContainer({ + expandedPanelId: 'theCoolestPanelOnThisDashboard', + }); + + dashboardState.handleDashboardContainerChanges(dashboardContainer); + expect(dashboardState.setExpandedPanelId).toHaveBeenCalledWith( + 'theCoolestPanelOnThisDashboard' + ); + }); + + test('expanedPanelId is not updated when it is the same', () => { + dashboardState.setExpandedPanelId = jest + .fn() + .mockImplementation(dashboardState.setExpandedPanelId); + + const dashboardContainer = initDashboardContainer({ + expandedPanelId: 'theCoolestPanelOnThisDashboard', + }); + + dashboardState.handleDashboardContainerChanges(dashboardContainer); + dashboardState.handleDashboardContainerChanges(dashboardContainer); + expect(dashboardState.setExpandedPanelId).toHaveBeenCalledTimes(1); + + dashboardContainer.updateInput({ expandedPanelId: 'woah it changed' }); + dashboardState.handleDashboardContainerChanges(dashboardContainer); + expect(dashboardState.setExpandedPanelId).toHaveBeenCalledTimes(2); + }); + }); + describe('isDirty', function () { beforeAll(() => { initDashboardState(); diff --git a/src/plugins/dashboard/public/application/dashboard_state_manager.ts b/src/plugins/dashboard/public/application/dashboard_state_manager.ts index 910a2b470b2eb..93a63b0535259 100644 --- a/src/plugins/dashboard/public/application/dashboard_state_manager.ts +++ b/src/plugins/dashboard/public/application/dashboard_state_manager.ts @@ -267,6 +267,10 @@ export class DashboardStateManager { this.setFullScreenMode(input.isFullScreenMode); } + if (input.expandedPanelId !== this.getExpandedPanelId()) { + this.setExpandedPanelId(input.expandedPanelId); + } + if (!_.isEqual(input.query, this.getQuery())) { this.setQuery(input.query); } @@ -282,6 +286,14 @@ export class DashboardStateManager { this.stateContainer.transitions.set('fullScreenMode', fullScreenMode); } + public getExpandedPanelId() { + return this.appState.expandedPanelId; + } + + public setExpandedPanelId(expandedPanelId?: string) { + this.stateContainer.transitions.set('expandedPanelId', expandedPanelId); + } + public setFilters(filters: Filter[]) { this.stateContainer.transitions.set('filters', filters); } diff --git a/src/plugins/dashboard/public/application/listing/dashboard_listing.test.js b/src/plugins/dashboard/public/application/listing/dashboard_listing.test.js index 6acb491f9a20c..99b1ebf047d74 100644 --- a/src/plugins/dashboard/public/application/listing/dashboard_listing.test.js +++ b/src/plugins/dashboard/public/application/listing/dashboard_listing.test.js @@ -20,7 +20,7 @@ jest.mock( 'lodash', () => ({ - ...require.requireActual('lodash'), + ...jest.requireActual('lodash'), // mock debounce to fire immediately with no internal timer debounce: (func) => { function debounced(...args) { diff --git a/src/plugins/dashboard/public/application/top_nav/get_top_nav_config.ts b/src/plugins/dashboard/public/application/top_nav/get_top_nav_config.ts index dbdadeb4e4e7c..77c4a2235d471 100644 --- a/src/plugins/dashboard/public/application/top_nav/get_top_nav_config.ts +++ b/src/plugins/dashboard/public/application/top_nav/get_top_nav_config.ts @@ -48,12 +48,12 @@ export function getTopNavConfig( ]; case ViewMode.EDIT: return [ - getCreateNewConfig(actions[TopNavIds.VISUALIZE]), - getSaveConfig(actions[TopNavIds.SAVE]), - getViewConfig(actions[TopNavIds.EXIT_EDIT_MODE]), - getAddConfig(actions[TopNavIds.ADD_EXISTING]), getOptionsConfig(actions[TopNavIds.OPTIONS]), getShareConfig(actions[TopNavIds.SHARE]), + getAddConfig(actions[TopNavIds.ADD_EXISTING]), + getViewConfig(actions[TopNavIds.EXIT_EDIT_MODE]), + getSaveConfig(actions[TopNavIds.SAVE]), + getCreateNewConfig(actions[TopNavIds.VISUALIZE]), ]; default: return []; @@ -79,7 +79,9 @@ function getFullScreenConfig(action: NavAction) { */ function getEditConfig(action: NavAction) { return { + emphasize: true, id: 'edit', + iconType: 'pencil', label: i18n.translate('dashboard.topNave.editButtonAriaLabel', { defaultMessage: 'edit', }), @@ -168,7 +170,7 @@ function getAddConfig(action: NavAction) { function getCreateNewConfig(action: NavAction) { return { emphasize: true, - iconType: 'plusInCircle', + iconType: 'plusInCircleFilled', id: 'addNew', label: i18n.translate('dashboard.topNave.addNewButtonAriaLabel', { defaultMessage: 'Create new', diff --git a/src/plugins/dashboard/public/types.ts b/src/plugins/dashboard/public/types.ts index 21c6bbc1bfc51..2764f4b075579 100644 --- a/src/plugins/dashboard/public/types.ts +++ b/src/plugins/dashboard/public/types.ts @@ -89,6 +89,7 @@ export interface DashboardAppState { query: Query | string; filters: Filter[]; viewMode: ViewMode; + expandedPanelId?: string; savedQuery?: string; } diff --git a/src/plugins/dashboard/server/saved_objects/dashboard_migrations.ts b/src/plugins/dashboard/server/saved_objects/dashboard_migrations.ts index 1e8356a1ef100..ac91c5a92048a 100644 --- a/src/plugins/dashboard/server/saved_objects/dashboard_migrations.ts +++ b/src/plugins/dashboard/server/saved_objects/dashboard_migrations.ts @@ -114,4 +114,5 @@ export const dashboardSavedObjectTypeMigrations = { '6.7.2': flow(migrateMatchAllQuery), '7.0.0': flow(migrations700), '7.3.0': flow(migrations730), + '7.9.3': flow(migrateMatchAllQuery), }; diff --git a/src/plugins/dashboard/server/saved_objects/migrate_match_all_query.test.ts b/src/plugins/dashboard/server/saved_objects/migrate_match_all_query.test.ts index 8a91c422eed3d..ce7a5ffcd9fe1 100644 --- a/src/plugins/dashboard/server/saved_objects/migrate_match_all_query.test.ts +++ b/src/plugins/dashboard/server/saved_objects/migrate_match_all_query.test.ts @@ -49,4 +49,21 @@ describe('migrate match_all query', () => { }, }); }); + + it('should return original doc if searchSourceJSON cannot be parsed', () => { + const migratedDoc = migrateMatchAllQuery( + { + attributes: { + kibanaSavedObjectMeta: 'kibanaSavedObjectMeta', + }, + } as Parameters[0], + savedObjectMigrationContext + ); + + expect(migratedDoc).toEqual({ + attributes: { + kibanaSavedObjectMeta: 'kibanaSavedObjectMeta', + }, + }); + }); }); diff --git a/src/plugins/dashboard/server/saved_objects/migrate_match_all_query.ts b/src/plugins/dashboard/server/saved_objects/migrate_match_all_query.ts index 452d68aa92394..3d7aadab5602c 100644 --- a/src/plugins/dashboard/server/saved_objects/migrate_match_all_query.ts +++ b/src/plugins/dashboard/server/saved_objects/migrate_match_all_query.ts @@ -21,6 +21,12 @@ import { SavedObjectMigrationFn } from 'kibana/server'; import { get } from 'lodash'; import { DEFAULT_QUERY_LANGUAGE } from '../../../data/common'; +/** + * This migration script is related to: + * @link https://github.com/elastic/kibana/pull/62194 + * @link https://github.com/elastic/kibana/pull/14644 + * This is only a problem when you import an object from 5.x into 6.x but to be sure that all saved objects migrated we should execute it twice in 6.7.2 and 7.9.3 + */ export const migrateMatchAllQuery: SavedObjectMigrationFn = (doc) => { const searchSourceJSON = get(doc, 'attributes.kibanaSavedObjectMeta.searchSourceJSON'); @@ -31,6 +37,7 @@ export const migrateMatchAllQuery: SavedObjectMigrationFn = (doc) => { searchSource = JSON.parse(searchSourceJSON); } catch (e) { // Let it go, the data is invalid and we'll leave it as is + return doc; } if (searchSource.query?.match_all) { diff --git a/src/plugins/data/README.md b/src/plugins/data/README.md index da0b71122fd9e..33c07078c5348 100644 --- a/src/plugins/data/README.md +++ b/src/plugins/data/README.md @@ -1,9 +1,137 @@ # data -`data` plugin provides common data access services. +The data plugin provides common data access services, such as `search` and `query`, for solutions and application developers. -- `expressions` — run pipeline functions and render results. -- `filter` -- `index_patterns` -- `query` -- `search`: Elasticsearch API service and strategies \ No newline at end of file +## Autocomplete + +The autocomplete service provides suggestions for field names and values. + +It is wired into the `TopNavMenu` component, but can be used independently. + +### Fetch Query Suggestions + +The `getQuerySuggestions` function helps to construct a query. +KQL suggestion functions are registered in X-Pack, so this API does not return results in OSS. + +```.ts + + // `inputValue` is the user input + const querySuggestions = await autocomplete.getQuerySuggestions({ + language: 'kuery', + indexPatterns: [indexPattern], + query: inputValue, + }); + +``` + +### Fetch Value Suggestions + +The `getValueSuggestions` function returns suggestions for field values. +This is helpful when you want to provide a user with options, for example when constructing a filter. + +```.ts + + // `inputValue` is the user input + const valueSuggestions = await autocomplete.getValueSuggestions({ + indexPattern, + field, + query: inputValue, + }); + +``` + +## Field Formats + +Coming soon. + +## Index Patterns + +Coming soon. + +## Query + +The query service is responsible for managing the configuration of a search query (`QueryState`): filters, time range, query string, and settings such as the auto refresh behavior and saved queries. + +It contains sub-services for each of those configurations: + - `data.query.filterManager` - Manages the `filters` component of a `QueryState`. The global filter state (filters that are persisted between applications) are owned by this service. + - `data.query.timefilter` - Responsible for the time range filter and the auto refresh behavior settings. + - `data.query.queryString` - Responsible for the query string and query language settings. + - `data.query.savedQueries` - Responsible for persisting a `QueryState` into a `SavedObject`, so it can be restored and used by other applications. + + Any changes to the `QueryState` are published on the `data.query.state$`, which is useful when wanting to persist global state or run a search upon data changes. + + A simple use case is: + + ```.ts + function searchOnChange(indexPattern: IndexPattern, aggConfigs: AggConfigs) { + data.query.state$.subscribe(() => { + + // Constuct the query portion of the search request + const query = data.query.getEsQuery(indexPattern); + + // Construct a request + const request = { + params: { + index: indexPattern.title, + body: { + aggs: aggConfigs.toDsl(), + query, + }, + }, + }; + + // Search with the `data.query` config + const search$ = data.search.search(request); + + ... + }); + } + + ``` + +## Search + +Provides access to Elasticsearch using the high-level `SearchSource` API or low-level `Search Strategies`. + +### SearchSource + +The `SearchSource` API is a convenient way to construct and run an Elasticsearch search query. + +```.tsx + + const searchSource = await data.search.searchSource.create(); + const searchResponse = await searchSource + .setParent(undefined) + .setField('index', indexPattern) + .setField('filter', filters) + .fetch(); + +``` + +### Low-level search + +#### Default Search Strategy + +One benefit of using the low-level search API, is partial response support in X-Pack, allowing for a better and more responsive user experience. +In OSS only the final result is returned. + +```.ts + import { isCompleteResponse } from '../plugins/data/public'; + + const search$ = data.search.search(request) + .subscribe({ + next: (response) => { + if (isCompleteResponse(response)) { + // Final result + search$.unsubscribe(); + } else { + // Partial result - you can update the UI, but data is still loading + } + }, + error: (e: Error) => { + // Show customized toast notifications. + // You may choose to handle errors differently if you prefer. + data.search.showError(e); + }, + }); +``` diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.test.ts b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.test.ts index bfb5fd9da56e6..a8d53223c06d1 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.test.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.test.ts @@ -89,7 +89,6 @@ describe('IndexPattern', () => { describe('api', () => { test('should have expected properties', () => { - expect(indexPattern).toHaveProperty('popularizeField'); expect(indexPattern).toHaveProperty('getScriptedFields'); expect(indexPattern).toHaveProperty('getNonScriptedFields'); expect(indexPattern).toHaveProperty('addScriptedField'); @@ -241,50 +240,4 @@ describe('IndexPattern', () => { expect(restoredPattern.fieldFormatMap.bytes instanceof MockFieldFormatter).toEqual(true); }); }); - - describe('popularizeField', () => { - test('should increment the popularity count by default', () => { - indexPattern.fields.forEach(async (field) => { - const oldCount = field.count || 0; - - await indexPattern.popularizeField(field.name); - - expect(field.count).toEqual(oldCount + 1); - }); - }); - - test('should increment the popularity count', () => { - indexPattern.fields.forEach(async (field) => { - const oldCount = field.count || 0; - const incrementAmount = 4; - - await indexPattern.popularizeField(field.name, incrementAmount); - - expect(field.count).toEqual(oldCount + incrementAmount); - }); - }); - - test('should decrement the popularity count', () => { - indexPattern.fields.forEach(async (field) => { - const oldCount = field.count || 0; - const incrementAmount = 4; - const decrementAmount = -2; - - await indexPattern.popularizeField(field.name, incrementAmount); - await indexPattern.popularizeField(field.name, decrementAmount); - - expect(field.count).toEqual(oldCount + incrementAmount + decrementAmount); - }); - }); - - test('should not go below 0', () => { - indexPattern.fields.forEach(async (field) => { - const decrementAmount = -Number.MAX_VALUE; - - await indexPattern.popularizeField(field.name, decrementAmount); - - expect(field.count).toEqual(0); - }); - }); - }); }); diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts index e880c3a9ff825..5fc6344c935d5 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts @@ -74,7 +74,6 @@ export class IndexPattern implements IIndexPattern { public metaFields: string[]; // savedObject version public version: string | undefined; - private savedObjectsClient: SavedObjectsClientCommon; public sourceFilters?: SourceFilter[]; private originalSavedObjectBody: SavedObjectBody = {}; private shortDotsEnable: boolean = false; @@ -82,13 +81,11 @@ export class IndexPattern implements IIndexPattern { constructor({ spec = {}, - savedObjectsClient, fieldFormats, shortDotsEnable = false, metaFields = [], }: IndexPatternDeps) { // set dependencies - this.savedObjectsClient = savedObjectsClient; this.fieldFormats = fieldFormats; // set config this.shortDotsEnable = shortDotsEnable; @@ -267,39 +264,6 @@ export class IndexPattern implements IIndexPattern { } } - async popularizeField(fieldName: string, unit = 1) { - /** - * This function is just used by Discover and it's high likely to be removed in the near future - * It doesn't use the save function to skip the error message that's displayed when - * a user adds several columns in a higher frequency that the changes can be persisted to ES - * resulting in 409 errors - */ - if (!this.id) return; - const field = this.fields.getByName(fieldName); - if (!field) { - return; - } - const count = Math.max((field.count || 0) + unit, 0); - if (field.count === count) { - return; - } - field.count = count; - - try { - const res = await this.savedObjectsClient.update( - 'index-pattern', - this.id, - this.getAsSavedObjectBody(), - { - version: this.version, - } - ); - this.version = res.version; - } catch (e) { - // no need for an error message here - } - } - getNonScriptedFields() { return [...this.fields.getAll().filter((field) => !field.scripted)]; } diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts index eef8ef10ea754..9a86541376cd8 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.ts @@ -516,7 +516,8 @@ export class IndexPatternsService { async updateSavedObject( indexPattern: IndexPattern, - saveAttempts: number = 0 + saveAttempts: number = 0, + ignoreErrors: boolean = false ): Promise { if (!indexPattern.id) return; @@ -567,6 +568,9 @@ export class IndexPatternsService { } if (unresolvedCollision) { + if (ignoreErrors) { + return; + } const title = i18n.translate('data.indexPatterns.unableWriteLabel', { defaultMessage: 'Unable to write index pattern! Refresh the page to get the most up to date changes for this index pattern.', @@ -586,7 +590,7 @@ export class IndexPatternsService { indexPatternCache.clear(indexPattern.id!); // Try the save again - return this.updateSavedObject(indexPattern, saveAttempts); + return this.updateSavedObject(indexPattern, saveAttempts, ignoreErrors); } throw err; }); diff --git a/src/plugins/data/common/search/aggs/buckets/shard_delay.test.ts b/src/plugins/data/common/search/aggs/buckets/shard_delay.test.ts new file mode 100644 index 0000000000000..15399ffc43791 --- /dev/null +++ b/src/plugins/data/common/search/aggs/buckets/shard_delay.test.ts @@ -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 { AggConfigs } from '../agg_configs'; +import { FieldFormatsGetConfigFn, NumberFormat } from '../../../../common/field_formats'; +import { getShardDelayBucketAgg, SHARD_DELAY_AGG_NAME } from './shard_delay'; + +describe('Shard Delay Agg', () => { + const getConfig = (() => {}) as FieldFormatsGetConfigFn; + const getAggConfigs = () => { + const field = { name: 'bytes' }; + + const indexPattern = { + id: '1234', + title: 'logstash-*', + fields: { + getByName: () => field, + filter: () => [field], + }, + getFormatterForField: () => + new NumberFormat( + { + pattern: '0,0.[000] b', + }, + getConfig + ), + } as any; + + return new AggConfigs( + indexPattern, + [ + { + type: SHARD_DELAY_AGG_NAME, + params: { + duration: 1000, + }, + }, + ], + { + typesRegistry: { + get: getShardDelayBucketAgg, + } as any, + } + ); + }; + + describe('write', () => { + test('writes the delay as the value parameter', () => { + const aggConfigs = getAggConfigs(); + const agg = aggConfigs.aggs[0]; + expect(agg.write(aggConfigs)).toMatchInlineSnapshot(` + Object { + "params": Object { + "value": "5s", + }, + } + `); + }); + }); +}); diff --git a/src/plugins/data/common/search/aggs/buckets/shard_delay.ts b/src/plugins/data/common/search/aggs/buckets/shard_delay.ts new file mode 100644 index 0000000000000..2decf5a74bc85 --- /dev/null +++ b/src/plugins/data/common/search/aggs/buckets/shard_delay.ts @@ -0,0 +1,50 @@ +/* + * 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 { BucketAggType } from './bucket_agg_type'; +import { BaseAggParams } from '../types'; +import { aggShardDelayFnName } from './shard_delay_fn'; + +export const SHARD_DELAY_AGG_NAME = 'shard_delay'; + +export interface AggParamsShardDelay extends BaseAggParams { + delay?: number; +} + +export const getShardDelayBucketAgg = () => + new BucketAggType({ + name: SHARD_DELAY_AGG_NAME, + title: 'Shard Delay', + expressionName: aggShardDelayFnName, + createFilter: () => ({ match_all: {} }), + customLabels: false, + params: [ + { + name: 'delay', + type: 'string', + default: '5s', + write(aggConfig, output) { + output.params = { + ...output.params, + value: aggConfig.params.delay, + }; + }, + }, + ], + }); diff --git a/src/plugins/data/common/search/aggs/buckets/shard_delay_fn.test.ts b/src/plugins/data/common/search/aggs/buckets/shard_delay_fn.test.ts new file mode 100644 index 0000000000000..b0ebfb005c218 --- /dev/null +++ b/src/plugins/data/common/search/aggs/buckets/shard_delay_fn.test.ts @@ -0,0 +1,65 @@ +/* + * 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 { functionWrapper } from '../test_helpers'; +import { aggShardDelay } from './shard_delay_fn'; + +describe('agg_expression_functions', () => { + describe('aggShardDelay', () => { + const fn = functionWrapper(aggShardDelay()); + + test('correctly serializes', () => { + const actual = fn({ + delay: 1000, + }); + expect(actual).toMatchInlineSnapshot(` + Object { + "type": "agg_type", + "value": Object { + "enabled": true, + "id": undefined, + "params": Object { + "customLabel": undefined, + "delay": 1000, + "json": undefined, + }, + "schema": undefined, + "type": "shard_delay", + }, + } + `); + }); + + test('correctly parses json string argument', () => { + const actual = fn({ + delay: 1000, + json: '{ "foo": true }', + }); + + expect(actual.value.params.json).toEqual({ foo: true }); + + expect(() => { + fn({ + delay: 1000, + json: '/// intentionally malformed json ///', + }); + }).toThrowErrorMatchingInlineSnapshot(`"Unable to parse json argument string"`); + }); + }); +}); diff --git a/src/plugins/data/common/search/aggs/buckets/shard_delay_fn.ts b/src/plugins/data/common/search/aggs/buckets/shard_delay_fn.ts new file mode 100644 index 0000000000000..86de428fa03d7 --- /dev/null +++ b/src/plugins/data/common/search/aggs/buckets/shard_delay_fn.ts @@ -0,0 +1,105 @@ +/* + * 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 { Assign } from '@kbn/utility-types'; +import { ExpressionFunctionDefinition } from 'src/plugins/expressions/common'; +import { AggExpressionType, AggConfigSerialized } from '../'; +import { getParsedValue } from '../utils/get_parsed_value'; +import { AggParamsShardDelay, SHARD_DELAY_AGG_NAME } from './shard_delay'; + +export const aggShardDelayFnName = 'aggShardDelay'; + +type Input = any; +type AggArgs = AggParamsShardDelay & Pick; + +type Arguments = Assign; + +type Output = AggExpressionType; +type FunctionDefinition = ExpressionFunctionDefinition< + typeof aggShardDelayFnName, + Input, + Arguments, + Output +>; + +export const aggShardDelay = (): FunctionDefinition => ({ + name: aggShardDelayFnName, + help: i18n.translate('data.search.aggs.function.buckets.shardDelay.help', { + defaultMessage: 'Generates a serialized agg config for a Shard Delay agg', + }), + type: 'agg_type', + args: { + id: { + types: ['string'], + help: i18n.translate('data.search.aggs.buckets.shardDelay.id.help', { + defaultMessage: 'ID for this aggregation', + }), + }, + enabled: { + types: ['boolean'], + default: true, + help: i18n.translate('data.search.aggs.buckets.shardDelay.enabled.help', { + defaultMessage: 'Specifies whether this aggregation should be enabled', + }), + }, + schema: { + types: ['string'], + help: i18n.translate('data.search.aggs.buckets.shardDelay.schema.help', { + defaultMessage: 'Schema to use for this aggregation', + }), + }, + delay: { + types: ['number'], + help: i18n.translate('data.search.aggs.buckets.shardDelay.delay.help', { + defaultMessage: 'Delay in ms between shards to process.', + }), + }, + json: { + types: ['string'], + help: i18n.translate('data.search.aggs.buckets.shardDelay.json.help', { + defaultMessage: 'Advanced json to include when the agg is sent to Elasticsearch', + }), + }, + customLabel: { + types: ['string'], + help: i18n.translate('data.search.aggs.buckets.shardDelay.customLabel.help', { + defaultMessage: 'Represents a custom label for this aggregation', + }), + }, + }, + fn: (input, args) => { + const { id, enabled, schema, ...rest } = args; + + return { + type: 'agg_type', + value: { + id, + enabled, + schema, + type: SHARD_DELAY_AGG_NAME, + params: { + ...rest, + json: getParsedValue(args, 'json'), + delay: getParsedValue(args, 'delay'), + }, + }, + }; + }, +}); diff --git a/src/plugins/data/common/search/aggs/param_types/field.ts b/src/plugins/data/common/search/aggs/param_types/field.ts index 492294bdf4e5f..a0bc71ac8e156 100644 --- a/src/plugins/data/common/search/aggs/param_types/field.ts +++ b/src/plugins/data/common/search/aggs/param_types/field.ts @@ -90,9 +90,10 @@ export class FieldParamType extends BaseParamType { 'data.search.aggs.paramTypes.field.invalidSavedFieldParameterErrorMessage', { defaultMessage: - 'Saved {fieldParameter} parameter is now invalid. Please select a new field.', + 'Saved field "{fieldParameter}" is invalid for use with the "{aggType}" aggregation. Please select a new field.', values: { - fieldParameter: '"field"', + fieldParameter: fieldName, + aggType: aggConfig?.type?.title, }, } ) diff --git a/src/plugins/data/common/search/search_source/index.ts b/src/plugins/data/common/search/search_source/index.ts index 70c9cfcee2348..2ef1b4c3c5199 100644 --- a/src/plugins/data/common/search/search_source/index.ts +++ b/src/plugins/data/common/search/search_source/index.ts @@ -17,11 +17,12 @@ * under the License. */ -export { SearchSource, ISearchSource, SearchSourceDependencies } from './search_source'; export { createSearchSource } from './create_search_source'; -export { SortDirection, EsQuerySortValue, SearchSourceFields } from './types'; export { injectReferences } from './inject_references'; export { extractReferences } from './extract_references'; export { parseSearchSourceJSON } from './parse_json'; export * from './fetch'; export * from './legacy'; +export * from './search_source'; +export * from './search_source_service'; +export * from './types'; diff --git a/src/plugins/data/common/search/search_source/inject_references.test.ts b/src/plugins/data/common/search/search_source/inject_references.test.ts new file mode 100644 index 0000000000000..c607f16d24734 --- /dev/null +++ b/src/plugins/data/common/search/search_source/inject_references.test.ts @@ -0,0 +1,120 @@ +/* + * 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 { SavedObjectReference } from 'src/core/types'; +import { SearchSourceFields } from './types'; + +import { injectReferences } from './inject_references'; + +describe('injectSearchSourceReferences', () => { + let searchSourceJSON: SearchSourceFields & { indexRefName: string }; + let references: SavedObjectReference[]; + + beforeEach(() => { + searchSourceJSON = { + highlightAll: true, + version: true, + query: { + query: 'play_name:"Henry IV"', + language: 'kuery', + }, + indexRefName: 'kibanaSavedObjectMeta.searchSourceJSON.index', + }; + references = [ + { + name: 'kibanaSavedObjectMeta.searchSourceJSON.index', + type: 'index-pattern', + id: '033af690-fde7-11ea-91f3-fb9e73f9bbe9', + }, + ]; + }); + + test('injects references', () => { + const actual = injectReferences(searchSourceJSON, references); + expect(actual).toMatchInlineSnapshot(` + Object { + "highlightAll": true, + "index": "033af690-fde7-11ea-91f3-fb9e73f9bbe9", + "query": Object { + "language": "kuery", + "query": "play_name:\\"Henry IV\\"", + }, + "version": true, + } + `); + }); + + test('skips injecting references if none exists', () => { + // @ts-expect-error + delete searchSourceJSON.indexRefName; + references = []; + const actual = injectReferences(searchSourceJSON, references); + expect(actual).toMatchInlineSnapshot(` + Object { + "highlightAll": true, + "query": Object { + "language": "kuery", + "query": "play_name:\\"Henry IV\\"", + }, + "version": true, + } + `); + }); + + test('throws an error if there is a broken reference', () => { + searchSourceJSON.indexRefName = 'oops'; + expect(() => injectReferences(searchSourceJSON, references)).toThrowErrorMatchingInlineSnapshot( + `"Could not find reference for oops"` + ); + }); + + test('handles filters', () => { + searchSourceJSON.filter = [ + // @ts-expect-error + { meta: { indexRefName: 'kibanaSavedObjectMeta.searchSourceJSON.index' } }, + ]; + const actual = injectReferences(searchSourceJSON, references); + expect(actual).toMatchInlineSnapshot(` + Object { + "filter": Array [ + Object { + "meta": Object { + "index": "033af690-fde7-11ea-91f3-fb9e73f9bbe9", + }, + }, + ], + "highlightAll": true, + "index": "033af690-fde7-11ea-91f3-fb9e73f9bbe9", + "query": Object { + "language": "kuery", + "query": "play_name:\\"Henry IV\\"", + }, + "version": true, + } + `); + }); + + test('throws an error if there is a broken filter reference', () => { + // @ts-expect-error + searchSourceJSON.filter = [{ meta: { indexRefName: 'oops' } }]; + expect(() => injectReferences(searchSourceJSON, references)).toThrowErrorMatchingInlineSnapshot( + `"Could not find reference for oops"` + ); + }); +}); diff --git a/src/plugins/data/common/search/search_source/legacy/types.ts b/src/plugins/data/common/search/search_source/legacy/types.ts index 1a0a96a76a703..8ac713a658932 100644 --- a/src/plugins/data/common/search/search_source/legacy/types.ts +++ b/src/plugins/data/common/search/search_source/legacy/types.ts @@ -18,15 +18,36 @@ */ import { BehaviorSubject } from 'rxjs'; +import { ApiResponse } from '@elastic/elasticsearch'; import { SearchResponse } from 'elasticsearch'; import { FetchHandlers, SearchRequest } from '../fetch'; +interface MsearchHeaders { + index: string; + preference?: number | string; +} + +interface MsearchRequest { + header: MsearchHeaders; + body: any; +} + +// @internal +export interface MsearchRequestBody { + searches: MsearchRequest[]; +} + +// @internal +export interface MsearchResponse { + body: ApiResponse<{ responses: Array> }>; +} + // @internal export interface LegacyFetchHandlers { callMsearch: (params: { - body: SearchRequest; + body: MsearchRequestBody; signal: AbortSignal; - }) => Promise>>; + }) => Promise; loadingCount$: BehaviorSubject; } diff --git a/src/plugins/data/common/search/search_source/mocks.ts b/src/plugins/data/common/search/search_source/mocks.ts index f582861e37c15..d4c0707f950bb 100644 --- a/src/plugins/data/common/search/search_source/mocks.ts +++ b/src/plugins/data/common/search/search_source/mocks.ts @@ -20,8 +20,8 @@ import { BehaviorSubject } from 'rxjs'; import { uiSettingsServiceMock } from '../../../../../core/public/mocks'; -import { ISearchSource, SearchSource } from './search_source'; -import { SearchSourceFields } from './types'; +import { SearchSource } from './search_source'; +import { ISearchStartSearchSource, ISearchSource, SearchSourceFields } from './types'; export const searchSourceInstanceMock: MockedKeys = { setPreferredSearchStrategyId: jest.fn(), @@ -45,7 +45,7 @@ export const searchSourceInstanceMock: MockedKeys = { serialize: jest.fn(), }; -export const searchSourceMock = { +export const searchSourceCommonMock: jest.Mocked = { create: jest.fn().mockReturnValue(searchSourceInstanceMock), createEmpty: jest.fn().mockReturnValue(searchSourceInstanceMock), }; diff --git a/src/plugins/data/common/search/search_source/search_source.test.ts b/src/plugins/data/common/search/search_source/search_source.test.ts index 74abd9238bc2b..00e06663e998e 100644 --- a/src/plugins/data/common/search/search_source/search_source.test.ts +++ b/src/plugins/data/common/search/search_source/search_source.test.ts @@ -17,7 +17,7 @@ * under the License. */ -import { Observable, BehaviorSubject } from 'rxjs'; +import { BehaviorSubject } from 'rxjs'; import { IndexPattern } from '../../index_patterns'; import { GetConfigFn } from '../../types'; import { fetchSoon } from './legacy'; @@ -53,16 +53,7 @@ describe('SearchSource', () => { let searchSourceDependencies: SearchSourceDependencies; beforeEach(() => { - mockSearchMethod = jest.fn(() => { - return new Observable((subscriber) => { - setTimeout(() => { - subscriber.next({ - rawResponse: '', - }); - subscriber.complete(); - }, 100); - }); - }); + mockSearchMethod = jest.fn().mockResolvedValue({ rawResponse: '' }); searchSourceDependencies = { getConfig: jest.fn(), diff --git a/src/plugins/data/common/search/search_source/search_source.ts b/src/plugins/data/common/search/search_source/search_source.ts index d8a036ce970dd..3eafea06f9f5b 100644 --- a/src/plugins/data/common/search/search_source/search_source.ts +++ b/src/plugins/data/common/search/search_source/search_source.ts @@ -71,22 +71,15 @@ import { setWith } from '@elastic/safer-lodash-set'; import { uniqueId, uniq, extend, pick, difference, omit, isObject, keys, isFunction } from 'lodash'; -import { map } from 'rxjs/operators'; import { normalizeSortRequest } from './normalize_sort_request'; import { filterDocvalueFields } from './filter_docvalue_fields'; import { fieldWildcardFilter } from '../../../../kibana_utils/common'; import { IIndexPattern } from '../../index_patterns'; -import { ISearchGeneric } from '../..'; -import { SearchSourceOptions, SearchSourceFields } from './types'; +import { IEsSearchRequest, IEsSearchResponse, ISearchOptions } from '../..'; +import { ISearchSource, SearchSourceOptions, SearchSourceFields } from './types'; import { FetchHandlers, RequestFailure, getSearchParamsFromRequest, SearchRequest } from './fetch'; -import { - getEsQueryConfig, - buildEsQuery, - Filter, - UI_SETTINGS, - ISearchOptions, -} from '../../../common'; +import { getEsQueryConfig, buildEsQuery, Filter, UI_SETTINGS } from '../../../common'; import { getHighlightRequest } from '../../../common/field_formats'; import { fetchSoon } from './legacy'; import { extractReferences } from './extract_references'; @@ -108,7 +101,7 @@ export const searchSourceRequiredUiSettings = [ ]; export interface SearchSourceDependencies extends FetchHandlers { - search: ISearchGeneric; + search: (request: IEsSearchRequest, options: ISearchOptions) => Promise; } /** @public **/ @@ -264,7 +257,7 @@ export class SearchSource { if (getConfig(UI_SETTINGS.COURIER_BATCH_SEARCHES)) { response = await this.legacyFetch(searchRequest, options); } else { - response = await this.fetch$(searchRequest, options).toPromise(); + response = await this.fetchSearch(searchRequest, options); } // TODO: Remove casting when https://github.com/elastic/elasticsearch-js/issues/1287 is resolved @@ -308,17 +301,17 @@ export class SearchSource { /** * Run a search using the search service - * @return {Observable>} + * @return {Promise>} */ - private fetch$(searchRequest: SearchRequest, options: ISearchOptions) { + private fetchSearch(searchRequest: SearchRequest, options: ISearchOptions) { const { search, getConfig, onResponse } = this.dependencies; const params = getSearchParamsFromRequest(searchRequest, { getConfig, }); - return search({ params, indexType: searchRequest.indexType }, options).pipe( - map(({ rawResponse }) => onResponse(searchRequest, rawResponse)) + return search({ params, indexType: searchRequest.indexType }, options).then(({ rawResponse }) => + onResponse(searchRequest, rawResponse) ); } @@ -558,9 +551,3 @@ export class SearchSource { return [filterField]; } } - -/** - * search source interface - * @public - */ -export type ISearchSource = Pick; diff --git a/src/plugins/data/common/search/search_source/search_source_service.test.ts b/src/plugins/data/common/search/search_source/search_source_service.test.ts new file mode 100644 index 0000000000000..bbbaac11bbe91 --- /dev/null +++ b/src/plugins/data/common/search/search_source/search_source_service.test.ts @@ -0,0 +1,50 @@ +/* + * 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 { BehaviorSubject } from 'rxjs'; +import { IndexPatternsContract } from '../../index_patterns/index_patterns'; +import { SearchSourceService, SearchSourceDependencies } from './'; + +describe('SearchSource service', () => { + let dependencies: jest.Mocked; + + beforeEach(() => { + jest.resetModules(); + dependencies = { + getConfig: jest.fn(), + search: jest.fn(), + onResponse: jest.fn(), + legacy: { + callMsearch: jest.fn(), + loadingCount$: new BehaviorSubject(0), + }, + }; + }); + + describe('start()', () => { + test('exposes proper contract', () => { + const start = new SearchSourceService().start( + (jest.fn() as unknown) as jest.Mocked, + dependencies + ); + + expect(Object.keys(start)).toEqual(['create', 'createEmpty']); + }); + }); +}); diff --git a/src/plugins/data/common/search/search_source/search_source_service.ts b/src/plugins/data/common/search/search_source/search_source_service.ts new file mode 100644 index 0000000000000..40981402419c7 --- /dev/null +++ b/src/plugins/data/common/search/search_source/search_source_service.ts @@ -0,0 +1,42 @@ +/* + * 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 { createSearchSource, SearchSource, SearchSourceDependencies } from './'; +import { IndexPatternsContract } from '../../index_patterns/index_patterns'; + +export class SearchSourceService { + public setup() {} + + public start(indexPatterns: IndexPatternsContract, dependencies: SearchSourceDependencies) { + return { + /** + * creates searchsource based on serialized search source fields + */ + create: createSearchSource(indexPatterns, dependencies), + /** + * creates an enpty search source + */ + createEmpty: () => { + return new SearchSource({}, dependencies); + }, + }; + } + + public stop() {} +} diff --git a/src/plugins/data/common/search/search_source/types.ts b/src/plugins/data/common/search/search_source/types.ts index 0882aa9a2ceec..bbfc308e0459d 100644 --- a/src/plugins/data/common/search/search_source/types.ts +++ b/src/plugins/data/common/search/search_source/types.ts @@ -16,9 +16,32 @@ * specific language governing permissions and limitations * under the License. */ + import { NameList } from 'elasticsearch'; -import { IndexPattern, Query } from '../..'; -import { Filter } from '../../../common'; +import { Filter, IndexPattern, Query } from '../..'; +import { SearchSource } from './search_source'; + +/** + * search source interface + * @public + */ +export type ISearchSource = Pick; + +/** + * high level search service + * @public + */ +export interface ISearchStartSearchSource { + /** + * creates {@link SearchSource} based on provided serialized {@link SearchSourceFields} + * @param fields + */ + create: (fields?: SearchSourceFields) => Promise; + /** + * creates empty {@link SearchSource} + */ + createEmpty: () => ISearchSource; +} export type EsQuerySearchAfter = [string | number, string | number]; @@ -75,8 +98,6 @@ export interface SearchSourceOptions { callParentStartHandlers?: boolean; } -export { ISearchSource } from './search_source'; - export interface SortOptions { mode?: 'min' | 'max' | 'sum' | 'avg' | 'median'; type?: 'double' | 'long' | 'date' | 'date_nanos'; diff --git a/src/plugins/data/config.ts b/src/plugins/data/config.ts index 09cb2cb2afeca..83a384a049a75 100644 --- a/src/plugins/data/config.ts +++ b/src/plugins/data/config.ts @@ -28,6 +28,16 @@ export const configSchema = schema.object({ enabled: schema.boolean({ defaultValue: true }), }), }), + search: schema.object({ + aggs: schema.object({ + shardDelay: schema.object({ + // Whether or not to register the shard_delay (which is only available in snapshot versions + // of Elasticsearch) agg type/expression function to make it available in the UI for either + // functional or manual testing + enabled: schema.boolean({ defaultValue: false }), + }), + }), + }), }); export type ConfigSchema = TypeOf; diff --git a/src/plugins/data/public/mocks.ts b/src/plugins/data/public/mocks.ts index 0eb0e3b658045..1b83eb569b1a1 100644 --- a/src/plugins/data/public/mocks.ts +++ b/src/plugins/data/public/mocks.ts @@ -78,7 +78,7 @@ const createStartContract = (): Start => { }; }; -export { createSearchSourceMock } from './search/mocks'; +export { createSearchSourceMock } from '../common/search/search_source/mocks'; export { getCalculateAutoTimeExpression } from '../common/search/aggs'; export const dataPluginMock = { diff --git a/src/plugins/data/public/plugin.ts b/src/plugins/data/public/plugin.ts index 3b18e0fbed537..5abf4d3648af7 100644 --- a/src/plugins/data/public/plugin.ts +++ b/src/plugins/data/public/plugin.ts @@ -96,7 +96,7 @@ export class DataPublicPlugin private readonly storage: IStorageWrapper; constructor(initializerContext: PluginInitializerContext) { - this.searchService = new SearchService(); + this.searchService = new SearchService(initializerContext); this.queryService = new QueryService(); this.fieldFormatsService = new FieldFormatsService(); this.autocomplete = new AutocompleteService(initializerContext); diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index 1ee453a0f1411..b8eb7a556ac44 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -7,7 +7,8 @@ import { $Values } from '@kbn/utility-types'; import _ from 'lodash'; import { Action } from 'history'; -import { ApiResponse } from '@elastic/elasticsearch/lib/Transport'; +import { ApiResponse } from '@elastic/elasticsearch'; +import { ApiResponse as ApiResponse_2 } from '@elastic/elasticsearch/lib/Transport'; import { ApplicationStart } from 'kibana/public'; import { Assign } from '@kbn/utility-types'; import { BehaviorSubject } from 'rxjs'; @@ -1085,7 +1086,7 @@ export type IMetricAggType = MetricAggType; // @public (undocumented) export class IndexPattern implements IIndexPattern { // Warning: (ae-forgotten-export) The symbol "IndexPatternDeps" needs to be exported by the entry point index.d.ts - constructor({ spec, savedObjectsClient, fieldFormats, shortDotsEnable, metaFields, }: IndexPatternDeps); + constructor({ spec, fieldFormats, shortDotsEnable, metaFields, }: IndexPatternDeps); addScriptedField(name: string, script: string, fieldType?: string): Promise; // (undocumented) fieldFormatMap: Record; @@ -1162,8 +1163,6 @@ export class IndexPattern implements IIndexPattern { isTimeNanosBased(): boolean; // (undocumented) metaFields: string[]; - // (undocumented) - popularizeField(fieldName: string, unit?: number): Promise; removeScriptedField(fieldName: string): void; resetOriginalSavedObjectBody: () => void; // Warning: (ae-forgotten-export) The symbol "SourceFilter" needs to be exported by the entry point index.d.ts @@ -1385,7 +1384,7 @@ export class IndexPatternsService { refreshFields: (indexPattern: IndexPattern) => Promise; savedObjectToSpec: (savedObject: SavedObject) => IndexPatternSpec; setDefault: (id: string, force?: boolean) => Promise; - updateSavedObject(indexPattern: IndexPattern, saveAttempts?: number): Promise; + updateSavedObject(indexPattern: IndexPattern, saveAttempts?: number, ignoreErrors?: boolean): Promise; } // Warning: (ae-missing-release-tag) "TypeMeta" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) diff --git a/src/plugins/data/public/search/README.md b/src/plugins/data/public/search/README.md deleted file mode 100644 index 0a123ffa3f1e9..0000000000000 --- a/src/plugins/data/public/search/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# search - -The `search` service provides you with APIs to query Elasticsearch. - -The services are split into two parts: (1) low-level API; and (2) high-level API. - -## Low-level API - -With low level API you work directly with elasticsearch DSL - -```typescript -const results = await data.search.search(request, params); -``` - -## High-level API - -Using high-level API you work with Kibana abstractions around Elasticsearch DSL: filters, queries, and aggregations. Provided by the *Search Source* service. - -```typescript -const search = data.search.searchSource.createEmpty(); -search.setField('query', data.query.queryString); -const results = await search.fetch(); -``` diff --git a/src/plugins/data/public/search/errors/timeout_error.test.tsx b/src/plugins/data/public/search/errors/timeout_error.test.tsx index 87b491b976ebc..ad3384c389fbf 100644 --- a/src/plugins/data/public/search/errors/timeout_error.test.tsx +++ b/src/plugins/data/public/search/errors/timeout_error.test.tsx @@ -37,9 +37,9 @@ describe('SearchTimeoutError', () => { expect(component.find('EuiButton').length).toBe(1); component.find('EuiButton').simulate('click'); - expect(startMock.application.navigateToApp).toHaveBeenCalledWith('management', { - path: '/kibana/indexPatterns', - }); + expect(startMock.application.navigateToUrl).toHaveBeenCalledWith( + 'https://www.elastic.co/subscriptions' + ); }); it('Should create contact admin message', () => { diff --git a/src/plugins/data/public/search/errors/timeout_error.tsx b/src/plugins/data/public/search/errors/timeout_error.tsx index 56aecb42f5326..a9ff0c3b38ae6 100644 --- a/src/plugins/data/public/search/errors/timeout_error.tsx +++ b/src/plugins/data/public/search/errors/timeout_error.tsx @@ -78,9 +78,7 @@ export class SearchTimeoutError extends KbnError { private onClick(application: ApplicationStart) { switch (this.mode) { case TimeoutErrorMode.UPGRADE: - application.navigateToApp('management', { - path: `/kibana/indexPatterns`, - }); + application.navigateToUrl('https://www.elastic.co/subscriptions'); break; case TimeoutErrorMode.CHANGE: application.navigateToApp('management', { diff --git a/src/plugins/data/public/search/mocks.ts b/src/plugins/data/public/search/mocks.ts index e931b39eae2a5..8bad4cd269b3f 100644 --- a/src/plugins/data/public/search/mocks.ts +++ b/src/plugins/data/public/search/mocks.ts @@ -18,10 +18,8 @@ */ import { searchAggsSetupMock, searchAggsStartMock } from './aggs/mocks'; +import { searchSourceMock } from './search_source/mocks'; import { ISearchSetup, ISearchStart } from './types'; -import { searchSourceMock, createSearchSourceMock } from '../../common/search/search_source/mocks'; - -export * from '../../common/search/search_source/mocks'; function createSetupContract(): jest.Mocked { return { @@ -35,7 +33,7 @@ function createStartContract(): jest.Mocked { aggs: searchAggsStartMock(), search: jest.fn(), showError: jest.fn(), - searchSource: searchSourceMock, + searchSource: searchSourceMock.createStartContract(), }; } @@ -43,5 +41,3 @@ export const searchServiceMock = { createSetupContract, createStartContract, }; - -export { createSearchSourceMock }; diff --git a/src/plugins/data/public/search/search_service.test.ts b/src/plugins/data/public/search/search_service.test.ts index 738f1e8ffbca0..b59fa6fa16bf6 100644 --- a/src/plugins/data/public/search/search_service.test.ts +++ b/src/plugins/data/public/search/search_service.test.ts @@ -26,11 +26,15 @@ describe('Search service', () => { let searchService: SearchService; let mockCoreSetup: MockedKeys; let mockCoreStart: MockedKeys; + const initializerContext = coreMock.createPluginInitializerContext(); + initializerContext.config.get = jest.fn().mockReturnValue({ + search: { aggs: { shardDelay: { enabled: false } } }, + }); beforeEach(() => { - searchService = new SearchService(); mockCoreSetup = coreMock.createSetup(); mockCoreStart = coreMock.createStart(); + searchService = new SearchService(initializerContext); }); describe('setup()', () => { @@ -48,6 +52,7 @@ describe('Search service', () => { describe('start()', () => { it('exposes proper contract', async () => { const start = searchService.start(mockCoreStart, { + fieldFormats: {}, indexPatterns: {}, } as any); expect(start).toHaveProperty('aggs'); diff --git a/src/plugins/data/public/search/search_service.ts b/src/plugins/data/public/search/search_service.ts index 173baba5cab6f..5014418d6b70b 100644 --- a/src/plugins/data/public/search/search_service.ts +++ b/src/plugins/data/public/search/search_service.ts @@ -17,15 +17,16 @@ * under the License. */ -import { Plugin, CoreSetup, CoreStart } from 'src/core/public'; +import { Plugin, CoreSetup, CoreStart, PluginInitializerContext } from 'src/core/public'; import { BehaviorSubject } from 'rxjs'; import { ISearchSetup, ISearchStart, SearchEnhancements } from './types'; import { handleResponse } from './fetch'; import { - createSearchSource, + IEsSearchRequest, ISearchGeneric, - SearchSource, + ISearchOptions, + SearchSourceService, SearchSourceDependencies, } from '../../common/search'; import { getCallMsearch } from './legacy'; @@ -36,6 +37,12 @@ import { SearchUsageCollector, createUsageCollector } from './collectors'; import { UsageCollectionSetup } from '../../../usage_collection/public'; import { esdsl, esRawResponse } from './expressions'; import { ExpressionsSetup } from '../../../expressions/public'; +import { ConfigSchema } from '../../config'; +import { + SHARD_DELAY_AGG_NAME, + getShardDelayBucketAgg, +} from '../../common/search/aggs/buckets/shard_delay'; +import { aggShardDelay } from '../../common/search/aggs/buckets/shard_delay_fn'; /** @internal */ export interface SearchServiceSetupDependencies { @@ -51,9 +58,12 @@ export interface SearchServiceStartDependencies { export class SearchService implements Plugin { private readonly aggsService = new AggsService(); + private readonly searchSourceService = new SearchSourceService(); private searchInterceptor!: ISearchInterceptor; private usageCollector?: SearchUsageCollector; + constructor(private initializerContext: PluginInitializerContext) {} + public setup( { http, getStartServices, notifications, uiSettings }: CoreSetup, { expressions, usageCollection }: SearchServiceSetupDependencies @@ -75,11 +85,18 @@ export class SearchService implements Plugin { expressions.registerFunction(esdsl); expressions.registerType(esRawResponse); + const aggs = this.aggsService.setup({ + registerFunction: expressions.registerFunction, + uiSettings, + }); + + if (this.initializerContext.config.get().search.aggs.shardDelay.enabled) { + aggs.types.registerBucket(SHARD_DELAY_AGG_NAME, getShardDelayBucketAgg); + expressions.registerFunction(aggShardDelay); + } + return { - aggs: this.aggsService.setup({ - registerFunction: expressions.registerFunction, - uiSettings, - }), + aggs, usageCollector: this.usageCollector!, __enhance: (enhancements: SearchEnhancements) => { this.searchInterceptor = enhancements.searchInterceptor; @@ -100,7 +117,9 @@ export class SearchService implements Plugin { const searchSourceDependencies: SearchSourceDependencies = { getConfig: uiSettings.get.bind(uiSettings), - search, + search: (request: IEsSearchRequest, options: ISearchOptions) => { + return search(request, options).toPromise(); + }, onResponse: handleResponse, legacy: { callMsearch: getCallMsearch({ http }), @@ -114,22 +133,12 @@ export class SearchService implements Plugin { showError: (e: Error) => { this.searchInterceptor.showError(e); }, - searchSource: { - /** - * creates searchsource based on serialized search source fields - */ - create: createSearchSource(indexPatterns, searchSourceDependencies), - /** - * creates an enpty search source - */ - createEmpty: () => { - return new SearchSource({}, searchSourceDependencies); - }, - }, + searchSource: this.searchSourceService.start(indexPatterns, searchSourceDependencies), }; } public stop() { this.aggsService.stop(); + this.searchSourceService.stop(); } } diff --git a/src/plugins/data/public/search/search_source/mocks.ts b/src/plugins/data/public/search/search_source/mocks.ts new file mode 100644 index 0000000000000..bc382f09947c5 --- /dev/null +++ b/src/plugins/data/public/search/search_source/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. + */ + +import { searchSourceCommonMock } from '../../../common/search/search_source/mocks'; +import { ISearchStart } from '../types'; + +function createStartContract(): jest.Mocked { + return searchSourceCommonMock; +} + +export const searchSourceMock = { + createStartContract, +}; diff --git a/src/plugins/data/public/search/types.ts b/src/plugins/data/public/search/types.ts index a133a8cd4be93..85ef7aa4d97cb 100644 --- a/src/plugins/data/public/search/types.ts +++ b/src/plugins/data/public/search/types.ts @@ -21,10 +21,12 @@ import { PackageInfo } from 'kibana/server'; import { ISearchInterceptor } from './search_interceptor'; import { SearchUsageCollector } from './collectors'; import { AggsSetup, AggsSetupDependencies, AggsStartDependencies, AggsStart } from './aggs'; -import { ISearchGeneric, ISearchSource, SearchSourceFields } from '../../common/search'; +import { ISearchGeneric, ISearchStartSearchSource } from '../../common/search'; import { IndexPatternsContract } from '../../common/index_patterns/index_patterns'; import { UsageCollectionSetup } from '../../../usage_collection/public'; +export { ISearchStartSearchSource }; + export interface SearchEnhancements { searchInterceptor: ISearchInterceptor; } @@ -42,21 +44,6 @@ export interface ISearchSetup { __enhance: (enhancements: SearchEnhancements) => void; } -/** - * high level search service - * @public - */ -export interface ISearchStartSearchSource { - /** - * creates {@link SearchSource} based on provided serialized {@link SearchSourceFields} - * @param fields - */ - create: (fields?: SearchSourceFields) => Promise; - /** - * creates empty {@link SearchSource} - */ - createEmpty: () => ISearchSource; -} /** * search service * @public diff --git a/src/plugins/data/public/ui/filter_bar/filter_editor/index.tsx b/src/plugins/data/public/ui/filter_bar/filter_editor/index.tsx index 0e2bcc7581950..7bd4facc9caa9 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_editor/index.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_editor/index.tsx @@ -106,7 +106,11 @@ class FilterEditorUI extends Component { - + {this.state.isCustomEditorOpen ? ( { - geo.coordinates in US - -`; - -exports[`negated alias 1`] = ` - - - NOT - - geo.coordinates in US - -`; diff --git a/src/plugins/data/public/ui/filter_bar/filter_editor/lib/filter_label.test.js b/src/plugins/data/public/ui/filter_bar/filter_editor/lib/filter_label.test.js deleted file mode 100644 index 55df544ad010b..0000000000000 --- a/src/plugins/data/public/ui/filter_bar/filter_editor/lib/filter_label.test.js +++ /dev/null @@ -1,48 +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 React from 'react'; -import { FilterLabel } from './filter_label'; -import { shallow } from 'enzyme'; -import { phraseFilter } from '../../../../stubs'; - -test('alias', () => { - const filter = { - ...phraseFilter, - meta: { - ...phraseFilter.meta, - alias: 'geo.coordinates in US', - }, - }; - const component = shallow(); - expect(component).toMatchSnapshot(); -}); - -test('negated alias', () => { - const filter = { - ...phraseFilter, - meta: { - ...phraseFilter.meta, - alias: 'geo.coordinates in US', - negate: true, - }, - }; - const component = shallow(); - expect(component).toMatchSnapshot(); -}); diff --git a/src/plugins/data/public/ui/filter_bar/filter_editor/lib/filter_label.test.tsx b/src/plugins/data/public/ui/filter_bar/filter_editor/lib/filter_label.test.tsx new file mode 100644 index 0000000000000..59afc1606adf9 --- /dev/null +++ b/src/plugins/data/public/ui/filter_bar/filter_editor/lib/filter_label.test.tsx @@ -0,0 +1,156 @@ +/* + * 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 { FilterLabel } from './filter_label'; +import { render, cleanup } from '@testing-library/react/pure'; +import { phraseFilter } from '../../../../stubs'; + +afterEach(cleanup); + +test('alias', () => { + const filter = { + ...phraseFilter, + meta: { + ...phraseFilter.meta, + alias: 'geo.coordinates in US', + }, + }; + const { container } = render(); + expect(container).toMatchInlineSnapshot(` +
+ + geo.coordinates in US +
+ `); +}); + +test('negated alias', () => { + const filter = { + ...phraseFilter, + meta: { + ...phraseFilter.meta, + alias: 'geo.coordinates in US', + negate: true, + }, + }; + const { container } = render(); + expect(container).toMatchInlineSnapshot(` +
+ + NOT + + geo.coordinates in US +
+ `); +}); + +test('alias with warning status', () => { + const filter = { + ...phraseFilter, + meta: { + ...phraseFilter.meta, + alias: 'geo.coordinates in US', + negate: true, + }, + }; + const { container } = render( + + ); + expect(container).toMatchInlineSnapshot(` +
+ + NOT + + geo.coordinates in US + : + + Warning + +
+ `); +}); + +test('alias with error status', () => { + const filter = { + ...phraseFilter, + meta: { + ...phraseFilter.meta, + alias: 'geo.coordinates in US', + negate: true, + }, + }; + const { container } = render( + + ); + expect(container).toMatchInlineSnapshot(` +
+ + NOT + + geo.coordinates in US + : + + Error + +
+ `); +}); + +test('warning', () => { + const { container } = render(); + expect(container).toMatchInlineSnapshot(` +
+ + machine.os + : + + Warning + +
+ `); +}); + +test('error', () => { + const { container } = render(); + expect(container).toMatchInlineSnapshot(` +
+ + machine.os + : + + Error + +
+ `); +}); diff --git a/src/plugins/data/public/ui/filter_bar/filter_editor/lib/filter_label.tsx b/src/plugins/data/public/ui/filter_bar/filter_editor/lib/filter_label.tsx index 070631354d8b8..3b85d0753b8c5 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_editor/lib/filter_label.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_editor/lib/filter_label.tsx @@ -22,13 +22,15 @@ import { EuiTextColor } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { existsOperator, isOneOfOperator } from './filter_operators'; import { Filter, FILTERS } from '../../../../../common'; +import type { FilterLabelStatus } from '../../filter_item'; interface Props { filter: Filter; valueLabel?: string; + filterLabelStatus?: FilterLabelStatus; } -export function FilterLabel({ filter, valueLabel }: Props) { +export function FilterLabel({ filter, valueLabel, filterLabelStatus }: Props) { const prefixText = filter.meta.negate ? ` ${i18n.translate('data.filter.filterBar.negatedFilterPrefix', { defaultMessage: 'NOT ', @@ -50,6 +52,7 @@ export function FilterLabel({ filter, valueLabel }: Props) { {prefix} {filter.meta.alias} + {filterLabelStatus && <>: {getValue(valueLabel)}} ); } diff --git a/src/plugins/data/public/ui/filter_bar/filter_item.tsx b/src/plugins/data/public/ui/filter_bar/filter_item.tsx index 078fc8c9e1a8f..cbff20115f8ea 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_item.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_item.tsx @@ -49,7 +49,7 @@ interface Props { interface LabelOptions { title: string; - status: string; + status: FilterLabelStatus; message?: string; } @@ -57,6 +57,11 @@ const FILTER_ITEM_OK = ''; const FILTER_ITEM_WARNING = 'warn'; const FILTER_ITEM_ERROR = 'error'; +export type FilterLabelStatus = + | typeof FILTER_ITEM_OK + | typeof FILTER_ITEM_WARNING + | typeof FILTER_ITEM_ERROR; + export function FilterItem(props: Props) { const [isPopoverOpen, setIsPopoverOpen] = useState(false); const [indexPatternExists, setIndexPatternExists] = useState(undefined); @@ -260,7 +265,7 @@ export function FilterItem(props: Props) { } function getValueLabel(): LabelOptions { - const label = { + const label: LabelOptions = { title: '', message: '', status: FILTER_ITEM_OK, @@ -326,6 +331,7 @@ export function FilterItem(props: Props) { props.onRemove()} diff --git a/src/plugins/data/public/ui/filter_bar/filter_view/index.tsx b/src/plugins/data/public/ui/filter_bar/filter_view/index.tsx index f9328875cc910..3f9cbce06b315 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_view/index.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_view/index.tsx @@ -22,10 +22,12 @@ import { i18n } from '@kbn/i18n'; import React, { FC } from 'react'; import { FilterLabel } from '../filter_editor/lib/filter_label'; import { Filter, isFilterPinned } from '../../../../common'; +import type { FilterLabelStatus } from '../filter_item'; interface Props { filter: Filter; valueLabel: string; + filterLabelStatus: FilterLabelStatus; errorMessage?: string; [propName: string]: any; } @@ -36,6 +38,7 @@ export const FilterView: FC = ({ onClick, valueLabel, errorMessage, + filterLabelStatus, ...rest }: Props) => { const [ref, innerText] = useInnerText(); @@ -65,7 +68,7 @@ export const FilterView: FC = ({ iconType="cross" iconSide="right" closeButtonProps={{ - // Removing tab focus on close button because the same option can be optained through the context menu + // Removing tab focus on close button because the same option can be obtained through the context menu // Also, we may want to add a `DEL` keyboard press functionality tabIndex: -1, }} @@ -80,7 +83,11 @@ export const FilterView: FC = ({ {...rest} > - + ); diff --git a/src/plugins/data/public/ui/query_string_input/no_data_popover.tsx b/src/plugins/data/public/ui/query_string_input/no_data_popover.tsx index 561c33519f96f..7d5282a0545bc 100644 --- a/src/plugins/data/public/ui/query_string_input/no_data_popover.tsx +++ b/src/plugins/data/public/ui/query_string_input/no_data_popover.tsx @@ -63,6 +63,7 @@ export function NoDataPopover({ } minWidth={300} anchorPosition="downCenter" + anchorClassName="eui-displayBlock" step={1} stepsTotal={1} isStepOpen={noDataPopoverVisible} diff --git a/src/plugins/data/public/ui/query_string_input/query_string_input.tsx b/src/plugins/data/public/ui/query_string_input/query_string_input.tsx index bbd998c0b74de..ec45b80927f6d 100644 --- a/src/plugins/data/public/ui/query_string_input/query_string_input.tsx +++ b/src/plugins/data/public/ui/query_string_input/query_string_input.tsx @@ -613,6 +613,7 @@ export class QueryStringInputUI extends Component { })} aria-haspopup="true" aria-expanded={this.state.isSuggestionsVisible} + data-skip-axe="aria-required-children" >
as promised, not helpful
@@ -56,6 +57,7 @@ exports[`SuggestionComponent Should make the element active if the selected prop
as promised, not helpful
diff --git a/src/plugins/data/public/ui/typeahead/suggestion_component.tsx b/src/plugins/data/public/ui/typeahead/suggestion_component.tsx index 724287b874bf7..20cb60ddab9e1 100644 --- a/src/plugins/data/public/ui/typeahead/suggestion_component.tsx +++ b/src/plugins/data/public/ui/typeahead/suggestion_component.tsx @@ -72,7 +72,9 @@ export function SuggestionComponent(props: Props) {
-
{props.suggestion.text}
+
+ {props.suggestion.text} +
{props.shouldDisplayDescription && (
{props.suggestion.description}
)} diff --git a/src/plugins/data/server/index.ts b/src/plugins/data/server/index.ts index 43080cc5a5989..aac1fe1fde212 100644 --- a/src/plugins/data/server/index.ts +++ b/src/plugins/data/server/index.ts @@ -287,6 +287,7 @@ export { export const config: PluginConfigDescriptor = { exposeToBrowser: { autocomplete: true, + search: true, }, schema: configSchema, }; diff --git a/src/plugins/data/server/plugin.ts b/src/plugins/data/server/plugin.ts index 588885391262e..88f24b7ca5a70 100644 --- a/src/plugins/data/server/plugin.ts +++ b/src/plugins/data/server/plugin.ts @@ -111,13 +111,15 @@ export class DataServerPlugin public start(core: CoreStart) { const fieldFormats = this.fieldFormats.start(); + const indexPatterns = this.indexPatterns.start(core, { + fieldFormats, + logger: this.logger.get('indexPatterns'), + }); + return { - search: this.searchService.start(core, { fieldFormats }), fieldFormats, - indexPatterns: this.indexPatterns.start(core, { - fieldFormats, - logger: this.logger.get('indexPatterns'), - }), + indexPatterns, + search: this.searchService.start(core, { fieldFormats, indexPatterns }), }; } diff --git a/src/plugins/data/server/search/mocks.ts b/src/plugins/data/server/search/mocks.ts index 0c74ecb4b2c9d..0d4ba0cba24a3 100644 --- a/src/plugins/data/server/search/mocks.ts +++ b/src/plugins/data/server/search/mocks.ts @@ -19,6 +19,7 @@ import { ISearchSetup, ISearchStart } from './types'; import { searchAggsSetupMock, searchAggsStartMock } from './aggs/mocks'; +import { searchSourceMock } from './search_source/mocks'; export function createSearchSetupMock(): jest.Mocked { return { @@ -33,5 +34,6 @@ export function createSearchStartMock(): jest.Mocked { aggs: searchAggsStartMock(), getSearchStrategy: jest.fn(), search: jest.fn(), + searchSource: searchSourceMock.createStartContract(), }; } diff --git a/src/plugins/data/server/search/routes/call_msearch.test.ts b/src/plugins/data/server/search/routes/call_msearch.test.ts new file mode 100644 index 0000000000000..3d409e22aaa88 --- /dev/null +++ b/src/plugins/data/server/search/routes/call_msearch.test.ts @@ -0,0 +1,101 @@ +/* + * 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 { Observable } from 'rxjs'; +import { IUiSettingsClient, IScopedClusterClient, SharedGlobalConfig } from 'src/core/server'; + +import { + coreMock, + pluginInitializerContextConfigMock, +} from '../../../../../../src/core/server/mocks'; +import { convertRequestBody, getCallMsearch } from './call_msearch'; + +describe('callMsearch', () => { + let esClient: DeeplyMockedKeys; + let globalConfig$: Observable; + let uiSettings: IUiSettingsClient; + let callMsearch: ReturnType; + + beforeEach(() => { + const coreContext = coreMock.createRequestHandlerContext(); + esClient = coreContext.elasticsearch.client; + globalConfig$ = pluginInitializerContextConfigMock({}).legacy.globalConfig$; + uiSettings = coreContext.uiSettings.client; + + callMsearch = getCallMsearch({ esClient, globalConfig$, uiSettings }); + }); + + it('handler calls msearch with the given request', async () => { + const mockBody = { + searches: [{ header: { index: 'foo' }, body: { query: { match_all: {} } } }], + }; + + await callMsearch({ + body: mockBody, + signal: new AbortController().signal, + }); + + expect(esClient.asCurrentUser.msearch).toHaveBeenCalledTimes(1); + expect(esClient.asCurrentUser.msearch.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "body": "{\\"ignore_unavailable\\":true,\\"index\\":\\"foo\\"} + {\\"query\\":{\\"match_all\\":{}}} + ", + }, + Object { + "querystring": Object { + "ignore_throttled": true, + "ignore_unavailable": true, + "max_concurrent_shard_requests": undefined, + }, + }, + ] + `); + }); + + describe('convertRequestBody', () => { + it('combines header & body into proper msearch request', () => { + const request = { + searches: [{ header: { index: 'foo', preference: 0 }, body: { test: true } }], + }; + expect(convertRequestBody(request, { timeout: '30000ms' })).toMatchInlineSnapshot(` + "{\\"ignore_unavailable\\":true,\\"index\\":\\"foo\\",\\"preference\\":0} + {\\"timeout\\":\\"30000ms\\",\\"test\\":true} + " + `); + }); + + it('handles multiple searches', () => { + const request = { + searches: [ + { header: { index: 'foo', preference: 0 }, body: { test: true } }, + { header: { index: 'bar', preference: 1 }, body: { hello: 'world' } }, + ], + }; + expect(convertRequestBody(request, { timeout: '30000ms' })).toMatchInlineSnapshot(` + "{\\"ignore_unavailable\\":true,\\"index\\":\\"foo\\",\\"preference\\":0} + {\\"timeout\\":\\"30000ms\\",\\"test\\":true} + {\\"ignore_unavailable\\":true,\\"index\\":\\"bar\\",\\"preference\\":1} + {\\"timeout\\":\\"30000ms\\",\\"hello\\":\\"world\\"} + " + `); + }); + }); +}); diff --git a/src/plugins/data/server/search/routes/call_msearch.ts b/src/plugins/data/server/search/routes/call_msearch.ts new file mode 100644 index 0000000000000..764dcd189f8db --- /dev/null +++ b/src/plugins/data/server/search/routes/call_msearch.ts @@ -0,0 +1,100 @@ +/* + * 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 { Observable } from 'rxjs'; +import { first } from 'rxjs/operators'; +import { ApiResponse } from '@elastic/elasticsearch'; +import { SearchResponse } from 'elasticsearch'; +import { IUiSettingsClient, IScopedClusterClient, SharedGlobalConfig } from 'src/core/server'; + +import { MsearchRequestBody, MsearchResponse } from '../../../common/search/search_source'; +import { shimHitsTotal } from './shim_hits_total'; +import { getShardTimeout, getDefaultSearchParams, toSnakeCase } from '..'; + +/** @internal */ +export function convertRequestBody( + requestBody: MsearchRequestBody, + { timeout }: { timeout?: string } +): string { + return requestBody.searches.reduce((req, curr) => { + const header = JSON.stringify({ + ignore_unavailable: true, + ...curr.header, + }); + const body = JSON.stringify({ + timeout, + ...curr.body, + }); + return `${req}${header}\n${body}\n`; + }, ''); +} + +interface CallMsearchDependencies { + esClient: IScopedClusterClient; + globalConfig$: Observable; + uiSettings: IUiSettingsClient; +} + +/** + * Helper for the `/internal/_msearch` route, exported separately here + * so that it can be reused elsewhere in the data plugin on the server, + * e.g. SearchSource + * + * @internal + */ +export function getCallMsearch(dependencies: CallMsearchDependencies) { + return async (params: { + body: MsearchRequestBody; + signal?: AbortSignal; + }): Promise => { + const { esClient, globalConfig$, uiSettings } = dependencies; + + // get shardTimeout + const config = await globalConfig$.pipe(first()).toPromise(); + const timeout = getShardTimeout(config); + + // trackTotalHits is not supported by msearch + const { trackTotalHits, ...defaultParams } = await getDefaultSearchParams(uiSettings); + + const body = convertRequestBody(params.body, timeout); + + // Temporary workaround until https://github.com/elastic/elasticsearch-js/issues/1297 + const promise = esClient.asCurrentUser.msearch( + { + body, + }, + { + querystring: toSnakeCase(defaultParams), + } + ); + if (params.signal) { + params.signal.addEventListener('abort', () => promise.abort()); + } + const response = (await promise) as ApiResponse<{ responses: Array> }>; + + return { + body: { + ...response, + body: { + responses: response.body.responses?.map((r: SearchResponse) => shimHitsTotal(r)), + }, + }, + }; + }; +} diff --git a/src/plugins/data/server/search/routes/index.ts b/src/plugins/data/server/search/routes/index.ts index a290f08f9b843..f858653f26439 100644 --- a/src/plugins/data/server/search/routes/index.ts +++ b/src/plugins/data/server/search/routes/index.ts @@ -17,6 +17,7 @@ * under the License. */ +export * from './call_msearch'; export * from './msearch'; export * from './search'; export * from './shim_hits_total'; diff --git a/src/plugins/data/server/search/routes/msearch.test.ts b/src/plugins/data/server/search/routes/msearch.test.ts index 3a7d67c31b8be..2f414fe0b4920 100644 --- a/src/plugins/data/server/search/routes/msearch.test.ts +++ b/src/plugins/data/server/search/routes/msearch.test.ts @@ -30,7 +30,8 @@ import { httpServerMock, pluginInitializerContextConfigMock, } from '../../../../../../src/core/server/mocks'; -import { registerMsearchRoute, convertRequestBody } from './msearch'; +import { convertRequestBody } from './call_msearch'; +import { registerMsearchRoute } from './msearch'; import { DataPluginStart } from '../../plugin'; import { dataPluginMock } from '../../mocks'; @@ -49,7 +50,7 @@ describe('msearch route', () => { it('handler calls /_msearch with the given request', async () => { const response = { id: 'yay', body: { responses: [{ hits: { total: 5 } }] } }; - const mockClient = { transport: { request: jest.fn().mockResolvedValue(response) } }; + const mockClient = { msearch: jest.fn().mockResolvedValue(response) }; const mockContext = { core: { elasticsearch: { client: { asCurrentUser: mockClient } }, @@ -70,11 +71,16 @@ describe('msearch route', () => { const handler = mockRouter.post.mock.calls[0][1]; await handler((mockContext as unknown) as RequestHandlerContext, mockRequest, mockResponse); - expect(mockClient.transport.request.mock.calls[0][0].method).toBe('GET'); - expect(mockClient.transport.request.mock.calls[0][0].path).toBe('/_msearch'); - expect(mockClient.transport.request.mock.calls[0][0].body).toEqual( + expect(mockClient.msearch.mock.calls[0][0].body).toEqual( convertRequestBody(mockBody as any, {}) ); + expect(mockClient.msearch.mock.calls[0][1].querystring).toMatchInlineSnapshot(` + Object { + "ignore_throttled": true, + "ignore_unavailable": true, + "max_concurrent_shard_requests": undefined, + } + `); expect(mockResponse.ok).toBeCalled(); expect(mockResponse.ok.mock.calls[0][0]).toEqual({ body: response, @@ -89,7 +95,7 @@ describe('msearch route', () => { }, }; const mockClient = { - transport: { request: jest.fn().mockReturnValue(Promise.reject(response)) }, + msearch: jest.fn().mockReturnValue(Promise.reject(response)), }; const mockContext = { core: { @@ -111,40 +117,11 @@ describe('msearch route', () => { const handler = mockRouter.post.mock.calls[0][1]; await handler((mockContext as unknown) as RequestHandlerContext, mockRequest, mockResponse); - expect(mockClient.transport.request).toBeCalled(); + expect(mockClient.msearch).toBeCalled(); expect(mockResponse.customError).toBeCalled(); const error: any = mockResponse.customError.mock.calls[0][0]; expect(error.body.message).toBe('oh no'); expect(error.body.attributes.error).toBe('oops'); }); - - describe('convertRequestBody', () => { - it('combines header & body into proper msearch request', () => { - const request = { - searches: [{ header: { index: 'foo', preference: 0 }, body: { test: true } }], - }; - expect(convertRequestBody(request, { timeout: '30000ms' })).toMatchInlineSnapshot(` - "{\\"ignore_unavailable\\":true,\\"index\\":\\"foo\\",\\"preference\\":0} - {\\"timeout\\":\\"30000ms\\",\\"test\\":true} - " - `); - }); - - it('handles multiple searches', () => { - const request = { - searches: [ - { header: { index: 'foo', preference: 0 }, body: { test: true } }, - { header: { index: 'bar', preference: 1 }, body: { hello: 'world' } }, - ], - }; - expect(convertRequestBody(request, { timeout: '30000ms' })).toMatchInlineSnapshot(` - "{\\"ignore_unavailable\\":true,\\"index\\":\\"foo\\",\\"preference\\":0} - {\\"timeout\\":\\"30000ms\\",\\"test\\":true} - {\\"ignore_unavailable\\":true,\\"index\\":\\"bar\\",\\"preference\\":1} - {\\"timeout\\":\\"30000ms\\",\\"hello\\":\\"world\\"} - " - `); - }); - }); }); diff --git a/src/plugins/data/server/search/routes/msearch.ts b/src/plugins/data/server/search/routes/msearch.ts index e1ddb06e4fb6f..7b44aa18bf8fc 100644 --- a/src/plugins/data/server/search/routes/msearch.ts +++ b/src/plugins/data/server/search/routes/msearch.ts @@ -17,46 +17,12 @@ * under the License. */ -import { first } from 'rxjs/operators'; import { schema } from '@kbn/config-schema'; -import { SearchResponse } from 'elasticsearch'; import { IRouter } from 'src/core/server'; import { SearchRouteDependencies } from '../search_service'; -import { shimHitsTotal } from './shim_hits_total'; -import { getShardTimeout, getDefaultSearchParams, toSnakeCase } from '..'; -interface MsearchHeaders { - index: string; - preference?: number | string; -} - -interface MsearchRequest { - header: MsearchHeaders; - body: any; -} - -interface RequestBody { - searches: MsearchRequest[]; -} - -/** @internal */ -export function convertRequestBody( - requestBody: RequestBody, - { timeout }: { timeout?: string } -): string { - return requestBody.searches.reduce((req, curr) => { - const header = JSON.stringify({ - ignore_unavailable: true, - ...curr.header, - }); - const body = JSON.stringify({ - timeout, - ...curr.body, - }); - return `${req}${header}\n${body}\n`; - }, ''); -} +import { getCallMsearch } from './call_msearch'; /** * The msearch route takes in an array of searches, each consisting of header @@ -93,35 +59,15 @@ export function registerMsearchRoute(router: IRouter, deps: SearchRouteDependenc }, }, async (context, request, res) => { - const client = context.core.elasticsearch.client.asCurrentUser; - - // get shardTimeout - const config = await deps.globalConfig$.pipe(first()).toPromise(); - const timeout = getShardTimeout(config); - - const body = convertRequestBody(request.body, timeout); - - // trackTotalHits is not supported by msearch - const { trackTotalHits, ...defaultParams } = await getDefaultSearchParams( - context.core.uiSettings.client - ); + const callMsearch = getCallMsearch({ + esClient: context.core.elasticsearch.client, + globalConfig$: deps.globalConfig$, + uiSettings: context.core.uiSettings.client, + }); try { - const response = await client.transport.request({ - method: 'GET', - path: '/_msearch', - body, - querystring: toSnakeCase(defaultParams), - }); - - return res.ok({ - body: { - ...response, - body: { - responses: response.body.responses?.map((r: SearchResponse) => shimHitsTotal(r)), - }, - }, - }); + const response = await callMsearch({ body: request.body }); + return res.ok(response); } catch (err) { return res.customError({ statusCode: err.statusCode || 500, diff --git a/src/plugins/data/server/search/search_service.test.ts b/src/plugins/data/server/search/search_service.test.ts index 7057c9c7ca15c..a001d56b36514 100644 --- a/src/plugins/data/server/search/search_service.test.ts +++ b/src/plugins/data/server/search/search_service.test.ts @@ -22,6 +22,7 @@ import { coreMock } from '../../../../core/server/mocks'; import { DataPluginStart } from '../plugin'; import { createFieldFormatsStartMock } from '../field_formats/mocks'; +import { createIndexPatternsStartMock } from '../index_patterns/mocks'; import { SearchService, SearchServiceSetupDependencies } from './search_service'; @@ -54,6 +55,7 @@ describe('Search service', () => { it('exposes proper contract', async () => { const start = plugin.start(mockCoreStart, { fieldFormats: createFieldFormatsStartMock(), + indexPatterns: createIndexPatternsStartMock(), }); expect(start).toHaveProperty('aggs'); expect(start).toHaveProperty('getSearchStrategy'); diff --git a/src/plugins/data/server/search/search_service.ts b/src/plugins/data/server/search/search_service.ts index 90da8c5653ac1..1a9e7d83bc956 100644 --- a/src/plugins/data/server/search/search_service.ts +++ b/src/plugins/data/server/search/search_service.ts @@ -17,10 +17,12 @@ * under the License. */ -import { Observable } from 'rxjs'; +import { BehaviorSubject, Observable } from 'rxjs'; +import { pick } from 'lodash'; import { CoreSetup, CoreStart, + KibanaRequest, Logger, Plugin, PluginInitializerContext, @@ -28,12 +30,14 @@ import { SharedGlobalConfig, StartServicesAccessor, } from 'src/core/server'; +import { first } from 'rxjs/operators'; import { ISearchSetup, ISearchStart, ISearchStrategy, SearchEnhancements } from './types'; import { AggsService, AggsSetupDependencies } from './aggs'; import { FieldFormatsStart } from '../field_formats'; -import { registerMsearchRoute, registerSearchRoute } from './routes'; +import { IndexPatternsServiceStart } from '../index_patterns'; +import { getCallMsearch, registerMsearchRoute, registerSearchRoute } from './routes'; import { ES_SEARCH_STRATEGY, esSearchStrategyProvider } from './es_search'; import { DataPluginStart } from '../plugin'; import { UsageCollectionSetup } from '../../../usage_collection/server'; @@ -46,7 +50,16 @@ import { IEsSearchRequest, IEsSearchResponse, ISearchOptions, -} from '../../common'; + SearchSourceDependencies, + SearchSourceService, + searchSourceRequiredUiSettings, +} from '../../common/search'; +import { + getShardDelayBucketAgg, + SHARD_DELAY_AGG_NAME, +} from '../../common/search/aggs/buckets/shard_delay'; +import { aggShardDelay } from '../../common/search/aggs/buckets/shard_delay_fn'; +import { ConfigSchema } from '../../config'; type StrategyMap = Record>; @@ -59,6 +72,7 @@ export interface SearchServiceSetupDependencies { /** @internal */ export interface SearchServiceStartDependencies { fieldFormats: FieldFormatsStart; + indexPatterns: IndexPatternsServiceStart; } /** @internal */ @@ -69,11 +83,12 @@ export interface SearchRouteDependencies { export class SearchService implements Plugin { private readonly aggsService = new AggsService(); + private readonly searchSourceService = new SearchSourceService(); private defaultSearchStrategyName: string = ES_SEARCH_STRATEGY; private searchStrategies: StrategyMap = {}; constructor( - private initializerContext: PluginInitializerContext, + private initializerContext: PluginInitializerContext, private readonly logger: Logger ) {} @@ -105,20 +120,33 @@ export class SearchService implements Plugin { registerUsageCollector(usageCollection, this.initializerContext); } + const aggs = this.aggsService.setup({ registerFunction }); + + this.initializerContext.config + .create() + .pipe(first()) + .toPromise() + .then((value) => { + if (value.search.aggs.shardDelay.enabled) { + aggs.types.registerBucket(SHARD_DELAY_AGG_NAME, getShardDelayBucketAgg); + registerFunction(aggShardDelay); + } + }); + return { __enhance: (enhancements: SearchEnhancements) => { if (this.searchStrategies.hasOwnProperty(enhancements.defaultStrategy)) { this.defaultSearchStrategyName = enhancements.defaultStrategy; } }, - aggs: this.aggsService.setup({ registerFunction }), + aggs, registerSearchStrategy: this.registerSearchStrategy, usage, }; } public start( - { uiSettings }: CoreStart, - { fieldFormats }: SearchServiceStartDependencies + { elasticsearch, savedObjects, uiSettings }: CoreStart, + { fieldFormats, indexPatterns }: SearchServiceStartDependencies ): ISearchStart { return { aggs: this.aggsService.start({ fieldFormats, uiSettings }), @@ -130,6 +158,58 @@ export class SearchService implements Plugin { ) => { return this.search(context, searchRequest, options); }, + searchSource: { + asScoped: async (request: KibanaRequest) => { + const esClient = elasticsearch.client.asScoped(request); + const savedObjectsClient = savedObjects.getScopedClient(request); + const scopedIndexPatterns = await indexPatterns.indexPatternsServiceFactory(request); + const uiSettingsClient = uiSettings.asScopedToClient(savedObjectsClient); + + // cache ui settings, only including items which are explicitly needed by SearchSource + const uiSettingsCache = pick( + await uiSettingsClient.getAll(), + searchSourceRequiredUiSettings + ); + + const searchSourceDependencies: SearchSourceDependencies = { + getConfig: (key: string): T => uiSettingsCache[key], + search: (searchRequest, options) => { + /** + * Unless we want all SearchSource users to provide both a KibanaRequest + * (needed for index patterns) AND the RequestHandlerContext (needed for + * low-level search), we need to fake the context as it can be derived + * from the request object anyway. This will pose problems for folks who + * are registering custom search strategies as they are only getting a + * subset of the entire context. Ideally low-level search should be + * refactored to only require the needed dependencies: esClient & uiSettings. + */ + const fakeRequestHandlerContext = { + core: { + elasticsearch: { + client: esClient, + }, + uiSettings: { + client: uiSettingsClient, + }, + }, + } as RequestHandlerContext; + return this.search(fakeRequestHandlerContext, searchRequest, options); + }, + // onResponse isn't used on the server, so we just return the original value + onResponse: (req, res) => res, + legacy: { + callMsearch: getCallMsearch({ + esClient, + globalConfig$: this.initializerContext.config.legacy.globalConfig$, + uiSettings: uiSettingsClient, + }), + loadingCount$: new BehaviorSubject(0), + }, + }; + + return this.searchSourceService.start(scopedIndexPatterns, searchSourceDependencies); + }, + }, }; } diff --git a/src/plugins/data/server/search/search_source/mocks.ts b/src/plugins/data/server/search/search_source/mocks.ts new file mode 100644 index 0000000000000..7e9cc8f2ff42c --- /dev/null +++ b/src/plugins/data/server/search/search_source/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. + */ + +import { KibanaRequest } from 'src/core/server'; + +import { searchSourceCommonMock } from '../../../common/search/search_source/mocks'; +import { ISearchStart } from '../types'; + +function createStartContract(): MockedKeys { + return { + asScoped: async (request: jest.Mocked) => { + return searchSourceCommonMock; + }, + }; +} + +export const searchSourceMock = { + createStartContract, +}; diff --git a/src/plugins/data/server/search/types.ts b/src/plugins/data/server/search/types.ts index 4764bd77278ac..0de4ef529e896 100644 --- a/src/plugins/data/server/search/types.ts +++ b/src/plugins/data/server/search/types.ts @@ -17,8 +17,13 @@ * under the License. */ -import { RequestHandlerContext } from '../../../../core/server'; -import { ISearchOptions, IKibanaSearchRequest, IKibanaSearchResponse } from '../../common/search'; +import { KibanaRequest, RequestHandlerContext } from 'src/core/server'; +import { + ISearchOptions, + ISearchStartSearchSource, + IKibanaSearchRequest, + IKibanaSearchResponse, +} from '../../common/search'; import { AggsSetup, AggsStart } from './aggs'; import { SearchUsage } from './collectors'; import { IEsSearchRequest, IEsSearchResponse } from './es_search'; @@ -69,6 +74,9 @@ export interface ISearchStart< request: SearchStrategyRequest, options: ISearchOptions ) => Promise; + searchSource: { + asScoped: (request: KibanaRequest) => Promise; + }; } /** diff --git a/src/plugins/data/server/server.api.md b/src/plugins/data/server/server.api.md index eefc373559afb..fed0c1a02297e 100644 --- a/src/plugins/data/server/server.api.md +++ b/src/plugins/data/server/server.api.md @@ -5,173 +5,52 @@ ```ts import { $Values } from '@kbn/utility-types'; -import { ApiResponse } from '@elastic/elasticsearch/lib/Transport'; +import { ApiResponse } from '@elastic/elasticsearch'; import { Assign } from '@kbn/utility-types'; -import Boom from 'boom'; -import { BulkIndexDocumentsParams } from 'elasticsearch'; -import { CatAliasesParams } from 'elasticsearch'; -import { CatAllocationParams } from 'elasticsearch'; -import { CatCommonParams } from 'elasticsearch'; -import { CatFielddataParams } from 'elasticsearch'; -import { CatHealthParams } from 'elasticsearch'; -import { CatHelpParams } from 'elasticsearch'; -import { CatIndicesParams } from 'elasticsearch'; -import { CatRecoveryParams } from 'elasticsearch'; -import { CatSegmentsParams } from 'elasticsearch'; -import { CatShardsParams } from 'elasticsearch'; -import { CatSnapshotsParams } from 'elasticsearch'; -import { CatTasksParams } from 'elasticsearch'; -import { CatThreadPoolParams } from 'elasticsearch'; -import { ClearScrollParams } from 'elasticsearch'; -import { Client } from 'elasticsearch'; -import { ClusterAllocationExplainParams } from 'elasticsearch'; -import { ClusterGetSettingsParams } from 'elasticsearch'; -import { ClusterHealthParams } from 'elasticsearch'; -import { ClusterPendingTasksParams } from 'elasticsearch'; -import { ClusterPutSettingsParams } from 'elasticsearch'; -import { ClusterRerouteParams } from 'elasticsearch'; -import { ClusterStateParams } from 'elasticsearch'; -import { ClusterStatsParams } from 'elasticsearch'; +import { BehaviorSubject } from 'rxjs'; import { ConfigDeprecationProvider } from '@kbn/config'; import { CoreSetup } from 'src/core/server'; import { CoreSetup as CoreSetup_2 } from 'kibana/server'; import { CoreStart } from 'src/core/server'; import { CoreStart as CoreStart_2 } from 'kibana/server'; -import { CountParams } from 'elasticsearch'; -import { CreateDocumentParams } from 'elasticsearch'; -import { DeleteDocumentByQueryParams } from 'elasticsearch'; -import { DeleteDocumentParams } from 'elasticsearch'; -import { DeleteScriptParams } from 'elasticsearch'; -import { DeleteTemplateParams } from 'elasticsearch'; import { Duration } from 'moment'; -import { ElasticsearchClient as ElasticsearchClient_2 } from 'kibana/server'; +import { ElasticsearchClient } from 'kibana/server'; import { Ensure } from '@kbn/utility-types'; import { EnvironmentMode } from '@kbn/config'; import { ErrorToastOptions } from 'src/core/public/notifications'; -import { ExistsParams } from 'elasticsearch'; -import { ExplainParams } from 'elasticsearch'; import { ExpressionAstFunction } from 'src/plugins/expressions/common'; import { ExpressionsServerSetup } from 'src/plugins/expressions/server'; -import { FieldStatsParams } from 'elasticsearch'; -import { GenericParams } from 'elasticsearch'; -import { GetParams } from 'elasticsearch'; -import { GetResponse } from 'elasticsearch'; -import { GetScriptParams } from 'elasticsearch'; -import { GetSourceParams } from 'elasticsearch'; -import { GetTemplateParams } from 'elasticsearch'; -import { IncomingHttpHeaders } from 'http'; -import { IndexDocumentParams } from 'elasticsearch'; -import { IndicesAnalyzeParams } from 'elasticsearch'; -import { IndicesClearCacheParams } from 'elasticsearch'; -import { IndicesCloseParams } from 'elasticsearch'; -import { IndicesCreateParams } from 'elasticsearch'; -import { IndicesDeleteAliasParams } from 'elasticsearch'; -import { IndicesDeleteParams } from 'elasticsearch'; -import { IndicesDeleteTemplateParams } from 'elasticsearch'; -import { IndicesExistsAliasParams } from 'elasticsearch'; -import { IndicesExistsParams } from 'elasticsearch'; -import { IndicesExistsTemplateParams } from 'elasticsearch'; -import { IndicesExistsTypeParams } from 'elasticsearch'; -import { IndicesFlushParams } from 'elasticsearch'; -import { IndicesFlushSyncedParams } from 'elasticsearch'; -import { IndicesForcemergeParams } from 'elasticsearch'; -import { IndicesGetAliasParams } from 'elasticsearch'; -import { IndicesGetFieldMappingParams } from 'elasticsearch'; -import { IndicesGetMappingParams } from 'elasticsearch'; -import { IndicesGetParams } from 'elasticsearch'; -import { IndicesGetSettingsParams } from 'elasticsearch'; -import { IndicesGetTemplateParams } from 'elasticsearch'; -import { IndicesGetUpgradeParams } from 'elasticsearch'; -import { IndicesOpenParams } from 'elasticsearch'; -import { IndicesPutAliasParams } from 'elasticsearch'; -import { IndicesPutMappingParams } from 'elasticsearch'; -import { IndicesPutSettingsParams } from 'elasticsearch'; -import { IndicesPutTemplateParams } from 'elasticsearch'; -import { IndicesRecoveryParams } from 'elasticsearch'; -import { IndicesRefreshParams } from 'elasticsearch'; -import { IndicesRolloverParams } from 'elasticsearch'; -import { IndicesSegmentsParams } from 'elasticsearch'; -import { IndicesShardStoresParams } from 'elasticsearch'; -import { IndicesShrinkParams } from 'elasticsearch'; -import { IndicesStatsParams } from 'elasticsearch'; -import { IndicesUpdateAliasesParams } from 'elasticsearch'; -import { IndicesUpgradeParams } from 'elasticsearch'; -import { IndicesValidateQueryParams } from 'elasticsearch'; -import { InfoParams } from 'elasticsearch'; -import { IngestDeletePipelineParams } from 'elasticsearch'; -import { IngestGetPipelineParams } from 'elasticsearch'; -import { IngestPutPipelineParams } from 'elasticsearch'; -import { IngestSimulateParams } from 'elasticsearch'; import { ISearchOptions as ISearchOptions_2 } from 'src/plugins/data/public'; import { ISearchSource } from 'src/plugins/data/public'; -import { KibanaClient } from '@elastic/elasticsearch/api/kibana'; -import { KibanaConfigType as KibanaConfigType_2 } from 'src/core/server/kibana_config'; -import { KibanaRequest } from 'kibana/server'; -import { LegacyAPICaller as LegacyAPICaller_2 } from 'kibana/server'; -import { Logger } from '@kbn/logging'; -import { Logger as Logger_2 } from 'kibana/server'; +import { KibanaRequest } from 'src/core/server'; +import { KibanaRequest as KibanaRequest_2 } from 'kibana/server'; +import { LegacyAPICaller } from 'kibana/server'; +import { Logger } from 'kibana/server'; import { LoggerFactory } from '@kbn/logging'; -import { LogMeta } from '@kbn/logging'; -import { MGetParams } from 'elasticsearch'; -import { MGetResponse } from 'elasticsearch'; import { Moment } from 'moment'; import moment from 'moment'; -import { MSearchParams } from 'elasticsearch'; -import { MSearchResponse } from 'elasticsearch'; -import { MSearchTemplateParams } from 'elasticsearch'; -import { MTermVectorsParams } from 'elasticsearch'; -import { NodesHotThreadsParams } from 'elasticsearch'; -import { NodesInfoParams } from 'elasticsearch'; -import { NodesStatsParams } from 'elasticsearch'; +import { NameList } from 'elasticsearch'; import { Observable } from 'rxjs'; import { PackageInfo } from '@kbn/config'; import { PathConfigType } from '@kbn/utils'; -import { PingParams } from 'elasticsearch'; import { Plugin as Plugin_2 } from 'src/core/server'; import { Plugin as Plugin_3 } from 'kibana/server'; import { PluginInitializerContext as PluginInitializerContext_2 } from 'src/core/server'; -import { PutScriptParams } from 'elasticsearch'; -import { PutTemplateParams } from 'elasticsearch'; import { RecursiveReadonly } from '@kbn/utility-types'; -import { ReindexParams } from 'elasticsearch'; -import { ReindexRethrottleParams } from 'elasticsearch'; -import { RenderSearchTemplateParams } from 'elasticsearch'; import { RequestAdapter } from 'src/plugins/inspector/common'; +import { RequestHandlerContext } from 'src/core/server'; import { RequestStatistics } from 'src/plugins/inspector/common'; import { SavedObject } from 'src/core/server'; -import { SavedObjectsClientContract as SavedObjectsClientContract_2 } from 'src/core/server'; -import { ScrollParams } from 'elasticsearch'; +import { SavedObjectsClientContract } from 'src/core/server'; import { Search } from '@elastic/elasticsearch/api/requestParams'; -import { SearchParams } from 'elasticsearch'; import { SearchResponse } from 'elasticsearch'; -import { SearchShardsParams } from 'elasticsearch'; -import { SearchTemplateParams } from 'elasticsearch'; import { SerializedFieldFormat as SerializedFieldFormat_2 } from 'src/plugins/expressions/common'; import { ShardsResponse } from 'elasticsearch'; -import { SnapshotCreateParams } from 'elasticsearch'; -import { SnapshotCreateRepositoryParams } from 'elasticsearch'; -import { SnapshotDeleteParams } from 'elasticsearch'; -import { SnapshotDeleteRepositoryParams } from 'elasticsearch'; -import { SnapshotGetParams } from 'elasticsearch'; -import { SnapshotGetRepositoryParams } from 'elasticsearch'; -import { SnapshotRestoreParams } from 'elasticsearch'; -import { SnapshotStatusParams } from 'elasticsearch'; -import { SnapshotVerifyRepositoryParams } from 'elasticsearch'; -import { SuggestParams } from 'elasticsearch'; -import { TasksCancelParams } from 'elasticsearch'; -import { TasksGetParams } from 'elasticsearch'; -import { TasksListParams } from 'elasticsearch'; -import { TermvectorsParams } from 'elasticsearch'; import { ToastInputFields } from 'src/core/public/notifications'; -import { TransportRequestOptions } from '@elastic/elasticsearch/lib/Transport'; -import { TransportRequestParams } from '@elastic/elasticsearch/lib/Transport'; -import { TransportRequestPromise } from '@elastic/elasticsearch/lib/Transport'; import { Type } from '@kbn/config-schema'; import { TypeOf } from '@kbn/config-schema'; import { Unit } from '@elastic/datemath'; import { UnwrapPromiseOrReturn } from '@kbn/utility-types'; -import { UpdateDocumentByQueryParams } from 'elasticsearch'; -import { UpdateDocumentParams } from 'elasticsearch'; // Warning: (ae-forgotten-export) The symbol "AggConfigSerialized" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "AggConfigOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -623,7 +502,7 @@ export type IMetricAggType = MetricAggType; // @public (undocumented) export class IndexPattern implements IIndexPattern { // Warning: (ae-forgotten-export) The symbol "IndexPatternDeps" needs to be exported by the entry point index.d.ts - constructor({ spec, savedObjectsClient, fieldFormats, shortDotsEnable, metaFields, }: IndexPatternDeps); + constructor({ spec, fieldFormats, shortDotsEnable, metaFields, }: IndexPatternDeps); addScriptedField(name: string, script: string, fieldType?: string): Promise; // (undocumented) fieldFormatMap: Record; @@ -704,8 +583,6 @@ export class IndexPattern implements IIndexPattern { isTimeNanosBased(): boolean; // (undocumented) metaFields: string[]; - // (undocumented) - popularizeField(fieldName: string, unit?: number): Promise; removeScriptedField(fieldName: string): void; resetOriginalSavedObjectBody: () => void; // Warning: (ae-forgotten-export) The symbol "SourceFilter" needs to be exported by the entry point index.d.ts @@ -764,7 +641,7 @@ export const indexPatterns: { // // @public (undocumented) export class IndexPatternsFetcher { - constructor(callDataCluster: LegacyAPICaller_2); + constructor(callDataCluster: LegacyAPICaller); getFieldsForTimePattern(options: { pattern: string; metaFields: string[]; @@ -791,7 +668,7 @@ export class IndexPatternsService implements Plugin_3 Promise; + indexPatternsServiceFactory: (kibanaRequest: KibanaRequest_2) => Promise; }; } @@ -828,10 +705,12 @@ export interface ISearchStart ISearchStrategy; - // Warning: (ae-forgotten-export) The symbol "RequestHandlerContext" needs to be exported by the entry point index.d.ts - // // (undocumented) search: (context: RequestHandlerContext, request: SearchStrategyRequest, options: ISearchOptions) => Promise; + // (undocumented) + searchSource: { + asScoped: (request: KibanaRequest) => Promise; + }; } // Warning: (ae-missing-release-tag) "ISearchStrategy" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -989,13 +868,13 @@ export class Plugin implements Plugin_2>; fieldFormats: { fieldFormatServiceFactory: (uiSettings: import("../../../core/server").IUiSettingsClient) => Promise; }; indexPatterns: { indexPatternsServiceFactory: (kibanaRequest: import("../../../core/server").KibanaRequest) => Promise; }; + search: ISearchStart>; }; // (undocumented) stop(): void; @@ -1251,6 +1130,7 @@ export function usageProvider(core: CoreSetup_2): SearchUsage; // src/plugins/data/server/index.ts:252:1 - (ae-forgotten-export) The symbol "toAbsoluteDates" needs to be exported by the entry point index.d.ts // src/plugins/data/server/index_patterns/index_patterns_service.ts:50:14 - (ae-forgotten-export) The symbol "IndexPatternsService" needs to be exported by the entry point index.d.ts // src/plugins/data/server/plugin.ts:88:66 - (ae-forgotten-export) The symbol "DataEnhancements" needs to be exported by the entry point index.d.ts +// src/plugins/data/server/search/types.ts:78:5 - (ae-forgotten-export) The symbol "ISearchStartSearchSource" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) diff --git a/src/plugins/discover/public/application/angular/context/api/_stubs.js b/src/plugins/discover/public/application/angular/context/api/_stubs.js index 35ddf396c2dba..d82189db60935 100644 --- a/src/plugins/discover/public/application/angular/context/api/_stubs.js +++ b/src/plugins/discover/public/application/angular/context/api/_stubs.js @@ -74,7 +74,7 @@ export function createContextSearchSourceStub(hits, timeField = '@timestamp') { searchSourceStub.fetch = sinon.spy(() => { const timeField = searchSourceStub._stubTimeField; const lastQuery = searchSourceStub.setField.withArgs('query').lastCall.args[1]; - const timeRange = lastQuery.query.constant_score.filter.range[timeField]; + const timeRange = lastQuery.query.bool.must.constant_score.filter.range[timeField]; const lastSort = searchSourceStub.setField.withArgs('sort').lastCall.args[1]; const sortDirection = lastSort[0][timeField]; const sortFunction = diff --git a/src/plugins/discover/public/application/angular/context/api/context.predecessors.test.js b/src/plugins/discover/public/application/angular/context/api/context.predecessors.test.js index 4987c77f4bf25..4c0515906a494 100644 --- a/src/plugins/discover/public/application/angular/context/api/context.predecessors.test.js +++ b/src/plugins/discover/public/application/angular/context/api/context.predecessors.test.js @@ -124,7 +124,9 @@ describe('context app', function () { ).then((hits) => { const intervals = mockSearchSource.setField.args .filter(([property]) => property === 'query') - .map(([, { query }]) => get(query, ['constant_score', 'filter', 'range', '@timestamp'])); + .map(([, { query }]) => + get(query, ['bool', 'must', 'constant_score', 'filter', 'range', '@timestamp']) + ); expect( intervals.every(({ gte, lte }) => (gte && lte ? moment(gte).isBefore(lte) : true)) @@ -160,7 +162,9 @@ describe('context app', function () { ).then((hits) => { const intervals = mockSearchSource.setField.args .filter(([property]) => property === 'query') - .map(([, { query }]) => get(query, ['constant_score', 'filter', 'range', '@timestamp'])); + .map(([, { query }]) => + get(query, ['bool', 'must', 'constant_score', 'filter', 'range', '@timestamp']) + ); // should have started at the given time expect(intervals[0].gte).toEqual(moment(MS_PER_DAY * 1000).toISOString()); diff --git a/src/plugins/discover/public/application/angular/context/api/context.successors.test.js b/src/plugins/discover/public/application/angular/context/api/context.successors.test.js index ebf6e78585962..285d39cd4d8a4 100644 --- a/src/plugins/discover/public/application/angular/context/api/context.successors.test.js +++ b/src/plugins/discover/public/application/angular/context/api/context.successors.test.js @@ -125,7 +125,9 @@ describe('context app', function () { ).then((hits) => { const intervals = mockSearchSource.setField.args .filter(([property]) => property === 'query') - .map(([, { query }]) => get(query, ['constant_score', 'filter', 'range', '@timestamp'])); + .map(([, { query }]) => + get(query, ['bool', 'must', 'constant_score', 'filter', 'range', '@timestamp']) + ); expect( intervals.every(({ gte, lte }) => (gte && lte ? moment(gte).isBefore(lte) : true)) @@ -163,7 +165,9 @@ describe('context app', function () { ).then((hits) => { const intervals = mockSearchSource.setField.args .filter(([property]) => property === 'query') - .map(([, { query }]) => get(query, ['constant_score', 'filter', 'range', '@timestamp'])); + .map(([, { query }]) => + get(query, ['bool', 'must', 'constant_score', 'filter', 'range', '@timestamp']) + ); // should have started at the given time expect(intervals[0].lte).toEqual(moment(MS_PER_DAY * 3000).toISOString()); diff --git a/src/plugins/discover/public/application/angular/context/api/context.ts b/src/plugins/discover/public/application/angular/context/api/context.ts index e244176914a9b..ba8cffd1d7558 100644 --- a/src/plugins/discover/public/application/angular/context/api/context.ts +++ b/src/plugins/discover/public/application/angular/context/api/context.ts @@ -31,6 +31,7 @@ export interface EsHitRecord { fields: Record; sort: number[]; _source: Record; + _id: string; } export type EsHitRecordList = EsHitRecord[]; @@ -100,7 +101,8 @@ function fetchContextProvider(indexPatterns: IndexPatternsContract) { interval, searchAfter, remainingSize, - nanos + nanos, + anchor._id ); documents = diff --git a/src/plugins/discover/public/application/angular/context/api/utils/fetch_hits_in_interval.ts b/src/plugins/discover/public/application/angular/context/api/utils/fetch_hits_in_interval.ts index 9a199ea4a62fc..5ac4164191633 100644 --- a/src/plugins/discover/public/application/angular/context/api/utils/fetch_hits_in_interval.ts +++ b/src/plugins/discover/public/application/angular/context/api/utils/fetch_hits_in_interval.ts @@ -43,7 +43,8 @@ export async function fetchHitsInInterval( interval: IntervalValue[], searchAfter: EsQuerySearchAfter, maxCount: number, - nanosValue: string + nanosValue: string, + anchorId: string ): Promise { const range: RangeQuery = { format: 'strict_date_optional_time', @@ -61,10 +62,19 @@ export async function fetchHitsInInterval( .setField('size', maxCount) .setField('query', { query: { - constant_score: { - filter: { - range: { - [timeField]: range, + bool: { + must: { + constant_score: { + filter: { + range: { + [timeField]: range, + }, + }, + }, + }, + must_not: { + ids: { + values: [anchorId], }, }, }, diff --git a/src/plugins/discover/public/application/angular/context/query_parameters/actions.js b/src/plugins/discover/public/application/angular/context/query_parameters/actions.js index fcd4b8ac02cfb..cdf9283737226 100644 --- a/src/plugins/discover/public/application/angular/context/query_parameters/actions.js +++ b/src/plugins/discover/public/application/angular/context/query_parameters/actions.js @@ -19,6 +19,7 @@ import _ from 'lodash'; import { esFilters } from '../../../../../../data/public'; +import { popularizeField } from '../../../helpers/popularize_field'; import { MAX_CONTEXT_SIZE, MIN_CONTEXT_SIZE, QUERY_PARAMETER_KEYS } from './constants'; @@ -56,7 +57,7 @@ export function getQueryParameterActions(filterManager, indexPatterns) { filterManager.addFilters(newFilters); if (indexPatterns) { const indexPattern = await indexPatterns.get(indexPatternId); - indexPattern.popularizeField(field.name, 1); + await popularizeField(indexPattern, field.name, indexPatterns); } }; diff --git a/src/plugins/discover/public/application/angular/context_app.js b/src/plugins/discover/public/application/angular/context_app.js index f698ed84a8948..145d3afe23224 100644 --- a/src/plugins/discover/public/application/angular/context_app.js +++ b/src/plugins/discover/public/application/angular/context_app.js @@ -56,8 +56,8 @@ getAngularModule().directive('contextApp', function ContextApp() { }); function ContextAppController($scope, Private) { - const { filterManager, indexpatterns, uiSettings } = getServices(); - const queryParameterActions = getQueryParameterActions(filterManager, indexpatterns); + const { filterManager, indexPatterns, uiSettings } = getServices(); + const queryParameterActions = getQueryParameterActions(filterManager, indexPatterns); const queryActions = Private(QueryActionsProvider); this.state = createInitialState( parseInt(uiSettings.get(CONTEXT_STEP_SETTING), 10), diff --git a/src/plugins/discover/public/application/angular/discover.js b/src/plugins/discover/public/application/angular/discover.js index a396033e5dedb..92b96d11723e0 100644 --- a/src/plugins/discover/public/application/angular/discover.js +++ b/src/plugins/discover/public/application/angular/discover.js @@ -70,6 +70,7 @@ const { import { getRootBreadcrumbs, getSavedSearchBreadcrumbs } from '../helpers/breadcrumbs'; import { validateTimeRange } from '../helpers/validate_time_range'; +import { popularizeField } from '../helpers/popularize_field'; import { getIndexPatternId } from '../helpers/get_index_pattern_id'; import { addFatalError } from '../../../../kibana_legacy/public'; @@ -952,7 +953,9 @@ function discoverController($element, $route, $scope, $timeout, $window, Promise // TODO: On array fields, negating does not negate the combination, rather all terms $scope.filterQuery = function (field, values, operation) { - $scope.indexPattern.popularizeField(field, 1); + const { indexPattern } = $scope; + + popularizeField(indexPattern, field.name, indexPatterns); const newFilters = esFilters.generateFilters( filterManager, field, @@ -965,7 +968,8 @@ function discoverController($element, $route, $scope, $timeout, $window, Promise $scope.addColumn = function addColumn(columnName) { if (uiCapabilities.discover.save) { - $scope.indexPattern.popularizeField(columnName, 1); + const { indexPattern } = $scope; + popularizeField(indexPattern, columnName, indexPatterns); } const columns = columnActions.addColumn($scope.state.columns, columnName); setAppState({ columns }); @@ -973,7 +977,8 @@ function discoverController($element, $route, $scope, $timeout, $window, Promise $scope.removeColumn = function removeColumn(columnName) { if (uiCapabilities.discover.save) { - $scope.indexPattern.popularizeField(columnName, 1); + const { indexPattern } = $scope; + popularizeField(indexPattern, columnName, indexPatterns); } const columns = columnActions.removeColumn($scope.state.columns, columnName); // The state's sort property is an array of [sortByColumn,sortDirection] diff --git a/src/plugins/discover/public/application/components/sidebar/discover_field.test.tsx b/src/plugins/discover/public/application/components/sidebar/discover_field.test.tsx index 6211d302e7d20..8ab296bf1af4f 100644 --- a/src/plugins/discover/public/application/components/sidebar/discover_field.test.tsx +++ b/src/plugins/discover/public/application/components/sidebar/discover_field.test.tsx @@ -51,7 +51,17 @@ jest.mock('../../../kibana_services', () => ({ }), })); -function getComponent(selected = false, showDetails = false, useShortDots = false) { +function getComponent({ + selected = false, + showDetails = false, + useShortDots = false, + field, +}: { + selected?: boolean; + showDetails?: boolean; + useShortDots?: boolean; + field?: IndexPatternField; +}) { const indexPattern = getStubIndexPattern( 'logstash-*', (cfg: any) => cfg, @@ -60,23 +70,25 @@ function getComponent(selected = false, showDetails = false, useShortDots = fals coreMock.createSetup() ); - const field = new IndexPatternField( - { - name: 'bytes', - type: 'number', - esTypes: ['long'], - count: 10, - scripted: false, - searchable: true, - aggregatable: true, - readFromDocValues: true, - }, - 'bytes' - ); + const finalField = + field ?? + new IndexPatternField( + { + name: 'bytes', + type: 'number', + esTypes: ['long'], + count: 10, + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + 'bytes' + ); const props = { indexPattern, - field, + field: finalField, getDetails: jest.fn(() => ({ buckets: [], error: '', exists: 1, total: true, columns: [] })), onAddFilter: jest.fn(), onAddField: jest.fn(), @@ -91,18 +103,37 @@ function getComponent(selected = false, showDetails = false, useShortDots = fals describe('discover sidebar field', function () { it('should allow selecting fields', function () { - const { comp, props } = getComponent(); + const { comp, props } = getComponent({}); findTestSubject(comp, 'fieldToggle-bytes').simulate('click'); expect(props.onAddField).toHaveBeenCalledWith('bytes'); }); it('should allow deselecting fields', function () { - const { comp, props } = getComponent(true); + const { comp, props } = getComponent({ selected: true }); findTestSubject(comp, 'fieldToggle-bytes').simulate('click'); expect(props.onRemoveField).toHaveBeenCalledWith('bytes'); }); it('should trigger getDetails', function () { - const { comp, props } = getComponent(true); + const { comp, props } = getComponent({ selected: true }); findTestSubject(comp, 'field-bytes-showDetails').simulate('click'); expect(props.getDetails).toHaveBeenCalledWith(props.field); }); + it('should not allow clicking on _source', function () { + const field = new IndexPatternField( + { + name: '_source', + type: '_source', + esTypes: ['_source'], + searchable: true, + aggregatable: true, + readFromDocValues: true, + }, + '_source' + ); + const { comp, props } = getComponent({ + selected: true, + field, + }); + findTestSubject(comp, 'field-_source-showDetails').simulate('click'); + expect(props.getDetails).not.toHaveBeenCalled(); + }); }); diff --git a/src/plugins/discover/public/application/components/sidebar/discover_field.tsx b/src/plugins/discover/public/application/components/sidebar/discover_field.tsx index bb330cba68e2e..8ff603884239e 100644 --- a/src/plugins/discover/public/application/components/sidebar/discover_field.tsx +++ b/src/plugins/discover/public/application/components/sidebar/discover_field.tsx @@ -172,6 +172,19 @@ export function DiscoverField({ ); } + if (field.type === '_source') { + return ( + + ); + } + return ( { togglePopover(); }} - buttonProps={{ 'data-test-subj': `field-${field.name}-showDetails` }} + dataTestSubj={`field-${field.name}-showDetails`} fieldIcon={dscFieldIcon} fieldAction={actionButton} fieldName={fieldName} diff --git a/src/plugins/discover/public/application/embeddable/search_embeddable.ts b/src/plugins/discover/public/application/embeddable/search_embeddable.ts index 1de62fe5a0348..af88cacfcf992 100644 --- a/src/plugins/discover/public/application/embeddable/search_embeddable.ts +++ b/src/plugins/discover/public/application/embeddable/search_embeddable.ts @@ -221,7 +221,6 @@ export class SearchEmbeddable if (!searchScope.columns) { return; } - indexPattern.popularizeField(columnName, 1); const columns = columnActions.addColumn(searchScope.columns, columnName); this.updateInput({ columns }); }; diff --git a/src/plugins/discover/public/application/helpers/popularize_field.test.ts b/src/plugins/discover/public/application/helpers/popularize_field.test.ts new file mode 100644 index 0000000000000..f1ff67c23b92b --- /dev/null +++ b/src/plugins/discover/public/application/helpers/popularize_field.test.ts @@ -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. + */ + +import { IndexPattern, IndexPatternsService } from '../../../../data/public'; +import { popularizeField } from './popularize_field'; + +describe('Popularize field', () => { + test('returns undefined if index pattern lacks id', async () => { + const indexPattern = ({} as unknown) as IndexPattern; + const fieldName = '@timestamp'; + const indexPatternsService = ({} as unknown) as IndexPatternsService; + const result = await popularizeField(indexPattern, fieldName, indexPatternsService); + expect(result).toBeUndefined(); + }); + + test('returns undefined if field not found', async () => { + const indexPattern = ({ + fields: { + getByName: () => {}, + }, + } as unknown) as IndexPattern; + const fieldName = '@timestamp'; + const indexPatternsService = ({} as unknown) as IndexPatternsService; + const result = await popularizeField(indexPattern, fieldName, indexPatternsService); + expect(result).toBeUndefined(); + }); + + test('returns undefined if successful', async () => { + const field = { + count: 0, + }; + const indexPattern = ({ + id: 'id', + fields: { + getByName: () => field, + }, + } as unknown) as IndexPattern; + const fieldName = '@timestamp'; + const indexPatternsService = ({ + updateSavedObject: async () => {}, + } as unknown) as IndexPatternsService; + const result = await popularizeField(indexPattern, fieldName, indexPatternsService); + expect(result).toBeUndefined(); + expect(field.count).toEqual(1); + }); + + test('hides errors', async () => { + const field = { + count: 0, + }; + const indexPattern = ({ + id: 'id', + fields: { + getByName: () => field, + }, + } as unknown) as IndexPattern; + const fieldName = '@timestamp'; + const indexPatternsService = ({ + updateSavedObject: async () => { + throw new Error('unknown error'); + }, + } as unknown) as IndexPatternsService; + const result = await popularizeField(indexPattern, fieldName, indexPatternsService); + expect(result).toBeUndefined(); + }); +}); diff --git a/src/plugins/discover/public/application/helpers/popularize_field.ts b/src/plugins/discover/public/application/helpers/popularize_field.ts new file mode 100644 index 0000000000000..0aea86e47c954 --- /dev/null +++ b/src/plugins/discover/public/application/helpers/popularize_field.ts @@ -0,0 +1,41 @@ +/* + * 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 { IndexPattern, IndexPatternsService } from '../../../../data/public'; + +async function popularizeField( + indexPattern: IndexPattern, + fieldName: string, + indexPatternsService: IndexPatternsService +) { + if (!indexPattern.id) return; + const field = indexPattern.fields.getByName(fieldName); + if (!field) { + return; + } + + field.count++; + // Catch 409 errors caused by user adding columns in a higher frequency that the changes can be persisted to Elasticsearch + try { + await indexPatternsService.updateSavedObject(indexPattern, 0, true); + // eslint-disable-next-line no-empty + } catch {} +} + +export { popularizeField }; diff --git a/src/plugins/discover/server/saved_objects/search_migrations.test.ts b/src/plugins/discover/server/saved_objects/search_migrations.test.ts index babd25c03dbb2..3324a2d93f5ad 100644 --- a/src/plugins/discover/server/saved_objects/search_migrations.test.ts +++ b/src/plugins/discover/server/saved_objects/search_migrations.test.ts @@ -22,36 +22,61 @@ import { searchMigrations } from './search_migrations'; const savedObjectMigrationContext = (null as unknown) as SavedObjectMigrationContext; +const testMigrateMatchAllQuery = (migrationFn: Function) => { + it('should migrate obsolete match_all query', () => { + const migratedDoc = migrationFn( + { + type: 'search', + attributes: { + kibanaSavedObjectMeta: { + searchSourceJSON: JSON.stringify({ + query: { + match_all: {}, + }, + }), + }, + }, + }, + savedObjectMigrationContext + ); + const migratedSearchSource = JSON.parse( + migratedDoc.attributes.kibanaSavedObjectMeta.searchSourceJSON + ); + + expect(migratedSearchSource).toEqual({ + query: { + query: '', + language: 'kuery', + }, + }); + }); + + it('should return original doc if searchSourceJSON cannot be parsed', () => { + const migratedDoc = migrationFn( + { + type: 'search', + attributes: { + kibanaSavedObjectMeta: 'kibanaSavedObjectMeta', + }, + }, + savedObjectMigrationContext + ); + + expect(migratedDoc).toEqual({ + type: 'search', + attributes: { + kibanaSavedObjectMeta: 'kibanaSavedObjectMeta', + }, + }); + }); +}; + describe('migration search', () => { describe('6.7.2', () => { const migrationFn = searchMigrations['6.7.2']; - it('should migrate obsolete match_all query', () => { - const migratedDoc = migrationFn( - { - type: 'search', - attributes: { - kibanaSavedObjectMeta: { - searchSourceJSON: JSON.stringify({ - query: { - match_all: {}, - }, - }), - }, - }, - }, - savedObjectMigrationContext - ); - const migratedSearchSource = JSON.parse( - migratedDoc.attributes.kibanaSavedObjectMeta.searchSourceJSON - ); - - expect(migratedSearchSource).toEqual({ - query: { - query: '', - language: 'kuery', - }, - }); + describe('migrateMatchAllQuery', () => { + testMigrateMatchAllQuery(migrationFn); }); }); @@ -328,4 +353,12 @@ Object { expect(migratedDoc).toEqual(doc); }); }); + + describe('7.9.3', () => { + const migrationFn = searchMigrations['7.9.3']; + + describe('migrateMatchAllQuery', () => { + testMigrateMatchAllQuery(migrationFn); + }); + }); }); diff --git a/src/plugins/discover/server/saved_objects/search_migrations.ts b/src/plugins/discover/server/saved_objects/search_migrations.ts index 0302159c43c56..fdb086bd17a2d 100644 --- a/src/plugins/discover/server/saved_objects/search_migrations.ts +++ b/src/plugins/discover/server/saved_objects/search_migrations.ts @@ -21,6 +21,12 @@ import { flow, get } from 'lodash'; import { SavedObjectMigrationFn } from 'kibana/server'; import { DEFAULT_QUERY_LANGUAGE } from '../../../data/common'; +/** + * This migration script is related to: + * @link https://github.com/elastic/kibana/pull/62194 + * @link https://github.com/elastic/kibana/pull/14644 + * This is only a problem when you import an object from 5.x into 6.x but to be sure that all saved objects migrated we should execute it twice in 6.7.2 and 7.9.3 + */ const migrateMatchAllQuery: SavedObjectMigrationFn = (doc) => { const searchSourceJSON = get(doc, 'attributes.kibanaSavedObjectMeta.searchSourceJSON'); @@ -31,6 +37,7 @@ const migrateMatchAllQuery: SavedObjectMigrationFn = (doc) => { searchSource = JSON.parse(searchSourceJSON); } catch (e) { // Let it go, the data is invalid and we'll leave it as is + return doc; } if (searchSource.query?.match_all) { @@ -125,4 +132,5 @@ export const searchMigrations = { '6.7.2': flow(migrateMatchAllQuery), '7.0.0': flow(setNewReferences), '7.4.0': flow(migrateSearchSortToNestedArray), + '7.9.3': flow(migrateMatchAllQuery), }; diff --git a/src/plugins/embeddable/.storybook/main.js b/src/plugins/embeddable/.storybook/main.js new file mode 100644 index 0000000000000..1818aa44a9399 --- /dev/null +++ b/src/plugins/embeddable/.storybook/main.js @@ -0,0 +1,7 @@ +/* + * 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. + */ + +module.exports = require('@kbn/storybook').defaultConfig; diff --git a/src/plugins/embeddable/README.asciidoc b/src/plugins/embeddable/README.asciidoc new file mode 100644 index 0000000000000..10ec2b840ffa7 --- /dev/null +++ b/src/plugins/embeddable/README.asciidoc @@ -0,0 +1,44 @@ +[[embeddable-plugin]] +== Embeddables plugin + +Embeddables are re-usable widgets that can be rendered in any environment or plugin. Developers can embed them directly in their plugin. End users can dynamically add them to any embeddable _containers_. + +=== Embeddable containers + +Containers are a special type of embeddable that can contain nested embeddables. Embeddables can be dynamically added to embeddable _containers_. Currently only dashboard uses this interface. + +=== Examples + +Many example embeddables are implemented and registered https://github.com/elastic/kibana/tree/master/examples/embeddable_examples[here]. They can be played around with and explored https://github.com/elastic/kibana/tree/master/examples/embeddable_explorer[in the Embeddable Explorer example plugin]. Just run kibana with + +[source,sh] +-- +yarn start --run-examples +-- + +and navigate to the Embeddable explorer app. + +There is also an example of rendering dashboard container outside of dashboard app https://github.com/elastic/kibana/tree/master/examples/dashboard_embeddable_examples[here]. + +=== Docs + +(./docs/README.md)[Embeddable docs, guides & caveats] + +=== API docs + +==== Server API +https://github.com/elastic/kibana/blob/master/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.embeddablesetup.md[Server Setup contract] +https://github.com/elastic/kibana/blob/master/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.embeddablestart.md[Server Start contract] + +===== Browser API +https://github.com/elastic/kibana/blob/master/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablesetup.md[Browser Setup contract] +https://github.com/elastic/kibana/blob/master/docs/development/plugins/embeddable/public/kibana-plugin-plugins-embeddable-public.embeddablestart.md[Browser Start contract] + +=== Testing + +Run unit tests + +[source,sh] +-- +node scripts/jest embeddable +-- diff --git a/src/plugins/embeddable/README.md b/src/plugins/embeddable/README.md deleted file mode 100644 index 55abe8606159c..0000000000000 --- a/src/plugins/embeddable/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# Embeddables - -Embeddables are re-usable widgets that can be rendered in any environment or plugin. Developers can embed them directly in their plugin. End users can dynamically add them to any embeddable _containers_. - -## Embeddable containers - -Containers are a special type of embeddable that can contain nested embeddables. Embeddables can be dynamically added to embeddable _containers_. Currently only dashboard uses this interface. - -## Examples - -Many example embeddables are implemented and registered [here](https://github.com/elastic/kibana/tree/master/examples/embeddable_examples). They can be played around with and explored [in the Embeddable Explorer example plugin](https://github.com/elastic/kibana/tree/master/examples/embeddable_explorer). Just run kibana with - -``` -yarn start --run-examples -``` - -and navigate to the Embeddable explorer app. - -There is also an example of rendering dashboard container outside of dashboard app [here](https://github.com/elastic/kibana/tree/master/examples/dashboard_embeddable_examples). - -## Docs - -[Embeddable docs, guides & caveats](./docs/README.md) - -## Testing - -Run unit tests - -```shell -node scripts/jest embeddable -``` diff --git a/src/plugins/embeddable/public/components/panel_options_menu/__examples__/panel_options_menu.examples.tsx b/src/plugins/embeddable/public/components/panel_options_menu/__examples__/panel_options_menu.stories.tsx similarity index 100% rename from src/plugins/embeddable/public/components/panel_options_menu/__examples__/panel_options_menu.examples.tsx rename to src/plugins/embeddable/public/components/panel_options_menu/__examples__/panel_options_menu.stories.tsx diff --git a/src/plugins/embeddable/public/lib/embeddables/embeddable_renderer.test.tsx b/src/plugins/embeddable/public/lib/embeddables/embeddable_renderer.test.tsx index 51213288e47a7..f9be9d5bfade7 100644 --- a/src/plugins/embeddable/public/lib/embeddables/embeddable_renderer.test.tsx +++ b/src/plugins/embeddable/public/lib/embeddables/embeddable_renderer.test.tsx @@ -19,7 +19,7 @@ import React from 'react'; import { wait } from '@testing-library/dom'; -import { cleanup, render } from '@testing-library/react/pure'; +import { render } from '@testing-library/react'; import { HelloWorldEmbeddable, HelloWorldEmbeddableFactoryDefinition, @@ -29,8 +29,6 @@ import { EmbeddableRenderer } from './embeddable_renderer'; import { embeddablePluginMock } from '../../mocks'; describe('', () => { - afterEach(cleanup); - test('Render embeddable', () => { const embeddable = new HelloWorldEmbeddable({ id: 'hello' }); const { getByTestId } = render(); diff --git a/src/plugins/embeddable/public/lib/embeddables/error_embeddable.test.tsx b/src/plugins/embeddable/public/lib/embeddables/error_embeddable.test.tsx index 17a2ac3b2a32b..cb14d7ed11dc9 100644 --- a/src/plugins/embeddable/public/lib/embeddables/error_embeddable.test.tsx +++ b/src/plugins/embeddable/public/lib/embeddables/error_embeddable.test.tsx @@ -17,13 +17,10 @@ * under the License. */ import React from 'react'; -import { wait } from '@testing-library/dom'; -import { cleanup, render } from '@testing-library/react/pure'; +import { wait, render } from '@testing-library/react'; import { ErrorEmbeddable } from './error_embeddable'; import { EmbeddableRoot } from './embeddable_root'; -afterEach(cleanup); - test('ErrorEmbeddable renders an embeddable', async () => { const embeddable = new ErrorEmbeddable('some error occurred', { id: '123', title: 'Error' }); const { getByTestId, getByText } = render(); diff --git a/src/plugins/embeddable/public/lib/panel/_embeddable_panel.scss b/src/plugins/embeddable/public/lib/panel/_embeddable_panel.scss index f6057524cb832..cdc0f9f0e0451 100644 --- a/src/plugins/embeddable/public/lib/panel/_embeddable_panel.scss +++ b/src/plugins/embeddable/public/lib/panel/_embeddable_panel.scss @@ -54,12 +54,23 @@ .embPanel__titleInner { overflow: hidden; display: flex; + align-items: center; padding-right: $euiSizeS; } + .embPanel__titleTooltipAnchor { + max-width: 100%; + } + .embPanel__titleText { @include euiTextTruncate; } + + .embPanel__placeholderTitleText { + @include euiTextTruncate; + font-weight: $euiFontWeightRegular; + color: $euiColorMediumShade; + } } .embPanel__dragger:not(.embPanel__title) { @@ -159,4 +170,4 @@ pointer-events: none; filter: grayscale(100%); filter: gray; -} \ No newline at end of file +} diff --git a/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx b/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx index ca5cb5ca4f0d5..a2da31773696c 100644 --- a/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx +++ b/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx @@ -32,7 +32,12 @@ import { EmbeddableContext, contextMenuTrigger, } from '../triggers'; -import { IEmbeddable, EmbeddableOutput, EmbeddableError } from '../embeddables/i_embeddable'; +import { + IEmbeddable, + EmbeddableOutput, + EmbeddableError, + EmbeddableInput, +} from '../embeddables/i_embeddable'; import { ViewMode } from '../types'; import { RemovePanelAction } from './panel_header/panel_actions'; @@ -55,7 +60,7 @@ const removeById = (disabledActions: string[]) => ({ id }: { id: string }) => disabledActions.indexOf(id) === -1; interface Props { - embeddable: IEmbeddable; + embeddable: IEmbeddable; getActions: UiActionsService['getTriggerCompatibleActions']; getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory']; getAllEmbeddableFactories: EmbeddableStart['getEmbeddableFactories']; @@ -72,7 +77,7 @@ interface State { panels: EuiContextMenuPanelDescriptor[]; focusedPanelIndex?: string; viewMode: ViewMode; - hidePanelTitles: boolean; + hidePanelTitle: boolean; closeContextMenu: boolean; badges: Array>; notifications: Array>; @@ -90,17 +95,15 @@ export class EmbeddablePanel extends React.Component { constructor(props: Props) { super(props); const { embeddable } = this.props; - const viewMode = embeddable.getInput().viewMode - ? embeddable.getInput().viewMode - : ViewMode.EDIT; - const hidePanelTitles = embeddable.parent - ? Boolean(embeddable.parent.getInput().hidePanelTitles) - : false; + const viewMode = embeddable.getInput().viewMode ?? ViewMode.EDIT; + const hidePanelTitle = + Boolean(embeddable.parent?.getInput()?.hidePanelTitles) || + Boolean(embeddable.getInput()?.hidePanelTitles); this.state = { panels: [], viewMode, - hidePanelTitles, + hidePanelTitle, closeContextMenu: false, badges: [], notifications: [], @@ -150,9 +153,7 @@ export class EmbeddablePanel extends React.Component { embeddable.getInput$().subscribe(async () => { if (this.mounted) { this.setState({ - viewMode: embeddable.getInput().viewMode - ? embeddable.getInput().viewMode - : ViewMode.EDIT, + viewMode: embeddable.getInput().viewMode ?? ViewMode.EDIT, }); this.refreshBadges(); @@ -165,7 +166,9 @@ export class EmbeddablePanel extends React.Component { this.parentSubscription = parent.getInput$().subscribe(async () => { if (this.mounted && parent) { this.setState({ - hidePanelTitles: Boolean(parent.getInput().hidePanelTitles), + hidePanelTitle: + Boolean(embeddable.parent?.getInput()?.hidePanelTitles) || + Boolean(embeddable.getInput()?.hidePanelTitles), }); this.refreshBadges(); @@ -219,7 +222,7 @@ export class EmbeddablePanel extends React.Component { {!this.props.hideHeader && ( { const createGetUserData = (overlays: OverlayStart) => async function getUserData(context: { embeddable: IEmbeddable }) { - return new Promise<{ title: string | undefined }>((resolve) => { + return new Promise<{ title: string | undefined; hideTitle?: boolean }>((resolve) => { const session = overlays.openModal( toMountPoint( { + updateTitle={(title, hideTitle) => { session.close(); - resolve({ title }); + resolve({ title, hideTitle }); }} + cancel={() => session.close()} /> ), { diff --git a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/customize_title/customize_panel_action.ts b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/customize_title/customize_panel_action.ts index 36957c3b79491..d65539e344a78 100644 --- a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/customize_title/customize_panel_action.ts +++ b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/customize_title/customize_panel_action.ts @@ -24,7 +24,9 @@ import { IEmbeddable } from '../../../../embeddables'; export const ACTION_CUSTOMIZE_PANEL = 'ACTION_CUSTOMIZE_PANEL'; -type GetUserData = (context: ActionContext) => Promise<{ title: string | undefined }>; +type GetUserData = ( + context: ActionContext +) => Promise<{ title: string | undefined; hideTitle?: boolean }>; interface ActionContext { embeddable: IEmbeddable; @@ -52,7 +54,8 @@ export class CustomizePanelTitleAction implements Action { } public async execute({ embeddable }: ActionContext) { - const customTitle = await this.getDataFromUser({ embeddable }); - embeddable.updateInput(customTitle); + const data = await this.getDataFromUser({ embeddable }); + const { title, hideTitle } = data; + embeddable.updateInput({ title, hidePanelTitles: hideTitle }); } } diff --git a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/customize_title/customize_panel_modal.tsx b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/customize_title/customize_panel_modal.tsx index b590f20092939..ad986adb619b8 100644 --- a/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/customize_title/customize_panel_modal.tsx +++ b/src/plugins/embeddable/public/lib/panel/panel_header/panel_actions/customize_title/customize_panel_modal.tsx @@ -36,31 +36,28 @@ import { IEmbeddable } from '../../../../'; interface CustomizePanelProps { embeddable: IEmbeddable; - updateTitle: (newTitle: string | undefined) => void; + updateTitle: (newTitle: string | undefined, hideTitle: boolean | undefined) => void; + cancel: () => void; } interface State { title: string | undefined; - hideTitle: boolean; + hideTitle: boolean | undefined; } export class CustomizePanelModal extends Component { constructor(props: CustomizePanelProps) { super(props); this.state = { - hideTitle: props.embeddable.getOutput().title === '', - title: props.embeddable.getInput().title, + hideTitle: props.embeddable.getInput().hidePanelTitles, + title: props.embeddable.getInput().title ?? this.props.embeddable.getOutput().defaultTitle, }; } - private updateTitle = (title: string | undefined) => { - // An empty string will mean "use the default value", which is represented by setting - // title to undefined (where as an empty string is actually used to indicate "hide title"). - this.setState({ title: title === '' ? undefined : title }); - }; - private reset = () => { - this.setState({ title: undefined }); + this.setState({ + title: this.props.embeddable.getOutput().defaultTitle, + }); }; private onHideTitleToggle = () => { @@ -70,12 +67,11 @@ export class CustomizePanelModal extends Component { }; private save = () => { - if (this.state.hideTitle) { - this.props.updateTitle(''); - } else { - const newTitle = this.state.title === '' ? undefined : this.state.title; - this.props.updateTitle(newTitle); - } + const newTitle = + this.state.title === this.props.embeddable.getOutput().defaultTitle + ? undefined + : this.state.title; + this.props.updateTitle(newTitle, this.state.hideTitle); }; public render() { @@ -116,9 +112,8 @@ export class CustomizePanelModal extends Component { name="min" type="text" disabled={this.state.hideTitle} - placeholder={this.props.embeddable.getOutput().defaultTitle} value={this.state.title || ''} - onChange={(e) => this.updateTitle(e.target.value)} + onChange={(e) => this.setState({ title: e.target.value })} aria-label={i18n.translate( 'embeddableApi.customizePanel.modal.optionsMenuForm.panelTitleInputAriaLabel', { @@ -141,9 +136,7 @@ export class CustomizePanelModal extends Component { - this.props.updateTitle(this.props.embeddable.getOutput().title)} - > + this.props.cancel()}> Promise; closeContextMenu: boolean; badges: Array>; notifications: Array>; embeddable: IEmbeddable; headerId?: string; + showPlaceholderTitle?: boolean; } function renderBadges(badges: Array>, embeddable: IEmbeddable) { @@ -98,22 +99,11 @@ function renderNotifications( }); } -function renderTooltip(description: string) { - return ( - description !== '' && ( - - - - ) - ); -} +type EmbeddableWithDescription = IEmbeddable & { getDescription: () => string }; -const VISUALIZE_EMBEDDABLE_TYPE = 'visualization'; -type VisualizeEmbeddable = any; - -function getViewDescription(embeddable: IEmbeddable | VisualizeEmbeddable) { - if (embeddable.type === VISUALIZE_EMBEDDABLE_TYPE) { - const description = embeddable.getVisualizationDescription(); +function getViewDescription(embeddable: IEmbeddable | EmbeddableWithDescription) { + if ('getDescription' in embeddable) { + const description = embeddable.getDescription(); if (description) { return description; @@ -126,7 +116,7 @@ function getViewDescription(embeddable: IEmbeddable | VisualizeEmbeddable) { export function PanelHeader({ title, isViewMode, - hidePanelTitles, + hidePanelTitle, getActionContextMenuPanel, closeContextMenu, badges, @@ -134,13 +124,32 @@ export function PanelHeader({ embeddable, headerId, }: PanelHeaderProps) { - const viewDescription = getViewDescription(embeddable); - const showTitle = !isViewMode || (title && !hidePanelTitles) || viewDescription !== ''; - const showPanelBar = badges.length > 0 || showTitle; + const description = getViewDescription(embeddable); + const showTitle = !hidePanelTitle && (!isViewMode || title); + const showPanelBar = + !isViewMode || badges.length > 0 || notifications.length > 0 || showTitle || description; const classes = classNames('embPanel__header', { // eslint-disable-next-line @typescript-eslint/naming-convention 'embPanel__header--floater': !showPanelBar, }); + const placeholderTitle = i18n.translate('embeddableApi.panel.placeholderTitle', { + defaultMessage: '[No Title]', + }); + + const getAriaLabel = () => { + return ( + + {showPanelBar && title + ? i18n.translate('embeddableApi.panel.enhancedDashboardPanelAriaLabel', { + defaultMessage: 'Dashboard panel: {title}', + values: { title: title || placeholderTitle }, + }) + : i18n.translate('embeddableApi.panel.dashboardPanelAriaLabel', { + defaultMessage: 'Dashboard panel', + })} + + ); + }; if (!showPanelBar) { return ( @@ -151,44 +160,41 @@ export function PanelHeader({ closeContextMenu={closeContextMenu} title={title} /> + {getAriaLabel()}
); } + const renderTitle = () => { + const titleComponent = showTitle ? ( + + {title || placeholderTitle} + + ) : undefined; + return description ? ( + + + {titleComponent} + + + ) : ( + titleComponent + ); + }; + return (
-

- {showTitle ? ( - - - - - {i18n.translate('embeddableApi.panel.enhancedDashboardPanelAriaLabel', { - defaultMessage: 'Dashboard panel: {title}', - values: { title }, - })} - - - {renderTooltip(viewDescription)} - - ) : ( - - - {i18n.translate('embeddableApi.panel.dashboardPanelAriaLabel', { - defaultMessage: 'Dashboard panel', - })} - - - )} +

+ {getAriaLabel()} + {renderTitle()} {renderBadges(badges, embeddable)}

{renderNotifications(notifications, embeddable)} diff --git a/src/plugins/embeddable/public/public.api.md b/src/plugins/embeddable/public/public.api.md new file mode 100644 index 0000000000000..b01995ccaab08 --- /dev/null +++ b/src/plugins/embeddable/public/public.api.md @@ -0,0 +1,843 @@ +## API Report File for "kibana" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { Action } from 'history'; +import { Action as Action_3 } from 'src/plugins/ui_actions/public'; +import { ActionExecutionContext as ActionExecutionContext_2 } from 'src/plugins/ui_actions/public'; +import { ApiResponse } from '@elastic/elasticsearch/lib/Transport'; +import { ApiResponse as ApiResponse_2 } from '@elastic/elasticsearch'; +import { ApplicationStart as ApplicationStart_2 } from 'kibana/public'; +import { Assign } from '@kbn/utility-types'; +import { BehaviorSubject } from 'rxjs'; +import Boom from 'boom'; +import { CoreSetup as CoreSetup_2 } from 'src/core/public'; +import { CoreSetup as CoreSetup_3 } from 'kibana/public'; +import { CoreStart as CoreStart_2 } from 'kibana/public'; +import * as CSS from 'csstype'; +import { EmbeddableStart as EmbeddableStart_2 } from 'src/plugins/embeddable/public/plugin'; +import { Ensure } from '@kbn/utility-types'; +import { EnvironmentMode } from '@kbn/config'; +import { ErrorToastOptions as ErrorToastOptions_2 } from 'src/core/public/notifications'; +import { EuiBreadcrumb } from '@elastic/eui'; +import { EuiButtonEmptyProps } from '@elastic/eui'; +import { EuiComboBoxProps } from '@elastic/eui'; +import { EuiConfirmModalProps } from '@elastic/eui'; +import { EuiContextMenuPanelDescriptor } from '@elastic/eui'; +import { EuiGlobalToastListToast } from '@elastic/eui'; +import { ExclusiveUnion } from '@elastic/eui'; +import { ExpressionAstFunction } from 'src/plugins/expressions/common'; +import { History } from 'history'; +import { Href } from 'history'; +import { IconType } from '@elastic/eui'; +import { ISearchOptions } from 'src/plugins/data/public'; +import { ISearchSource } from 'src/plugins/data/public'; +import { IStorageWrapper } from 'src/plugins/kibana_utils/public'; +import { IUiSettingsClient as IUiSettingsClient_2 } from 'src/core/public'; +import { KibanaClient } from '@elastic/elasticsearch/api/kibana'; +import { KibanaConfigType } from 'src/core/server/kibana_config'; +import { Location } from 'history'; +import { LocationDescriptorObject } from 'history'; +import { Logger } from '@kbn/logging'; +import { LogMeta } from '@kbn/logging'; +import { MaybePromise } from '@kbn/utility-types'; +import { Moment } from 'moment'; +import { NameList } from 'elasticsearch'; +import { NotificationsStart as NotificationsStart_2 } from 'src/core/public'; +import { Observable } from 'rxjs'; +import { Optional } from '@kbn/utility-types'; +import { OverlayStart as OverlayStart_2 } from 'src/core/public'; +import { PackageInfo } from '@kbn/config'; +import { Path } from 'history'; +import { PluginInitializerContext } from 'src/core/public'; +import * as PropTypes from 'prop-types'; +import { PublicMethodsOf } from '@kbn/utility-types'; +import { PublicUiSettingsParams } from 'src/core/server/types'; +import React from 'react'; +import { RecursiveReadonly } from '@kbn/utility-types'; +import { RequestAdapter } from 'src/plugins/inspector/common'; +import { Required } from '@kbn/utility-types'; +import * as Rx from 'rxjs'; +import { SavedObject as SavedObject_2 } from 'src/core/server'; +import { SavedObjectAttributes } from 'kibana/server'; +import { SavedObjectAttributes as SavedObjectAttributes_2 } from 'src/core/public'; +import { SavedObjectAttributes as SavedObjectAttributes_3 } from 'kibana/public'; +import { SavedObjectsClientContract as SavedObjectsClientContract_3 } from 'src/core/public'; +import { Search } from '@elastic/elasticsearch/api/requestParams'; +import { SearchResponse } from 'elasticsearch'; +import { SerializedFieldFormat as SerializedFieldFormat_2 } from 'src/plugins/expressions/common'; +import { ShallowPromise } from '@kbn/utility-types'; +import { SimpleSavedObject as SimpleSavedObject_2 } from 'src/core/public'; +import { ToastInputFields as ToastInputFields_2 } from 'src/core/public/notifications'; +import { ToastsSetup as ToastsSetup_2 } from 'kibana/public'; +import { TransportRequestOptions } from '@elastic/elasticsearch/lib/Transport'; +import { TransportRequestParams } from '@elastic/elasticsearch/lib/Transport'; +import { TransportRequestPromise } from '@elastic/elasticsearch/lib/Transport'; +import { TypeOf } from '@kbn/config-schema'; +import { UiComponent } from 'src/plugins/kibana_utils/public'; +import { UnregisterCallback } from 'history'; +import { UserProvidedValues } from 'src/core/server/types'; + +// Warning: (ae-missing-release-tag) "ACTION_ADD_PANEL" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const ACTION_ADD_PANEL = "ACTION_ADD_PANEL"; + +// Warning: (ae-missing-release-tag) "ACTION_EDIT_PANEL" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const ACTION_EDIT_PANEL = "editPanel"; + +// Warning: (ae-missing-release-tag) "Adapters" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface Adapters { + // (undocumented) + [key: string]: any; +} + +// Warning: (ae-forgotten-export) The symbol "ActionContext" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "AddPanelAction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class AddPanelAction implements Action_3 { + // Warning: (ae-forgotten-export) The symbol "React" needs to be exported by the entry point index.d.ts + constructor(getFactory: EmbeddableStart_2['getEmbeddableFactory'], getAllFactories: EmbeddableStart_2['getEmbeddableFactories'], overlays: OverlayStart_2, notifications: NotificationsStart_2, SavedObjectFinder: React_2.ComponentType); + // (undocumented) + execute(context: ActionExecutionContext_2): Promise; + // (undocumented) + getDisplayName(): string; + // (undocumented) + getIconType(): string; + // (undocumented) + readonly id = "ACTION_ADD_PANEL"; + // (undocumented) + isCompatible(context: ActionExecutionContext_2): Promise; + // (undocumented) + readonly type = "ACTION_ADD_PANEL"; +} + +// Warning: (ae-missing-release-tag) "ChartActionContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ChartActionContext = ValueClickContext | RangeSelectContext; + +// Warning: (ae-missing-release-tag) "Container" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export abstract class Container = {}, TContainerInput extends ContainerInput = ContainerInput, TContainerOutput extends ContainerOutput = ContainerOutput> extends Embeddable implements IContainer { + constructor(input: TContainerInput, output: TContainerOutput, getFactory: EmbeddableStart['getEmbeddableFactory'], parent?: Container); + // (undocumented) + addNewEmbeddable = IEmbeddable>(type: string, explicitInput: Partial): Promise; + // (undocumented) + protected readonly children: { + [key: string]: IEmbeddable | ErrorEmbeddable; + }; + // (undocumented) + protected createNewPanelState>(factory: EmbeddableFactory, partial?: Partial): PanelState; + // (undocumented) + destroy(): void; + // (undocumented) + getChild(id: string): E; + // (undocumented) + getChildIds(): string[]; + // (undocumented) + protected readonly getFactory: EmbeddableStart['getEmbeddableFactory']; + protected abstract getInheritedInput(id: string): TChildInput; + // (undocumented) + getInputForChild(embeddableId: string): TEmbeddableInput; + // (undocumented) + protected getPanelState(embeddableId: string): PanelState; + // (undocumented) + readonly isContainer: boolean; + // (undocumented) + reload(): void; + // (undocumented) + removeEmbeddable(embeddableId: string): void; + // (undocumented) + untilEmbeddableLoaded(id: string): Promise; + // (undocumented) + updateInputForChild(id: string, changes: Partial): void; +} + +// Warning: (ae-missing-release-tag) "ContainerInput" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ContainerInput extends EmbeddableInput { + // (undocumented) + hidePanelTitles?: boolean; + // (undocumented) + panels: { + [key: string]: PanelState; + }; +} + +// Warning: (ae-missing-release-tag) "ContainerOutput" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ContainerOutput extends EmbeddableOutput { + // (undocumented) + embeddableLoaded: { + [key: string]: boolean; + }; +} + +// Warning: (ae-missing-release-tag) "CONTEXT_MENU_TRIGGER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const CONTEXT_MENU_TRIGGER = "CONTEXT_MENU_TRIGGER"; + +// Warning: (ae-forgotten-export) The symbol "Trigger" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "contextMenuTrigger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const contextMenuTrigger: Trigger<'CONTEXT_MENU_TRIGGER'>; + +// Warning: (ae-missing-release-tag) "defaultEmbeddableFactoryProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const defaultEmbeddableFactoryProvider: = IEmbeddable, T extends SavedObjectAttributes_3 = SavedObjectAttributes_3>(def: EmbeddableFactoryDefinition) => EmbeddableFactory; + +// Warning: (ae-forgotten-export) The symbol "ActionContext" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "EditPanelAction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class EditPanelAction implements Action_3 { + constructor(getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'], application: ApplicationStart_2, stateTransfer?: EmbeddableStateTransfer | undefined); + // (undocumented) + currentAppId: string | undefined; + // (undocumented) + execute(context: ActionContext_3): Promise; + // Warning: (ae-forgotten-export) The symbol "NavigationContext" needs to be exported by the entry point index.d.ts + // + // (undocumented) + getAppTarget({ embeddable }: ActionContext_3): NavigationContext | undefined; + // (undocumented) + getDisplayName({ embeddable }: ActionContext_3): string; + // (undocumented) + getHref({ embeddable }: ActionContext_3): Promise; + // (undocumented) + getIconType(): string; + // (undocumented) + readonly id = "editPanel"; + // (undocumented) + isCompatible({ embeddable }: ActionContext_3): Promise; + // (undocumented) + order: number; + // (undocumented) + readonly type = "editPanel"; +} + +// Warning: (ae-missing-release-tag) "Embeddable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export abstract class Embeddable implements IEmbeddable { + constructor(input: TEmbeddableInput, output: TEmbeddableOutput, parent?: IContainer); + destroy(): void; + // (undocumented) + getInput$(): Readonly>; + // (undocumented) + getInput(): Readonly; + getInspectorAdapters(): Adapters | undefined; + // (undocumented) + getIsContainer(): this is IContainer; + // (undocumented) + getOutput$(): Readonly>; + // (undocumented) + getOutput(): Readonly; + getRoot(): IEmbeddable | IContainer; + // (undocumented) + getTitle(): string; + // (undocumented) + readonly id: string; + // (undocumented) + protected input: TEmbeddableInput; + // (undocumented) + readonly isContainer: boolean; + // (undocumented) + protected output: TEmbeddableOutput; + // (undocumented) + readonly parent?: IContainer; + abstract reload(): void; + // (undocumented) + render(el: HTMLElement): void; + // Warning: (ae-forgotten-export) The symbol "RenderCompleteDispatcher" needs to be exported by the entry point index.d.ts + // + // (undocumented) + protected renderComplete: RenderCompleteDispatcher; + // (undocumented) + static runtimeId: number; + // (undocumented) + readonly runtimeId: number; + // Warning: (ae-forgotten-export) The symbol "TriggerContextMapping" needs to be exported by the entry point index.d.ts + // + // (undocumented) + supportedTriggers(): Array; + // (undocumented) + abstract readonly type: string; + // (undocumented) + updateInput(changes: Partial): void; + // (undocumented) + protected updateOutput(outputChanges: Partial): void; +} + +// Warning: (ae-forgotten-export) The symbol "State" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "EmbeddableChildPanel" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export class EmbeddableChildPanel extends React.Component { + constructor(props: EmbeddableChildPanelProps); + // (undocumented) + [panel: string]: any; + // (undocumented) + componentDidMount(): Promise; + // (undocumented) + componentWillUnmount(): void; + // (undocumented) + embeddable: IEmbeddable | ErrorEmbeddable; + // (undocumented) + mounted: boolean; + // (undocumented) + render(): JSX.Element; + } + +// Warning: (ae-missing-release-tag) "EmbeddableChildPanelProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface EmbeddableChildPanelProps { + // (undocumented) + className?: string; + // (undocumented) + container: IContainer; + // (undocumented) + embeddableId: string; + // (undocumented) + PanelComponent: EmbeddableStart['EmbeddablePanel']; +} + +// Warning: (ae-missing-release-tag) "EmbeddableContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface EmbeddableContext { + // (undocumented) + embeddable: IEmbeddable; +} + +// @public +export interface EmbeddableEditorState { + // (undocumented) + embeddableId?: string; + // (undocumented) + originatingApp: string; + // (undocumented) + valueInput?: EmbeddableInput; +} + +// Warning: (ae-forgotten-export) The symbol "PersistableState" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "EmbeddableFactory" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface EmbeddableFactory = IEmbeddable, TSavedObjectAttributes extends SavedObjectAttributes_2 = SavedObjectAttributes_2> extends PersistableState { + canCreateNew(): boolean; + create(initialInput: TEmbeddableInput, parent?: IContainer): Promise; + createFromSavedObject(savedObjectId: string, input: Partial, parent?: IContainer): Promise; + getDefaultInput(partial: Partial): Partial; + getDisplayName(): string; + getExplicitInput(): Promise>; + readonly isContainerType: boolean; + readonly isEditable: () => Promise; + // Warning: (ae-forgotten-export) The symbol "SavedObjectMetaData" needs to be exported by the entry point index.d.ts + // + // (undocumented) + readonly savedObjectMetaData?: SavedObjectMetaData; + // (undocumented) + readonly type: string; +} + +// Warning: (ae-missing-release-tag) "EmbeddableFactoryDefinition" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type EmbeddableFactoryDefinition = IEmbeddable, T extends SavedObjectAttributes = SavedObjectAttributes> = Pick, 'create' | 'type' | 'isEditable' | 'getDisplayName'> & Partial, 'createFromSavedObject' | 'isContainerType' | 'getExplicitInput' | 'savedObjectMetaData' | 'canCreateNew' | 'getDefaultInput' | 'telemetry' | 'extract' | 'inject'>>; + +// Warning: (ae-missing-release-tag) "EmbeddableFactoryNotFoundError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class EmbeddableFactoryNotFoundError extends Error { + constructor(type: string); + // (undocumented) + code: string; +} + +// Warning: (ae-missing-release-tag) "EmbeddableInput" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type EmbeddableInput = { + viewMode?: ViewMode; + title?: string; + id: string; + lastReloadRequestTime?: number; + hidePanelTitles?: boolean; + enhancements?: SerializableState; + disabledActions?: string[]; + disableTriggers?: boolean; + timeRange?: TimeRange; + query?: Query; + filters?: Filter[]; +}; + +// Warning: (ae-missing-release-tag) "EmbeddableInstanceConfiguration" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface EmbeddableInstanceConfiguration { + // (undocumented) + id: string; + // (undocumented) + savedObjectId?: string; +} + +// Warning: (ae-missing-release-tag) "EmbeddableOutput" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface EmbeddableOutput { + // (undocumented) + defaultTitle?: string; + // (undocumented) + editable?: boolean; + // (undocumented) + editApp?: string; + // (undocumented) + editPath?: string; + // (undocumented) + editUrl?: string; + // Warning: (ae-forgotten-export) The symbol "EmbeddableError" needs to be exported by the entry point index.d.ts + // + // (undocumented) + error?: EmbeddableError; + // (undocumented) + loading?: boolean; + // (undocumented) + savedObjectId?: string; + // (undocumented) + title?: string; +} + +// @public +export interface EmbeddablePackageState { + // (undocumented) + embeddableId?: string; + // (undocumented) + input: Optional | Optional; + // (undocumented) + type: string; +} + +// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "State" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "EmbeddablePanel" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class EmbeddablePanel extends React.Component { + constructor(props: Props); + // (undocumented) + closeMyContextMenuPanel: () => void; + // (undocumented) + componentDidMount(): void; + // (undocumented) + componentWillUnmount(): void; + // (undocumented) + onBlur: (blurredPanelIndex: string) => void; + // (undocumented) + onFocus: (focusedPanelIndex: string) => void; + // (undocumented) + render(): JSX.Element; + // (undocumented) + UNSAFE_componentWillMount(): void; +} + +// Warning: (ae-missing-release-tag) "EmbeddablePanelHOC" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type EmbeddablePanelHOC = React.FC<{ + embeddable: IEmbeddable; + hideHeader?: boolean; +}>; + +// @public +export const EmbeddableRenderer: (props: EmbeddableRendererProps) => JSX.Element; + +// Warning: (ae-forgotten-export) The symbol "EmbeddableRendererPropsWithEmbeddable" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "EmbeddableRendererWithFactory" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "EmbeddableRendererProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type EmbeddableRendererProps = EmbeddableRendererPropsWithEmbeddable | EmbeddableRendererWithFactory; + +// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "EmbeddableRoot" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class EmbeddableRoot extends React.Component { + constructor(props: Props_2); + // (undocumented) + componentDidMount(): void; + // (undocumented) + componentDidUpdate(prevProps?: Props_2): void; + // (undocumented) + render(): JSX.Element; + // (undocumented) + shouldComponentUpdate(newProps: Props_2): boolean; +} + +// Warning: (ae-missing-release-tag) "EmbeddableSetup" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface EmbeddableSetup { + // (undocumented) + registerEmbeddableFactory: = IEmbeddable>(id: string, factory: EmbeddableFactoryDefinition) => () => EmbeddableFactory; + // (undocumented) + registerEnhancement: (enhancement: EnhancementRegistryDefinition) => void; + // Warning: (ae-forgotten-export) The symbol "EmbeddableFactoryProvider" needs to be exported by the entry point index.d.ts + // + // (undocumented) + setCustomEmbeddableFactoryProvider: (customProvider: EmbeddableFactoryProvider) => void; +} + +// Warning: (ae-missing-release-tag) "EmbeddableSetupDependencies" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface EmbeddableSetupDependencies { + // Warning: (ae-forgotten-export) The symbol "DataPublicPluginSetup" needs to be exported by the entry point index.d.ts + // + // (undocumented) + data: DataPublicPluginSetup; + // Warning: (ae-forgotten-export) The symbol "UiActionsSetup" needs to be exported by the entry point index.d.ts + // + // (undocumented) + uiActions: UiActionsSetup; +} + +// Warning: (ae-missing-release-tag) "EmbeddableStart" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface EmbeddableStart extends PersistableState { + // (undocumented) + EmbeddablePanel: EmbeddablePanelHOC; + // (undocumented) + getEmbeddableFactories: () => IterableIterator; + // (undocumented) + getEmbeddableFactory: = IEmbeddable>(embeddableFactoryId: string) => EmbeddableFactory | undefined; + // (undocumented) + getEmbeddablePanel: (stateTransfer?: EmbeddableStateTransfer) => EmbeddablePanelHOC; + // Warning: (ae-forgotten-export) The symbol "ScopedHistory" needs to be exported by the entry point index.d.ts + // + // (undocumented) + getStateTransfer: (history?: ScopedHistory) => EmbeddableStateTransfer; +} + +// Warning: (ae-missing-release-tag) "EmbeddableStartDependencies" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface EmbeddableStartDependencies { + // Warning: (ae-forgotten-export) The symbol "DataPublicPluginStart" needs to be exported by the entry point index.d.ts + // + // (undocumented) + data: DataPublicPluginStart; + // Warning: (ae-forgotten-export) The symbol "Start" needs to be exported by the entry point index.d.ts + // + // (undocumented) + inspector: Start; + // Warning: (ae-forgotten-export) The symbol "UiActionsStart" needs to be exported by the entry point index.d.ts + // + // (undocumented) + uiActions: UiActionsStart; +} + +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "ScopedHistory" +// +// @public +export class EmbeddableStateTransfer { + // Warning: (ae-forgotten-export) The symbol "ApplicationStart" needs to be exported by the entry point index.d.ts + // Warning: (ae-forgotten-export) The symbol "PublicAppInfo" needs to be exported by the entry point index.d.ts + constructor(navigateToApp: ApplicationStart['navigateToApp'], scopedHistory?: ScopedHistory | undefined, appList?: ReadonlyMap | undefined); + getAppNameFromId: (appId: string) => string | undefined; + getIncomingEditorState(options?: { + keysToRemoveAfterFetch?: string[]; + }): EmbeddableEditorState | undefined; + getIncomingEmbeddablePackage(options?: { + keysToRemoveAfterFetch?: string[]; + }): EmbeddablePackageState | undefined; + // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "ApplicationStart" + navigateToEditor(appId: string, options?: { + path?: string; + state: EmbeddableEditorState; + appendToExistingState?: boolean; + }): Promise; + // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "ApplicationStart" + navigateToWithEmbeddablePackage(appId: string, options?: { + path?: string; + state: EmbeddablePackageState; + appendToExistingState?: boolean; + }): Promise; + } + +// Warning: (ae-forgotten-export) The symbol "PersistableStateDefinition" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "EnhancementRegistryDefinition" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface EnhancementRegistryDefinition

extends PersistableStateDefinition

{ + // (undocumented) + id: string; +} + +// Warning: (ae-missing-release-tag) "ErrorEmbeddable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class ErrorEmbeddable extends Embeddable { + constructor(error: Error | string, input: EmbeddableInput, parent?: IContainer); + // (undocumented) + destroy(): void; + // (undocumented) + error: Error | string; + // (undocumented) + reload(): void; + // (undocumented) + render(dom: HTMLElement): void; + // (undocumented) + readonly type = "error"; +} + +// Warning: (ae-missing-release-tag) "IContainer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface IContainer = ContainerInput, O extends ContainerOutput = ContainerOutput> extends IEmbeddable { + addNewEmbeddable = Embeddable>(type: string, explicitInput: Partial): Promise; + getChild = Embeddable>(id: string): E; + getInputForChild(id: string): EEI; + removeEmbeddable(embeddableId: string): void; + untilEmbeddableLoaded(id: string): Promise; + updateInputForChild(id: string, changes: Partial): void; +} + +// Warning: (ae-missing-release-tag) "IEmbeddable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface IEmbeddable { + destroy(): void; + enhancements?: object; + getInput$(): Readonly>; + getInput(): Readonly; + getInspectorAdapters(): Adapters | undefined; + getIsContainer(): this is IContainer; + getOutput$(): Readonly>; + getOutput(): Readonly; + getRoot(): IEmbeddable | IContainer; + getTitle(): string | undefined; + readonly id: string; + readonly isContainer: boolean; + readonly parent?: IContainer; + reload(): void; + render(domNode: HTMLElement | Element): void; + readonly runtimeId?: number; + supportedTriggers(): Array; + readonly type: string; + updateInput(changes: Partial): void; +} + +// Warning: (ae-missing-release-tag) "isErrorEmbeddable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function isErrorEmbeddable(embeddable: TEmbeddable | ErrorEmbeddable): embeddable is ErrorEmbeddable; + +// Warning: (ae-missing-release-tag) "isRangeSelectTriggerContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const isRangeSelectTriggerContext: (context: ChartActionContext) => context is RangeSelectContext>; + +// Warning: (ae-missing-release-tag) "isReferenceOrValueEmbeddable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function isReferenceOrValueEmbeddable(incoming: unknown): incoming is ReferenceOrValueEmbeddable; + +// Warning: (ae-missing-release-tag) "isSavedObjectEmbeddableInput" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function isSavedObjectEmbeddableInput(input: EmbeddableInput | SavedObjectEmbeddableInput): input is SavedObjectEmbeddableInput; + +// Warning: (ae-missing-release-tag) "isValueClickTriggerContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const isValueClickTriggerContext: (context: ChartActionContext) => context is ValueClickContext>; + +// Warning: (ae-missing-release-tag) "openAddPanelFlyout" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function openAddPanelFlyout(options: { + embeddable: IContainer; + getFactory: EmbeddableStart['getEmbeddableFactory']; + getAllFactories: EmbeddableStart['getEmbeddableFactories']; + overlays: OverlayStart_2; + notifications: NotificationsStart_2; + SavedObjectFinder: React.ComponentType; +}): Promise; + +// Warning: (ae-missing-release-tag) "OutputSpec" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface OutputSpec { + // (undocumented) + [key: string]: PropertySpec; +} + +// Warning: (ae-missing-release-tag) "PANEL_BADGE_TRIGGER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const PANEL_BADGE_TRIGGER = "PANEL_BADGE_TRIGGER"; + +// Warning: (ae-missing-release-tag) "PANEL_NOTIFICATION_TRIGGER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const PANEL_NOTIFICATION_TRIGGER = "PANEL_NOTIFICATION_TRIGGER"; + +// Warning: (ae-missing-release-tag) "panelBadgeTrigger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const panelBadgeTrigger: Trigger<'PANEL_BADGE_TRIGGER'>; + +// Warning: (ae-missing-release-tag) "PanelNotFoundError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class PanelNotFoundError extends Error { + constructor(); + // (undocumented) + code: string; +} + +// Warning: (ae-missing-release-tag) "panelNotificationTrigger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const panelNotificationTrigger: Trigger<'PANEL_NOTIFICATION_TRIGGER'>; + +// Warning: (ae-missing-release-tag) "PanelState" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface PanelState { + // (undocumented) + explicitInput: Partial & { + id: string; + }; + // (undocumented) + type: string; +} + +// Warning: (ae-forgotten-export) The symbol "EmbeddablePublicPlugin" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "plugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function plugin(initializerContext: PluginInitializerContext): EmbeddablePublicPlugin; + +// Warning: (ae-missing-release-tag) "PropertySpec" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface PropertySpec { + // (undocumented) + accessPath: string; + // (undocumented) + description: string; + // (undocumented) + displayName: string; + // (undocumented) + id: string; + // (undocumented) + value?: string; +} + +// Warning: (ae-missing-release-tag) "RangeSelectContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface RangeSelectContext { + // (undocumented) + data: { + table: KibanaDatatable; + column: number; + range: number[]; + timeFieldName?: string; + }; + // (undocumented) + embeddable?: T; +} + +// @public +export interface ReferenceOrValueEmbeddable { + getInputAsRefType: () => Promise; + getInputAsValueType: () => Promise; + inputIsRefType: (input: ValTypeInput | RefTypeInput) => input is RefTypeInput; +} + +// Warning: (ae-missing-release-tag) "SavedObjectEmbeddableInput" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface SavedObjectEmbeddableInput extends EmbeddableInput { + // (undocumented) + savedObjectId: string; +} + +// Warning: (ae-missing-release-tag) "ValueClickContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ValueClickContext { + // (undocumented) + data: { + data: Array<{ + table: Pick; + column: number; + row: number; + value: any; + }>; + timeFieldName?: string; + negate?: boolean; + }; + // (undocumented) + embeddable?: T; +} + +// Warning: (ae-missing-release-tag) "ViewMode" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export enum ViewMode { + // (undocumented) + EDIT = "edit", + // (undocumented) + VIEW = "view" +} + +// Warning: (ae-missing-release-tag) "withEmbeddableSubscription" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const withEmbeddableSubscription: = IEmbeddable, ExtraProps = {}>(WrappedComponent: React.ComponentType<{ + input: I; + output: O; + embeddable: E; +} & ExtraProps>) => React.ComponentType<{ + embeddable: E; +} & ExtraProps>; + + +// Warnings were encountered during analysis: +// +// src/plugins/embeddable/common/types.ts:44:3 - (ae-forgotten-export) The symbol "SerializableState" needs to be exported by the entry point index.d.ts +// src/plugins/embeddable/common/types.ts:59:3 - (ae-forgotten-export) The symbol "TimeRange" needs to be exported by the entry point index.d.ts +// src/plugins/embeddable/common/types.ts:64:3 - (ae-forgotten-export) The symbol "Query" needs to be exported by the entry point index.d.ts +// src/plugins/embeddable/common/types.ts:69:3 - (ae-forgotten-export) The symbol "Filter" needs to be exported by the entry point index.d.ts +// src/plugins/embeddable/public/lib/triggers/triggers.ts:45:5 - (ae-forgotten-export) The symbol "KibanaDatatable" needs to be exported by the entry point index.d.ts + +// (No @packageDocumentation comment for this package) + +``` diff --git a/src/plugins/embeddable/public/tests/customize_panel_modal.test.tsx b/src/plugins/embeddable/public/tests/customize_panel_modal.test.tsx index d12a55dd827e6..24d94020af4dc 100644 --- a/src/plugins/embeddable/public/tests/customize_panel_modal.test.tsx +++ b/src/plugins/embeddable/public/tests/customize_panel_modal.test.tsx @@ -33,9 +33,9 @@ import { HelloWorldContainer } from '../lib/test_samples/embeddables/hello_world import { coreMock } from '../../../../core/public/mocks'; import { testPlugin } from './test_plugin'; import { CustomizePanelModal } from '../lib/panel/panel_header/panel_actions/customize_title/customize_panel_modal'; -import { mount } from 'enzyme'; import { EmbeddableStart } from '../plugin'; import { createEmbeddablePanelMock } from '../mocks'; +import { mountWithIntl } from '../../../../test_utils/public/enzyme_helpers'; let api: EmbeddableStart; let container: Container; @@ -84,19 +84,20 @@ beforeEach(async () => { } }); -test('Is initialized with the embeddables title', async () => { - const component = mount( {}} />); +test('Value is initialized with the embeddables title', async () => { + const component = mountWithIntl( + {}} cancel={() => {}} /> + ); const inputField = findTestSubject(component, 'customEmbeddablePanelTitleInput').find('input'); - expect(inputField.props().placeholder).toBe(embeddable.getOutput().title); - expect(inputField.props().placeholder).toBe(embeddable.getOutput().defaultTitle); - expect(inputField.props().value).toBe(''); + expect(inputField.props().value).toBe(embeddable.getOutput().title); + expect(inputField.props().value).toBe(embeddable.getOutput().defaultTitle); }); test('Calls updateTitle with a new title', async () => { const updateTitle = jest.fn(); - const component = mount( - + const component = mountWithIntl( + {}} /> ); const inputField = findTestSubject(component, 'customEmbeddablePanelTitleInput').find('input'); @@ -105,15 +106,15 @@ test('Calls updateTitle with a new title', async () => { findTestSubject(component, 'saveNewTitleButton').simulate('click'); - expect(updateTitle).toBeCalledWith('new title'); + expect(updateTitle).toBeCalledWith('new title', undefined); }); test('Input value shows custom title if one given', async () => { embeddable.updateInput({ title: 'new title' }); const updateTitle = jest.fn(); - const component = mount( - + const component = mountWithIntl( + {}} /> ); const inputField = findTestSubject(component, 'customEmbeddablePanelTitleInput').find('input'); @@ -122,12 +123,12 @@ test('Input value shows custom title if one given', async () => { expect(inputField.props().value).toBe('new title'); }); -test('Reset updates the input with the default title when the embeddable has no title override', async () => { +test('Reset updates the input value with the default title when the embeddable has a title override', async () => { const updateTitle = jest.fn(); embeddable.updateInput({ title: 'my custom title' }); - const component = mount( - + const component = mountWithIntl( + {}} /> ); const inputField = findTestSubject(component, 'customEmbeddablePanelTitleInput').find('input'); @@ -135,13 +136,14 @@ test('Reset updates the input with the default title when the embeddable has no inputField.simulate('change', event); findTestSubject(component, 'resetCustomEmbeddablePanelTitle').simulate('click'); - expect(inputField.props().placeholder).toBe(embeddable.getOutput().defaultTitle); + const inputAfter = findTestSubject(component, 'customEmbeddablePanelTitleInput').find('input'); + expect(inputAfter.props().value).toBe(embeddable.getOutput().defaultTitle); }); -test('Reset updates the input with the default title when the embeddable has a title override', async () => { +test('Reset updates the input with the default title when the embeddable has no title override', async () => { const updateTitle = jest.fn(); - const component = mount( - + const component = mountWithIntl( + {}} /> ); const inputField = findTestSubject(component, 'customEmbeddablePanelTitleInput').find('input'); @@ -149,13 +151,14 @@ test('Reset updates the input with the default title when the embeddable has a t inputField.simulate('change', event); findTestSubject(component, 'resetCustomEmbeddablePanelTitle').simulate('click'); - expect(inputField.props().placeholder).toBe(embeddable.getOutput().defaultTitle); + await component.update(); + expect(inputField.props().value).toBe(embeddable.getOutput().defaultTitle); }); test('Reset calls updateTitle with undefined', async () => { const updateTitle = jest.fn(); - const component = mount( - + const component = mountWithIntl( + {}} /> ); const inputField = findTestSubject(component, 'customEmbeddablePanelTitleInput').find('input'); @@ -165,19 +168,21 @@ test('Reset calls updateTitle with undefined', async () => { findTestSubject(component, 'resetCustomEmbeddablePanelTitle').simulate('click'); findTestSubject(component, 'saveNewTitleButton').simulate('click'); - expect(updateTitle).toBeCalledWith(undefined); + expect(updateTitle).toBeCalledWith(undefined, undefined); }); test('Can set title to an empty string', async () => { const updateTitle = jest.fn(); - const component = mount( - + const component = mountWithIntl( + {}} /> ); - const inputField = findTestSubject(component, 'customizePanelHideTitle'); - inputField.simulate('click'); + const inputField = findTestSubject(component, 'customEmbeddablePanelTitleInput'); + const event = { target: { value: '' } }; + inputField.simulate('change', event); findTestSubject(component, 'saveNewTitleButton').simulate('click'); - expect(inputField.props().value).toBeUndefined(); - expect(updateTitle).toBeCalledWith(''); + const inputFieldAfter = findTestSubject(component, 'customEmbeddablePanelTitleInput'); + expect(inputFieldAfter.props().value).toBe(''); + expect(updateTitle).toBeCalledWith('', undefined); }); diff --git a/src/plugins/embeddable/scripts/storybook.js b/src/plugins/embeddable/scripts/storybook.js deleted file mode 100644 index 0d7712fe973f4..0000000000000 --- a/src/plugins/embeddable/scripts/storybook.js +++ /dev/null @@ -1,26 +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 { join } from 'path'; - -// eslint-disable-next-line -require('@kbn/storybook').runStorybookCli({ - name: 'embeddable', - storyGlobs: [join(__dirname, '..', 'public', 'components', '**', '*.examples.tsx')], -}); diff --git a/src/plugins/embeddable/server/server.api.md b/src/plugins/embeddable/server/server.api.md new file mode 100644 index 0000000000000..c4fad2917343b --- /dev/null +++ b/src/plugins/embeddable/server/server.api.md @@ -0,0 +1,50 @@ +## API Report File for "kibana" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { CoreSetup } from 'kibana/server'; +import { CoreStart } from 'kibana/server'; +import { Plugin } from 'kibana/server'; +import { SavedObjectReference as SavedObjectReference_2 } from 'kibana/server'; + +// Warning: (ae-forgotten-export) The symbol "EmbeddableInput" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "PersistableStateDefinition" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "EmbeddableRegistryDefinition" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface EmbeddableRegistryDefinition

extends PersistableStateDefinition

{ + // (undocumented) + id: string; +} + +// Warning: (ae-missing-release-tag) "EmbeddableSetup" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface EmbeddableSetup { + // (undocumented) + registerEmbeddableFactory: (factory: EmbeddableRegistryDefinition) => void; + // (undocumented) + registerEnhancement: (enhancement: EnhancementRegistryDefinition) => void; +} + +// Warning: (ae-forgotten-export) The symbol "SerializableState" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "EnhancementRegistryDefinition" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface EnhancementRegistryDefinition

extends PersistableStateDefinition

{ + // (undocumented) + id: string; +} + +// Warning: (ae-forgotten-export) The symbol "EmbeddableServerPlugin" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "plugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const plugin: () => EmbeddableServerPlugin; + + +// (No @packageDocumentation comment for this package) + +``` diff --git a/src/plugins/es_ui_shared/static/forms/components/index.ts b/src/plugins/es_ui_shared/static/forms/components/index.ts index 6e319978e9392..1108c56161966 100644 --- a/src/plugins/es_ui_shared/static/forms/components/index.ts +++ b/src/plugins/es_ui_shared/static/forms/components/index.ts @@ -17,6 +17,21 @@ * under the License. */ +/* +@TODO + +The brace/mode/json import below is loaded eagerly - before this plugin is explicitly loaded by users. This makes +the brace JSON mode, used for JSON syntax highlighting and grammar checking, available across all of Kibana plugins. + +This is not ideal because we are loading JS that is not necessary for Kibana to start, but the alternative +is breaking JSON mode for an unknown number of ace editors across Kibana - not all components reference the underlying +EuiCodeEditor (for instance, explicitly). + +Importing here is a way of preventing a more sophisticated solution to this problem since we want to, eventually, +migrate all code editors over to Monaco. Once that is done, we should remove this import. + */ +import 'brace/mode/json'; + export * from './field'; export * from './form_row'; export * from './fields'; diff --git a/src/plugins/expressions/README.asciidoc b/src/plugins/expressions/README.asciidoc new file mode 100644 index 0000000000000..e07f6e2909ab8 --- /dev/null +++ b/src/plugins/expressions/README.asciidoc @@ -0,0 +1,55 @@ +[[kibana-expressions-plugin]] +== `expressions` plugin + +Expression pipeline is a chain of functions that *pipe* its output to the +input of the next function. Functions can be configured using arguments provided +by the user. The final output of the expression pipeline can be rendered using +one of the *renderers* registered in `expressions` plugin. + +All the arguments to expression functions need to be serializable, as well as input and output. +Expression functions should try to stay 'pure'. This makes functions easy to reuse and also +make it possible to serialize the whole chain as well as output at every step of execution. + +Expressions power visualizations in Dashboard and Lens, as well as, every +*element* in Canvas is backed by an expression. + +This plugin provides methods which will parse & execute an *expression pipeline* +string for you, as well as a series of registries for advanced users who might +want to incorporate their own functions, types, and renderers into the service +for use in their own application. + +=== Examples + +Below is an example of serialized expression for one Canvas element that fetches +data using `essql` function, pipes it further to `math` and `metric` functions, +and final `render` function renders the result. + +[source] +filters +| essql + query="SELECT COUNT(timestamp) as total_errors + FROM kibana_sample_data_logs + WHERE tags LIKE '%warning%' OR tags LIKE '%error%'" +| math "total_errors" +| metric "TOTAL ISSUES" + metricFont={font family="'Open Sans', Helvetica, Arial, sans-serif" size=48 align="left" color="#FFFFFF" weight="normal" underline=false italic=false} + labelFont={font family="'Open Sans', Helvetica, Arial, sans-serif" size=30 align="left" color="#FFFFFF" weight="lighter" underline=false italic=false} +| render +[/source] + +[role="screenshot"] +image::https://user-images.githubusercontent.com/9773803/74162514-3250a880-4c21-11ea-9e68-86f66862a183.png[] + +=== API documentation + +==== Server API +https://github.com/elastic/kibana/blob/master/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserversetup.md[Server Setup contract] +https://github.com/elastic/kibana/blob/master/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserverstart.md[Server Start contract] + +===== Browser API +https://github.com/elastic/kibana/blob/master/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservicesetup.md[Browser Setup contract] +https://github.com/elastic/kibana/blob/master/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsstart.md[Browser Start contract] + + +==== Other documentation +https://www.elastic.co/guide/en/kibana/current/canvas-function-arguments.html[See Canvas documentation about expressions] diff --git a/src/plugins/expressions/README.md b/src/plugins/expressions/README.md deleted file mode 100644 index c1f032ace37c9..0000000000000 --- a/src/plugins/expressions/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# `expressions` plugin - -This plugin provides methods which will parse & execute an *expression pipeline* -string for you, as well as a series of registries for advanced users who might -want to incorporate their own functions, types, and renderers into the service -for use in their own application. - -Expression pipeline is a chain of functions that *pipe* its output to the -input of the next function. Functions can be configured using arguments provided -by the user. The final output of the expression pipeline can be rendered using -one of the *renderers* registered in `expressions` plugin. - -Expressions power visualizations in Dashboard and Lens, as well as, every -*element* in Canvas is backed by an expression. - -Below is an example of one Canvas element that fetches data using `essql` function, -pipes it further to `math` and `metric` functions, and final `render` function -renders the result. - -``` -filters -| essql - query="SELECT COUNT(timestamp) as total_errors - FROM kibana_sample_data_logs - WHERE tags LIKE '%warning%' OR tags LIKE '%error%'" -| math "total_errors" -| metric "TOTAL ISSUES" - metricFont={font family="'Open Sans', Helvetica, Arial, sans-serif" size=48 align="left" color="#FFFFFF" weight="normal" underline=false italic=false} - labelFont={font family="'Open Sans', Helvetica, Arial, sans-serif" size=30 align="left" color="#FFFFFF" weight="lighter" underline=false italic=false} -| render -``` - -![image](https://user-images.githubusercontent.com/9773803/74162514-3250a880-4c21-11ea-9e68-86f66862a183.png) - -[See Canvas documentation about expressions](https://www.elastic.co/guide/en/kibana/current/canvas-function-arguments.html). diff --git a/src/plugins/expressions/common/ast/types.ts b/src/plugins/expressions/common/ast/types.ts index d5039d0adb318..09fb4fae3f201 100644 --- a/src/plugins/expressions/common/ast/types.ts +++ b/src/plugins/expressions/common/ast/types.ts @@ -18,7 +18,6 @@ */ import { ExpressionValue, ExpressionValueError } from '../expression_types'; -import { ExpressionFunction } from '../../common'; export type ExpressionAstNode = | ExpressionAstExpression @@ -48,9 +47,9 @@ export interface ExpressionAstFunctionDebug { success: boolean; /** - * Reference to the expression function this AST node represents. + * Id of expression function. */ - fn: ExpressionFunction; + fn: string; /** * Input that expression function received as its first argument. diff --git a/src/plugins/expressions/common/execution/execution.test.ts b/src/plugins/expressions/common/execution/execution.test.ts index 2b8aa4b5e68f0..ff331d7c5ddaf 100644 --- a/src/plugins/expressions/common/execution/execution.test.ts +++ b/src/plugins/expressions/common/execution/execution.test.ts @@ -491,7 +491,7 @@ describe('Execution', () => { await execution.result; for (const node of execution.state.get().ast.chain) { - expect(node.debug?.fn.name).toBe('add'); + expect(node.debug?.fn).toBe('add'); } }); @@ -667,7 +667,7 @@ describe('Execution', () => { expect(node2.debug).toMatchObject({ success: false, - fn: expect.any(Object), + fn: 'throws', input: expect.any(Object), args: expect.any(Object), error: expect.any(Object), diff --git a/src/plugins/expressions/common/execution/execution.ts b/src/plugins/expressions/common/execution/execution.ts index 3533500a2fbc5..d4c9b0a25d45b 100644 --- a/src/plugins/expressions/common/execution/execution.ts +++ b/src/plugins/expressions/common/execution/execution.ts @@ -235,7 +235,7 @@ export class Execution< const timeEnd: number = now(); (link as ExpressionAstFunction).debug = { success: true, - fn, + fn: fn.name, input, args: resolvedArgs, output, @@ -253,7 +253,7 @@ export class Execution< if (this.params.debug) { (link as ExpressionAstFunction).debug = { success: false, - fn, + fn: fn.name, input, args, error, diff --git a/src/plugins/expressions/common/execution/execution_contract.ts b/src/plugins/expressions/common/execution/execution_contract.ts index 8c784352b9fdf..20c5b2dd434b5 100644 --- a/src/plugins/expressions/common/execution/execution_contract.ts +++ b/src/plugins/expressions/common/execution/execution_contract.ts @@ -18,6 +18,8 @@ */ import { Execution } from './execution'; +import { ExpressionValueError } from '../expression_types/specs'; +import { ExpressionAstExpression } from '../ast'; /** * `ExecutionContract` is a wrapper around `Execution` class. It provides the @@ -53,7 +55,7 @@ export class ExecutionContract< * wraps that error into `ExpressionValueError` type and returns that. * This function never throws. */ - getData = async () => { + getData = async (): Promise => { try { return await this.execution.result; } catch (e) { @@ -80,7 +82,7 @@ export class ExecutionContract< /** * Get AST used to execute the expression. */ - getAst = () => this.execution.state.get().ast; + getAst = (): ExpressionAstExpression => this.execution.state.get().ast; /** * Get Inspector adapters provided to all functions of expression through diff --git a/src/plugins/expressions/common/expression_renderers/types.ts b/src/plugins/expressions/common/expression_renderers/types.ts index 7b3e812eafedd..b760e7b32a7d2 100644 --- a/src/plugins/expressions/common/expression_renderers/types.ts +++ b/src/plugins/expressions/common/expression_renderers/types.ts @@ -28,7 +28,7 @@ export interface ExpressionRenderDefinition { /** * A user friendly name of the renderer as will be displayed to user in UI. */ - displayName: string; + displayName?: string; /** * Help text as will be displayed to user. A sentence or few about what this diff --git a/src/plugins/expressions/common/expression_types/specs/error.ts b/src/plugins/expressions/common/expression_types/specs/error.ts index c95a019f4e8d2..ebaedcbba0d23 100644 --- a/src/plugins/expressions/common/expression_types/specs/error.ts +++ b/src/plugins/expressions/common/expression_types/specs/error.ts @@ -28,6 +28,7 @@ export type ExpressionValueError = ExpressionValueBoxed< { error: { message: string; + type?: string; name?: string; stack?: string; original?: Error; diff --git a/src/plugins/expressions/common/service/expressions_services.ts b/src/plugins/expressions/common/service/expressions_services.ts index f1053c7bb8411..b5c98fada07c4 100644 --- a/src/plugins/expressions/common/service/expressions_services.ts +++ b/src/plugins/expressions/common/service/expressions_services.ts @@ -18,9 +18,11 @@ */ import { Executor } from '../executor'; -import { ExpressionRendererRegistry } from '../expression_renderers'; +import { AnyExpressionRenderDefinition, ExpressionRendererRegistry } from '../expression_renderers'; import { ExpressionAstExpression } from '../ast'; import { ExecutionContract } from '../execution/execution_contract'; +import { AnyExpressionTypeDefinition } from '../expression_types'; +import { AnyExpressionFunctionDefinition } from '../expression_functions'; /** * The public contract that `ExpressionsService` provides to other plugins @@ -45,18 +47,88 @@ export type ExpressionsServiceSetup = Pick< * The public contract that `ExpressionsService` provides to other plugins * in Kibana Platform in *start* life-cycle. */ -export type ExpressionsServiceStart = Pick< - ExpressionsService, - | 'getFunction' - | 'getFunctions' - | 'getRenderer' - | 'getRenderers' - | 'getType' - | 'getTypes' - | 'run' - | 'execute' - | 'fork' ->; +export interface ExpressionsServiceStart { + /** + * Get a registered `ExpressionFunction` by its name, which was registered + * using the `registerFunction` method. The returned `ExpressionFunction` + * instance is an internal representation of the function in Expressions + * service - do not mutate that object. + */ + getFunction: (name: string) => ReturnType; + + /** + * Get a registered `ExpressionRenderer` by its name, which was registered + * using the `registerRenderer` method. The returned `ExpressionRenderer` + * instance is an internal representation of the renderer in Expressions + * service - do not mutate that object. + */ + getRenderer: (name: string) => ReturnType; + + /** + * Get a registered `ExpressionType` by its name, which was registered + * using the `registerType` method. The returned `ExpressionType` + * instance is an internal representation of the type in Expressions + * service - do not mutate that object. + */ + getType: (name: string) => ReturnType; + + /** + * Executes expression string or a parsed expression AST and immediately + * returns the result. + * + * Below example will execute `sleep 100 | clog` expression with `123` initial + * input to the first function. + * + * ```ts + * expressions.run('sleep 100 | clog', 123); + * ``` + * + * - `sleep 100` will delay execution by 100 milliseconds and pass the `123` input as + * its output. + * - `clog` will print to console `123` and pass it as its output. + * - The final result of the execution will be `123`. + * + * Optionally, you can pass an object as the third argument which will be used + * to extend the `ExecutionContext`—an object passed to each function + * as the third argument, that allows functions to perform side-effects. + * + * ```ts + * expressions.run('...', null, { elasticsearchClient }); + * ``` + */ + run: = Record>( + ast: string | ExpressionAstExpression, + input: Input, + context?: ExtraContext + ) => Promise; + + /** + * Starts expression execution and immediately returns `ExecutionContract` + * instance that tracks the progress of the execution and can be used to + * interact with the execution. + */ + execute: < + Input = unknown, + Output = unknown, + ExtraContext extends Record = Record + >( + ast: string | ExpressionAstExpression, + // This any is for legacy reasons. + input: Input, + context?: ExtraContext + ) => ExecutionContract; + + /** + * Create a new instance of `ExpressionsService`. The new instance inherits + * all state of the original `ExpressionsService`, including all expression + * types, expression functions and context. Also, all new types and functions + * registered in the original services AFTER the forking event will be + * available in the forked instance. However, all new types and functions + * registered in the forked instances will NOT be available to the original + * service. + */ + fork: () => ExpressionsService; +} export interface ExpressionServiceParams { executor?: Executor; @@ -127,58 +199,21 @@ export class ExpressionsService { * passed to all functions that can be used for side-effects. */ public readonly registerFunction = ( - ...args: Parameters - ): ReturnType => this.executor.registerFunction(...args); + functionDefinition: AnyExpressionFunctionDefinition | (() => AnyExpressionFunctionDefinition) + ): void => this.executor.registerFunction(functionDefinition); public readonly registerType = ( - ...args: Parameters - ): ReturnType => this.executor.registerType(...args); + typeDefinition: AnyExpressionTypeDefinition | (() => AnyExpressionTypeDefinition) + ): void => this.executor.registerType(typeDefinition); public readonly registerRenderer = ( - ...args: Parameters - ): ReturnType => this.renderers.register(...args); + definition: AnyExpressionRenderDefinition | (() => AnyExpressionRenderDefinition) + ): void => this.renderers.register(definition); - /** - * Executes expression string or a parsed expression AST and immediately - * returns the result. - * - * Below example will execute `sleep 100 | clog` expression with `123` initial - * input to the first function. - * - * ```ts - * expressions.run('sleep 100 | clog', 123); - * ``` - * - * - `sleep 100` will delay execution by 100 milliseconds and pass the `123` input as - * its output. - * - `clog` will print to console `123` and pass it as its output. - * - The final result of the execution will be `123`. - * - * Optionally, you can pass an object as the third argument which will be used - * to extend the `ExecutionContext`—an object passed to each function - * as the third argument, that allows functions to perform side-effects. - * - * ```ts - * expressions.run('...', null, { elasticsearchClient }); - * ``` - */ - public readonly run = < - Input, - Output, - ExtraContext extends Record = Record - >( - ast: string | ExpressionAstExpression, - input: Input, - context?: ExtraContext - ): Promise => this.executor.run(ast, input, context); + public readonly run: ExpressionsServiceStart['run'] = (ast, input, context) => + this.executor.run(ast, input, context); - /** - * Get a registered `ExpressionFunction` by its name, which was registered - * using the `registerFunction` method. The returned `ExpressionFunction` - * instance is an internal representation of the function in Expressions - * service - do not mutate that object. - */ - public readonly getFunction = (name: string): ReturnType => + public readonly getFunction: ExpressionsServiceStart['getFunction'] = (name) => this.executor.getFunction(name); /** @@ -188,13 +223,7 @@ export class ExpressionsService { public readonly getFunctions = (): ReturnType => this.executor.getFunctions(); - /** - * Get a registered `ExpressionRenderer` by its name, which was registered - * using the `registerRenderer` method. The returned `ExpressionRenderer` - * instance is an internal representation of the renderer in Expressions - * service - do not mutate that object. - */ - public readonly getRenderer = (name: string): ReturnType => + public readonly getRenderer: ExpressionsServiceStart['getRenderer'] = (name) => this.renderers.get(name); /** @@ -204,13 +233,7 @@ export class ExpressionsService { public readonly getRenderers = (): ReturnType => this.renderers.toJS(); - /** - * Get a registered `ExpressionType` by its name, which was registered - * using the `registerType` method. The returned `ExpressionType` - * instance is an internal representation of the type in Expressions - * service - do not mutate that object. - */ - public readonly getType = (name: string): ReturnType => + public readonly getType: ExpressionsServiceStart['getType'] = (name) => this.executor.getType(name); /** @@ -219,36 +242,13 @@ export class ExpressionsService { */ public readonly getTypes = (): ReturnType => this.executor.getTypes(); - /** - * Starts expression execution and immediately returns `ExecutionContract` - * instance that tracks the progress of the execution and can be used to - * interact with the execution. - */ - public readonly execute = < - Input = unknown, - Output = unknown, - ExtraContext extends Record = Record - >( - ast: string | ExpressionAstExpression, - // This any is for legacy reasons. - input: Input = { type: 'null' } as any, - context?: ExtraContext - ): ExecutionContract => { - const execution = this.executor.createExecution(ast, context); + public readonly execute: ExpressionsServiceStart['execute'] = ((ast, input, context) => { + const execution = this.executor.createExecution(ast, context); execution.start(input); return execution.contract; - }; + }) as ExpressionsServiceStart['execute']; - /** - * Create a new instance of `ExpressionsService`. The new instance inherits - * all state of the original `ExpressionsService`, including all expression - * types, expression functions and context. Also, all new types and functions - * registered in the original services AFTER the forking event will be - * available in the forked instance. However, all new types and functions - * registered in the forked instances will NOT be available to the original - * service. - */ - public readonly fork = (): ExpressionsService => { + public readonly fork = () => { const executor = this.executor.fork(); const renderers = this.renderers; const fork = new ExpressionsService({ executor, renderers }); diff --git a/src/plugins/expressions/public/index.ts b/src/plugins/expressions/public/index.ts index 87406db89a2a8..039890c9233cf 100644 --- a/src/plugins/expressions/public/index.ts +++ b/src/plugins/expressions/public/index.ts @@ -122,4 +122,7 @@ export { TypeToString, UnmappedTypeStrings, ExpressionValueRender as Render, + ExpressionsService, + ExpressionsServiceSetup, + ExpressionsServiceStart, } from '../common'; diff --git a/src/plugins/expressions/public/mocks.tsx b/src/plugins/expressions/public/mocks.tsx index 3865b4d20620a..f6546a6b7ff35 100644 --- a/src/plugins/expressions/public/mocks.tsx +++ b/src/plugins/expressions/public/mocks.tsx @@ -49,11 +49,8 @@ const createStartContract = (): Start => { ExpressionRenderHandler: jest.fn(), fork: jest.fn(), getFunction: jest.fn(), - getFunctions: jest.fn(), getRenderer: jest.fn(), - getRenderers: jest.fn(), getType: jest.fn(), - getTypes: jest.fn(), loader: jest.fn(), ReactExpressionRenderer: jest.fn((props) => <>), render: jest.fn(), diff --git a/src/plugins/expressions/public/plugin.test.ts b/src/plugins/expressions/public/plugin.test.ts index 08f7135f033f1..d9dde1f6def68 100644 --- a/src/plugins/expressions/public/plugin.test.ts +++ b/src/plugins/expressions/public/plugin.test.ts @@ -67,7 +67,7 @@ describe('ExpressionsPublicPlugin', () => { const { doStart } = await expressionsPluginMock.createPlugin(); const start = await doStart(); - const handler = start.execute('clog'); + const handler = start.execute('clog', null); expect(handler.getAst()).toMatchInlineSnapshot(` Object { "chain": Array [ @@ -85,7 +85,7 @@ describe('ExpressionsPublicPlugin', () => { test('"kibana" function return value of type "kibana_context"', async () => { const { doStart } = await expressionsPluginMock.createPlugin(); const start = await doStart(); - const execution = start.execute('kibana'); + const execution = start.execute('kibana', null); const result = await execution.getData(); expect((result as any).type).toBe('kibana_context'); diff --git a/src/plugins/expressions/public/plugin.ts b/src/plugins/expressions/public/plugin.ts index 9768ece899dd4..4ad0e53cdd9c0 100644 --- a/src/plugins/expressions/public/plugin.ts +++ b/src/plugins/expressions/public/plugin.ts @@ -21,20 +21,26 @@ import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from 'src/core import { ExpressionsService, ExpressionsServiceSetup, - ExpressionsServiceStart, ExecutionContext, + ExpressionsServiceStart, } from '../common'; import { setRenderersRegistry, setNotifications, setExpressionsService } from './services'; import { ReactExpressionRenderer } from './react_expression_renderer'; -import { ExpressionLoader, loader } from './loader'; +import { ExpressionLoader, IExpressionLoader, loader } from './loader'; import { render, ExpressionRenderHandler } from './render'; +/** + * Expressions public setup contract, extends {@link ExpressionsServiceSetup} + */ export type ExpressionsSetup = ExpressionsServiceSetup; +/** + * Expressions public start contrect, extends {@link ExpressionServiceStart} + */ export interface ExpressionsStart extends ExpressionsServiceStart { ExpressionLoader: typeof ExpressionLoader; ExpressionRenderHandler: typeof ExpressionRenderHandler; - loader: typeof loader; + loader: IExpressionLoader; ReactExpressionRenderer: typeof ReactExpressionRenderer; render: typeof render; } diff --git a/src/plugins/expressions/public/public.api.md b/src/plugins/expressions/public/public.api.md new file mode 100644 index 0000000000000..5c0fd8ab1a572 --- /dev/null +++ b/src/plugins/expressions/public/public.api.md @@ -0,0 +1,1164 @@ +## API Report File for "kibana" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { CoreSetup } from 'src/core/public'; +import { CoreStart } from 'src/core/public'; +import { Ensure } from '@kbn/utility-types'; +import { EnvironmentMode } from '@kbn/config'; +import { EventEmitter } from 'events'; +import { Observable } from 'rxjs'; +import { PackageInfo } from '@kbn/config'; +import { Plugin as Plugin_2 } from 'src/core/public'; +import { PluginInitializerContext as PluginInitializerContext_2 } from 'src/core/public'; +import React from 'react'; +import { UnwrapPromiseOrReturn } from '@kbn/utility-types'; + +// Warning: (ae-missing-release-tag) "AnyExpressionFunctionDefinition" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type AnyExpressionFunctionDefinition = ExpressionFunctionDefinition, any>; + +// Warning: (ae-missing-release-tag) "AnyExpressionTypeDefinition" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type AnyExpressionTypeDefinition = ExpressionTypeDefinition; + +// Warning: (ae-forgotten-export) The symbol "SingleArgumentType" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "MultipleArgumentType" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "UnresolvedSingleArgumentType" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "UnresolvedMultipleArgumentType" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "ArgumentType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type ArgumentType = SingleArgumentType | MultipleArgumentType | UnresolvedSingleArgumentType | UnresolvedMultipleArgumentType; + +// Warning: (ae-missing-release-tag) "buildExpression" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function buildExpression(initialState?: ExpressionAstFunctionBuilder[] | ExpressionAstExpression | string): ExpressionAstExpressionBuilder; + +// Warning: (ae-forgotten-export) The symbol "InferFunctionDefinition" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "FunctionArgs" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "buildExpressionFunction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function buildExpressionFunction(fnName: InferFunctionDefinition['name'], +initialArgs: { + [K in keyof FunctionArgs]: FunctionArgs[K] | ExpressionAstExpressionBuilder | ExpressionAstExpressionBuilder[]; +}): ExpressionAstFunctionBuilder; + +// Warning: (ae-missing-release-tag) "Datatable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface Datatable { + // (undocumented) + columns: DatatableColumn[]; + // (undocumented) + rows: DatatableRow[]; + // Warning: (ae-forgotten-export) The symbol "name" needs to be exported by the entry point index.d.ts + // + // (undocumented) + type: typeof name; +} + +// Warning: (ae-missing-release-tag) "DatatableColumn" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface DatatableColumn { + // (undocumented) + id: string; + // Warning: (ae-forgotten-export) The symbol "DatatableColumnMeta" needs to be exported by the entry point index.d.ts + // + // (undocumented) + meta: DatatableColumnMeta; + // (undocumented) + name: string; +} + +// Warning: (ae-missing-release-tag) "DatatableColumnType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type DatatableColumnType = 'string' | 'number' | 'boolean' | 'date' | 'null'; + +// Warning: (ae-missing-release-tag) "DatatableRow" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type DatatableRow = Record; + +// Warning: (ae-forgotten-export) The symbol "Adapters" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "DefaultInspectorAdapters" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "Execution" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class Execution = Record, Input = unknown, Output = unknown, InspectorAdapters extends Adapters = ExtraContext['inspectorAdapters'] extends object ? ExtraContext['inspectorAdapters'] : DefaultInspectorAdapters> { + constructor(params: ExecutionParams); + cancel(): void; + // (undocumented) + cast(value: any, toTypeNames?: string[]): any; + readonly context: ExecutionContext & ExtraContext; + readonly contract: ExecutionContract; + // (undocumented) + readonly expression: string; + input: Input; + // (undocumented) + get inspectorAdapters(): InspectorAdapters; + // Warning: (ae-forgotten-export) The symbol "ExpressionExecOptions" needs to be exported by the entry point index.d.ts + // + // (undocumented) + interpret(ast: ExpressionAstNode, input: T, options?: ExpressionExecOptions): Promise; + // (undocumented) + invokeChain(chainArr: ExpressionAstFunction[], input: unknown): Promise; + // (undocumented) + invokeFunction(fn: ExpressionFunction, input: unknown, args: Record): Promise; + // (undocumented) + readonly params: ExecutionParams; + // (undocumented) + resolveArgs(fnDef: ExpressionFunction, input: unknown, argAsts: any): Promise; + // (undocumented) + get result(): Promise; + start(input?: Input): void; + readonly state: ExecutionContainer; +} + +// Warning: (ae-forgotten-export) The symbol "StateContainer" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "ExecutionPureTransitions" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "ExecutionContainer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExecutionContainer = StateContainer, ExecutionPureTransitions>; + +// Warning: (ae-missing-release-tag) "ExecutionContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface ExecutionContext { + abortSignal: AbortSignal; + getInitialInput: () => Input; + // Warning: (ae-forgotten-export) The symbol "SavedObjectAttributes" needs to be exported by the entry point index.d.ts + // Warning: (ae-forgotten-export) The symbol "SavedObject" needs to be exported by the entry point index.d.ts + getSavedObject?: (type: string, id: string) => Promise>; + inspectorAdapters: InspectorAdapters; + // Warning: (ae-forgotten-export) The symbol "ExecutionContextSearch" needs to be exported by the entry point index.d.ts + search?: ExecutionContextSearch; + types: Record; + variables: Record; +} + +// Warning: (ae-missing-release-tag) "ExecutionContract" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export class ExecutionContract = Record, Input = unknown, Output = unknown, InspectorAdapters = unknown> { + constructor(execution: Execution); + cancel: () => void; + // (undocumented) + protected readonly execution: Execution; + getAst: () => ExpressionAstExpression; + getData: () => Promise; + getExpression: () => string; + inspect: () => InspectorAdapters; + // (undocumented) + get isPending(): boolean; +} + +// Warning: (ae-missing-release-tag) "ExecutionParams" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ExecutionParams = Record> { + // (undocumented) + ast?: ExpressionAstExpression; + // (undocumented) + context?: ExtraContext; + debug?: boolean; + // (undocumented) + executor: Executor; + // (undocumented) + expression?: string; +} + +// Warning: (ae-missing-release-tag) "ExecutionState" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ExecutionState extends ExecutorState { + // (undocumented) + ast: ExpressionAstExpression; + error?: Error; + result?: Output; + state: 'not-started' | 'pending' | 'result' | 'error'; +} + +// Warning: (ae-missing-release-tag) "Executor" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class Executor = Record> { + constructor(state?: ExecutorState); + // (undocumented) + get context(): Record; + // (undocumented) + createExecution = Record, Input = unknown, Output = unknown>(ast: string | ExpressionAstExpression, context?: ExtraContext, { debug }?: ExpressionExecOptions): Execution; + // (undocumented) + static createWithDefaults = Record>(state?: ExecutorState): Executor; + // (undocumented) + extendContext(extraContext: Record): void; + // (undocumented) + fork(): Executor; + // @deprecated (undocumented) + readonly functions: FunctionsRegistry; + // (undocumented) + getFunction(name: string): ExpressionFunction | undefined; + // (undocumented) + getFunctions(): Record; + // (undocumented) + getType(name: string): ExpressionType | undefined; + // (undocumented) + getTypes(): Record; + // (undocumented) + registerFunction(functionDefinition: AnyExpressionFunctionDefinition | (() => AnyExpressionFunctionDefinition)): void; + // (undocumented) + registerType(typeDefinition: AnyExpressionTypeDefinition | (() => AnyExpressionTypeDefinition)): void; + run = Record>(ast: string | ExpressionAstExpression, input: Input, context?: ExtraContext): Promise; + // (undocumented) + readonly state: ExecutorContainer; + // @deprecated (undocumented) + readonly types: TypesRegistry; +} + +// Warning: (ae-forgotten-export) The symbol "ExecutorPureTransitions" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "ExecutorPureSelectors" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "ExecutorContainer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExecutorContainer = Record> = StateContainer, ExecutorPureTransitions, ExecutorPureSelectors>; + +// Warning: (ae-missing-release-tag) "ExecutorState" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ExecutorState = Record> { + // (undocumented) + context: Context; + // (undocumented) + functions: Record; + // (undocumented) + types: Record; +} + +// Warning: (ae-missing-release-tag) "ExpressionAstArgument" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExpressionAstArgument = string | boolean | number | ExpressionAstExpression; + +// Warning: (ae-missing-release-tag) "ExpressionAstExpression" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ExpressionAstExpression { + // (undocumented) + chain: ExpressionAstFunction[]; + // (undocumented) + type: 'expression'; +} + +// Warning: (ae-missing-release-tag) "ExpressionAstExpressionBuilder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ExpressionAstExpressionBuilder { + findFunction: (fnName: InferFunctionDefinition['name']) => Array> | []; + functions: ExpressionAstFunctionBuilder[]; + toAst: () => ExpressionAstExpression; + toString: () => string; + type: 'expression_builder'; +} + +// Warning: (ae-missing-release-tag) "ExpressionAstFunction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ExpressionAstFunction { + // (undocumented) + arguments: Record; + // Warning: (ae-forgotten-export) The symbol "ExpressionAstFunctionDebug" needs to be exported by the entry point index.d.ts + debug?: ExpressionAstFunctionDebug; + // (undocumented) + function: string; + // (undocumented) + type: 'function'; +} + +// Warning: (ae-missing-release-tag) "ExpressionAstFunctionBuilder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ExpressionAstFunctionBuilder { + // Warning: (ae-forgotten-export) The symbol "FunctionArgName" needs to be exported by the entry point index.d.ts + addArgument: >(name: A, value: FunctionArgs[A] | ExpressionAstExpressionBuilder) => this; + // Warning: (ae-forgotten-export) The symbol "FunctionBuilderArguments" needs to be exported by the entry point index.d.ts + arguments: FunctionBuilderArguments; + getArgument: >(name: A) => Array[A] | ExpressionAstExpressionBuilder> | undefined; + name: InferFunctionDefinition['name']; + // Warning: (ae-forgotten-export) The symbol "OptionalKeys" needs to be exported by the entry point index.d.ts + removeArgument: >>(name: A) => this; + replaceArgument: >(name: A, value: Array[A] | ExpressionAstExpressionBuilder>) => this; + toAst: () => ExpressionAstFunction; + toString: () => string; + type: 'expression_function_builder'; +} + +// Warning: (ae-missing-release-tag) "ExpressionAstNode" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExpressionAstNode = ExpressionAstExpression | ExpressionAstFunction | ExpressionAstArgument; + +// Warning: (ae-missing-release-tag) "ExpressionExecutor" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public @deprecated (undocumented) +export interface ExpressionExecutor { + // Warning: (ae-forgotten-export) The symbol "ExpressionInterpreter" needs to be exported by the entry point index.d.ts + // + // (undocumented) + interpreter: ExpressionInterpreter; +} + +// Warning: (ae-missing-release-tag) "ExpressionFunction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class ExpressionFunction { + constructor(functionDefinition: AnyExpressionFunctionDefinition); + // (undocumented) + accepts: (type: string) => boolean; + aliases: string[]; + args: Record; + fn: (input: ExpressionValue, params: Record, handlers: object) => ExpressionValue; + help: string; + inputTypes: string[] | undefined; + name: string; + type: string; +} + +// Warning: (ae-missing-release-tag) "ExpressionFunctionDefinition" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface ExpressionFunctionDefinition, Output, Context extends ExecutionContext = ExecutionContext> { + aliases?: string[]; + args: { + [key in keyof Arguments]: ArgumentType; + }; + // @deprecated (undocumented) + context?: { + types: AnyExpressionFunctionDefinition['inputTypes']; + }; + fn(input: Input, args: Arguments, context: Context): Output; + help: string; + inputTypes?: Array>; + name: Name; + type?: TypeToString>; +} + +// @public +export interface ExpressionFunctionDefinitions { + // Warning: (ae-forgotten-export) The symbol "ExpressionFunctionClog" needs to be exported by the entry point index.d.ts + // + // (undocumented) + clog: ExpressionFunctionClog; + // Warning: (ae-forgotten-export) The symbol "ExpressionFunctionFont" needs to be exported by the entry point index.d.ts + // + // (undocumented) + font: ExpressionFunctionFont; + // (undocumented) + kibana: ExpressionFunctionKibana; + // Warning: (ae-forgotten-export) The symbol "ExpressionFunctionKibanaContext" needs to be exported by the entry point index.d.ts + // + // (undocumented) + kibana_context: ExpressionFunctionKibanaContext; + // Warning: (ae-forgotten-export) The symbol "ExpressionFunctionTheme" needs to be exported by the entry point index.d.ts + // + // (undocumented) + theme: ExpressionFunctionTheme; + // Warning: (ae-forgotten-export) The symbol "ExpressionFunctionVar" needs to be exported by the entry point index.d.ts + // + // (undocumented) + var: ExpressionFunctionVar; + // Warning: (ae-forgotten-export) The symbol "ExpressionFunctionVarSet" needs to be exported by the entry point index.d.ts + // + // (undocumented) + var_set: ExpressionFunctionVarSet; +} + +// Warning: (ae-missing-release-tag) "ExpressionFunctionKibana" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExpressionFunctionKibana = ExpressionFunctionDefinition<'kibana', ExpressionValueSearchContext | null, object, ExpressionValueSearchContext>; + +// Warning: (ae-missing-release-tag) "ExpressionFunctionParameter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class ExpressionFunctionParameter { + constructor(name: string, arg: ArgumentType); + // (undocumented) + accepts(type: string): boolean; + // (undocumented) + aliases: string[]; + // (undocumented) + default: any; + // (undocumented) + help: string; + // (undocumented) + multi: boolean; + // (undocumented) + name: string; + // (undocumented) + options: any[]; + // (undocumented) + required: boolean; + // (undocumented) + resolve: boolean; + // (undocumented) + types: string[]; +} + +// Warning: (ae-missing-release-tag) "ExpressionImage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ExpressionImage { + // (undocumented) + dataurl: string; + // (undocumented) + mode: string; + // (undocumented) + type: 'image'; +} + +// Warning: (ae-missing-release-tag) "ExpressionRenderDefinition" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ExpressionRenderDefinition { + displayName?: string; + help?: string; + name: string; + render: (domNode: HTMLElement, config: Config, handlers: IInterpreterRenderHandlers) => void | Promise; + reuseDomNode: boolean; + validate?: () => undefined | Error; +} + +// Warning: (ae-missing-release-tag) "ExpressionRenderer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class ExpressionRenderer { + constructor(config: ExpressionRenderDefinition); + // (undocumented) + readonly displayName: string; + // (undocumented) + readonly help: string; + // (undocumented) + readonly name: string; + // (undocumented) + readonly render: ExpressionRenderDefinition['render']; + // (undocumented) + readonly reuseDomNode: boolean; + // (undocumented) + readonly validate: () => void | Error; +} + +// Warning: (ae-missing-release-tag) "ExpressionRendererComponent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExpressionRendererComponent = React.FC; + +// Warning: (ae-missing-release-tag) "ExpressionRendererEvent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ExpressionRendererEvent { + // (undocumented) + data: any; + // (undocumented) + name: string; +} + +// Warning: (ae-missing-release-tag) "ExpressionRendererRegistry" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class ExpressionRendererRegistry implements IRegistry { + // (undocumented) + get(id: string): ExpressionRenderer | null; + // Warning: (ae-forgotten-export) The symbol "AnyExpressionRenderDefinition" needs to be exported by the entry point index.d.ts + // + // (undocumented) + register(definition: AnyExpressionRenderDefinition | (() => AnyExpressionRenderDefinition)): void; + // (undocumented) + toArray(): ExpressionRenderer[]; + // (undocumented) + toJS(): Record; +} + +// Warning: (ae-missing-release-tag) "ExpressionRenderError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ExpressionRenderError extends Error { + // (undocumented) + type?: string; +} + +// Warning: (ae-missing-release-tag) "ExpressionRenderHandler" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class ExpressionRenderHandler { + // Warning: (ae-forgotten-export) The symbol "ExpressionRenderHandlerParams" needs to be exported by the entry point index.d.ts + constructor(element: HTMLElement, { onRenderError }?: Partial); + // (undocumented) + destroy: () => void; + // (undocumented) + events$: Observable; + // (undocumented) + getElement: () => HTMLElement; + // (undocumented) + handleRenderError: (error: ExpressionRenderError) => void; + // (undocumented) + render$: Observable; + // (undocumented) + render: (data: any, uiState?: any) => Promise; + // Warning: (ae-forgotten-export) The symbol "UpdateValue" needs to be exported by the entry point index.d.ts + // + // (undocumented) + update$: Observable; + } + +// Warning: (ae-missing-release-tag) "ExpressionsPublicPlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +class ExpressionsPublicPlugin implements Plugin_2 { + constructor(initializerContext: PluginInitializerContext_2); + // (undocumented) + setup(core: CoreSetup): ExpressionsSetup; + // (undocumented) + start(core: CoreStart): ExpressionsStart; + // (undocumented) + stop(): void; +} + +export { ExpressionsPublicPlugin } + +export { ExpressionsPublicPlugin as Plugin } + +// Warning: (ae-missing-release-tag) "ExpressionsService" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export class ExpressionsService { + // Warning: (ae-forgotten-export) The symbol "ExpressionServiceParams" needs to be exported by the entry point index.d.ts + constructor({ executor, renderers, }?: ExpressionServiceParams); + // (undocumented) + readonly execute: ExpressionsServiceStart['execute']; + // (undocumented) + readonly executor: Executor; + // (undocumented) + readonly fork: () => ExpressionsService; + // (undocumented) + readonly getFunction: ExpressionsServiceStart['getFunction']; + readonly getFunctions: () => ReturnType; + // (undocumented) + readonly getRenderer: ExpressionsServiceStart['getRenderer']; + readonly getRenderers: () => ReturnType; + // (undocumented) + readonly getType: ExpressionsServiceStart['getType']; + readonly getTypes: () => ReturnType; + readonly registerFunction: (functionDefinition: AnyExpressionFunctionDefinition | (() => AnyExpressionFunctionDefinition)) => void; + // (undocumented) + readonly registerRenderer: (definition: AnyExpressionRenderDefinition | (() => AnyExpressionRenderDefinition)) => void; + // (undocumented) + readonly registerType: (typeDefinition: AnyExpressionTypeDefinition | (() => AnyExpressionTypeDefinition)) => void; + // (undocumented) + readonly renderers: ExpressionRendererRegistry; + // (undocumented) + readonly run: ExpressionsServiceStart['run']; + setup(): ExpressionsServiceSetup; + start(): ExpressionsServiceStart; + // (undocumented) + stop(): void; +} + +// Warning: (ae-missing-release-tag) "ExpressionsServiceSetup" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type ExpressionsServiceSetup = Pick; + +// Warning: (ae-missing-release-tag) "ExpressionsServiceStart" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface ExpressionsServiceStart { + execute: = Record>(ast: string | ExpressionAstExpression, input: Input, context?: ExtraContext) => ExecutionContract; + fork: () => ExpressionsService; + getFunction: (name: string) => ReturnType; + getRenderer: (name: string) => ReturnType; + getType: (name: string) => ReturnType; + run: = Record>(ast: string | ExpressionAstExpression, input: Input, context?: ExtraContext) => Promise; +} + +// Warning: (ae-missing-release-tag) "ExpressionsSetup" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type ExpressionsSetup = ExpressionsServiceSetup; + +// Warning: (ae-missing-release-tag) "ExpressionsStart" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "ExpressionServiceStart" +// +// @public +export interface ExpressionsStart extends ExpressionsServiceStart { + // Warning: (ae-forgotten-export) The symbol "ExpressionLoader" needs to be exported by the entry point index.d.ts + // + // (undocumented) + ExpressionLoader: typeof ExpressionLoader; + // (undocumented) + ExpressionRenderHandler: typeof ExpressionRenderHandler; + // Warning: (ae-forgotten-export) The symbol "IExpressionLoader" needs to be exported by the entry point index.d.ts + // + // (undocumented) + loader: IExpressionLoader; + // (undocumented) + ReactExpressionRenderer: typeof ReactExpressionRenderer; + // Warning: (ae-forgotten-export) The symbol "render" needs to be exported by the entry point index.d.ts + // + // (undocumented) + render: typeof render; +} + +// Warning: (ae-missing-release-tag) "ExpressionType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class ExpressionType { + constructor(definition: AnyExpressionTypeDefinition); + // (undocumented) + castsFrom: (value: ExpressionValue) => boolean; + // (undocumented) + castsTo: (value: ExpressionValue) => boolean; + // (undocumented) + create: unknown; + // (undocumented) + deserialize?: (serialized: any) => ExpressionValue; + // (undocumented) + from: (value: ExpressionValue, types: Record) => any; + // (undocumented) + getFromFn: (typeName: string) => undefined | ExpressionValueConverter; + // (undocumented) + getToFn: (typeName: string) => undefined | ExpressionValueConverter; + help: string; + // (undocumented) + name: string; + serialize?: (value: ExpressionValue) => any; + // (undocumented) + to: (value: ExpressionValue, toTypeName: string, types: Record) => any; + validate: (type: any) => void | Error; +} + +// Warning: (ae-missing-release-tag) "ExpressionTypeDefinition" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface ExpressionTypeDefinition { + // (undocumented) + deserialize?: (type: SerializedType) => Value; + // (undocumented) + from?: { + [type: string]: ExpressionValueConverter; + }; + // (undocumented) + help?: string; + // (undocumented) + name: Name; + // (undocumented) + serialize?: (type: Value) => SerializedType; + // (undocumented) + to?: { + [type: string]: ExpressionValueConverter; + }; + // (undocumented) + validate?: (type: any) => void | Error; +} + +// Warning: (ae-missing-release-tag) "ExpressionTypeStyle" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface ExpressionTypeStyle { + // (undocumented) + css: string; + // Warning: (ae-forgotten-export) The symbol "CSSStyle" needs to be exported by the entry point index.d.ts + // + // (undocumented) + spec: CSSStyle; + // (undocumented) + type: 'style'; +} + +// Warning: (ae-missing-release-tag) "ExpressionValue" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExpressionValue = ExpressionValueUnboxed | ExpressionValueBoxed; + +// Warning: (ae-missing-release-tag) "ExpressionValueBoxed" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExpressionValueBoxed = { + type: Type; +} & Value; + +// Warning: (ae-missing-release-tag) "ExpressionValueConverter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExpressionValueConverter = (input: I, availableTypes: Record) => O; + +// Warning: (ae-missing-release-tag) "ExpressionValueError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExpressionValueError = ExpressionValueBoxed<'error', { + error: { + message: string; + type?: string; + name?: string; + stack?: string; + original?: Error; + }; + info?: unknown; +}>; + +// Warning: (ae-missing-release-tag) "ExpressionValueFilter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type ExpressionValueFilter = ExpressionValueBoxed<'filter', { + filterType?: string; + value?: string; + column?: string; + and: ExpressionValueFilter[]; + to?: string; + from?: string; + query?: string | null; +}>; + +// Warning: (ae-missing-release-tag) "ExpressionValueNum" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExpressionValueNum = ExpressionValueBoxed<'num', { + value: number; +}>; + +// Warning: (ae-forgotten-export) The symbol "name" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "ExpressionValueRender" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +type ExpressionValueRender = ExpressionValueBoxed; + +export { ExpressionValueRender } + +export { ExpressionValueRender as Render } + +// Warning: (ae-missing-release-tag) "ExpressionValueSearchContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExpressionValueSearchContext = ExpressionValueBoxed<'kibana_context', ExecutionContextSearch>; + +// Warning: (ae-missing-release-tag) "ExpressionValueUnboxed" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExpressionValueUnboxed = any; + +// Warning: (ae-missing-release-tag) "Font" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface Font { + // (undocumented) + label: FontLabel; + // (undocumented) + value: FontValue; +} + +// Warning: (ae-forgotten-export) The symbol "fonts" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "FontLabel" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type FontLabel = typeof fonts[number]['label']; + +// Warning: (ae-missing-release-tag) "FontStyle" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export enum FontStyle { + // (undocumented) + ITALIC = "italic", + // (undocumented) + NORMAL = "normal" +} + +// Warning: (ae-missing-release-tag) "FontValue" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type FontValue = typeof fonts[number]['value']; + +// Warning: (ae-missing-release-tag) "FontWeight" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export enum FontWeight { + // (undocumented) + BOLD = "bold", + // (undocumented) + BOLDER = "bolder", + // (undocumented) + EIGHT = "800", + // (undocumented) + FIVE = "500", + // (undocumented) + FOUR = "400", + // (undocumented) + LIGHTER = "lighter", + // (undocumented) + NINE = "900", + // (undocumented) + NORMAL = "normal", + // (undocumented) + ONE = "100", + // (undocumented) + SEVEN = "700", + // (undocumented) + SIX = "600", + // (undocumented) + THREE = "300", + // (undocumented) + TWO = "200" +} + +// Warning: (ae-missing-release-tag) "format" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function format(ast: T, type: T extends ExpressionAstExpression ? 'expression' : 'argument'): string; + +// Warning: (ae-missing-release-tag) "formatExpression" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function formatExpression(ast: ExpressionAstExpression): string; + +// Warning: (ae-missing-release-tag) "FunctionsRegistry" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class FunctionsRegistry implements IRegistry { + constructor(executor: Executor); + // (undocumented) + get(id: string): ExpressionFunction | null; + // (undocumented) + register(functionDefinition: AnyExpressionFunctionDefinition | (() => AnyExpressionFunctionDefinition)): void; + // (undocumented) + toArray(): ExpressionFunction[]; + // (undocumented) + toJS(): Record; +} + +// Warning: (ae-missing-release-tag) "IExpressionLoaderParams" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface IExpressionLoaderParams { + // (undocumented) + context?: ExpressionValue; + // (undocumented) + customFunctions?: []; + // (undocumented) + customRenderers?: []; + // (undocumented) + disableCaching?: boolean; + // (undocumented) + inspectorAdapters?: Adapters; + // Warning: (ae-forgotten-export) The symbol "RenderErrorHandlerFnType" needs to be exported by the entry point index.d.ts + // + // (undocumented) + onRenderError?: RenderErrorHandlerFnType; + // (undocumented) + searchContext?: ExecutionContextSearch; + // (undocumented) + uiState?: unknown; + // (undocumented) + variables?: Record; +} + +// Warning: (ae-missing-release-tag) "IInterpreterRenderHandlers" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface IInterpreterRenderHandlers { + done: () => void; + // (undocumented) + event: (event: any) => void; + // (undocumented) + onDestroy: (fn: () => void) => void; + // (undocumented) + reload: () => void; + // (undocumented) + update: (params: any) => void; +} + +// Warning: (ae-missing-release-tag) "InterpreterErrorType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public @deprecated (undocumented) +export type InterpreterErrorType = ExpressionValueError; + +// Warning: (ae-missing-release-tag) "IRegistry" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface IRegistry { + // (undocumented) + get(id: string): T | null; + // (undocumented) + toArray(): T[]; + // (undocumented) + toJS(): Record; +} + +// Warning: (ae-missing-release-tag) "isExpressionAstBuilder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function isExpressionAstBuilder(val: any): val is ExpressionAstExpressionBuilder; + +// Warning: (ae-missing-release-tag) "KIBANA_CONTEXT_NAME" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type KIBANA_CONTEXT_NAME = 'kibana_context'; + +// Warning: (ae-missing-release-tag) "KibanaContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type KibanaContext = ExpressionValueSearchContext; + +// Warning: (ae-missing-release-tag) "KibanaDatatable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface KibanaDatatable { + // (undocumented) + columns: KibanaDatatableColumn[]; + // (undocumented) + rows: KibanaDatatableRow[]; + // Warning: (ae-forgotten-export) The symbol "name" needs to be exported by the entry point index.d.ts + // + // (undocumented) + type: typeof name_3; +} + +// Warning: (ae-missing-release-tag) "KibanaDatatableColumn" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface KibanaDatatableColumn { + // (undocumented) + formatHint?: SerializedFieldFormat; + // (undocumented) + id: string; + // (undocumented) + meta?: KibanaDatatableColumnMeta; + // (undocumented) + name: string; +} + +// Warning: (ae-missing-release-tag) "KibanaDatatableColumnMeta" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface KibanaDatatableColumnMeta { + // (undocumented) + aggConfigParams?: Record; + // (undocumented) + indexPatternId?: string; + // (undocumented) + type: string; +} + +// Warning: (ae-missing-release-tag) "KibanaDatatableRow" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface KibanaDatatableRow { + // (undocumented) + [key: string]: unknown; +} + +// Warning: (ae-missing-release-tag) "KnownTypeToString" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type KnownTypeToString = T extends string ? 'string' : T extends boolean ? 'boolean' : T extends number ? 'number' : T extends null ? 'null' : T extends { + type: string; +} ? T['type'] : never; + +// Warning: (ae-missing-release-tag) "Overflow" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export enum Overflow { + // (undocumented) + AUTO = "auto", + // (undocumented) + HIDDEN = "hidden", + // (undocumented) + SCROLL = "scroll", + // (undocumented) + VISIBLE = "visible" +} + +// Warning: (ae-missing-release-tag) "parse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function parse(expression: E, startRule: S): S extends 'expression' ? ExpressionAstExpression : ExpressionAstArgument; + +// Warning: (ae-missing-release-tag) "parseExpression" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function parseExpression(expression: string): ExpressionAstExpression; + +// Warning: (ae-forgotten-export) The symbol "PluginInitializerContext" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "plugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function plugin(initializerContext: PluginInitializerContext): ExpressionsPublicPlugin; + +// Warning: (ae-missing-release-tag) "PointSeries" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type PointSeries = ExpressionValueBoxed<'pointseries', { + columns: PointSeriesColumns; + rows: PointSeriesRow[]; +}>; + +// Warning: (ae-missing-release-tag) "PointSeriesColumn" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface PointSeriesColumn { + // (undocumented) + expression: string; + // (undocumented) + role: 'measure' | 'dimension'; + // (undocumented) + type: 'number' | 'string'; +} + +// Warning: (ae-missing-release-tag) "PointSeriesColumnName" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type PointSeriesColumnName = 'x' | 'y' | 'color' | 'size' | 'text'; + +// Warning: (ae-missing-release-tag) "PointSeriesColumns" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type PointSeriesColumns = Record | {}; + +// Warning: (ae-missing-release-tag) "PointSeriesRow" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type PointSeriesRow = Record; + +// Warning: (ae-missing-release-tag) "Range" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface Range { + // (undocumented) + from: number; + // (undocumented) + to: number; + // Warning: (ae-forgotten-export) The symbol "name" needs to be exported by the entry point index.d.ts + // + // (undocumented) + type: typeof name_4; +} + +// Warning: (ae-missing-release-tag) "ReactExpressionRenderer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const ReactExpressionRenderer: ({ className, dataAttrs, padding, renderError, expression, onEvent, reload$, ...expressionLoaderOptions }: ReactExpressionRendererProps) => JSX.Element; + +// Warning: (ae-missing-release-tag) "ReactExpressionRendererProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ReactExpressionRendererProps extends IExpressionLoaderParams { + // (undocumented) + className?: string; + // (undocumented) + dataAttrs?: string[]; + // (undocumented) + expression: string | ExpressionAstExpression; + // (undocumented) + onEvent?: (event: ExpressionRendererEvent) => void; + // (undocumented) + padding?: 'xs' | 's' | 'm' | 'l' | 'xl'; + reload$?: Observable; + // (undocumented) + renderError?: (error?: string | null) => React.ReactElement | React.ReactElement[]; +} + +// Warning: (ae-missing-release-tag) "ReactExpressionRendererType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ReactExpressionRendererType = React.ComponentType; + +// Warning: (ae-missing-release-tag) "SerializedDatatable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface SerializedDatatable extends Datatable { + // (undocumented) + rows: string[][]; +} + +// Warning: (ae-missing-release-tag) "SerializedFieldFormat" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface SerializedFieldFormat> { + // (undocumented) + id?: string; + // (undocumented) + params?: TParams; +} + +// Warning: (ae-missing-release-tag) "Style" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type Style = ExpressionTypeStyle; + +// Warning: (ae-missing-release-tag) "TextAlignment" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export enum TextAlignment { + // (undocumented) + CENTER = "center", + // (undocumented) + JUSTIFY = "justify", + // (undocumented) + LEFT = "left", + // (undocumented) + RIGHT = "right" +} + +// Warning: (ae-missing-release-tag) "TextDecoration" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export enum TextDecoration { + // (undocumented) + NONE = "none", + // (undocumented) + UNDERLINE = "underline" +} + +// Warning: (ae-missing-release-tag) "TypesRegistry" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class TypesRegistry implements IRegistry { + constructor(executor: Executor); + // (undocumented) + get(id: string): ExpressionType | null; + // (undocumented) + register(typeDefinition: AnyExpressionTypeDefinition | (() => AnyExpressionTypeDefinition)): void; + // (undocumented) + toArray(): ExpressionType[]; + // (undocumented) + toJS(): Record; +} + +// Warning: (ae-missing-release-tag) "TypeString" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type TypeString = KnownTypeToString>; + +// Warning: (ae-missing-release-tag) "TypeToString" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type TypeToString = KnownTypeToString | UnmappedTypeStrings; + +// Warning: (ae-missing-release-tag) "UnmappedTypeStrings" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type UnmappedTypeStrings = 'date' | 'filter'; + + +// (No @packageDocumentation comment for this package) + +``` diff --git a/src/plugins/expressions/server/mocks.ts b/src/plugins/expressions/server/mocks.ts index 0512789d76ab0..0beb4750c0d10 100644 --- a/src/plugins/expressions/server/mocks.ts +++ b/src/plugins/expressions/server/mocks.ts @@ -46,11 +46,8 @@ const createStartContract = (): Start => { execute: jest.fn(), fork: jest.fn(), getFunction: jest.fn(), - getFunctions: jest.fn(), getRenderer: jest.fn(), - getRenderers: jest.fn(), getType: jest.fn(), - getTypes: jest.fn(), run: jest.fn(), }; diff --git a/src/plugins/expressions/server/server.api.md b/src/plugins/expressions/server/server.api.md new file mode 100644 index 0000000000000..d8872ee416017 --- /dev/null +++ b/src/plugins/expressions/server/server.api.md @@ -0,0 +1,968 @@ +## API Report File for "kibana" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { CoreSetup } from 'src/core/server'; +import { CoreStart } from 'src/core/server'; +import { Ensure } from '@kbn/utility-types'; +import { EventEmitter } from 'events'; +import { Observable } from 'rxjs'; +import { Plugin as Plugin_2 } from 'src/core/server'; +import { PluginInitializerContext } from 'src/core/server'; +import { UnwrapPromiseOrReturn } from '@kbn/utility-types'; + +// Warning: (ae-missing-release-tag) "AnyExpressionFunctionDefinition" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type AnyExpressionFunctionDefinition = ExpressionFunctionDefinition, any>; + +// Warning: (ae-missing-release-tag) "AnyExpressionTypeDefinition" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type AnyExpressionTypeDefinition = ExpressionTypeDefinition; + +// Warning: (ae-forgotten-export) The symbol "SingleArgumentType" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "MultipleArgumentType" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "UnresolvedSingleArgumentType" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "UnresolvedMultipleArgumentType" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "ArgumentType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type ArgumentType = SingleArgumentType | MultipleArgumentType | UnresolvedSingleArgumentType | UnresolvedMultipleArgumentType; + +// Warning: (ae-missing-release-tag) "buildExpression" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function buildExpression(initialState?: ExpressionAstFunctionBuilder[] | ExpressionAstExpression | string): ExpressionAstExpressionBuilder; + +// Warning: (ae-forgotten-export) The symbol "InferFunctionDefinition" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "FunctionArgs" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "buildExpressionFunction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function buildExpressionFunction(fnName: InferFunctionDefinition['name'], +initialArgs: { + [K in keyof FunctionArgs]: FunctionArgs[K] | ExpressionAstExpressionBuilder | ExpressionAstExpressionBuilder[]; +}): ExpressionAstFunctionBuilder; + +// Warning: (ae-missing-release-tag) "Datatable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface Datatable { + // (undocumented) + columns: DatatableColumn[]; + // (undocumented) + rows: DatatableRow[]; + // Warning: (ae-forgotten-export) The symbol "name" needs to be exported by the entry point index.d.ts + // + // (undocumented) + type: typeof name; +} + +// Warning: (ae-missing-release-tag) "DatatableColumn" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface DatatableColumn { + // (undocumented) + id: string; + // Warning: (ae-forgotten-export) The symbol "DatatableColumnMeta" needs to be exported by the entry point index.d.ts + // + // (undocumented) + meta: DatatableColumnMeta; + // (undocumented) + name: string; +} + +// Warning: (ae-missing-release-tag) "DatatableColumnType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type DatatableColumnType = 'string' | 'number' | 'boolean' | 'date' | 'null'; + +// Warning: (ae-missing-release-tag) "DatatableRow" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type DatatableRow = Record; + +// Warning: (ae-forgotten-export) The symbol "Adapters" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "DefaultInspectorAdapters" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "Execution" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class Execution = Record, Input = unknown, Output = unknown, InspectorAdapters extends Adapters = ExtraContext['inspectorAdapters'] extends object ? ExtraContext['inspectorAdapters'] : DefaultInspectorAdapters> { + constructor(params: ExecutionParams); + cancel(): void; + // (undocumented) + cast(value: any, toTypeNames?: string[]): any; + readonly context: ExecutionContext & ExtraContext; + // Warning: (ae-forgotten-export) The symbol "ExecutionContract" needs to be exported by the entry point index.d.ts + readonly contract: ExecutionContract; + // (undocumented) + readonly expression: string; + input: Input; + // (undocumented) + get inspectorAdapters(): InspectorAdapters; + // Warning: (ae-forgotten-export) The symbol "ExpressionExecOptions" needs to be exported by the entry point index.d.ts + // + // (undocumented) + interpret(ast: ExpressionAstNode, input: T, options?: ExpressionExecOptions): Promise; + // (undocumented) + invokeChain(chainArr: ExpressionAstFunction[], input: unknown): Promise; + // (undocumented) + invokeFunction(fn: ExpressionFunction, input: unknown, args: Record): Promise; + // (undocumented) + readonly params: ExecutionParams; + // (undocumented) + resolveArgs(fnDef: ExpressionFunction, input: unknown, argAsts: any): Promise; + // (undocumented) + get result(): Promise; + start(input?: Input): void; + readonly state: ExecutionContainer; +} + +// Warning: (ae-forgotten-export) The symbol "StateContainer" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "ExecutionPureTransitions" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "ExecutionContainer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExecutionContainer = StateContainer, ExecutionPureTransitions>; + +// Warning: (ae-missing-release-tag) "ExecutionContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface ExecutionContext { + abortSignal: AbortSignal; + getInitialInput: () => Input; + // Warning: (ae-forgotten-export) The symbol "SavedObjectAttributes" needs to be exported by the entry point index.d.ts + // Warning: (ae-forgotten-export) The symbol "SavedObject" needs to be exported by the entry point index.d.ts + getSavedObject?: (type: string, id: string) => Promise>; + inspectorAdapters: InspectorAdapters; + // Warning: (ae-forgotten-export) The symbol "ExecutionContextSearch" needs to be exported by the entry point index.d.ts + search?: ExecutionContextSearch; + types: Record; + variables: Record; +} + +// Warning: (ae-missing-release-tag) "ExecutionParams" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ExecutionParams = Record> { + // (undocumented) + ast?: ExpressionAstExpression; + // (undocumented) + context?: ExtraContext; + debug?: boolean; + // (undocumented) + executor: Executor; + // (undocumented) + expression?: string; +} + +// Warning: (ae-missing-release-tag) "ExecutionState" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ExecutionState extends ExecutorState { + // (undocumented) + ast: ExpressionAstExpression; + error?: Error; + result?: Output; + state: 'not-started' | 'pending' | 'result' | 'error'; +} + +// Warning: (ae-missing-release-tag) "Executor" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class Executor = Record> { + constructor(state?: ExecutorState); + // (undocumented) + get context(): Record; + // (undocumented) + createExecution = Record, Input = unknown, Output = unknown>(ast: string | ExpressionAstExpression, context?: ExtraContext, { debug }?: ExpressionExecOptions): Execution; + // (undocumented) + static createWithDefaults = Record>(state?: ExecutorState): Executor; + // (undocumented) + extendContext(extraContext: Record): void; + // (undocumented) + fork(): Executor; + // @deprecated (undocumented) + readonly functions: FunctionsRegistry; + // (undocumented) + getFunction(name: string): ExpressionFunction | undefined; + // (undocumented) + getFunctions(): Record; + // (undocumented) + getType(name: string): ExpressionType | undefined; + // (undocumented) + getTypes(): Record; + // (undocumented) + registerFunction(functionDefinition: AnyExpressionFunctionDefinition | (() => AnyExpressionFunctionDefinition)): void; + // (undocumented) + registerType(typeDefinition: AnyExpressionTypeDefinition | (() => AnyExpressionTypeDefinition)): void; + run = Record>(ast: string | ExpressionAstExpression, input: Input, context?: ExtraContext): Promise; + // (undocumented) + readonly state: ExecutorContainer; + // @deprecated (undocumented) + readonly types: TypesRegistry; +} + +// Warning: (ae-forgotten-export) The symbol "ExecutorPureTransitions" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "ExecutorPureSelectors" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "ExecutorContainer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExecutorContainer = Record> = StateContainer, ExecutorPureTransitions, ExecutorPureSelectors>; + +// Warning: (ae-missing-release-tag) "ExecutorState" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ExecutorState = Record> { + // (undocumented) + context: Context; + // (undocumented) + functions: Record; + // (undocumented) + types: Record; +} + +// Warning: (ae-missing-release-tag) "ExpressionAstArgument" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExpressionAstArgument = string | boolean | number | ExpressionAstExpression; + +// Warning: (ae-missing-release-tag) "ExpressionAstExpression" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ExpressionAstExpression { + // (undocumented) + chain: ExpressionAstFunction[]; + // (undocumented) + type: 'expression'; +} + +// Warning: (ae-missing-release-tag) "ExpressionAstExpressionBuilder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ExpressionAstExpressionBuilder { + findFunction: (fnName: InferFunctionDefinition['name']) => Array> | []; + functions: ExpressionAstFunctionBuilder[]; + toAst: () => ExpressionAstExpression; + toString: () => string; + type: 'expression_builder'; +} + +// Warning: (ae-missing-release-tag) "ExpressionAstFunction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ExpressionAstFunction { + // (undocumented) + arguments: Record; + // Warning: (ae-forgotten-export) The symbol "ExpressionAstFunctionDebug" needs to be exported by the entry point index.d.ts + debug?: ExpressionAstFunctionDebug; + // (undocumented) + function: string; + // (undocumented) + type: 'function'; +} + +// Warning: (ae-missing-release-tag) "ExpressionAstFunctionBuilder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ExpressionAstFunctionBuilder { + // Warning: (ae-forgotten-export) The symbol "FunctionArgName" needs to be exported by the entry point index.d.ts + addArgument: >(name: A, value: FunctionArgs[A] | ExpressionAstExpressionBuilder) => this; + // Warning: (ae-forgotten-export) The symbol "FunctionBuilderArguments" needs to be exported by the entry point index.d.ts + arguments: FunctionBuilderArguments; + getArgument: >(name: A) => Array[A] | ExpressionAstExpressionBuilder> | undefined; + name: InferFunctionDefinition['name']; + // Warning: (ae-forgotten-export) The symbol "OptionalKeys" needs to be exported by the entry point index.d.ts + removeArgument: >>(name: A) => this; + replaceArgument: >(name: A, value: Array[A] | ExpressionAstExpressionBuilder>) => this; + toAst: () => ExpressionAstFunction; + toString: () => string; + type: 'expression_function_builder'; +} + +// Warning: (ae-missing-release-tag) "ExpressionAstNode" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExpressionAstNode = ExpressionAstExpression | ExpressionAstFunction | ExpressionAstArgument; + +// Warning: (ae-missing-release-tag) "ExpressionFunction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class ExpressionFunction { + constructor(functionDefinition: AnyExpressionFunctionDefinition); + // (undocumented) + accepts: (type: string) => boolean; + aliases: string[]; + args: Record; + fn: (input: ExpressionValue, params: Record, handlers: object) => ExpressionValue; + help: string; + inputTypes: string[] | undefined; + name: string; + type: string; +} + +// Warning: (ae-missing-release-tag) "ExpressionFunctionDefinition" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface ExpressionFunctionDefinition, Output, Context extends ExecutionContext = ExecutionContext> { + aliases?: string[]; + args: { + [key in keyof Arguments]: ArgumentType; + }; + // @deprecated (undocumented) + context?: { + types: AnyExpressionFunctionDefinition['inputTypes']; + }; + fn(input: Input, args: Arguments, context: Context): Output; + help: string; + inputTypes?: Array>; + name: Name; + type?: TypeToString>; +} + +// @public +export interface ExpressionFunctionDefinitions { + // Warning: (ae-forgotten-export) The symbol "ExpressionFunctionClog" needs to be exported by the entry point index.d.ts + // + // (undocumented) + clog: ExpressionFunctionClog; + // Warning: (ae-forgotten-export) The symbol "ExpressionFunctionFont" needs to be exported by the entry point index.d.ts + // + // (undocumented) + font: ExpressionFunctionFont; + // (undocumented) + kibana: ExpressionFunctionKibana; + // Warning: (ae-forgotten-export) The symbol "ExpressionFunctionKibanaContext" needs to be exported by the entry point index.d.ts + // + // (undocumented) + kibana_context: ExpressionFunctionKibanaContext; + // Warning: (ae-forgotten-export) The symbol "ExpressionFunctionTheme" needs to be exported by the entry point index.d.ts + // + // (undocumented) + theme: ExpressionFunctionTheme; + // Warning: (ae-forgotten-export) The symbol "ExpressionFunctionVar" needs to be exported by the entry point index.d.ts + // + // (undocumented) + var: ExpressionFunctionVar; + // Warning: (ae-forgotten-export) The symbol "ExpressionFunctionVarSet" needs to be exported by the entry point index.d.ts + // + // (undocumented) + var_set: ExpressionFunctionVarSet; +} + +// Warning: (ae-missing-release-tag) "ExpressionFunctionKibana" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExpressionFunctionKibana = ExpressionFunctionDefinition<'kibana', ExpressionValueSearchContext | null, object, ExpressionValueSearchContext>; + +// Warning: (ae-missing-release-tag) "ExpressionFunctionParameter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class ExpressionFunctionParameter { + constructor(name: string, arg: ArgumentType); + // (undocumented) + accepts(type: string): boolean; + // (undocumented) + aliases: string[]; + // (undocumented) + default: any; + // (undocumented) + help: string; + // (undocumented) + multi: boolean; + // (undocumented) + name: string; + // (undocumented) + options: any[]; + // (undocumented) + required: boolean; + // (undocumented) + resolve: boolean; + // (undocumented) + types: string[]; +} + +// Warning: (ae-missing-release-tag) "ExpressionImage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ExpressionImage { + // (undocumented) + dataurl: string; + // (undocumented) + mode: string; + // (undocumented) + type: 'image'; +} + +// Warning: (ae-missing-release-tag) "ExpressionRenderDefinition" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ExpressionRenderDefinition { + displayName?: string; + help?: string; + name: string; + render: (domNode: HTMLElement, config: Config, handlers: IInterpreterRenderHandlers) => void | Promise; + reuseDomNode: boolean; + validate?: () => undefined | Error; +} + +// Warning: (ae-missing-release-tag) "ExpressionRenderer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class ExpressionRenderer { + constructor(config: ExpressionRenderDefinition); + // (undocumented) + readonly displayName: string; + // (undocumented) + readonly help: string; + // (undocumented) + readonly name: string; + // (undocumented) + readonly render: ExpressionRenderDefinition['render']; + // (undocumented) + readonly reuseDomNode: boolean; + // (undocumented) + readonly validate: () => void | Error; +} + +// Warning: (ae-missing-release-tag) "ExpressionRendererRegistry" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class ExpressionRendererRegistry implements IRegistry { + // (undocumented) + get(id: string): ExpressionRenderer | null; + // Warning: (ae-forgotten-export) The symbol "AnyExpressionRenderDefinition" needs to be exported by the entry point index.d.ts + // + // (undocumented) + register(definition: AnyExpressionRenderDefinition | (() => AnyExpressionRenderDefinition)): void; + // (undocumented) + toArray(): ExpressionRenderer[]; + // (undocumented) + toJS(): Record; +} + +// Warning: (ae-missing-release-tag) "ExpressionsServerPlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +class ExpressionsServerPlugin implements Plugin_2 { + constructor(initializerContext: PluginInitializerContext); + // Warning: (ae-forgotten-export) The symbol "ExpressionsService" needs to be exported by the entry point index.d.ts + // + // (undocumented) + readonly expressions: ExpressionsService; + // (undocumented) + setup(core: CoreSetup): ExpressionsServerSetup; + // (undocumented) + start(core: CoreStart): ExpressionsServerStart; + // (undocumented) + stop(): void; +} + +export { ExpressionsServerPlugin } + +export { ExpressionsServerPlugin as Plugin } + +// Warning: (ae-forgotten-export) The symbol "ExpressionsServiceSetup" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "ExpressionsServerSetup" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExpressionsServerSetup = ExpressionsServiceSetup; + +// Warning: (ae-forgotten-export) The symbol "ExpressionsServiceStart" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "ExpressionsServerStart" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExpressionsServerStart = ExpressionsServiceStart; + +// Warning: (ae-missing-release-tag) "ExpressionType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class ExpressionType { + constructor(definition: AnyExpressionTypeDefinition); + // (undocumented) + castsFrom: (value: ExpressionValue) => boolean; + // (undocumented) + castsTo: (value: ExpressionValue) => boolean; + // (undocumented) + create: unknown; + // (undocumented) + deserialize?: (serialized: any) => ExpressionValue; + // (undocumented) + from: (value: ExpressionValue, types: Record) => any; + // (undocumented) + getFromFn: (typeName: string) => undefined | ExpressionValueConverter; + // (undocumented) + getToFn: (typeName: string) => undefined | ExpressionValueConverter; + help: string; + // (undocumented) + name: string; + serialize?: (value: ExpressionValue) => any; + // (undocumented) + to: (value: ExpressionValue, toTypeName: string, types: Record) => any; + validate: (type: any) => void | Error; +} + +// Warning: (ae-missing-release-tag) "ExpressionTypeDefinition" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface ExpressionTypeDefinition { + // (undocumented) + deserialize?: (type: SerializedType) => Value; + // (undocumented) + from?: { + [type: string]: ExpressionValueConverter; + }; + // (undocumented) + help?: string; + // (undocumented) + name: Name; + // (undocumented) + serialize?: (type: Value) => SerializedType; + // (undocumented) + to?: { + [type: string]: ExpressionValueConverter; + }; + // (undocumented) + validate?: (type: any) => void | Error; +} + +// Warning: (ae-missing-release-tag) "ExpressionTypeStyle" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface ExpressionTypeStyle { + // (undocumented) + css: string; + // Warning: (ae-forgotten-export) The symbol "CSSStyle" needs to be exported by the entry point index.d.ts + // + // (undocumented) + spec: CSSStyle; + // (undocumented) + type: 'style'; +} + +// Warning: (ae-missing-release-tag) "ExpressionValue" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExpressionValue = ExpressionValueUnboxed | ExpressionValueBoxed; + +// Warning: (ae-missing-release-tag) "ExpressionValueBoxed" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExpressionValueBoxed = { + type: Type; +} & Value; + +// Warning: (ae-missing-release-tag) "ExpressionValueConverter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExpressionValueConverter = (input: I, availableTypes: Record) => O; + +// Warning: (ae-missing-release-tag) "ExpressionValueError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExpressionValueError = ExpressionValueBoxed<'error', { + error: { + message: string; + type?: string; + name?: string; + stack?: string; + original?: Error; + }; + info?: unknown; +}>; + +// Warning: (ae-missing-release-tag) "ExpressionValueFilter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type ExpressionValueFilter = ExpressionValueBoxed<'filter', { + filterType?: string; + value?: string; + column?: string; + and: ExpressionValueFilter[]; + to?: string; + from?: string; + query?: string | null; +}>; + +// Warning: (ae-missing-release-tag) "ExpressionValueNum" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExpressionValueNum = ExpressionValueBoxed<'num', { + value: number; +}>; + +// Warning: (ae-forgotten-export) The symbol "name" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "ExpressionValueRender" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +type ExpressionValueRender = ExpressionValueBoxed; + +export { ExpressionValueRender } + +export { ExpressionValueRender as Render } + +// Warning: (ae-missing-release-tag) "ExpressionValueSearchContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExpressionValueSearchContext = ExpressionValueBoxed<'kibana_context', ExecutionContextSearch>; + +// Warning: (ae-missing-release-tag) "ExpressionValueUnboxed" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ExpressionValueUnboxed = any; + +// Warning: (ae-missing-release-tag) "Font" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface Font { + // (undocumented) + label: FontLabel; + // (undocumented) + value: FontValue; +} + +// Warning: (ae-forgotten-export) The symbol "fonts" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "FontLabel" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type FontLabel = typeof fonts[number]['label']; + +// Warning: (ae-missing-release-tag) "FontStyle" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export enum FontStyle { + // (undocumented) + ITALIC = "italic", + // (undocumented) + NORMAL = "normal" +} + +// Warning: (ae-missing-release-tag) "FontValue" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type FontValue = typeof fonts[number]['value']; + +// Warning: (ae-missing-release-tag) "FontWeight" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export enum FontWeight { + // (undocumented) + BOLD = "bold", + // (undocumented) + BOLDER = "bolder", + // (undocumented) + EIGHT = "800", + // (undocumented) + FIVE = "500", + // (undocumented) + FOUR = "400", + // (undocumented) + LIGHTER = "lighter", + // (undocumented) + NINE = "900", + // (undocumented) + NORMAL = "normal", + // (undocumented) + ONE = "100", + // (undocumented) + SEVEN = "700", + // (undocumented) + SIX = "600", + // (undocumented) + THREE = "300", + // (undocumented) + TWO = "200" +} + +// Warning: (ae-missing-release-tag) "format" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function format(ast: T, type: T extends ExpressionAstExpression ? 'expression' : 'argument'): string; + +// Warning: (ae-missing-release-tag) "formatExpression" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function formatExpression(ast: ExpressionAstExpression): string; + +// Warning: (ae-missing-release-tag) "FunctionsRegistry" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class FunctionsRegistry implements IRegistry { + constructor(executor: Executor); + // (undocumented) + get(id: string): ExpressionFunction | null; + // (undocumented) + register(functionDefinition: AnyExpressionFunctionDefinition | (() => AnyExpressionFunctionDefinition)): void; + // (undocumented) + toArray(): ExpressionFunction[]; + // (undocumented) + toJS(): Record; +} + +// Warning: (ae-missing-release-tag) "IInterpreterRenderHandlers" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface IInterpreterRenderHandlers { + done: () => void; + // (undocumented) + event: (event: any) => void; + // (undocumented) + onDestroy: (fn: () => void) => void; + // (undocumented) + reload: () => void; + // (undocumented) + update: (params: any) => void; +} + +// Warning: (ae-missing-release-tag) "InterpreterErrorType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public @deprecated (undocumented) +export type InterpreterErrorType = ExpressionValueError; + +// Warning: (ae-missing-release-tag) "IRegistry" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface IRegistry { + // (undocumented) + get(id: string): T | null; + // (undocumented) + toArray(): T[]; + // (undocumented) + toJS(): Record; +} + +// Warning: (ae-missing-release-tag) "isExpressionAstBuilder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function isExpressionAstBuilder(val: any): val is ExpressionAstExpressionBuilder; + +// Warning: (ae-missing-release-tag) "KIBANA_CONTEXT_NAME" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type KIBANA_CONTEXT_NAME = 'kibana_context'; + +// Warning: (ae-missing-release-tag) "KibanaContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type KibanaContext = ExpressionValueSearchContext; + +// Warning: (ae-missing-release-tag) "KibanaDatatable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface KibanaDatatable { + // (undocumented) + columns: KibanaDatatableColumn[]; + // (undocumented) + rows: KibanaDatatableRow[]; + // Warning: (ae-forgotten-export) The symbol "name" needs to be exported by the entry point index.d.ts + // + // (undocumented) + type: typeof name_3; +} + +// Warning: (ae-missing-release-tag) "KibanaDatatableColumn" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface KibanaDatatableColumn { + // (undocumented) + formatHint?: SerializedFieldFormat; + // (undocumented) + id: string; + // (undocumented) + meta?: KibanaDatatableColumnMeta; + // (undocumented) + name: string; +} + +// Warning: (ae-missing-release-tag) "KibanaDatatableColumnMeta" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface KibanaDatatableColumnMeta { + // (undocumented) + aggConfigParams?: Record; + // (undocumented) + indexPatternId?: string; + // (undocumented) + type: string; +} + +// Warning: (ae-missing-release-tag) "KibanaDatatableRow" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface KibanaDatatableRow { + // (undocumented) + [key: string]: unknown; +} + +// Warning: (ae-missing-release-tag) "KnownTypeToString" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type KnownTypeToString = T extends string ? 'string' : T extends boolean ? 'boolean' : T extends number ? 'number' : T extends null ? 'null' : T extends { + type: string; +} ? T['type'] : never; + +// Warning: (ae-missing-release-tag) "Overflow" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export enum Overflow { + // (undocumented) + AUTO = "auto", + // (undocumented) + HIDDEN = "hidden", + // (undocumented) + SCROLL = "scroll", + // (undocumented) + VISIBLE = "visible" +} + +// Warning: (ae-missing-release-tag) "parse" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function parse(expression: E, startRule: S): S extends 'expression' ? ExpressionAstExpression : ExpressionAstArgument; + +// Warning: (ae-missing-release-tag) "parseExpression" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function parseExpression(expression: string): ExpressionAstExpression; + +// Warning: (ae-missing-release-tag) "plugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function plugin(initializerContext: PluginInitializerContext): ExpressionsServerPlugin; + +// Warning: (ae-missing-release-tag) "PointSeries" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type PointSeries = ExpressionValueBoxed<'pointseries', { + columns: PointSeriesColumns; + rows: PointSeriesRow[]; +}>; + +// Warning: (ae-missing-release-tag) "PointSeriesColumn" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface PointSeriesColumn { + // (undocumented) + expression: string; + // (undocumented) + role: 'measure' | 'dimension'; + // (undocumented) + type: 'number' | 'string'; +} + +// Warning: (ae-missing-release-tag) "PointSeriesColumnName" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type PointSeriesColumnName = 'x' | 'y' | 'color' | 'size' | 'text'; + +// Warning: (ae-missing-release-tag) "PointSeriesColumns" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type PointSeriesColumns = Record | {}; + +// Warning: (ae-missing-release-tag) "PointSeriesRow" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type PointSeriesRow = Record; + +// Warning: (ae-missing-release-tag) "Range" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface Range { + // (undocumented) + from: number; + // (undocumented) + to: number; + // Warning: (ae-forgotten-export) The symbol "name" needs to be exported by the entry point index.d.ts + // + // (undocumented) + type: typeof name_4; +} + +// Warning: (ae-missing-release-tag) "SerializedDatatable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface SerializedDatatable extends Datatable { + // (undocumented) + rows: string[][]; +} + +// Warning: (ae-missing-release-tag) "SerializedFieldFormat" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface SerializedFieldFormat> { + // (undocumented) + id?: string; + // (undocumented) + params?: TParams; +} + +// Warning: (ae-missing-release-tag) "Style" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type Style = ExpressionTypeStyle; + +// Warning: (ae-missing-release-tag) "TextAlignment" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export enum TextAlignment { + // (undocumented) + CENTER = "center", + // (undocumented) + JUSTIFY = "justify", + // (undocumented) + LEFT = "left", + // (undocumented) + RIGHT = "right" +} + +// Warning: (ae-missing-release-tag) "TextDecoration" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export enum TextDecoration { + // (undocumented) + NONE = "none", + // (undocumented) + UNDERLINE = "underline" +} + +// Warning: (ae-missing-release-tag) "TypesRegistry" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class TypesRegistry implements IRegistry { + constructor(executor: Executor); + // (undocumented) + get(id: string): ExpressionType | null; + // (undocumented) + register(typeDefinition: AnyExpressionTypeDefinition | (() => AnyExpressionTypeDefinition)): void; + // (undocumented) + toArray(): ExpressionType[]; + // (undocumented) + toJS(): Record; +} + +// Warning: (ae-missing-release-tag) "TypeString" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type TypeString = KnownTypeToString>; + +// Warning: (ae-missing-release-tag) "TypeToString" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type TypeToString = KnownTypeToString | UnmappedTypeStrings; + +// Warning: (ae-missing-release-tag) "UnmappedTypeStrings" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type UnmappedTypeStrings = 'date' | 'filter'; + + +// (No @packageDocumentation comment for this package) + +``` diff --git a/src/plugins/home/public/application/components/app_navigation_handler.ts b/src/plugins/home/public/application/components/app_navigation_handler.ts index 61d85c033b544..b6230bc9f1e38 100644 --- a/src/plugins/home/public/application/components/app_navigation_handler.ts +++ b/src/plugins/home/public/application/components/app_navigation_handler.ts @@ -24,12 +24,7 @@ export const createAppNavigationHandler = (targetUrl: string) => (event: MouseEv if (event.altKey || event.metaKey || event.ctrlKey) { return; } - if (targetUrl.startsWith('/app/')) { - const [, appId, path] = /\/app\/(.*?)((\/|\?|#|$).*)/.exec(targetUrl) || []; - if (!appId) { - return; - } - event.preventDefault(); - getServices().application.navigateToApp(appId, { path }); - } + const { application, addBasePath } = getServices(); + event.preventDefault(); + application.navigateToUrl(addBasePath(targetUrl)); }; diff --git a/src/plugins/home/public/application/components/sample_data/index.tsx b/src/plugins/home/public/application/components/sample_data/index.tsx index 2a51b48b08469..5f15994acc1cb 100644 --- a/src/plugins/home/public/application/components/sample_data/index.tsx +++ b/src/plugins/home/public/application/components/sample_data/index.tsx @@ -30,8 +30,8 @@ import { EuiButton, EuiButtonEmpty, } from '@elastic/eui'; - import { FormattedMessage } from '@kbn/i18n/react'; +import { getServices } from '../../kibana_services'; interface Props { urlBasePath: string; @@ -40,22 +40,29 @@ interface Props { } export function SampleDataCard({ urlBasePath, onDecline, onConfirm }: Props) { + const IS_DARK_THEME = getServices().uiSettings.get('theme:darkMode'); + const cardGraphicFile = !IS_DARK_THEME + ? 'illustration_integrations_lightmode.png' + : 'illustration_integrations_darkmode.png'; + const cardGraphicURL = `${urlBasePath}/plugins/home/assets/common/${cardGraphicFile}`; + return ( } + title={ + + } description={ } footer={

); diff --git a/src/plugins/kibana_react/tsconfig.json b/src/plugins/kibana_react/tsconfig.json new file mode 100644 index 0000000000000..52899f868dbfb --- /dev/null +++ b/src/plugins/kibana_react/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "composite": true, + "outDir": "./target/types", + "emitDeclarationOnly": true, + "declaration": true, + "declarationMap": true + }, + "include": [ + "public/**/*", + "../../../typings/**/*" + ], + "references": [ + { "path": "../kibana_utils/tsconfig.json" } + ] +} diff --git a/src/plugins/kibana_usage_collection/server/collectors/ui_metric/schema.ts b/src/plugins/kibana_usage_collection/server/collectors/ui_metric/schema.ts new file mode 100644 index 0000000000000..53bb1f9b93949 --- /dev/null +++ b/src/plugins/kibana_usage_collection/server/collectors/ui_metric/schema.ts @@ -0,0 +1,103 @@ +/* + * 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 { MakeSchemaFrom } from 'src/plugins/usage_collection/server'; +import { UIMetricUsage } from './telemetry_ui_metric_collector'; + +const commonSchema: MakeSchemaFrom[string] = { + type: 'array', + items: { + key: { type: 'keyword' }, + value: { type: 'long' }, + }, +}; + +// TODO: Find a way to retrieve it automatically +// plugin `data` registers all UI Metric for each appId where searches are performed (keys below are copy-pasted from application_usage) +const uiMetricFromDataPluginSchema: MakeSchemaFrom = { + // OSS + dashboards: commonSchema, + dev_tools: commonSchema, + discover: commonSchema, + home: commonSchema, + kibana: commonSchema, // It's a forward app so we'll likely never report it + management: commonSchema, + short_url_redirect: commonSchema, // It's a forward app so we'll likely never report it + timelion: commonSchema, + visualize: commonSchema, + + // X-Pack + apm: commonSchema, + csm: commonSchema, + canvas: commonSchema, + dashboard_mode: commonSchema, // It's a forward app so we'll likely never report it + enterpriseSearch: commonSchema, + appSearch: commonSchema, + workplaceSearch: commonSchema, + graph: commonSchema, + logs: commonSchema, + metrics: commonSchema, + infra: commonSchema, // It's a forward app so we'll likely never report it + ingestManager: commonSchema, + lens: commonSchema, + maps: commonSchema, + ml: commonSchema, + monitoring: commonSchema, + 'observability-overview': commonSchema, + security_account: commonSchema, + security_access_agreement: commonSchema, + security_capture_url: commonSchema, // It's a forward app so we'll likely never report it + security_logged_out: commonSchema, + security_login: commonSchema, + security_logout: commonSchema, + security_overwritten_session: commonSchema, + securitySolution: commonSchema, + 'securitySolution:overview': commonSchema, + 'securitySolution:detections': commonSchema, + 'securitySolution:hosts': commonSchema, + 'securitySolution:network': commonSchema, + 'securitySolution:timelines': commonSchema, + 'securitySolution:case': commonSchema, + 'securitySolution:administration': commonSchema, + siem: commonSchema, + space_selector: commonSchema, + uptime: commonSchema, +}; + +// TODO: Find a way to retrieve it automatically +// Searching `reportUiStats` across Kibana +export const uiMetricSchema: MakeSchemaFrom = { + console: commonSchema, + DashboardPanelVersionInUrl: commonSchema, + Kibana_home: commonSchema, // eslint-disable-line @typescript-eslint/naming-convention + visualize: commonSchema, + canvas: commonSchema, + cross_cluster_replication: commonSchema, + index_lifecycle_management: commonSchema, + index_management: commonSchema, + ingest_pipelines: commonSchema, + apm: commonSchema, + infra_logs: commonSchema, + infra_metrics: commonSchema, + stack_monitoring: commonSchema, + remote_clusters: commonSchema, + rollup_jobs: commonSchema, + securitySolution: commonSchema, + snapshot_restore: commonSchema, + ...uiMetricFromDataPluginSchema, +}; diff --git a/src/plugins/kibana_usage_collection/server/collectors/ui_metric/telemetry_ui_metric_collector.ts b/src/plugins/kibana_usage_collection/server/collectors/ui_metric/telemetry_ui_metric_collector.ts index 9c02a9cbf3204..4cae892d30b5d 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/ui_metric/telemetry_ui_metric_collector.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/ui_metric/telemetry_ui_metric_collector.ts @@ -23,11 +23,19 @@ import { SavedObjectsServiceSetup, } from 'kibana/server'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; +import { uiMetricSchema } from './schema'; interface UIMetricsSavedObjects extends SavedObjectAttributes { count: number; } +interface UIMetricElement { + key: string; + value: number; +} + +export type UIMetricUsage = Record; + export function registerUiMetricUsageCollector( usageCollection: UsageCollectionSetup, registerType: SavedObjectsServiceSetup['registerType'], @@ -46,8 +54,9 @@ export function registerUiMetricUsageCollector( }, }); - const collector = usageCollection.makeUsageCollector({ + const collector = usageCollection.makeUsageCollector({ type: 'ui_metric', + schema: uiMetricSchema, fetch: async () => { const savedObjectsClient = getSavedObjectsClient(); if (typeof savedObjectsClient === 'undefined') { @@ -73,7 +82,7 @@ export function registerUiMetricUsageCollector( ...accum, [appName]: [...(accum[appName] || []), pair], }; - }, {} as Record>); + }, {} as UIMetricUsage); return uiMetricsByAppName; }, diff --git a/src/plugins/kibana_utils/kibana.json b/src/plugins/kibana_utils/kibana.json index 7e2127c27548e..3e20b68bca431 100644 --- a/src/plugins/kibana_utils/kibana.json +++ b/src/plugins/kibana_utils/kibana.json @@ -2,6 +2,7 @@ "id": "kibanaUtils", "version": "kibana", "ui": true, + "server": false, "extraPublicDirs": [ "common", "demos/state_containers/todomvc", diff --git a/src/plugins/kibana_utils/tsconfig.json b/src/plugins/kibana_utils/tsconfig.json new file mode 100644 index 0000000000000..bd65e06c78608 --- /dev/null +++ b/src/plugins/kibana_utils/tsconfig.json @@ -0,0 +1,22 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "composite": true, + "outDir": "./target/types", + "emitDeclarationOnly": true, + "declaration": true, + "declarationMap": true + }, + "include": [ + "common/**/*", + "demos/**/*", + "public/**/*", + "server/**/*", + "index.ts", + "../../../typings/**/*" + ], + "references": [ + { "path": "../../test_utils/tsconfig.json" }, + { "path": "../../core/tsconfig.json" } + ] +} diff --git a/src/plugins/management/public/components/management_app_wrapper/management_app_wrapper.tsx b/src/plugins/management/public/components/management_app_wrapper/management_app_wrapper.tsx index 02da2a46540c2..bcfb86c331084 100644 --- a/src/plugins/management/public/components/management_app_wrapper/management_app_wrapper.tsx +++ b/src/plugins/management/public/components/management_app_wrapper/management_app_wrapper.tsx @@ -32,7 +32,7 @@ interface ManagementSectionWrapperProps { export class ManagementAppWrapper extends Component { private unmount?: Unmount; - private mountElementRef = createRef(); + private mountElementRef = createRef(); componentDidMount() { const { setBreadcrumbs, app, onAppMounted, history } = this.props; @@ -64,6 +64,6 @@ export class ManagementAppWrapper extends Component; + return } > - + , this.el diff --git a/src/plugins/vis_type_markdown/public/markdown_vis_controller.test.tsx b/src/plugins/vis_type_markdown/public/markdown_vis_controller.test.tsx index 36850fc820ded..7bc8cdbd14170 100644 --- a/src/plugins/vis_type_markdown/public/markdown_vis_controller.test.tsx +++ b/src/plugins/vis_type_markdown/public/markdown_vis_controller.test.tsx @@ -18,12 +18,9 @@ */ import React from 'react'; -import { wait } from '@testing-library/dom'; -import { render, cleanup } from '@testing-library/react/pure'; +import { wait, render } from '@testing-library/react'; import MarkdownVisComponent from './markdown_vis_controller'; -afterEach(cleanup); - describe('markdown vis controller', () => { it('should set html from markdown params', async () => { const vis = { diff --git a/src/plugins/vis_type_tagcloud/public/tag_cloud_vis_renderer.tsx b/src/plugins/vis_type_tagcloud/public/tag_cloud_vis_renderer.tsx index d37aa5f6fe409..b433ed9cbed21 100644 --- a/src/plugins/vis_type_tagcloud/public/tag_cloud_vis_renderer.tsx +++ b/src/plugins/vis_type_tagcloud/public/tag_cloud_vis_renderer.tsx @@ -25,7 +25,6 @@ import { ExpressionRenderDefinition } from '../../expressions/common/expression_ import { TagCloudVisDependencies } from './plugin'; import { TagCloudVisRenderValue } from './tag_cloud_fn'; -// @ts-ignore const TagCloudChart = lazy(() => import('./components/tag_cloud_chart')); export const getTagCloudVisRenderer: ( diff --git a/src/plugins/vis_type_timelion/public/__snapshots__/to_ast.test.ts.snap b/src/plugins/vis_type_timelion/public/__snapshots__/to_ast.test.ts.snap new file mode 100644 index 0000000000000..9e32a6c4ae17c --- /dev/null +++ b/src/plugins/vis_type_timelion/public/__snapshots__/to_ast.test.ts.snap @@ -0,0 +1,21 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`timelion vis toExpressionAst function should match basic snapshot 1`] = ` +Object { + "chain": Array [ + Object { + "arguments": Object { + "expression": Array [ + ".es(*)", + ], + "interval": Array [ + "auto", + ], + }, + "function": "timelion_vis", + "type": "function", + }, + ], + "type": "expression", +} +`; diff --git a/src/plugins/vis_type_timelion/public/_timelion_editor.scss b/src/plugins/vis_type_timelion/public/_timelion_editor.scss deleted file mode 100644 index a9331930a86ff..0000000000000 --- a/src/plugins/vis_type_timelion/public/_timelion_editor.scss +++ /dev/null @@ -1,15 +0,0 @@ -.visEditor--timelion { - vis-options-react-wrapper, - .visEditorSidebar__options, - .visEditorSidebar__timelionOptions { - flex: 1 1 auto; - display: flex; - flex-direction: column; - } - - .visEditor__sidebar { - @include euiBreakpoint('xs', 's', 'm') { - width: 100%; - } - } -} diff --git a/src/plugins/vis_type_timelion/public/_timelion_vis.scss b/src/plugins/vis_type_timelion/public/_timelion_vis.scss deleted file mode 100644 index e7175bf3c0c2a..0000000000000 --- a/src/plugins/vis_type_timelion/public/_timelion_vis.scss +++ /dev/null @@ -1,12 +0,0 @@ -.timVis { - min-width: 100%; - display: flex; - flex-direction: column; - - .timChart { - min-width: 100%; - flex: 1; - display: flex; - flex-direction: column; - } -} diff --git a/src/plugins/vis_type_timelion/public/components/_index.scss b/src/plugins/vis_type_timelion/public/components/_index.scss deleted file mode 100644 index 707c9dafebe2b..0000000000000 --- a/src/plugins/vis_type_timelion/public/components/_index.scss +++ /dev/null @@ -1,2 +0,0 @@ -@import 'panel'; -@import 'timelion_expression_input'; diff --git a/src/plugins/vis_type_timelion/public/components/_panel.scss b/src/plugins/vis_type_timelion/public/components/_panel.scss deleted file mode 100644 index c4d591bc82cad..0000000000000 --- a/src/plugins/vis_type_timelion/public/components/_panel.scss +++ /dev/null @@ -1,60 +0,0 @@ -.timChart { - height: 100%; - width: 100%; - display: flex; - flex-direction: column; - - // Custom Jquery FLOT / schema selectors - // Cannot change at the moment - - .chart-top-title { - @include euiFontSizeXS; - flex: 0; - text-align: center; - font-weight: $euiFontWeightBold; - } - - .chart-canvas { - min-width: 100%; - flex: 1; - overflow: hidden; - } - - .legendLabel { - white-space: nowrap; - text-overflow: ellipsis; - overflow-x: hidden; - line-height: normal; - } - - .legendColorBox { - vertical-align: middle; - } - - .ngLegendValue { - color: $euiTextColor; - cursor: pointer; - - &:focus, - &:hover { - text-decoration: underline; - } - } - - .ngLegendValueNumber { - margin-left: $euiSizeXS; - margin-right: $euiSizeXS; - font-weight: $euiFontWeightBold; - } - - .flot-tick-label { - font-size: $euiFontSizeXS; - color: $euiColorDarkShade; - } -} - -.timChart__legendCaption { - color: $euiTextColor; - white-space: nowrap; - font-weight: $euiFontWeightBold; -} diff --git a/src/plugins/vis_type_timelion/public/components/_timelion_vis.scss b/src/plugins/vis_type_timelion/public/components/_timelion_vis.scss new file mode 100644 index 0000000000000..6729d400523cd --- /dev/null +++ b/src/plugins/vis_type_timelion/public/components/_timelion_vis.scss @@ -0,0 +1,68 @@ +.timChart { + height: 100%; + width: 100%; + display: flex; + flex-direction: column; + + // Custom Jquery FLOT / schema selectors + // Cannot change at the moment + + .chart-top-title { + @include euiFontSizeXS; + flex: 0; + text-align: center; + font-weight: $euiFontWeightBold; + } + + .chart-canvas { + min-width: 100%; + flex: 1; + overflow: hidden; + } + + .legendLabel { + white-space: nowrap; + text-overflow: ellipsis; + overflow-x: hidden; + line-height: normal; + } + + .legendColorBox { + vertical-align: middle; + } + + .ngLegendValue { + color: $euiTextColor; + cursor: pointer; + + &:focus, + &:hover { + text-decoration: underline; + } + } + + .ngLegendValueNumber { + margin-left: $euiSizeXS; + margin-right: $euiSizeXS; + font-weight: $euiFontWeightBold; + } + + .flot-tick-label { + font-size: $euiFontSizeXS; + color: $euiColorDarkShade; + } +} + +.timChart__legendCaption { + color: $euiTextColor; + white-space: nowrap; + font-weight: $euiFontWeightBold; +} + +.visEditor--timelion { + .visEditorSidebar__timelionOptions { + flex: 1 1 auto; + display: flex; + flex-direction: column; + } +} diff --git a/src/plugins/vis_type_timelion/public/components/chart.tsx b/src/plugins/vis_type_timelion/public/components/chart.tsx deleted file mode 100644 index 15a376d4e9638..0000000000000 --- a/src/plugins/vis_type_timelion/public/components/chart.tsx +++ /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 React from 'react'; - -import { Sheet } from '../helpers/timelion_request_handler'; -import { Panel } from './panel'; -import { ExprVisAPIEvents } from '../../../visualizations/public'; - -interface ChartComponentProp { - applyFilter: ExprVisAPIEvents['applyFilter']; - interval: string; - renderComplete(): void; - seriesList: Sheet; -} - -function ChartComponent(props: ChartComponentProp) { - if (!props.seriesList) { - return null; - } - - return ; -} - -export { ChartComponent }; diff --git a/src/plugins/vis_type_timelion/public/components/index.scss b/src/plugins/vis_type_timelion/public/components/index.scss new file mode 100644 index 0000000000000..a541c66e6e913 --- /dev/null +++ b/src/plugins/vis_type_timelion/public/components/index.scss @@ -0,0 +1,2 @@ +@import 'timelion_vis'; +@import 'timelion_expression_input'; diff --git a/src/plugins/vis_type_timelion/public/components/index.ts b/src/plugins/vis_type_timelion/public/components/index.ts index c70caab8dd70c..8d7d32a3ba262 100644 --- a/src/plugins/vis_type_timelion/public/components/index.ts +++ b/src/plugins/vis_type_timelion/public/components/index.ts @@ -19,4 +19,3 @@ export * from './timelion_expression_input'; export * from './timelion_interval'; -export * from './timelion_vis'; diff --git a/src/plugins/vis_type_timelion/public/components/panel.tsx b/src/plugins/vis_type_timelion/public/components/panel.tsx deleted file mode 100644 index 9c30a6b75d6db..0000000000000 --- a/src/plugins/vis_type_timelion/public/components/panel.tsx +++ /dev/null @@ -1,399 +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 React, { useState, useEffect, useMemo, useCallback } from 'react'; -import $ from 'jquery'; -import moment from 'moment-timezone'; -import { debounce, compact, get, each, cloneDeep, last, map } from 'lodash'; - -import { useKibana } from '../../../kibana_react/public'; -import '../flot'; -import { DEFAULT_TIME_FORMAT } from '../../common/lib'; - -import { - buildSeriesData, - buildOptions, - SERIES_ID_ATTR, - colors, - Axis, -} from '../helpers/panel_utils'; - -import { Series, Sheet } from '../helpers/timelion_request_handler'; -import { tickFormatters } from '../helpers/tick_formatters'; -import { generateTicksProvider } from '../helpers/tick_generator'; -import { TimelionVisDependencies } from '../plugin'; -import { ExprVisAPIEvents } from '../../../visualizations/public'; - -interface CrosshairPlot extends jquery.flot.plot { - setCrosshair: (pos: Position) => void; - clearCrosshair: () => void; -} - -interface PanelProps { - applyFilter: ExprVisAPIEvents['applyFilter']; - interval: string; - seriesList: Sheet; - renderComplete(): void; -} - -interface Position { - x: number; - x1: number; - y: number; - y1: number; - pageX: number; - pageY: number; -} - -interface Range { - to: number; - from: number; -} - -interface Ranges { - xaxis: Range; - yaxis: Range; -} - -const DEBOUNCE_DELAY = 50; -// ensure legend is the same height with or without a caption so legend items do not move around -const emptyCaption = '
'; - -function Panel({ interval, seriesList, renderComplete, applyFilter }: PanelProps) { - const kibana = useKibana(); - const [chart, setChart] = useState(() => cloneDeep(seriesList.list)); - const [canvasElem, setCanvasElem] = useState(); - const [chartElem, setChartElem] = useState(); - - const [originalColorMap, setOriginalColorMap] = useState(() => new Map()); - - const [highlightedSeries, setHighlightedSeries] = useState(null); - const [focusedSeries, setFocusedSeries] = useState(); - const [plot, setPlot] = useState(); - - // Used to toggle the series, and for displaying values on hover - const [legendValueNumbers, setLegendValueNumbers] = useState>(); - const [legendCaption, setLegendCaption] = useState>(); - - const canvasRef = useCallback((node: HTMLDivElement | null) => { - if (node !== null) { - setCanvasElem(node); - } - }, []); - - const elementRef = useCallback((node: HTMLDivElement | null) => { - if (node !== null) { - setChartElem(node); - } - }, []); - - useEffect( - () => () => { - if (chartElem) { - $(chartElem).off('plotselected').off('plothover').off('mouseleave'); - } - }, - [chartElem] - ); - - /* eslint-disable-next-line react-hooks/exhaustive-deps */ - const highlightSeries = useCallback( - debounce(({ currentTarget }: JQuery.TriggeredEvent) => { - const id = Number(currentTarget.getAttribute(SERIES_ID_ATTR)); - if (highlightedSeries === id) { - return; - } - - setHighlightedSeries(id); - setChart((chartState) => - chartState.map((series: Series, seriesIndex: number) => { - series.color = - seriesIndex === id - ? originalColorMap.get(series) // color it like it was - : 'rgba(128,128,128,0.1)'; // mark as grey - - return series; - }) - ); - }, DEBOUNCE_DELAY), - [originalColorMap, highlightedSeries] - ); - - const focusSeries = useCallback( - (event: JQuery.TriggeredEvent) => { - const id = Number(event.currentTarget.getAttribute(SERIES_ID_ATTR)); - setFocusedSeries(id); - highlightSeries(event); - }, - [highlightSeries] - ); - - const toggleSeries = useCallback(({ currentTarget }: JQuery.TriggeredEvent) => { - const id = Number(currentTarget.getAttribute(SERIES_ID_ATTR)); - - setChart((chartState) => - chartState.map((series: Series, seriesIndex: number) => { - if (seriesIndex === id) { - series._hide = !series._hide; - } - return series; - }) - ); - }, []); - - const updateCaption = useCallback( - (plotData: any) => { - if (canvasElem && get(plotData, '[0]._global.legend.showTime', true)) { - const caption = $(''); - caption.html(emptyCaption); - setLegendCaption(caption); - - const canvasNode = $(canvasElem); - canvasNode.find('div.legend table').append(caption); - setLegendValueNumbers(canvasNode.find('.ngLegendValueNumber')); - - const legend = $(canvasElem).find('.ngLegendValue'); - if (legend) { - legend.click(toggleSeries); - legend.focus(focusSeries); - legend.mouseover(highlightSeries); - } - - // legend has been re-created. Apply focus on legend element when previously set - if (focusedSeries || focusedSeries === 0) { - canvasNode.find('div.legend table .legendLabel>span').get(focusedSeries).focus(); - } - } - }, - [focusedSeries, canvasElem, toggleSeries, focusSeries, highlightSeries] - ); - - const updatePlot = useCallback( - (chartValue: Series[], grid?: boolean) => { - if (canvasElem && canvasElem.clientWidth > 0 && canvasElem.clientHeight > 0) { - const options = buildOptions( - interval, - kibana.services.timefilter, - kibana.services.uiSettings, - chartElem && chartElem.clientWidth, - grid - ); - const updatedSeries = buildSeriesData(chartValue, options); - - if (options.yaxes) { - options.yaxes.forEach((yaxis: Axis) => { - if (yaxis && yaxis.units) { - const formatters = tickFormatters(); - yaxis.tickFormatter = formatters[yaxis.units.type as keyof typeof formatters]; - const byteModes = ['bytes', 'bytes/s']; - if (byteModes.includes(yaxis.units.type)) { - yaxis.tickGenerator = generateTicksProvider(); - } - } - }); - } - - const newPlot = $.plot($(canvasElem), updatedSeries, options); - setPlot(newPlot); - renderComplete(); - - updateCaption(newPlot.getData()); - } - }, - [canvasElem, chartElem, renderComplete, kibana.services, interval, updateCaption] - ); - - useEffect(() => { - updatePlot(chart, seriesList.render && seriesList.render.grid); - }, [chart, updatePlot, seriesList.render]); - - useEffect(() => { - const colorsSet: Array<[Series, string]> = []; - const newChart = seriesList.list.map((series: Series, seriesIndex: number) => { - const newSeries = { ...series }; - if (!newSeries.color) { - const colorIndex = seriesIndex % colors.length; - newSeries.color = colors[colorIndex]; - } - colorsSet.push([newSeries, newSeries.color]); - return newSeries; - }); - setChart(newChart); - setOriginalColorMap(new Map(colorsSet)); - }, [seriesList.list]); - - const unhighlightSeries = useCallback(() => { - if (highlightedSeries === null) { - return; - } - - setHighlightedSeries(null); - setFocusedSeries(null); - - setChart((chartState) => - chartState.map((series: Series) => { - series.color = originalColorMap.get(series); // reset the colors - return series; - }) - ); - }, [originalColorMap, highlightedSeries]); - - // Shamelessly borrowed from the flotCrosshairs example - const setLegendNumbers = useCallback( - (pos: Position) => { - unhighlightSeries(); - - const axes = plot!.getAxes(); - if (pos.x < axes.xaxis.min! || pos.x > axes.xaxis.max!) { - return; - } - - const dataset = plot!.getData(); - if (legendCaption) { - legendCaption.text( - moment(pos.x).format(get(dataset, '[0]._global.legend.timeFormat', DEFAULT_TIME_FORMAT)) - ); - } - for (let i = 0; i < dataset.length; ++i) { - const series = dataset[i]; - const useNearestPoint = series.lines!.show && !series.lines!.steps; - const precision = get(series, '_meta.precision', 2); - - // We're setting this flag on top on the series object belonging to the flot library, so we're simply casting here. - if ((series as { _hide?: boolean })._hide) { - continue; - } - - const currentPoint = series.data.find((point: [number, number], index: number) => { - if (index + 1 === series.data.length) { - return true; - } - if (useNearestPoint) { - return pos.x - point[0] < series.data[index + 1][0] - pos.x; - } else { - return pos.x < series.data[index + 1][0]; - } - }); - - const y = currentPoint[1]; - - if (legendValueNumbers) { - if (y == null) { - legendValueNumbers.eq(i).empty(); - } else { - let label = y.toFixed(precision); - const formatter = ((series.yaxis as unknown) as Axis).tickFormatter; - if (formatter) { - label = formatter(Number(label), (series.yaxis as unknown) as Axis); - } - legendValueNumbers.eq(i).text(`(${label})`); - } - } - } - }, - [plot, legendValueNumbers, unhighlightSeries, legendCaption] - ); - - /* eslint-disable-next-line react-hooks/exhaustive-deps */ - const debouncedSetLegendNumbers = useCallback( - debounce(setLegendNumbers, DEBOUNCE_DELAY, { - maxWait: DEBOUNCE_DELAY, - leading: true, - trailing: false, - }), - [setLegendNumbers] - ); - - const clearLegendNumbers = useCallback(() => { - if (legendCaption) { - legendCaption.html(emptyCaption); - } - each(legendValueNumbers!, (num: Node) => { - $(num).empty(); - }); - }, [legendCaption, legendValueNumbers]); - - const plotHoverHandler = useCallback( - (event: JQuery.TriggeredEvent, pos: Position) => { - if (!plot) { - return; - } - (plot as CrosshairPlot).setCrosshair(pos); - debouncedSetLegendNumbers(pos); - }, - [plot, debouncedSetLegendNumbers] - ); - const mouseLeaveHandler = useCallback(() => { - if (!plot) { - return; - } - (plot as CrosshairPlot).clearCrosshair(); - clearLegendNumbers(); - }, [plot, clearLegendNumbers]); - - const plotSelectedHandler = useCallback( - (event: JQuery.TriggeredEvent, ranges: Ranges) => { - applyFilter({ - timeFieldName: '*', - filters: [ - { - range: { - '*': { - gte: ranges.xaxis.from, - lte: ranges.xaxis.to, - }, - }, - }, - ], - }); - }, - [applyFilter] - ); - - useEffect(() => { - if (chartElem) { - $(chartElem).off('plotselected').on('plotselected', plotSelectedHandler); - } - }, [chartElem, plotSelectedHandler]); - - useEffect(() => { - if (chartElem) { - $(chartElem).off('mouseleave').on('mouseleave', mouseLeaveHandler); - } - }, [chartElem, mouseLeaveHandler]); - - useEffect(() => { - if (chartElem) { - $(chartElem).off('plothover').on('plothover', plotHoverHandler); - } - }, [chartElem, plotHoverHandler]); - - const title: string = useMemo(() => last(compact(map(seriesList.list, '_title'))) || '', [ - seriesList.list, - ]); - - return ( -
; } } diff --git a/src/plugins/maps_legacy/config.ts b/src/plugins/maps_legacy/config.ts index 46d4a8fb6cb90..f49d56dedd45f 100644 --- a/src/plugins/maps_legacy/config.ts +++ b/src/plugins/maps_legacy/config.ts @@ -29,7 +29,7 @@ export const configSchema = schema.object({ manifestServiceUrl: schema.string({ defaultValue: '' }), emsFileApiUrl: schema.string({ defaultValue: 'https://vector.maps.elastic.co' }), emsTileApiUrl: schema.string({ defaultValue: 'https://tiles.maps.elastic.co' }), - emsLandingPageUrl: schema.string({ defaultValue: 'https://maps.elastic.co/v7.7' }), + emsLandingPageUrl: schema.string({ defaultValue: 'https://maps.elastic.co/v7.10' }), emsFontLibraryUrl: schema.string({ defaultValue: 'https://tiles.maps.elastic.co/fonts/{fontstack}/{range}.pbf', }), diff --git a/src/plugins/navigation/public/top_nav_menu/__snapshots__/top_nav_menu_item.test.tsx.snap b/src/plugins/navigation/public/top_nav_menu/__snapshots__/top_nav_menu_item.test.tsx.snap index 570699aa0c0e2..155377e5ea335 100644 --- a/src/plugins/navigation/public/top_nav_menu/__snapshots__/top_nav_menu_item.test.tsx.snap +++ b/src/plugins/navigation/public/top_nav_menu/__snapshots__/top_nav_menu_item.test.tsx.snap @@ -2,7 +2,6 @@ exports[`TopNavMenu Should render emphasized item which should be clickable 1`] = ` * > * { // TEMP fix to adjust spacing between EuiHeaderList__list items margin: 0 $euiSizeXS; diff --git a/src/plugins/navigation/public/top_nav_menu/top_nav_menu_item.tsx b/src/plugins/navigation/public/top_nav_menu/top_nav_menu_item.tsx index 96a205b737273..e503ebb839f48 100644 --- a/src/plugins/navigation/public/top_nav_menu/top_nav_menu_item.tsx +++ b/src/plugins/navigation/public/top_nav_menu/top_nav_menu_item.tsx @@ -48,7 +48,7 @@ export function TopNavMenuItem(props: TopNavMenuData) { }; const btn = props.emphasize ? ( - + {upperFirst(props.label || props.id!)} ) : ( diff --git a/src/plugins/region_map/public/region_map_type.js b/src/plugins/region_map/public/region_map_type.js index 105554f48f550..4cd30d32698ed 100644 --- a/src/plugins/region_map/public/region_map_type.js +++ b/src/plugins/region_map/public/region_map_type.js @@ -32,7 +32,6 @@ export function createRegionMapTypeDefinition(dependencies) { return { name: 'region_map', - isDeprecated: true, getDeprecationMessage, title: i18n.translate('regionMap.mapVis.regionMapTitle', { defaultMessage: 'Region Map' }), description: i18n.translate('regionMap.mapVis.regionMapDescription', { diff --git a/src/plugins/saved_objects/public/save_modal/__snapshots__/saved_object_save_modal.test.tsx.snap b/src/plugins/saved_objects/public/save_modal/__snapshots__/saved_object_save_modal.test.tsx.snap index eff5ab4f1e2c7..c923c5c2aed90 100644 --- a/src/plugins/saved_objects/public/save_modal/__snapshots__/saved_object_save_modal.test.tsx.snap +++ b/src/plugins/saved_objects/public/save_modal/__snapshots__/saved_object_save_modal.test.tsx.snap @@ -25,6 +25,7 @@ exports[`SavedObjectSaveModal should render matching snapshot 1`] = ` + {!this.props.showDescription && this.props.description && ( - - {this.props.description} - + + {this.props.description} + )} + + + {this.renderCopyOnSave()} { expect(mockSavedObjectsClient.bulkGet).toHaveBeenCalledWith(mockSelectedSavedObjects); expect(mockSavedObjectsClient.delete).toHaveBeenCalledWith( mockSavedObjects[0].type, - mockSavedObjects[0].id + mockSavedObjects[0].id, + { force: true } ); expect(mockSavedObjectsClient.delete).toHaveBeenCalledWith( mockSavedObjects[1].type, - mockSavedObjects[1].id + mockSavedObjects[1].id, + { force: true } ); expect(component.state('selectedSavedObjects').length).toBe(0); }); diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.tsx index d879a71cc2269..5011c0299abe8 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.tsx +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.tsx @@ -468,7 +468,7 @@ export class SavedObjectsTable extends Component - savedObjectsClient.delete(object.type, object.id) + savedObjectsClient.delete(object.type, object.id, { force: true }) ); await Promise.all(deletes); diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json index 6531262b6f1da..1f474dcbb8ff4 100644 --- a/src/plugins/telemetry/schema/oss_plugins.json +++ b/src/plugins/telemetry/schema/oss_plugins.json @@ -1623,6 +1623,751 @@ } } }, + "ui_metric": { + "properties": { + "console": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "DashboardPanelVersionInUrl": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "Kibana_home": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "visualize": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "canvas": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "cross_cluster_replication": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "index_lifecycle_management": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "index_management": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "ingest_pipelines": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "apm": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "infra_logs": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "infra_metrics": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "stack_monitoring": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "remote_clusters": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "rollup_jobs": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "securitySolution": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "snapshot_restore": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "dashboards": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "dev_tools": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "discover": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "home": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "kibana": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "management": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "short_url_redirect": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "timelion": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "csm": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "dashboard_mode": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "enterpriseSearch": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "appSearch": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "workplaceSearch": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "graph": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "logs": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "metrics": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "infra": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "ingestManager": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "lens": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "maps": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "ml": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "monitoring": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "observability-overview": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "security_account": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "security_access_agreement": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "security_capture_url": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "security_logged_out": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "security_login": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "security_logout": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "security_overwritten_session": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "securitySolution:overview": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "securitySolution:detections": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "securitySolution:hosts": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "securitySolution:network": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "securitySolution:timelines": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "securitySolution:case": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "securitySolution:administration": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "siem": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "space_selector": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + }, + "uptime": { + "type": "array", + "items": { + "properties": { + "key": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + } + } + } + }, "telemetry": { "properties": { "opt_in_status": { diff --git a/src/plugins/telemetry/server/collectors/usage/schema.ts b/src/plugins/telemetry/server/collectors/usage/schema.ts index 8f4d555d75c49..4bfb6f75c7c8f 100644 --- a/src/plugins/telemetry/server/collectors/usage/schema.ts +++ b/src/plugins/telemetry/server/collectors/usage/schema.ts @@ -31,7 +31,7 @@ const licenseSchema: MakeSchemaFrom = { max_resource_units: { type: 'long' }, }; -export const staticTelemetrySchema: MakeSchemaFrom> = { +export const staticTelemetrySchema: MakeSchemaFrom = { ece: { kb_uuid: { type: 'keyword' }, es_uuid: { type: 'keyword' }, diff --git a/src/plugins/telemetry_management_section/README.md b/src/plugins/telemetry_management_section/README.md index 0f795786720c9..c23a8591f6794 100644 --- a/src/plugins/telemetry_management_section/README.md +++ b/src/plugins/telemetry_management_section/README.md @@ -1,5 +1,5 @@ # Telemetry Management Section -This plugin adds the Advanced Settings section for the Usage Data collection (aka Telemetry). +This plugin adds the Advanced Settings section for the Usage and Security Data collection (aka Telemetry). The reason for having it separated from the `telemetry` plugin is to avoid circular dependencies. The plugin `advancedSettings` depends on the `home` app that depends on the `telemetry` plugin because of the telemetry banner in the welcome screen. diff --git a/src/plugins/telemetry_management_section/public/components/__snapshots__/opt_in_security_example_flyout.test.tsx.snap b/src/plugins/telemetry_management_section/public/components/__snapshots__/opt_in_security_example_flyout.test.tsx.snap new file mode 100644 index 0000000000000..0b9d426008ca4 --- /dev/null +++ b/src/plugins/telemetry_management_section/public/components/__snapshots__/opt_in_security_example_flyout.test.tsx.snap @@ -0,0 +1,134 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`security flyout renders as expected renders as expected 1`] = ` + + + + +

+ Endpoint security data +

+
+ + + This is a representative sample of the endpoint security alert event that we collect. Endpoint security data is collected only when the Elastic Endpoint is enabled. It includes information about the endpoint configuration and detection events. + + +
+ + + { + "@timestamp": "2020-09-22T14:34:56.82202300Z", + "agent": { + "build": { + "original": "version: 7.9.1, compiled: Thu Aug 27 14:50:21 2020, branch: 7.9, commit: b594beb958817dee9b9d908191ed766d483df3ea" + }, + "id": "22dd8544-bcac-46cb-b970-5e681bb99e0b", + "type": "endpoint", + "version": "7.9.1" + }, + "Endpoint": { + "policy": { + "applied": { + "artifacts": { + "global": { + "identifiers": [ + { + "sha256": "6a546aade5563d3e8dffc1fe2d93d33edda8f9ca3e17ac3cc9ac707620cb9ecd", + "name": "endpointpe-v4-blocklist" + }, + { + "sha256": "04f9f87accc5d5aea433427bd1bd4ec6908f8528c78ceed26f70df7875a99385", + "name": "endpointpe-v4-exceptionlist" + }, + { + "sha256": "1471838597fcd79a54ea4a3ec9a9beee1a86feaedab6c98e61102559ced822a8", + "name": "endpointpe-v4-model" + }, + { + "sha256": "824859b0c6749cc31951d92a73bbdddfcfe9f38abfe432087934d4dab9766ce8", + "name": "global-exceptionlist-windows" + } + ], + "version": "1.0.0" + }, + "user": { + "identifiers": [ + { + "sha256": "d801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658", + "name": "endpoint-exceptionlist-windows-v1" + } + ], + "version": "1.0.0" + } + } + } + } + }, + "ecs": { + "version": "1.5.0" + }, + "elastic": { + "agent": { + "id": "b2e88aea-2671-402a-828a-957526bac315" + } + }, + "file": { + "path": "C:\\\\Windows\\\\Temp\\\\mimikatz.exe", + "size": 1263880, + "created": "2020-05-19T07:50:06.0Z", + "accessed": "2020-09-22T14:29:19.93531400Z", + "mtime": "2020-09-22T14:29:03.6040000Z", + "directory": "C:\\\\Windows\\\\Temp", + "hash": { + "sha1": "c9fb7f8a4c6b7b12b493a99a8dc6901d17867388", + "sha256": "cb1553a3c88817e4cc774a5a93f9158f6785bd3815447d04b6c3f4c2c4b21ed7", + "md5": "465d5d850f54d9cde767bda90743df30" + }, + "Ext": { + "code_signature": { + "trusted": true, + "subject_name": "Open Source Developer, Benjamin Delpy", + "exists": true, + "status": "trusted" + }, + "malware_classification": { + "identifier": "endpointpe-v4-model", + "score": 0.99956864118576, + "threshold": 0.71, + "version": "0.0.0" + } + } + }, + "host": { + "os": { + "Ext": { + "variant": "Windows 10 Enterprise Evaluation" + }, + "kernel": "2004 (10.0.19041.388)", + "name": "Windows", + "family": "windows", + "version": "2004 (10.0.19041.388)", + "platform": "windows", + "full": "Windows 10 Enterprise Evaluation 2004 (10.0.19041.388)" + } + }, + "event": { + "kind": "alert" + }, + "cluster_uuid": "kLbKvSMcRiiFAR0t8LebDA", + "cluster_name": "elasticsearch" +} + + +
+
+`; diff --git a/src/plugins/telemetry_management_section/public/components/__snapshots__/telemetry_management_section.test.tsx.snap b/src/plugins/telemetry_management_section/public/components/__snapshots__/telemetry_management_section.test.tsx.snap index ab29656c557c2..7357598c8495f 100644 --- a/src/plugins/telemetry_management_section/public/components/__snapshots__/telemetry_management_section.test.tsx.snap +++ b/src/plugins/telemetry_management_section/public/components/__snapshots__/telemetry_management_section.test.tsx.snap @@ -49,7 +49,7 @@ exports[`TelemetryManagementSectionComponent renders as expected 1`] = ` -

- - - + + + , + "endpointSecurityData": + + , + } + } + />

, "displayName": "Provide usage statistics", @@ -286,205 +303,4 @@ exports[`TelemetryManagementSectionComponent renders null because allowChangingO /> `; -exports[`TelemetryManagementSectionComponent renders null because query does not match the SEARCH_TERMS 1`] = ` - -`; - exports[`TelemetryManagementSectionComponent test the wrapper (for coverage purposes) 1`] = `null`; diff --git a/src/plugins/telemetry_management_section/public/components/opt_in_security_example_flyout.test.tsx b/src/plugins/telemetry_management_section/public/components/opt_in_security_example_flyout.test.tsx new file mode 100644 index 0000000000000..c80d0daf5a695 --- /dev/null +++ b/src/plugins/telemetry_management_section/public/components/opt_in_security_example_flyout.test.tsx @@ -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. + */ +import React from 'react'; +import { shallowWithIntl } from 'test_utils/enzyme_helpers'; +import { OptInSecurityExampleFlyout } from './opt_in_security_example_flyout'; + +describe('security flyout renders as expected', () => { + it('renders as expected', () => { + expect(shallowWithIntl()).toMatchSnapshot(); + }); +}); diff --git a/src/plugins/telemetry_management_section/public/components/opt_in_security_example_flyout.tsx b/src/plugins/telemetry_management_section/public/components/opt_in_security_example_flyout.tsx new file mode 100644 index 0000000000000..af0de5b268ddc --- /dev/null +++ b/src/plugins/telemetry_management_section/public/components/opt_in_security_example_flyout.tsx @@ -0,0 +1,235 @@ +/* + * 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 * as React from 'react'; + +import { + EuiCallOut, + EuiCodeBlock, + EuiFlexGroup, + EuiFlexItem, + EuiFlyout, + EuiFlyoutHeader, + EuiFlyoutBody, + EuiLoadingSpinner, + EuiPortal, // EuiPortal is a temporary requirement to use EuiFlyout with "ownFocus" + EuiText, + EuiTextColor, + EuiTitle, +} from '@elastic/eui'; + +import { FormattedMessage } from '@kbn/i18n/react'; + +interface Props { + onClose: () => void; +} + +interface State { + isLoading: boolean; + hasPrivilegeToRead: boolean; +} + +/** + * React component for displaying the example data associated with the Telemetry opt-in banner. + */ +export class OptInSecurityExampleFlyout extends React.PureComponent { + public readonly state: State = { + isLoading: true, + hasPrivilegeToRead: false, + }; + + async componentDidMount() { + try { + this.setState({ + isLoading: false, + hasPrivilegeToRead: true, + }); + } catch (err) { + this.setState({ + isLoading: false, + hasPrivilegeToRead: err.status !== 403, + }); + } + } + + renderBody({ isLoading, hasPrivilegeToRead }: State) { + if (isLoading) { + return ( + + + + + + ); + } + + if (!hasPrivilegeToRead) { + return ( + + } + color="danger" + iconType="cross" + > + + + ); + } + + return ( + + {JSON.stringify(this.exampleSecurityPayload, null, 2)} + + ); + } + + render() { + return ( + + + + +

Endpoint security data

+
+ + + This is a representative sample of the endpoint security alert event that we + collect. Endpoint security data is collected only when the Elastic Endpoint is + enabled. It includes information about the endpoint configuration and detection + events. + + +
+ {this.renderBody(this.state)} +
+
+ ); + } + + exampleSecurityPayload = { + '@timestamp': '2020-09-22T14:34:56.82202300Z', + agent: { + build: { + original: + 'version: 7.9.1, compiled: Thu Aug 27 14:50:21 2020, branch: 7.9, commit: b594beb958817dee9b9d908191ed766d483df3ea', + }, + id: '22dd8544-bcac-46cb-b970-5e681bb99e0b', + type: 'endpoint', + version: '7.9.1', + }, + Endpoint: { + policy: { + applied: { + artifacts: { + global: { + identifiers: [ + { + sha256: '6a546aade5563d3e8dffc1fe2d93d33edda8f9ca3e17ac3cc9ac707620cb9ecd', + name: 'endpointpe-v4-blocklist', + }, + { + sha256: '04f9f87accc5d5aea433427bd1bd4ec6908f8528c78ceed26f70df7875a99385', + name: 'endpointpe-v4-exceptionlist', + }, + { + sha256: '1471838597fcd79a54ea4a3ec9a9beee1a86feaedab6c98e61102559ced822a8', + name: 'endpointpe-v4-model', + }, + { + sha256: '824859b0c6749cc31951d92a73bbdddfcfe9f38abfe432087934d4dab9766ce8', + name: 'global-exceptionlist-windows', + }, + ], + version: '1.0.0', + }, + user: { + identifiers: [ + { + sha256: 'd801aa1fb7ddcc330a5e3173372ea6af4a3d08ec58074478e85aa5603e926658', + name: 'endpoint-exceptionlist-windows-v1', + }, + ], + version: '1.0.0', + }, + }, + }, + }, + }, + ecs: { + version: '1.5.0', + }, + elastic: { + agent: { + id: 'b2e88aea-2671-402a-828a-957526bac315', + }, + }, + file: { + path: 'C:\\Windows\\Temp\\mimikatz.exe', + size: 1263880, + created: '2020-05-19T07:50:06.0Z', + accessed: '2020-09-22T14:29:19.93531400Z', + mtime: '2020-09-22T14:29:03.6040000Z', + directory: 'C:\\Windows\\Temp', + hash: { + sha1: 'c9fb7f8a4c6b7b12b493a99a8dc6901d17867388', + sha256: 'cb1553a3c88817e4cc774a5a93f9158f6785bd3815447d04b6c3f4c2c4b21ed7', + md5: '465d5d850f54d9cde767bda90743df30', + }, + Ext: { + code_signature: { + trusted: true, + subject_name: 'Open Source Developer, Benjamin Delpy', + exists: true, + status: 'trusted', + }, + malware_classification: { + identifier: 'endpointpe-v4-model', + score: 0.99956864118576, + threshold: 0.71, + version: '0.0.0', + }, + }, + }, + host: { + os: { + Ext: { + variant: 'Windows 10 Enterprise Evaluation', + }, + kernel: '2004 (10.0.19041.388)', + name: 'Windows', + family: 'windows', + version: '2004 (10.0.19041.388)', + platform: 'windows', + full: 'Windows 10 Enterprise Evaluation 2004 (10.0.19041.388)', + }, + }, + event: { + kind: 'alert', + }, + cluster_uuid: 'kLbKvSMcRiiFAR0t8LebDA', + cluster_name: 'elasticsearch', + }; +} diff --git a/src/plugins/telemetry_management_section/public/components/telemetry_management_section.test.tsx b/src/plugins/telemetry_management_section/public/components/telemetry_management_section.test.tsx index c13f639f31447..993295746ea5b 100644 --- a/src/plugins/telemetry_management_section/public/components/telemetry_management_section.test.tsx +++ b/src/plugins/telemetry_management_section/public/components/telemetry_management_section.test.tsx @@ -21,6 +21,7 @@ import { mountWithIntl, shallowWithIntl } from 'test_utils/enzyme_helpers'; import TelemetryManagementSection from './telemetry_management_section'; import { TelemetryService } from '../../../telemetry/public/services'; import { coreMock } from '../../../../core/public/mocks'; +import { render } from '@testing-library/react'; describe('TelemetryManagementSectionComponent', () => { const coreStart = coreMock.createStart(); @@ -73,19 +74,31 @@ describe('TelemetryManagementSectionComponent', () => { http: coreSetup.http, }); - const component = mountWithIntl( - + const component = render( + Fallback}> + + ); + try { - expect( - component.setProps({ ...component.props(), query: { text: 'asssdasdsad' } }) - ).toMatchSnapshot(); + component.rerender( + Fallback}> + + + ); expect(onQueryMatchChange).toHaveBeenCalledWith(false); expect(onQueryMatchChange).toHaveBeenCalledTimes(1); } finally { @@ -199,7 +212,7 @@ describe('TelemetryManagementSectionComponent', () => { /> ); try { - const toggleExampleComponent = component.find('p > EuiLink[onClick]'); + const toggleExampleComponent = component.find('FormattedMessage > EuiLink[onClick]').at(0); const updatedView = toggleExampleComponent.simulate('click'); updatedView.find('OptInExampleFlyout'); updatedView.simulate('close'); @@ -208,6 +221,42 @@ describe('TelemetryManagementSectionComponent', () => { } }); + it('shows the OptInSecurityExampleFlyout', () => { + const onQueryMatchChange = jest.fn(); + const telemetryService = new TelemetryService({ + config: { + enabled: true, + url: '', + banner: true, + allowChangingOptInStatus: true, + optIn: false, + optInStatusUrl: '', + sendUsageFrom: 'browser', + }, + reportOptInStatusChange: false, + notifications: coreStart.notifications, + http: coreSetup.http, + }); + + const component = mountWithIntl( + + ); + try { + const toggleExampleComponent = component.find('FormattedMessage > EuiLink[onClick]').at(1); + const updatedView = toggleExampleComponent.simulate('click'); + updatedView.find('OptInSecurityExampleFlyout'); + updatedView.simulate('close'); + } finally { + component.unmount(); + } + }); + it('toggles the OptIn button', async () => { const onQueryMatchChange = jest.fn(); const telemetryService = new TelemetryService({ diff --git a/src/plugins/telemetry_management_section/public/components/telemetry_management_section.tsx b/src/plugins/telemetry_management_section/public/components/telemetry_management_section.tsx index db104e9c7baab..822d8b49661c1 100644 --- a/src/plugins/telemetry_management_section/public/components/telemetry_management_section.tsx +++ b/src/plugins/telemetry_management_section/public/components/telemetry_management_section.tsx @@ -34,7 +34,8 @@ import { i18n } from '@kbn/i18n'; import { TelemetryPluginSetup } from 'src/plugins/telemetry/public'; import { PRIVACY_STATEMENT_URL } from '../../../telemetry/common/constants'; import { OptInExampleFlyout } from './opt_in_example_flyout'; -import { Field } from '../../../advanced_settings/public'; +import { OptInSecurityExampleFlyout } from './opt_in_security_example_flyout'; +import { LazyField } from '../../../advanced_settings/public'; import { ToastsStart } from '../../../../core/public'; type TelemetryService = TelemetryPluginSetup['telemetryService']; @@ -53,6 +54,7 @@ interface Props { interface State { processing: boolean; showExample: boolean; + showSecurityExample: boolean; queryMatches: boolean | null; enabled: boolean; } @@ -61,6 +63,7 @@ export class TelemetryManagementSection extends Component { state: State = { processing: false, showExample: false, + showSecurityExample: false, queryMatches: null, enabled: this.props.telemetryService.getIsOptedIn() || false, }; @@ -87,7 +90,7 @@ export class TelemetryManagementSection extends Component { render() { const { telemetryService } = this.props; - const { showExample, queryMatches, enabled, processing } = this.state; + const { showExample, showSecurityExample, queryMatches, enabled, processing } = this.state; if (!telemetryService.getCanChangeOptInStatus()) { return null; @@ -105,6 +108,7 @@ export class TelemetryManagementSection extends Component { onClose={this.toggleExample} /> )} + {showSecurityExample && } @@ -119,7 +123,7 @@ export class TelemetryManagementSection extends Component { {this.maybeGetAppliesSettingMessage()} - { />

- - - + + + + ), + endpointSecurityData: ( + + + + ), + }} + />

); @@ -245,6 +262,12 @@ export class TelemetryManagementSection extends Component { showExample: !this.state.showExample, }); }; + + toggleSecurityExample = () => { + this.setState({ + showSecurityExample: !this.state.showSecurityExample, + }); + }; } // required for lazy loading diff --git a/src/plugins/tile_map/public/tile_map_type.js b/src/plugins/tile_map/public/tile_map_type.js index 7073958a1b318..cc19a8bbcef91 100644 --- a/src/plugins/tile_map/public/tile_map_type.js +++ b/src/plugins/tile_map/public/tile_map_type.js @@ -33,7 +33,6 @@ export function createTileMapTypeDefinition(dependencies) { return { name: 'tile_map', - isDeprecated: true, getDeprecationMessage, title: i18n.translate('tileMap.vis.mapTitle', { defaultMessage: 'Coordinate Map', diff --git a/src/plugins/timelion/public/index.scss b/src/plugins/timelion/public/index.scss index 6bf7133287c51..f39e0c18a2870 100644 --- a/src/plugins/timelion/public/index.scss +++ b/src/plugins/timelion/public/index.scss @@ -10,3 +10,9 @@ @import './app'; @import './base'; @import './directives/index'; + +// these styles is needed to be loaded here explicitly if the timelion visualization was not opened in browser +// styles for timelion visualization are lazy loaded only while a vis is opened +// this will duplicate styles only if both Timelion app and timelion visualization are loaded +// could be left here as it is since the Timelion app is deprecated +@import '../../vis_type_timelion/public/components/index.scss'; diff --git a/src/plugins/ui_actions/README.asciidoc b/src/plugins/ui_actions/README.asciidoc new file mode 100644 index 0000000000000..577aa2eae354b --- /dev/null +++ b/src/plugins/ui_actions/README.asciidoc @@ -0,0 +1,26 @@ +[[uiactions-plugin]] +== UI Actions + +An API for: + +- creating custom functionality (`actions`) +- creating custom user interaction events (`triggers`) +- attaching and detaching `actions` to `triggers`. +- emitting `trigger` events +- executing `actions` attached to a given `trigger`. +- exposing a context menu for the user to choose the appropriate action when there are multiple actions attached to a single trigger. + +=== Examples + +https://github.com/elastic/kibana/blob/master/examples/ui_action_examples/README.md[ui_action examples] + +=== API Docs + +==== Server API +https://github.com/elastic/kibana/blob/master/docs/development/plugins/ui_actions/server/kibana-plugin-plugins-ui_actions-server.uiactionssetup.md[Browser Setup contract] +https://github.com/elastic/kibana/blob/master/docs/development/plugins/ui_actions/server/kibana-plugin-plugins-ui_actions-server.uiactionsstart.md[Browser Start contract] + +==== Browser API +https://github.com/elastic/kibana/blob/master/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionssetup.md[Browser Setup contract] +https://github.com/elastic/kibana/blob/master/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsstart.md[Browser Start contract] + diff --git a/src/plugins/ui_actions/README.md b/src/plugins/ui_actions/README.md deleted file mode 100644 index c4e02b551c884..0000000000000 --- a/src/plugins/ui_actions/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# UI Actions - -An API for: - -- creating custom functionality (`actions`) -- creating custom user interaction events (`triggers`) -- attaching and detaching `actions` to `triggers`. -- emitting `trigger` events -- executing `actions` attached to a given `trigger`. -- exposing a context menu for the user to choose the appropriate action when there are multiple actions attached to a single trigger. diff --git a/src/plugins/ui_actions/public/public.api.md b/src/plugins/ui_actions/public/public.api.md new file mode 100644 index 0000000000000..8b3d81a589365 --- /dev/null +++ b/src/plugins/ui_actions/public/public.api.md @@ -0,0 +1,337 @@ +## API Report File for "kibana" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +import { CoreSetup } from 'src/core/public'; +import { CoreStart } from 'src/core/public'; +import { EnvironmentMode } from '@kbn/config'; +import { EuiContextMenuPanelDescriptor } from '@elastic/eui'; +import { Observable } from 'rxjs'; +import { PackageInfo } from '@kbn/config'; +import { Plugin } from 'src/core/public'; +import { PluginInitializerContext as PluginInitializerContext_2 } from 'src/core/public'; +import React from 'react'; +import * as Rx from 'rxjs'; +import { UiComponent } from 'src/plugins/kibana_utils/public'; + +// Warning: (ae-forgotten-export) The symbol "BaseContext" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "Action" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface Action extends Partial>> { + execute(context: ActionExecutionContext): Promise; + getDisplayName(context: ActionExecutionContext): string; + getHref?(context: ActionExecutionContext): Promise; + getIconType(context: ActionExecutionContext): string | undefined; + id: string; + isCompatible(context: ActionExecutionContext): Promise; + MenuItem?: UiComponent<{ + context: ActionExecutionContext; + }>; + order?: number; + shouldAutoExecute?(context: ActionExecutionContext): Promise; + readonly type: T; +} + +// Warning: (ae-missing-release-tag) "ACTION_VISUALIZE_FIELD" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const ACTION_VISUALIZE_FIELD = "ACTION_VISUALIZE_FIELD"; + +// Warning: (ae-missing-release-tag) "ACTION_VISUALIZE_GEO_FIELD" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const ACTION_VISUALIZE_GEO_FIELD = "ACTION_VISUALIZE_GEO_FIELD"; + +// Warning: (ae-missing-release-tag) "ActionByType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ActionByType = Action; + +// Warning: (ae-missing-release-tag) "ActionContextMapping" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface ActionContextMapping { + // Warning: (ae-forgotten-export) The symbol "DEFAULT_ACTION" needs to be exported by the entry point index.d.ts + // + // (undocumented) + [DEFAULT_ACTION]: BaseContext; + // (undocumented) + [ACTION_VISUALIZE_FIELD]: VisualizeFieldContext; + // (undocumented) + [ACTION_VISUALIZE_GEO_FIELD]: VisualizeFieldContext; +} + +// Warning: (ae-missing-release-tag) "ActionDefinitionByType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ActionDefinitionByType = UiActionsActionDefinition; + +// Warning: (ae-missing-release-tag) "ActionExecutionContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export type ActionExecutionContext = Context & ActionExecutionMeta; + +// Warning: (ae-missing-release-tag) "ActionExecutionMeta" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface ActionExecutionMeta { + trigger: Trigger; +} + +// Warning: (ae-missing-release-tag) "ActionType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ActionType = keyof ActionContextMapping; + +// Warning: (ae-missing-release-tag) "APPLY_FILTER_TRIGGER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const APPLY_FILTER_TRIGGER = "FILTER_TRIGGER"; + +// Warning: (ae-missing-release-tag) "applyFilterTrigger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const applyFilterTrigger: Trigger<'FILTER_TRIGGER'>; + +// Warning: (ae-forgotten-export) The symbol "BuildContextMenuParams" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "buildContextMenuForActions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export function buildContextMenuForActions({ actions, title, closeMenu, }: BuildContextMenuParams): Promise; + +// Warning: (ae-forgotten-export) The symbol "ActionDefinitionByType" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "createAction" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function createAction(action: ActionDefinitionByType_2): ActionByType; + +// Warning: (ae-missing-release-tag) "IncompatibleActionError" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class IncompatibleActionError extends Error { + constructor(); + // (undocumented) + code: string; +} + +// Warning: (ae-forgotten-export) The symbol "PluginInitializerContext" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "UiActionsPlugin" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "plugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function plugin(initializerContext: PluginInitializerContext): UiActionsPlugin; + +// Warning: (ae-missing-release-tag) "SELECT_RANGE_TRIGGER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const SELECT_RANGE_TRIGGER = "SELECT_RANGE_TRIGGER"; + +// Warning: (ae-missing-release-tag) "selectRangeTrigger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const selectRangeTrigger: Trigger<'SELECT_RANGE_TRIGGER'>; + +// Warning: (ae-missing-release-tag) "Trigger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface Trigger { + description?: string; + id: ID; + title?: string; +} + +// Warning: (ae-missing-release-tag) "TriggerContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type TriggerContext = T extends TriggerId ? TriggerContextMapping[T] : never; + +// Warning: (ae-missing-release-tag) "TriggerContextMapping" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface TriggerContextMapping { + // Warning: (ae-forgotten-export) The symbol "DEFAULT_TRIGGER" needs to be exported by the entry point index.d.ts + // Warning: (ae-forgotten-export) The symbol "TriggerContext" needs to be exported by the entry point index.d.ts + // + // (undocumented) + [DEFAULT_TRIGGER]: TriggerContext_2; + // Warning: (ae-forgotten-export) The symbol "ApplyGlobalFilterActionContext" needs to be exported by the entry point index.d.ts + // + // (undocumented) + [APPLY_FILTER_TRIGGER]: ApplyGlobalFilterActionContext; + // Warning: (ae-forgotten-export) The symbol "RangeSelectContext" needs to be exported by the entry point index.d.ts + // + // (undocumented) + [SELECT_RANGE_TRIGGER]: RangeSelectContext; + // Warning: (ae-forgotten-export) The symbol "ValueClickContext" needs to be exported by the entry point index.d.ts + // + // (undocumented) + [VALUE_CLICK_TRIGGER]: ValueClickContext; + // (undocumented) + [VISUALIZE_FIELD_TRIGGER]: VisualizeFieldContext; + // (undocumented) + [VISUALIZE_GEO_FIELD_TRIGGER]: VisualizeFieldContext; +} + +// Warning: (ae-missing-release-tag) "TriggerId" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type TriggerId = keyof TriggerContextMapping; + +// Warning: (ae-forgotten-export) The symbol "ActionDefinitionContext" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "ActionDefinition" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface UiActionsActionDefinition extends Partial>> { + execute(context: ActionDefinitionContext): Promise; + getHref?(context: ActionDefinitionContext): Promise; + readonly id: string; + isCompatible?(context: ActionDefinitionContext): Promise; + shouldAutoExecute?(context: ActionDefinitionContext): Promise; + readonly type?: ActionType; +} + +// Warning: (ae-missing-release-tag) "Presentable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public +export interface UiActionsPresentable { + getDisplayName(context: Context): string; + getDisplayNameTooltip(context: Context): string; + getHref?(context: Context): Promise; + getIconType(context: Context): string | undefined; + readonly grouping?: UiActionsPresentableGrouping; + readonly id: string; + isCompatible(context: Context): Promise; + readonly MenuItem?: UiComponent<{ + context: Context; + }>; + readonly order: number; +} + +// Warning: (ae-forgotten-export) The symbol "PresentableGroup" needs to be exported by the entry point index.d.ts +// Warning: (ae-missing-release-tag) "PresentableGrouping" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type UiActionsPresentableGrouping = Array>; + +// Warning: (ae-missing-release-tag) "UiActionsService" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export class UiActionsService { + constructor({ triggers, actions, triggerToActions, }?: UiActionsServiceParams); + // Warning: (ae-forgotten-export) The symbol "ActionRegistry" needs to be exported by the entry point index.d.ts + // + // (undocumented) + protected readonly actions: ActionRegistry; + readonly addTriggerAction: (triggerId: T, action: UiActionsActionDefinition | Action) => void; + // (undocumented) + readonly attachAction: (triggerId: T, actionId: string) => void; + readonly clear: () => void; + // (undocumented) + readonly detachAction: (triggerId: TriggerId, actionId: string) => void; + // @deprecated (undocumented) + readonly executeTriggerActions: (triggerId: T, context: TriggerContext) => Promise; + // Warning: (ae-forgotten-export) The symbol "UiActionsExecutionService" needs to be exported by the entry point index.d.ts + // + // (undocumented) + readonly executionService: UiActionsExecutionService; + readonly fork: () => UiActionsService; + // (undocumented) + readonly getAction: >(id: string) => Action, "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel" | "togglePanel" | "replacePanel" | "clonePanel" | "addToFromLibrary" | "unlinkFromLibrary" | "ACTION_LIBRARY_NOTIFICATION" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK">; + // Warning: (ae-forgotten-export) The symbol "TriggerContract" needs to be exported by the entry point index.d.ts + // + // (undocumented) + readonly getTrigger: (triggerId: T) => TriggerContract; + // (undocumented) + readonly getTriggerActions: (triggerId: T) => Action[]; + // (undocumented) + readonly getTriggerCompatibleActions: (triggerId: T, context: TriggerContextMapping[T]) => Promise[]>; + // (undocumented) + readonly hasAction: (actionId: string) => boolean; + // Warning: (ae-forgotten-export) The symbol "ActionContext" needs to be exported by the entry point index.d.ts + // + // (undocumented) + readonly registerAction:
>(definition: A) => Action, "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel" | "togglePanel" | "replacePanel" | "clonePanel" | "addToFromLibrary" | "unlinkFromLibrary" | "ACTION_LIBRARY_NOTIFICATION" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK">; + // (undocumented) + readonly registerTrigger: (trigger: Trigger) => void; + // Warning: (ae-forgotten-export) The symbol "TriggerRegistry" needs to be exported by the entry point index.d.ts + // + // (undocumented) + protected readonly triggers: TriggerRegistry; + // Warning: (ae-forgotten-export) The symbol "TriggerToActionsRegistry" needs to be exported by the entry point index.d.ts + // + // (undocumented) + protected readonly triggerToActions: TriggerToActionsRegistry; + // (undocumented) + readonly unregisterAction: (actionId: string) => void; +} + +// Warning: (ae-missing-release-tag) "UiActionsServiceParams" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface UiActionsServiceParams { + // (undocumented) + readonly actions?: ActionRegistry; + // (undocumented) + readonly triggers?: TriggerRegistry; + readonly triggerToActions?: TriggerToActionsRegistry; +} + +// Warning: (ae-missing-release-tag) "UiActionsSetup" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type UiActionsSetup = Pick; + +// Warning: (ae-missing-release-tag) "UiActionsStart" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type UiActionsStart = PublicMethodsOf; + +// Warning: (ae-missing-release-tag) "VALUE_CLICK_TRIGGER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const VALUE_CLICK_TRIGGER = "VALUE_CLICK_TRIGGER"; + +// Warning: (ae-missing-release-tag) "valueClickTrigger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const valueClickTrigger: Trigger<'VALUE_CLICK_TRIGGER'>; + +// Warning: (ae-missing-release-tag) "VISUALIZE_FIELD_TRIGGER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const VISUALIZE_FIELD_TRIGGER = "VISUALIZE_FIELD_TRIGGER"; + +// Warning: (ae-missing-release-tag) "VISUALIZE_GEO_FIELD_TRIGGER" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const VISUALIZE_GEO_FIELD_TRIGGER = "VISUALIZE_GEO_FIELD_TRIGGER"; + +// Warning: (ae-missing-release-tag) "VisualizeFieldContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export interface VisualizeFieldContext { + // (undocumented) + contextualFields?: string[]; + // (undocumented) + fieldName: string; + // (undocumented) + indexPatternId: string; +} + +// Warning: (ae-missing-release-tag) "visualizeFieldTrigger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const visualizeFieldTrigger: Trigger<'VISUALIZE_FIELD_TRIGGER'>; + +// Warning: (ae-missing-release-tag) "visualizeGeoFieldTrigger" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export const visualizeGeoFieldTrigger: Trigger<'VISUALIZE_GEO_FIELD_TRIGGER'>; + + +// (No @packageDocumentation comment for this package) + +``` diff --git a/src/plugins/ui_actions/public/tests/execute_trigger_actions.test.ts b/src/plugins/ui_actions/public/tests/execute_trigger_actions.test.ts index 81120990001e3..af2510467ba87 100644 --- a/src/plugins/ui_actions/public/tests/execute_trigger_actions.test.ts +++ b/src/plugins/ui_actions/public/tests/execute_trigger_actions.test.ts @@ -22,7 +22,7 @@ import { openContextMenu } from '../context_menu'; import { uiActionsPluginMock } from '../mocks'; import { Trigger } from '../triggers'; import { TriggerId, ActionType } from '../types'; -import { wait } from '@testing-library/dom'; +import { waitFor } from '@testing-library/dom'; jest.mock('../context_menu'); @@ -85,7 +85,7 @@ test('executes a single action mapped to a trigger', async () => { expect(executeFn).toBeCalledWith(expect.objectContaining(context)); }); -test('throws an error if there are no compatible actions to execute', async () => { +test("doesn't throw an error if there are no compatible actions to execute", async () => { const { setup, doStart } = uiActions; const trigger: Trigger = { id: 'MY-TRIGGER' as TriggerId, @@ -98,9 +98,7 @@ test('throws an error if there are no compatible actions to execute', async () = const start = doStart(); await expect( start.executeTriggerActions('MY-TRIGGER' as TriggerId, context) - ).rejects.toMatchObject( - new Error('No compatible actions found to execute for trigger [triggerId = MY-TRIGGER].') - ); + ).resolves.toBeUndefined(); }); test('does not execute an incompatible action', async () => { @@ -149,7 +147,7 @@ test('shows a context menu when more than one action is mapped to a trigger', as jest.runAllTimers(); - await wait(() => { + await waitFor(() => { expect(executeFn).toBeCalledTimes(0); expect(openContextMenu).toHaveBeenCalledTimes(1); }); @@ -197,7 +195,7 @@ test("doesn't show a context menu for auto executable actions", async () => { jest.runAllTimers(); - await wait(() => { + await waitFor(() => { expect(executeFn).toBeCalledTimes(2); expect(openContextMenu).toHaveBeenCalledTimes(0); }); diff --git a/src/plugins/ui_actions/public/triggers/trigger_internal.ts b/src/plugins/ui_actions/public/triggers/trigger_internal.ts index c91468d31add5..c766b5c798ecb 100644 --- a/src/plugins/ui_actions/public/triggers/trigger_internal.ts +++ b/src/plugins/ui_actions/public/triggers/trigger_internal.ts @@ -35,12 +35,6 @@ export class TriggerInternal { const triggerId = this.trigger.id; const actions = await this.service.getTriggerCompatibleActions!(triggerId, context); - if (!actions.length) { - throw new Error( - `No compatible actions found to execute for trigger [triggerId = ${triggerId}].` - ); - } - await Promise.all([ actions.map((action) => this.service.executionService.execute({ diff --git a/src/plugins/usage_collection/server/collector/collector.ts b/src/plugins/usage_collection/server/collector/collector.ts index b0bc18a0cf0eb..8491bdb0c957c 100644 --- a/src/plugins/usage_collection/server/collector/collector.ts +++ b/src/plugins/usage_collection/server/collector/collector.ts @@ -38,16 +38,17 @@ export type RecursiveMakeSchemaFrom = U extends object ? MakeSchemaFrom : { type: AllowedSchemaTypes }; +// Using Required to enforce all optional keys in the object export type MakeSchemaFrom = { - [Key in keyof Base]: Base[Key] extends Array + [Key in keyof Required]: Required[Key] extends Array ? { type: 'array'; items: RecursiveMakeSchemaFrom } - : RecursiveMakeSchemaFrom; + : RecursiveMakeSchemaFrom[Key]>; }; export interface CollectorOptions { type: string; init?: Function; - schema?: MakeSchemaFrom>; // Using Required to enforce all optional keys in the object + schema?: MakeSchemaFrom; fetch: (callCluster: LegacyAPICaller, esClient?: ElasticsearchClient) => Promise | T; /* * A hook for allowing the fetched data payload to be organized into a typed diff --git a/src/plugins/vis_default_editor/public/components/controls/components/number_list/number_list.test.tsx b/src/plugins/vis_default_editor/public/components/controls/components/number_list/number_list.test.tsx index 82d4b9142fb76..7964da23d8f50 100644 --- a/src/plugins/vis_default_editor/public/components/controls/components/number_list/number_list.test.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/components/number_list/number_list.test.tsx @@ -33,10 +33,10 @@ jest.mock('@elastic/eui', () => ({ let counter = 1; return () => `12${counter++}`; }), - EuiSpacer: require.requireActual('@elastic/eui').EuiSpacer, - EuiFlexItem: require.requireActual('@elastic/eui').EuiFlexItem, - EuiButtonEmpty: require.requireActual('@elastic/eui').EuiButtonEmpty, - EuiFormErrorText: require.requireActual('@elastic/eui').EuiFormErrorText, + EuiSpacer: jest.requireActual('@elastic/eui').EuiSpacer, + EuiFlexItem: jest.requireActual('@elastic/eui').EuiFlexItem, + EuiButtonEmpty: jest.requireActual('@elastic/eui').EuiButtonEmpty, + EuiFormErrorText: jest.requireActual('@elastic/eui').EuiFormErrorText, })); describe('NumberList', () => { diff --git a/src/plugins/vis_default_editor/public/components/sidebar/index.ts b/src/plugins/vis_default_editor/public/components/sidebar/index.ts index 31228aad85d1e..09b6e229d9fcc 100644 --- a/src/plugins/vis_default_editor/public/components/sidebar/index.ts +++ b/src/plugins/vis_default_editor/public/components/sidebar/index.ts @@ -18,5 +18,3 @@ */ export { DefaultEditorSideBar } from './sidebar'; -export { DefaultEditorDataTab } from './data_tab'; -export { OptionTab } from './navbar'; diff --git a/src/plugins/vis_default_editor/public/components/sidebar/navbar.tsx b/src/plugins/vis_default_editor/public/components/sidebar/navbar.tsx index a1b5003a092f7..33ef5cc2353d7 100644 --- a/src/plugins/vis_default_editor/public/components/sidebar/navbar.tsx +++ b/src/plugins/vis_default_editor/public/components/sidebar/navbar.tsx @@ -20,32 +20,20 @@ import React from 'react'; import { EuiTabs, EuiTab } from '@elastic/eui'; -import { VisOptionsProps } from '../../vis_options_props'; -import { DefaultEditorDataTabProps } from './data_tab'; - -export interface OptionTab { - editor: React.ComponentType; - name: string; - title: string; -} +import { OptionTab } from './use_option_tabs'; interface DefaultEditorNavBarProps { optionTabs: OptionTab[]; - selectedTab: string; setSelectedTab(name: string): void; } -function DefaultEditorNavBar({ - selectedTab, - setSelectedTab, - optionTabs, -}: DefaultEditorNavBarProps) { +function DefaultEditorNavBar({ setSelectedTab, optionTabs }: DefaultEditorNavBarProps) { return ( - {optionTabs.map(({ name, title }) => ( + {optionTabs.map(({ name, title, isSelected = false }) => ( setSelectedTab(name)} > diff --git a/src/plugins/vis_default_editor/public/components/sidebar/sidebar.tsx b/src/plugins/vis_default_editor/public/components/sidebar/sidebar.tsx index bcbc5afec1fdc..c0a6b48794970 100644 --- a/src/plugins/vis_default_editor/public/components/sidebar/sidebar.tsx +++ b/src/plugins/vis_default_editor/public/components/sidebar/sidebar.tsx @@ -30,18 +30,18 @@ import { } from 'src/plugins/visualizations/public'; import { TimeRange } from 'src/plugins/data/public'; import { SavedObject } from 'src/plugins/saved_objects/public'; -import { DefaultEditorNavBar, OptionTab } from './navbar'; +import { DefaultEditorNavBar } from './navbar'; import { DefaultEditorControls } from './controls'; import { setStateParamValue, useEditorReducer, useEditorFormState, discardChanges } from './state'; import { DefaultEditorAggCommonProps } from '../agg_common_props'; import { SidebarTitle } from './sidebar_title'; import { Schema } from '../../schemas'; +import { useOptionTabs } from './use_option_tabs'; interface DefaultEditorSideBarProps { embeddableHandler: VisualizeEmbeddableContract; isCollapsed: boolean; onClickCollapse: () => void; - optionTabs: OptionTab[]; uiState: PersistedState; vis: Vis; isLinkedSearch: boolean; @@ -54,7 +54,6 @@ function DefaultEditorSideBar({ embeddableHandler, isCollapsed, onClickCollapse, - optionTabs, uiState, vis, isLinkedSearch, @@ -62,10 +61,10 @@ function DefaultEditorSideBar({ savedSearch, timeRange, }: DefaultEditorSideBarProps) { - const [selectedTab, setSelectedTab] = useState(optionTabs[0].name); const [isDirty, setDirty] = useState(false); const [state, dispatch] = useEditorReducer(vis, eventEmitter); const { formState, setTouched, setValidity, resetValidity } = useEditorFormState(); + const [optionTabs, setSelectedTab] = useOptionTabs(vis); const responseAggs = useMemo(() => (state.data.aggs ? state.data.aggs.getResponseAggs() : []), [ state.data.aggs, @@ -201,31 +200,23 @@ function DefaultEditorSideBar({ )} {optionTabs.length > 1 && ( - + )} - {optionTabs.map(({ editor: Editor, name }) => { - const isTabSelected = selectedTab === name; - - return ( -
- -
- ); - })} + {optionTabs.map(({ editor: Editor, name, isSelected = false }) => ( +
+ +
+ ))} diff --git a/src/plugins/vis_default_editor/public/components/sidebar/use_option_tabs.ts b/src/plugins/vis_default_editor/public/components/sidebar/use_option_tabs.ts new file mode 100644 index 0000000000000..337533df50fad --- /dev/null +++ b/src/plugins/vis_default_editor/public/components/sidebar/use_option_tabs.ts @@ -0,0 +1,72 @@ +/* + * 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 { useCallback, useState } from 'react'; +import { i18n } from '@kbn/i18n'; + +import { Vis } from 'src/plugins/visualizations/public'; +import { DefaultEditorDataTab, DefaultEditorDataTabProps } from './data_tab'; +import { VisOptionsProps } from '../../vis_options_props'; + +export interface OptionTab { + editor: React.ComponentType; + name: string; + title: string; + isSelected?: boolean; +} + +export const useOptionTabs = ({ type: visType }: Vis): [OptionTab[], (name: string) => void] => { + const [optionTabs, setOptionTabs] = useState(() => { + const tabs = [ + ...(visType.schemas.buckets || visType.schemas.metrics + ? [ + { + name: 'data', + title: i18n.translate('visDefaultEditor.sidebar.tabs.dataLabel', { + defaultMessage: 'Data', + }), + editor: DefaultEditorDataTab, + }, + ] + : []), + + ...(!visType.editorConfig.optionTabs && visType.editorConfig.optionsTemplate + ? [ + { + name: 'options', + title: i18n.translate('visDefaultEditor.sidebar.tabs.optionsLabel', { + defaultMessage: 'Options', + }), + editor: visType.editorConfig.optionsTemplate, + }, + ] + : visType.editorConfig.optionTabs), + ]; + // set up the first tab as selected + tabs[0].isSelected = true; + + return tabs; + }); + + const setSelectedTab = useCallback((name: string) => { + setOptionTabs((tabs) => tabs.map((tab) => ({ ...tab, isSelected: tab.name === name }))); + }, []); + + return [optionTabs, setSelectedTab]; +}; diff --git a/src/plugins/vis_default_editor/public/default_editor.tsx b/src/plugins/vis_default_editor/public/default_editor.tsx index 60b6ebab5ad8e..ed94e52ee2399 100644 --- a/src/plugins/vis_default_editor/public/default_editor.tsx +++ b/src/plugins/vis_default_editor/public/default_editor.tsx @@ -20,13 +20,14 @@ import './index.scss'; import React, { useEffect, useRef, useState, useCallback } from 'react'; +import { EventEmitter } from 'events'; import { EditorRenderProps } from 'src/plugins/visualize/public'; +import { Vis, VisualizeEmbeddableContract } from 'src/plugins/visualizations/public'; import { KibanaContextProvider, PanelsContainer, Panel } from '../../kibana_react/public'; import { Storage } from '../../kibana_utils/public'; import { DefaultEditorSideBar } from './components/sidebar'; -import { DefaultEditorControllerState } from './default_editor_controller'; import { getInitialWidth } from './editor_size'; const localStorage = new Storage(window.localStorage); @@ -38,13 +39,16 @@ function DefaultEditor({ uiState, timeRange, filters, - optionTabs, query, embeddableHandler, eventEmitter, linked, savedSearch, -}: DefaultEditorControllerState & EditorRenderProps) { +}: EditorRenderProps & { + vis: Vis; + eventEmitter: EventEmitter; + embeddableHandler: VisualizeEmbeddableContract; +}) { const visRef = useRef(null); const [isCollapsed, setIsCollapsed] = useState(false); @@ -105,7 +109,6 @@ function DefaultEditor({ embeddableHandler={embeddableHandler} isCollapsed={isCollapsed} onClickCollapse={onClickCollapse} - optionTabs={optionTabs} vis={vis} uiState={uiState} isLinkedSearch={linked} diff --git a/src/plugins/vis_default_editor/public/default_editor_controller.tsx b/src/plugins/vis_default_editor/public/default_editor_controller.tsx index 56fb15ea8354a..0efd6e7746fd2 100644 --- a/src/plugins/vis_default_editor/public/default_editor_controller.tsx +++ b/src/plugins/vis_default_editor/public/default_editor_controller.tsx @@ -19,63 +19,21 @@ import React, { Suspense, lazy } from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; -import { i18n } from '@kbn/i18n'; import { EventEmitter } from 'events'; import { EuiErrorBoundary, EuiLoadingChart } from '@elastic/eui'; import { EditorRenderProps } from 'src/plugins/visualize/public'; import { Vis, VisualizeEmbeddableContract } from 'src/plugins/visualizations/public'; -import { DefaultEditorDataTab, OptionTab } from './components/sidebar'; const DefaultEditor = lazy(() => import('./default_editor')); -export interface DefaultEditorControllerState { - vis: Vis; - eventEmitter: EventEmitter; - embeddableHandler: VisualizeEmbeddableContract; - optionTabs: OptionTab[]; -} - class DefaultEditorController { - private el: HTMLElement; - private state: DefaultEditorControllerState; - - constructor(el: HTMLElement, vis: Vis, eventEmitter: EventEmitter, embeddableHandler: any) { - this.el = el; - const { type: visType } = vis; - - const optionTabs = [ - ...(visType.schemas.buckets || visType.schemas.metrics - ? [ - { - name: 'data', - title: i18n.translate('visDefaultEditor.sidebar.tabs.dataLabel', { - defaultMessage: 'Data', - }), - editor: DefaultEditorDataTab, - }, - ] - : []), - - ...(!visType.editorConfig.optionTabs && visType.editorConfig.optionsTemplate - ? [ - { - name: 'options', - title: i18n.translate('visDefaultEditor.sidebar.tabs.optionsLabel', { - defaultMessage: 'Options', - }), - editor: visType.editorConfig.optionsTemplate, - }, - ] - : visType.editorConfig.optionTabs), - ]; - this.state = { - vis, - optionTabs, - eventEmitter, - embeddableHandler, - }; - } + constructor( + private el: HTMLElement, + private vis: Vis, + private eventEmitter: EventEmitter, + private embeddableHandler: VisualizeEmbeddableContract + ) {} render(props: EditorRenderProps) { render( @@ -94,7 +52,12 @@ class DefaultEditorController {
`; @@ -48,28 +58,38 @@ exports[`Storyshots arguments/AxisConfig/components simple template 1`] = ` } >
- + className="euiSwitch__body" + > + + + + +
-
{title}
-
-
- ); -} - -export { Panel }; diff --git a/src/plugins/vis_type_timelion/public/components/timelion_vis.tsx b/src/plugins/vis_type_timelion/public/components/timelion_vis.tsx deleted file mode 100644 index aa594c749b600..0000000000000 --- a/src/plugins/vis_type_timelion/public/components/timelion_vis.tsx +++ /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. - */ - -import React from 'react'; - -import { IUiSettingsClient } from 'kibana/public'; -import { ChartComponent } from './chart'; -import { VisParams } from '../timelion_vis_fn'; -import { TimelionSuccessResponse } from '../helpers/timelion_request_handler'; -import { ExprVis } from '../../../visualizations/public'; - -export interface TimelionVisComponentProp { - config: IUiSettingsClient; - renderComplete(): void; - updateStatus: object; - vis: ExprVis; - visData: TimelionSuccessResponse; - visParams: VisParams; -} - -function TimelionVisComponent(props: TimelionVisComponentProp) { - return ( -
- -
- ); -} - -export { TimelionVisComponent }; diff --git a/src/plugins/vis_type_timelion/public/components/timelion_vis_component.tsx b/src/plugins/vis_type_timelion/public/components/timelion_vis_component.tsx new file mode 100644 index 0000000000000..a7b623ac8680c --- /dev/null +++ b/src/plugins/vis_type_timelion/public/components/timelion_vis_component.tsx @@ -0,0 +1,414 @@ +/* + * 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, { useState, useEffect, useMemo, useCallback } from 'react'; +import $ from 'jquery'; +import moment from 'moment-timezone'; +import { debounce, compact, get, each, cloneDeep, last, map } from 'lodash'; +import { useResizeObserver } from '@elastic/eui'; + +import { IInterpreterRenderHandlers } from 'src/plugins/expressions'; +import { useKibana } from '../../../kibana_react/public'; +import '../flot'; +import { DEFAULT_TIME_FORMAT } from '../../common/lib'; + +import { + buildSeriesData, + buildOptions, + SERIES_ID_ATTR, + colors, + Axis, +} from '../helpers/panel_utils'; + +import { Series, Sheet } from '../helpers/timelion_request_handler'; +import { tickFormatters } from '../helpers/tick_formatters'; +import { generateTicksProvider } from '../helpers/tick_generator'; +import { TimelionVisDependencies } from '../plugin'; + +import './index.scss'; + +interface CrosshairPlot extends jquery.flot.plot { + setCrosshair: (pos: Position) => void; + clearCrosshair: () => void; +} + +interface TimelionVisComponentProps { + fireEvent: IInterpreterRenderHandlers['event']; + interval: string; + seriesList: Sheet; + renderComplete: IInterpreterRenderHandlers['done']; +} + +interface Position { + x: number; + x1: number; + y: number; + y1: number; + pageX: number; + pageY: number; +} + +interface Range { + to: number; + from: number; +} + +interface Ranges { + xaxis: Range; + yaxis: Range; +} + +const DEBOUNCE_DELAY = 50; +// ensure legend is the same height with or without a caption so legend items do not move around +const emptyCaption = '
'; + +function TimelionVisComponent({ + interval, + seriesList, + renderComplete, + fireEvent, +}: TimelionVisComponentProps) { + const kibana = useKibana(); + const [chart, setChart] = useState(() => cloneDeep(seriesList.list)); + const [canvasElem, setCanvasElem] = useState(); + const [chartElem, setChartElem] = useState(null); + + const [originalColorMap, setOriginalColorMap] = useState(() => new Map()); + + const [highlightedSeries, setHighlightedSeries] = useState(null); + const [focusedSeries, setFocusedSeries] = useState(); + const [plot, setPlot] = useState(); + + // Used to toggle the series, and for displaying values on hover + const [legendValueNumbers, setLegendValueNumbers] = useState>(); + const [legendCaption, setLegendCaption] = useState>(); + + const canvasRef = useCallback((node: HTMLDivElement | null) => { + if (node !== null) { + setCanvasElem(node); + } + }, []); + + const elementRef = useCallback((node: HTMLDivElement | null) => { + if (node !== null) { + setChartElem(node); + } + }, []); + + useEffect( + () => () => { + if (chartElem) { + $(chartElem).off('plotselected').off('plothover').off('mouseleave'); + } + }, + [chartElem] + ); + + /* eslint-disable-next-line react-hooks/exhaustive-deps */ + const highlightSeries = useCallback( + debounce(({ currentTarget }: JQuery.TriggeredEvent) => { + const id = Number(currentTarget.getAttribute(SERIES_ID_ATTR)); + if (highlightedSeries === id) { + return; + } + + setHighlightedSeries(id); + setChart((chartState) => + chartState.map((series: Series, seriesIndex: number) => { + series.color = + seriesIndex === id + ? originalColorMap.get(series) // color it like it was + : 'rgba(128,128,128,0.1)'; // mark as grey + + return series; + }) + ); + }, DEBOUNCE_DELAY), + [originalColorMap, highlightedSeries] + ); + + const focusSeries = useCallback( + (event: JQuery.TriggeredEvent) => { + const id = Number(event.currentTarget.getAttribute(SERIES_ID_ATTR)); + setFocusedSeries(id); + highlightSeries(event); + }, + [highlightSeries] + ); + + const toggleSeries = useCallback(({ currentTarget }: JQuery.TriggeredEvent) => { + const id = Number(currentTarget.getAttribute(SERIES_ID_ATTR)); + + setChart((chartState) => + chartState.map((series: Series, seriesIndex: number) => { + if (seriesIndex === id) { + series._hide = !series._hide; + } + return series; + }) + ); + }, []); + + const updateCaption = useCallback( + (plotData: any) => { + if (canvasElem && get(plotData, '[0]._global.legend.showTime', true)) { + const caption = $(''); + caption.html(emptyCaption); + setLegendCaption(caption); + + const canvasNode = $(canvasElem); + canvasNode.find('div.legend table').append(caption); + setLegendValueNumbers(canvasNode.find('.ngLegendValueNumber')); + + const legend = $(canvasElem).find('.ngLegendValue'); + if (legend) { + legend.click(toggleSeries); + legend.focus(focusSeries); + legend.mouseover(highlightSeries); + } + + // legend has been re-created. Apply focus on legend element when previously set + if (focusedSeries || focusedSeries === 0) { + canvasNode.find('div.legend table .legendLabel>span').get(focusedSeries).focus(); + } + } + }, + [focusedSeries, canvasElem, toggleSeries, focusSeries, highlightSeries] + ); + + const updatePlot = useCallback( + (chartValue: Series[], grid?: boolean) => { + if (canvasElem && canvasElem.clientWidth > 0 && canvasElem.clientHeight > 0) { + const options = buildOptions( + interval, + kibana.services.timefilter, + kibana.services.uiSettings, + chartElem?.clientWidth, + grid + ); + const updatedSeries = buildSeriesData(chartValue, options); + + if (options.yaxes) { + options.yaxes.forEach((yaxis: Axis) => { + if (yaxis && yaxis.units) { + const formatters = tickFormatters(); + yaxis.tickFormatter = formatters[yaxis.units.type as keyof typeof formatters]; + const byteModes = ['bytes', 'bytes/s']; + if (byteModes.includes(yaxis.units.type)) { + yaxis.tickGenerator = generateTicksProvider(); + } + } + }); + } + + const newPlot = $.plot($(canvasElem), updatedSeries, options); + setPlot(newPlot); + renderComplete(); + + updateCaption(newPlot.getData()); + } + }, + [canvasElem, chartElem?.clientWidth, renderComplete, kibana.services, interval, updateCaption] + ); + + const dimensions = useResizeObserver(chartElem); + + useEffect(() => { + updatePlot(chart, seriesList.render && seriesList.render.grid); + }, [chart, updatePlot, seriesList.render, dimensions]); + + useEffect(() => { + const colorsSet: Array<[Series, string]> = []; + const newChart = seriesList.list.map((series: Series, seriesIndex: number) => { + const newSeries = { ...series }; + if (!newSeries.color) { + const colorIndex = seriesIndex % colors.length; + newSeries.color = colors[colorIndex]; + } + colorsSet.push([newSeries, newSeries.color]); + return newSeries; + }); + setChart(newChart); + setOriginalColorMap(new Map(colorsSet)); + }, [seriesList.list]); + + const unhighlightSeries = useCallback(() => { + if (highlightedSeries === null) { + return; + } + + setHighlightedSeries(null); + setFocusedSeries(null); + + setChart((chartState) => + chartState.map((series: Series) => { + series.color = originalColorMap.get(series); // reset the colors + return series; + }) + ); + }, [originalColorMap, highlightedSeries]); + + // Shamelessly borrowed from the flotCrosshairs example + const setLegendNumbers = useCallback( + (pos: Position) => { + unhighlightSeries(); + + const axes = plot!.getAxes(); + if (pos.x < axes.xaxis.min! || pos.x > axes.xaxis.max!) { + return; + } + + const dataset = plot!.getData(); + if (legendCaption) { + legendCaption.text( + moment(pos.x).format(get(dataset, '[0]._global.legend.timeFormat', DEFAULT_TIME_FORMAT)) + ); + } + for (let i = 0; i < dataset.length; ++i) { + const series = dataset[i]; + const useNearestPoint = series.lines!.show && !series.lines!.steps; + const precision = get(series, '_meta.precision', 2); + + // We're setting this flag on top on the series object belonging to the flot library, so we're simply casting here. + if ((series as { _hide?: boolean })._hide) { + continue; + } + + const currentPoint = series.data.find((point: [number, number], index: number) => { + if (index + 1 === series.data.length) { + return true; + } + if (useNearestPoint) { + return pos.x - point[0] < series.data[index + 1][0] - pos.x; + } else { + return pos.x < series.data[index + 1][0]; + } + }); + + const y = currentPoint[1]; + + if (legendValueNumbers) { + if (y == null) { + legendValueNumbers.eq(i).empty(); + } else { + let label = y.toFixed(precision); + const formatter = ((series.yaxis as unknown) as Axis).tickFormatter; + if (formatter) { + label = formatter(Number(label), (series.yaxis as unknown) as Axis); + } + legendValueNumbers.eq(i).text(`(${label})`); + } + } + } + }, + [plot, legendValueNumbers, unhighlightSeries, legendCaption] + ); + + /* eslint-disable-next-line react-hooks/exhaustive-deps */ + const debouncedSetLegendNumbers = useCallback( + debounce(setLegendNumbers, DEBOUNCE_DELAY, { + maxWait: DEBOUNCE_DELAY, + leading: true, + trailing: false, + }), + [setLegendNumbers] + ); + + const clearLegendNumbers = useCallback(() => { + if (legendCaption) { + legendCaption.html(emptyCaption); + } + each(legendValueNumbers!, (num: Node) => { + $(num).empty(); + }); + }, [legendCaption, legendValueNumbers]); + + const plotHoverHandler = useCallback( + (event: JQuery.TriggeredEvent, pos: Position) => { + if (!plot) { + return; + } + (plot as CrosshairPlot).setCrosshair(pos); + debouncedSetLegendNumbers(pos); + }, + [plot, debouncedSetLegendNumbers] + ); + const mouseLeaveHandler = useCallback(() => { + if (!plot) { + return; + } + (plot as CrosshairPlot).clearCrosshair(); + clearLegendNumbers(); + }, [plot, clearLegendNumbers]); + + const plotSelectedHandler = useCallback( + (event: JQuery.TriggeredEvent, ranges: Ranges) => { + fireEvent({ + name: 'applyFilter', + data: { + timeFieldName: '*', + filters: [ + { + range: { + '*': { + gte: ranges.xaxis.from, + lte: ranges.xaxis.to, + }, + }, + }, + ], + }, + }); + }, + [fireEvent] + ); + + useEffect(() => { + if (chartElem) { + $(chartElem).off('plotselected').on('plotselected', plotSelectedHandler); + } + }, [chartElem, plotSelectedHandler]); + + useEffect(() => { + if (chartElem) { + $(chartElem).off('mouseleave').on('mouseleave', mouseLeaveHandler); + } + }, [chartElem, mouseLeaveHandler]); + + useEffect(() => { + if (chartElem) { + $(chartElem).off('plothover').on('plothover', plotHoverHandler); + } + }, [chartElem, plotHoverHandler]); + + const title: string = useMemo(() => last(compact(map(seriesList.list, '_title'))) || '', [ + seriesList.list, + ]); + + return ( +
+
{title}
+
+
+ ); +} + +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { TimelionVisComponent as default }; diff --git a/src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts b/src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts index 3442f84599fb8..975d12a152d89 100644 --- a/src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts +++ b/src/plugins/vis_type_timelion/public/helpers/timelion_request_handler.ts @@ -19,10 +19,10 @@ import { i18n } from '@kbn/i18n'; import { KIBANA_CONTEXT_NAME } from 'src/plugins/expressions/public'; -import { VisParams } from '../../../visualizations/public'; import { TimeRange, Filter, esQuery, Query } from '../../../data/public'; import { TimelionVisDependencies } from '../plugin'; import { getTimezone } from './get_timezone'; +import { TimelionVisParams } from '../timelion_vis_fn'; interface Stats { cacheCount: number; @@ -77,7 +77,7 @@ export function getTimelionRequestHandler({ timeRange: TimeRange; filters: Filter[]; query: Query; - visParams: VisParams; + visParams: TimelionVisParams; }): Promise { const expression = visParams.expression; diff --git a/src/plugins/vis_type_timelion/public/index.scss b/src/plugins/vis_type_timelion/public/index.scss deleted file mode 100644 index 00e9a88520961..0000000000000 --- a/src/plugins/vis_type_timelion/public/index.scss +++ /dev/null @@ -1,3 +0,0 @@ -@import './timelion_vis'; -@import './timelion_editor'; -@import './components/index'; diff --git a/src/plugins/vis_type_timelion/public/plugin.ts b/src/plugins/vis_type_timelion/public/plugin.ts index e2c7efec34c7f..bb8fb6b298a07 100644 --- a/src/plugins/vis_type_timelion/public/plugin.ts +++ b/src/plugins/vis_type_timelion/public/plugin.ts @@ -39,8 +39,8 @@ import { getTimelionVisDefinition } from './timelion_vis_type'; import { setIndexPatterns, setSavedObjectsClient } from './helpers/plugin_services'; import { ConfigSchema } from '../config'; -import './index.scss'; import { getArgValueSuggestions } from './helpers/arg_value_suggestions'; +import { getTimelionVisRenderer } from './timelion_vis_renderer'; /** @internal */ export interface TimelionVisDependencies extends Partial { @@ -93,7 +93,8 @@ export class TimelionVisPlugin }; expressions.registerFunction(() => getTimelionVisualizationConfig(dependencies)); - visualizations.createReactVisualization(getTimelionVisDefinition(dependencies)); + expressions.registerRenderer(getTimelionVisRenderer(dependencies)); + visualizations.createBaseVisualization(getTimelionVisDefinition(dependencies)); return { isUiEnabled: this.initializerContext.config.get().ui.enabled, diff --git a/src/plugins/vis_type_timelion/public/timelion_options.tsx b/src/plugins/vis_type_timelion/public/timelion_options.tsx index dfe017d3a273f..1ef8088c7a714 100644 --- a/src/plugins/vis_type_timelion/public/timelion_options.tsx +++ b/src/plugins/vis_type_timelion/public/timelion_options.tsx @@ -21,30 +21,45 @@ import React, { useCallback } from 'react'; import { EuiPanel } from '@elastic/eui'; import { VisOptionsProps } from 'src/plugins/vis_default_editor/public'; -import { VisParams } from './timelion_vis_fn'; +import { KibanaContextProvider } from '../../kibana_react/public'; + +import { TimelionVisParams } from './timelion_vis_fn'; import { TimelionInterval, TimelionExpressionInput } from './components'; +import { TimelionVisDependencies } from './plugin'; -export type TimelionOptionsProps = VisOptionsProps; +export type TimelionOptionsProps = VisOptionsProps; -function TimelionOptions({ stateParams, setValue, setValidity }: TimelionOptionsProps) { - const setInterval = useCallback((value: VisParams['interval']) => setValue('interval', value), [ - setValue, - ]); +function TimelionOptions({ + services, + stateParams, + setValue, + setValidity, +}: TimelionOptionsProps & { + services: TimelionVisDependencies; +}) { + const setInterval = useCallback( + (value: TimelionVisParams['interval']) => setValue('interval', value), + [setValue] + ); const setExpressionInput = useCallback( - (value: VisParams['expression']) => setValue('expression', value), + (value: TimelionVisParams['expression']) => setValue('expression', value), [setValue] ); return ( - - - - + + + + + + ); } -export { TimelionOptions }; +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { TimelionOptions as default }; diff --git a/src/plugins/vis_type_timelion/public/timelion_vis_fn.ts b/src/plugins/vis_type_timelion/public/timelion_vis_fn.ts index d3c6ca5d90371..a0cd410e197ff 100644 --- a/src/plugins/vis_type_timelion/public/timelion_vis_fn.ts +++ b/src/plugins/vis_type_timelion/public/timelion_vis_fn.ts @@ -24,29 +24,39 @@ import { KibanaContext, Render, } from 'src/plugins/expressions/public'; -import { getTimelionRequestHandler } from './helpers/timelion_request_handler'; +import { + getTimelionRequestHandler, + TimelionSuccessResponse, +} from './helpers/timelion_request_handler'; import { TIMELION_VIS_NAME } from './timelion_vis_type'; import { TimelionVisDependencies } from './plugin'; import { Filter, Query, TimeRange } from '../../data/common'; type Input = KibanaContext | null; -type Output = Promise>; +type Output = Promise>; interface Arguments { expression: string; interval: string; } -interface RenderValue { - visData: Input; +export interface TimelionRenderValue { + visData: TimelionSuccessResponse; visType: 'timelion'; - visParams: VisParams; + visParams: TimelionVisParams; } -export type VisParams = Arguments; +export type TimelionVisParams = Arguments; + +export type TimelionExpressionFunctionDefinition = ExpressionFunctionDefinition< + 'timelion_vis', + Input, + Arguments, + Output +>; export const getTimelionVisualizationConfig = ( dependencies: TimelionVisDependencies -): ExpressionFunctionDefinition<'timelion_vis', Input, Arguments, Output> => ({ +): TimelionExpressionFunctionDefinition => ({ name: 'timelion_vis', type: 'render', inputTypes: ['kibana_context', 'null'], @@ -82,7 +92,7 @@ export const getTimelionVisualizationConfig = ( return { type: 'render', - as: 'visualization', + as: 'timelion_vis', value: { visParams, visType: TIMELION_VIS_NAME, diff --git a/src/plugins/vis_type_timelion/public/timelion_vis_renderer.tsx b/src/plugins/vis_type_timelion/public/timelion_vis_renderer.tsx new file mode 100644 index 0000000000000..13a279138a8e4 --- /dev/null +++ b/src/plugins/vis_type_timelion/public/timelion_vis_renderer.tsx @@ -0,0 +1,65 @@ +/* + * 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, { lazy } from 'react'; +import { render, unmountComponentAtNode } from 'react-dom'; + +import { ExpressionRenderDefinition } from 'src/plugins/expressions'; +import { KibanaContextProvider } from '../../kibana_react/public'; +import { VisualizationContainer } from '../../visualizations/public'; +import { TimelionVisDependencies } from './plugin'; +import { TimelionRenderValue } from './timelion_vis_fn'; +// @ts-ignore +const TimelionVisComponent = lazy(() => import('./components/timelion_vis_component')); + +export const getTimelionVisRenderer: ( + deps: TimelionVisDependencies +) => ExpressionRenderDefinition = (deps) => ({ + name: 'timelion_vis', + displayName: 'Timelion visualization', + reuseDomNode: true, + render: (domNode, { visData, visParams }, handlers) => { + handlers.onDestroy(() => { + unmountComponentAtNode(domNode); + }); + + const [seriesList] = visData.sheet; + const showNoResult = !seriesList || !seriesList.list.length; + + if (showNoResult) { + // send the render complete event when there is no data to show + // to notify that a chart is updated + handlers.done(); + } + + render( + + + + + , + domNode + ); + }, +}); diff --git a/src/plugins/vis_type_timelion/public/timelion_vis_type.tsx b/src/plugins/vis_type_timelion/public/timelion_vis_type.tsx index 8fdde175708e0..a5425478e46ac 100644 --- a/src/plugins/vis_type_timelion/public/timelion_vis_type.tsx +++ b/src/plugins/vis_type_timelion/public/timelion_vis_type.tsx @@ -17,18 +17,19 @@ * under the License. */ -import React from 'react'; +import React, { lazy } from 'react'; import { i18n } from '@kbn/i18n'; -import { KibanaContextProvider } from '../../kibana_react/public'; import { DefaultEditorSize } from '../../vis_default_editor/public'; import { getTimelionRequestHandler } from './helpers/timelion_request_handler'; -import { TimelionVisComponent, TimelionVisComponentProp } from './components'; -import { TimelionOptions, TimelionOptionsProps } from './timelion_options'; +import { TimelionOptionsProps } from './timelion_options'; import { TimelionVisDependencies } from './plugin'; +import { toExpressionAst } from './to_ast'; import { VIS_EVENT_TO_TRIGGER } from '../../visualizations/public'; +const TimelionOptions = lazy(() => import('./timelion_options')); + export const TIMELION_VIS_NAME = 'timelion'; export function getTimelionVisDefinition(dependencies: TimelionVisDependencies) { @@ -48,21 +49,15 @@ export function getTimelionVisDefinition(dependencies: TimelionVisDependencies) expression: '.es(*)', interval: 'auto', }, - component: (props: TimelionVisComponentProp) => ( - - - - ), }, editorConfig: { optionsTemplate: (props: TimelionOptionsProps) => ( - - - + ), defaultSize: DefaultEditorSize.MEDIUM, }, requestHandler: timelionRequestHandler, + toExpressionAst, responseHandler: 'none', inspectorAdapters: {}, getSupportedTriggers: () => { diff --git a/src/plugins/vis_type_timelion/public/to_ast.test.ts b/src/plugins/vis_type_timelion/public/to_ast.test.ts new file mode 100644 index 0000000000000..8a9d4b83f94d2 --- /dev/null +++ b/src/plugins/vis_type_timelion/public/to_ast.test.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 { Vis } from 'src/plugins/visualizations/public'; +import { TimelionVisParams } from './timelion_vis_fn'; +import { toExpressionAst } from './to_ast'; + +describe('timelion vis toExpressionAst function', () => { + let vis: Vis; + + beforeEach(() => { + vis = { + params: { + expression: '.es(*)', + interval: 'auto', + }, + } as any; + }); + + it('should match basic snapshot', () => { + const actual = toExpressionAst(vis); + expect(actual).toMatchSnapshot(); + }); +}); diff --git a/src/plugins/vis_type_timelion/public/to_ast.ts b/src/plugins/vis_type_timelion/public/to_ast.ts new file mode 100644 index 0000000000000..7044bbf4e5831 --- /dev/null +++ b/src/plugins/vis_type_timelion/public/to_ast.ts @@ -0,0 +1,37 @@ +/* + * 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 { buildExpression, buildExpressionFunction } from '../../expressions/public'; +import { Vis } from '../../visualizations/public'; +import { TimelionExpressionFunctionDefinition, TimelionVisParams } from './timelion_vis_fn'; + +const escapeString = (data: string): string => { + return data.replace(/\\/g, `\\\\`).replace(/'/g, `\\'`); +}; + +export const toExpressionAst = (vis: Vis) => { + const timelion = buildExpressionFunction('timelion_vis', { + expression: escapeString(vis.params.expression), + interval: escapeString(vis.params.interval), + }); + + const ast = buildExpression([timelion]); + + return ast.toAst(); +}; diff --git a/src/plugins/vis_type_timeseries/common/vis_schema.ts b/src/plugins/vis_type_timeseries/common/vis_schema.ts index d3d863df8617f..b33215934c5df 100644 --- a/src/plugins/vis_type_timeseries/common/vis_schema.ts +++ b/src/plugins/vis_type_timeseries/common/vis_schema.ts @@ -111,7 +111,7 @@ export const metricsItems = schema.object({ field: stringOptionalNullable, mode: schema.oneOf([schema.literal('line'), schema.literal('band')]), shade: schema.oneOf([numberOptional, stringOptionalNullable]), - value: schema.oneOf([numberOptional, stringOptionalNullable]), + value: schema.maybe(schema.oneOf([numberOptional, stringOptionalNullable])), percentile: stringOptionalNullable, }) ) diff --git a/src/plugins/vis_type_timeseries/public/application/components/splits/terms.test.js b/src/plugins/vis_type_timeseries/public/application/components/splits/terms.test.js index 4d322cd7b7e61..da840adb75cd3 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/splits/terms.test.js +++ b/src/plugins/vis_type_timeseries/public/application/components/splits/terms.test.js @@ -23,12 +23,12 @@ import { SplitByTermsUI } from './terms'; jest.mock('@elastic/eui', () => ({ htmlIdGenerator: jest.fn(() => () => '42'), - EuiFlexGroup: require.requireActual('@elastic/eui').EuiFlexGroup, - EuiFlexItem: require.requireActual('@elastic/eui').EuiFlexItem, - EuiFormRow: require.requireActual('@elastic/eui').EuiFormRow, - EuiFieldNumber: require.requireActual('@elastic/eui').EuiFieldNumber, - EuiComboBox: require.requireActual('@elastic/eui').EuiComboBox, - EuiFieldText: require.requireActual('@elastic/eui').EuiFieldText, + EuiFlexGroup: jest.requireActual('@elastic/eui').EuiFlexGroup, + EuiFlexItem: jest.requireActual('@elastic/eui').EuiFlexItem, + EuiFormRow: jest.requireActual('@elastic/eui').EuiFormRow, + EuiFieldNumber: jest.requireActual('@elastic/eui').EuiFieldNumber, + EuiComboBox: jest.requireActual('@elastic/eui').EuiComboBox, + EuiFieldText: jest.requireActual('@elastic/eui').EuiFieldText, })); describe('src/legacy/core_plugins/metrics/public/components/splits/terms.test.js', () => { diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js index c14148d4a020f..2434285bd94c6 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js @@ -163,14 +163,9 @@ export class TimeseriesVisualization extends Component { const mainAxisGroupId = yAxisIdGenerator('main_group'); const seriesModel = model.series.filter((s) => !s.hidden).map((s) => cloneDeep(s)); - const firstSeries = seriesModel.find((s) => s.formatter && !s.separate_axis); const mainAxisScaleType = TimeseriesVisualization.getAxisScaleType(model); const mainAxisDomain = TimeseriesVisualization.getYAxisDomain(model); - const tickFormatter = TimeseriesVisualization.getTickFormatter( - firstSeries, - this.props.getConfig - ); const yAxis = []; let mainDomainAdded = false; @@ -203,7 +198,7 @@ export class TimeseriesVisualization extends Component { series .filter((r) => startsWith(r.id, seriesGroup.id)) .forEach((seriesDataRow) => { - seriesDataRow.tickFormatter = seriesGroupTickFormatter; + seriesDataRow.tickFormat = seriesGroupTickFormatter; seriesDataRow.groupId = groupId; seriesDataRow.yScaleType = yScaleType; seriesDataRow.hideInLegend = Boolean(seriesGroup.hide_in_legend); @@ -224,7 +219,7 @@ export class TimeseriesVisualization extends Component { }); } else if (!mainDomainAdded) { TimeseriesVisualization.addYAxis(yAxis, { - tickFormatter, + tickFormatter: series.length === 1 ? undefined : (val) => val, id: yAxisIdGenerator('main'), groupId: mainAxisGroupId, position: model.axis_position, diff --git a/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/decorators/area_decorator.js b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/decorators/area_decorator.js index 300af551e5020..561c985b3b5c3 100644 --- a/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/decorators/area_decorator.js +++ b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/decorators/area_decorator.js @@ -42,6 +42,7 @@ export function AreaSeriesDecorator({ sortIndex, y1AccessorFormat, y0AccessorFormat, + tickFormat, }) { const id = seriesId; const groupId = seriesGroupId; @@ -67,6 +68,7 @@ export function AreaSeriesDecorator({ enableHistogramMode, useDefaultGroupDomain, sortIndex, + tickFormat, ...areaSeriesStyle, }; diff --git a/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/decorators/bar_decorator.js b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/decorators/bar_decorator.js index 239f1d4f1838e..2d6c54de41431 100644 --- a/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/decorators/bar_decorator.js +++ b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/decorators/bar_decorator.js @@ -41,6 +41,7 @@ export function BarSeriesDecorator({ sortIndex, y1AccessorFormat, y0AccessorFormat, + tickFormat, }) { const id = seriesId; const groupId = seriesGroupId; @@ -66,6 +67,7 @@ export function BarSeriesDecorator({ enableHistogramMode, useDefaultGroupDomain, sortIndex, + tickFormat, ...barSeriesStyle, }; diff --git a/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js index 5f0cc5188b1fd..1209a105af805 100644 --- a/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js +++ b/src/plugins/vis_type_timeseries/public/application/visualizations/views/timeseries/index.js @@ -176,6 +176,7 @@ export const TimeSeries = ({ useDefaultGroupDomain, y1AccessorFormat, y0AccessorFormat, + tickFormat, }, sortIndex ) => { @@ -207,6 +208,7 @@ export const TimeSeries = ({ sortIndex={sortIndex} y1AccessorFormat={y1AccessorFormat} y0AccessorFormat={y0AccessorFormat} + tickFormat={tickFormat} /> ); } @@ -233,6 +235,7 @@ export const TimeSeries = ({ sortIndex={sortIndex} y1AccessorFormat={y1AccessorFormat} y0AccessorFormat={y0AccessorFormat} + tickFormat={tickFormat} /> ); } diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/get_annotations.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/get_annotations.js index d8a230dfeef4e..32109e99ab17e 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/get_annotations.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/get_annotations.js @@ -55,7 +55,7 @@ export async function getAnnotations({ if (!searches.length) return { responses: [] }; try { - const data = await searchStrategy.search(req.framework.core, req.requestContext, searches); + const data = await searchStrategy.search(req, searches); return annotations.reduce((acc, annotation, index) => { acc[annotation.id] = handleAnnotationResponseBy(data[index].rawResponse, annotation); diff --git a/src/plugins/vis_type_vega/kibana.json b/src/plugins/vis_type_vega/kibana.json index 231e252fe2c8a..f889db21d7474 100644 --- a/src/plugins/vis_type_vega/kibana.json +++ b/src/plugins/vis_type_vega/kibana.json @@ -4,5 +4,6 @@ "server": true, "ui": true, "requiredPlugins": ["data", "visualizations", "mapsLegacy", "expressions", "inspector"], + "optionalPlugins": ["home","usageCollection"], "requiredBundles": ["kibanaUtils", "kibanaReact", "visDefaultEditor"] } diff --git a/src/plugins/vis_type_vega/public/__snapshots__/vega_visualization.test.js.snap b/src/plugins/vis_type_vega/public/__snapshots__/vega_visualization.test.js.snap index 639559dff3091..8b813ee06b1b3 100644 --- a/src/plugins/vis_type_vega/public/__snapshots__/vega_visualization.test.js.snap +++ b/src/plugins/vis_type_vega/public/__snapshots__/vega_visualization.test.js.snap @@ -1,9 +1,9 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`VegaVisualizations VegaVisualization - basics should show vega blank rectangle on top of a map (vegamap) 1`] = `"
"`; +exports[`VegaVisualizations VegaVisualization - basics should show vega blank rectangle on top of a map (vegamap) 1`] = `"
"`; -exports[`VegaVisualizations VegaVisualization - basics should show vega graph (may fail in dev env) 1`] = `"
"`; +exports[`VegaVisualizations VegaVisualization - basics should show vega graph (may fail in dev env) 1`] = `"
"`; -exports[`VegaVisualizations VegaVisualization - basics should show vegalite graph and update on resize (may fail in dev env) 1`] = `"
"`; +exports[`VegaVisualizations VegaVisualization - basics should show vegalite graph and update on resize (may fail in dev env) 1`] = `"
  • \\"width\\" and \\"height\\" params are ignored because \\"autosize\\" is enabled. Set \\"autosize\\": \\"none\\" to disable
"`; -exports[`VegaVisualizations VegaVisualization - basics should show vegalite graph and update on resize (may fail in dev env) 2`] = `"
"`; +exports[`VegaVisualizations VegaVisualization - basics should show vegalite graph and update on resize (may fail in dev env) 2`] = `"
  • \\"width\\" and \\"height\\" params are ignored because \\"autosize\\" is enabled. Set \\"autosize\\": \\"none\\" to disable
"`; diff --git a/src/plugins/vis_type_vega/public/data_model/types.ts b/src/plugins/vis_type_vega/public/data_model/types.ts index 14848bf5e8739..11bdf4f064023 100644 --- a/src/plugins/vis_type_vega/public/data_model/types.ts +++ b/src/plugins/vis_type_vega/public/data_model/types.ts @@ -43,10 +43,17 @@ interface Encoding { y: Coordinate; } -interface AutoSize { - type: string; - contains: string; -} +type AutoSize = + | 'pad' + | 'fit' + | 'fit-x' + | 'fit-y' + | 'none' + | { + type: string; + contains: string; + } + | { signal: string }; interface Padding { left: number; @@ -105,8 +112,8 @@ export interface VegaSpec { title?: string; autosize?: AutoSize; projections?: Projection[]; - width?: number; - height?: number; + width?: number | 'container'; + height?: number | 'container'; padding?: number | Padding; _hostConfig?: KibanaConfig; config: VegaSpecConfig; diff --git a/src/plugins/vis_type_vega/public/data_model/vega_parser.test.js b/src/plugins/vis_type_vega/public/data_model/vega_parser.test.js index 5c7656efe925b..c9f8e0a4394ec 100644 --- a/src/plugins/vis_type_vega/public/data_model/vega_parser.test.js +++ b/src/plugins/vis_type_vega/public/data_model/vega_parser.test.js @@ -371,43 +371,95 @@ describe('VegaParser._parseConfig', () => { test('_hostConfig', check({ _hostConfig: { a: 1 } }, { a: 1 }, {}, 1)); }); -describe('VegaParser._calcSizing', () => { - function check( - spec, - useResize, - paddingWidth, - paddingHeight, - isVegaLite, - expectedSpec, - warnCount - ) { +describe('VegaParser._compileWithAutosize', () => { + function check(spec, useResize, expectedSpec, warnCount) { return async () => { expectedSpec = expectedSpec || cloneDeep(spec); const vp = new VegaParser(spec); - vp.isVegaLite = !!isVegaLite; - vp._calcSizing(); + vp._compileWithAutosize(); expect(vp.useResize).toEqual(useResize); - expect(vp.paddingWidth).toEqual(paddingWidth); - expect(vp.paddingHeight).toEqual(paddingHeight); expect(vp.spec).toEqual(expectedSpec); expect(vp.warnings).toHaveLength(warnCount || 0); }; } - test('no size', check({ autosize: {} }, false, 0, 0)); - test('fit', check({ autosize: 'fit' }, true, 0, 0)); - test('fit obj', check({ autosize: { type: 'fit' } }, true, 0, 0)); - test('padding const', check({ autosize: 'fit', padding: 10 }, true, 20, 20)); test( - 'padding obj', - check({ autosize: 'fit', padding: { left: 5, bottom: 7, right: 6, top: 8 } }, true, 11, 15) + 'empty config', + check({}, true, { + autosize: { type: 'fit', contains: 'padding' }, + width: 'container', + height: 'container', + }) + ); + test( + 'no warnings for default config', + check({ width: 'container', height: 'container' }, true, { + autosize: { type: 'fit', contains: 'padding' }, + width: 'container', + height: 'container', + }) + ); + test( + 'warning when attempting to use invalid setting', + check( + { width: '300', height: '300' }, + true, + { + autosize: { type: 'fit', contains: 'padding' }, + width: 'container', + height: 'container', + }, + 1 + ) ); test( - 'width height', - check({ autosize: 'fit', width: 1, height: 2 }, true, 0, 0, false, false, 1) + 'autosize none', + check({ autosize: 'none' }, false, { autosize: { type: 'none', contains: 'padding' } }) + ); + test( + 'autosize=fit', + check({ autosize: 'fit' }, true, { + autosize: { type: 'fit', contains: 'padding' }, + width: 'container', + height: 'container', + }) ); test( - 'VL width height', - check({ autosize: 'fit', width: 1, height: 2 }, true, 0, 0, true, { autosize: 'fit' }, 0) + 'autosize=pad', + check({ autosize: 'pad' }, true, { + autosize: { type: 'pad', contains: 'padding' }, + width: 'container', + height: 'container', + }) + ); + test( + 'empty autosize object', + check({ autosize: {} }, true, { + autosize: { type: 'fit', contains: 'padding' }, + height: 'container', + width: 'container', + }) + ); + test( + 'warning on falsy arguments', + check( + { autosize: false }, + true, + { + autosize: { type: 'fit', contains: 'padding' }, + height: 'container', + width: 'container', + }, + 1 + ) + ); + test( + 'partial autosize object', + check({ autosize: { contains: 'content' } }, true, { + autosize: { contains: 'content', type: 'fit' }, + height: 'container', + width: 'container', + }) ); + test('autosize signals are ignored', check({ autosize: { signal: 'asdf' } }, undefined)); }); diff --git a/src/plugins/vis_type_vega/public/data_model/vega_parser.ts b/src/plugins/vis_type_vega/public/data_model/vega_parser.ts index ccb89207e222f..894c34c494c16 100644 --- a/src/plugins/vis_type_vega/public/data_model/vega_parser.ts +++ b/src/plugins/vis_type_vega/public/data_model/vega_parser.ts @@ -75,8 +75,6 @@ export class VegaParser { mapConfig?: object; vlspec?: VegaSpec; useResize?: boolean; - paddingWidth?: number; - paddingHeight?: number; containerDir?: ControlsLocation | ControlsDirection; controlsDir?: ControlsLocation; searchAPI: SearchAPI; @@ -157,9 +155,9 @@ The URL is an identifier only. Kibana and your browser will never access this UR this._parseControlPlacement(); if (this.useMap) { this.mapConfig = this._parseMapConfig(); - } else if (this.spec && this.spec.autosize === undefined) { - // Default autosize should be fit, unless it's a map (leaflet-vega handles that) - this.spec.autosize = { type: 'fit', contains: 'padding' }; + this.useResize = false; + } else if (this.spec) { + this._compileWithAutosize(); } await this._resolveDataUrls(); @@ -167,15 +165,86 @@ The URL is an identifier only. Kibana and your browser will never access this UR if (this.isVegaLite) { this._compileVegaLite(); } + } + + /** + * Ensure that Vega and Vega-Lite will take the full width of the container unless + * the user has explicitly disabled this setting by setting it to "none". + * Also sets the default width to include the padding. This creates the least configuration + * needed for most cases, with the option to do more. + */ + private _compileWithAutosize() { + const defaultAutosize = { + type: 'fit', + contains: 'padding', + }; + + let autosize = this.spec.autosize; + let useResize = true; + + if (!this.isVegaLite && autosize && typeof autosize === 'object' && 'signal' in autosize) { + // Vega supports dynamic autosize information, so we ignore it + return; + } + + if (!autosize && typeof autosize !== 'undefined') { + this._onWarning( + i18n.translate('visTypeVega.vegaParser.autoSizeDoesNotAllowFalse', { + defaultMessage: + '{autoSizeParam} is enabled, it can only be disabled by setting {autoSizeParam} to {noneParam}', + values: { + autoSizeParam: '"autosize"', + noneParam: '"none"', + }, + }) + ); + } + + if (typeof autosize === 'string') { + useResize = autosize !== 'none'; + autosize = { ...defaultAutosize, type: autosize }; + } else if (typeof autosize === 'object') { + autosize = { ...defaultAutosize, ...autosize } as { + type: string; + contains: string; + }; + useResize = Boolean(autosize?.type && autosize?.type !== 'none'); + } else { + autosize = defaultAutosize; + } + + if ( + useResize && + ((this.spec.width && this.spec.width !== 'container') || + (this.spec.height && this.spec.height !== 'container')) + ) { + this._onWarning( + i18n.translate('visTypeVega.vegaParser.widthAndHeightParamsAreIgnored', { + defaultMessage: + '{widthParam} and {heightParam} params are ignored because {autoSizeParam} is enabled. Set {autoSizeParam}: {noneParam} to disable', + values: { + widthParam: '"width"', + heightParam: '"height"', + autoSizeParam: '"autosize"', + noneParam: '"none"', + }, + }) + ); + } - this._calcSizing(); + if (useResize) { + this.spec.width = 'container'; + this.spec.height = 'container'; + } + + this.spec.autosize = autosize; + this.useResize = useResize; } /** * Convert VegaLite to Vega spec - * @private */ - _compileVegaLite() { + private _compileVegaLite() { this.vlspec = this.spec; const logger = vega.logger(vega.Warn); // note: eslint has a false positive here logger.warn = this._onWarning.bind(this); @@ -226,62 +295,6 @@ The URL is an identifier only. Kibana and your browser will never access this UR } } - /** - * Process graph size and padding - * @private - */ - _calcSizing() { - this.useResize = false; - - // Padding is not included in the width/height by default - this.paddingWidth = 0; - this.paddingHeight = 0; - if (this.spec) { - if (!this.useMap) { - // when useResize is true, vega's canvas size will be set based on the size of the container, - // and will be automatically updated on resize events. - // We delete width & height if the autosize is set to "fit" - // We also set useResize=true in case autosize=none, and width & height are not set - const autosize = this.spec.autosize?.type || this.spec.autosize; - if (autosize === 'fit' || (autosize === 'none' && !this.spec.width && !this.spec.height)) { - this.useResize = true; - } - } - - if (this.useResize && this.spec.padding && this.spec.autosize?.contains !== 'padding') { - if (typeof this.spec.padding === 'object') { - this.paddingWidth += (+this.spec.padding.left || 0) + (+this.spec.padding.right || 0); - this.paddingHeight += (+this.spec.padding.top || 0) + (+this.spec.padding.bottom || 0); - } else { - this.paddingWidth += 2 * (+this.spec.padding || 0); - this.paddingHeight += 2 * (+this.spec.padding || 0); - } - } - - if (this.useResize && (this.spec.width || this.spec.height)) { - if (this.isVegaLite) { - delete this.spec.width; - delete this.spec.height; - } else { - this._onWarning( - i18n.translate( - 'visTypeVega.vegaParser.widthAndHeightParamsAreIgnoredWithAutosizeFitWarningMessage', - { - defaultMessage: - 'The {widthParam} and {heightParam} params are ignored with {autosizeParam}', - values: { - autosizeParam: 'autosize=fit', - widthParam: '"width"', - heightParam: '"height"', - }, - } - ) - ); - } - } - } - } - /** * Calculate container-direction CSS property for binding placement * @private diff --git a/src/plugins/vis_type_vega/public/vega_view/vega_base_view.js b/src/plugins/vis_type_vega/public/vega_view/vega_base_view.js index 9b51b68e93bb4..979432b2aed2a 100644 --- a/src/plugins/vis_type_vega/public/vega_view/vega_base_view.js +++ b/src/plugins/vis_type_vega/public/vega_view/vega_base_view.js @@ -193,9 +193,8 @@ export class VegaBaseView { // This might be due to https://github.com/jquery/jquery/issues/3808 // Which is being fixed as part of jQuery 3.3.0 const heightExtraPadding = 6; - const width = Math.max(0, this._$container.width() - this._parser.paddingWidth); - const height = - Math.max(0, this._$container.height() - this._parser.paddingHeight) - heightExtraPadding; + const width = Math.max(0, this._$container.width()); + const height = Math.max(0, this._$container.height()) - heightExtraPadding; if (view.width() !== width || view.height() !== height) { view.width(width).height(height); diff --git a/src/plugins/vis_type_vega/server/index.ts b/src/plugins/vis_type_vega/server/index.ts index 4c809ff3c5a93..b8844c620b562 100644 --- a/src/plugins/vis_type_vega/server/index.ts +++ b/src/plugins/vis_type_vega/server/index.ts @@ -17,9 +17,10 @@ * under the License. */ -import { PluginConfigDescriptor } from 'kibana/server'; +import { PluginConfigDescriptor, PluginInitializerContext } from 'kibana/server'; import { configSchema, ConfigSchema } from '../config'; +import { VisTypeVegaPlugin } from './plugin'; export const config: PluginConfigDescriptor = { exposeToBrowser: { @@ -32,7 +33,8 @@ export const config: PluginConfigDescriptor = { ], }; -export const plugin = () => ({ - setup() {}, - start() {}, -}); +export function plugin(initializerContext: PluginInitializerContext) { + return new VisTypeVegaPlugin(initializerContext); +} + +export { VisTypeVegaPluginStart, VisTypeVegaPluginSetup } from './types'; diff --git a/src/plugins/vis_type_vega/server/plugin.ts b/src/plugins/vis_type_vega/server/plugin.ts new file mode 100644 index 0000000000000..95a02a80ef201 --- /dev/null +++ b/src/plugins/vis_type_vega/server/plugin.ts @@ -0,0 +1,47 @@ +/* + * 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 { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from '../../../core/server'; +import { registerVegaUsageCollector } from './usage_collector'; +import { + ConfigObservable, + VisTypeVegaPluginSetupDependencies, + VisTypeVegaPluginSetup, + VisTypeVegaPluginStart, +} from './types'; + +export class VisTypeVegaPlugin implements Plugin { + private readonly config: ConfigObservable; + + constructor(initializerContext: PluginInitializerContext) { + this.config = initializerContext.config.legacy.globalConfig$; + } + + public setup(core: CoreSetup, { home, usageCollection }: VisTypeVegaPluginSetupDependencies) { + if (usageCollection) { + registerVegaUsageCollector(usageCollection, this.config, { home }); + } + return {}; + } + + public start(core: CoreStart) { + return {}; + } + public stop() {} +} diff --git a/src/plugins/vis_type_vega/server/types.ts b/src/plugins/vis_type_vega/server/types.ts new file mode 100644 index 0000000000000..16a22d6b6aa50 --- /dev/null +++ b/src/plugins/vis_type_vega/server/types.ts @@ -0,0 +1,41 @@ +/* + * 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 { Observable } from 'rxjs'; +import { HomeServerPluginSetup } from '../../home/server'; +import { UsageCollectionSetup } from '../../usage_collection/server'; + +export type ConfigObservable = Observable<{ kibana: { index: string } }>; + +export interface VegaSavedObjectAttributes { + title: string; + type: string; + params: { + spec: string; + }; +} + +export interface VisTypeVegaPluginSetupDependencies { + usageCollection?: UsageCollectionSetup; + home?: HomeServerPluginSetup; +} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface VisTypeVegaPluginSetup {} +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface VisTypeVegaPluginStart {} diff --git a/src/plugins/vis_type_vega/server/usage_collector/get_usage_collector.test.ts b/src/plugins/vis_type_vega/server/usage_collector/get_usage_collector.test.ts new file mode 100644 index 0000000000000..f2854896791c1 --- /dev/null +++ b/src/plugins/vis_type_vega/server/usage_collector/get_usage_collector.test.ts @@ -0,0 +1,172 @@ +/* + * 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 { of } from 'rxjs'; + +import { LegacyAPICaller } from 'src/core/server'; +import { getUsageCollector } from './get_usage_collector'; +import { HomeServerPluginSetup } from '../../../home/server'; + +const mockedSavedObjects = [ + // vega-lite lib spec + { + _id: 'visualization:vega-1', + _source: { + type: 'visualization', + visualization: { + visState: JSON.stringify({ + type: 'vega', + params: { + spec: '{"$schema": "https://vega.github.io/schema/vega-lite/v4.json" }', + }, + }), + }, + }, + }, + // vega lib spec + { + _id: 'visualization:vega-2', + _source: { + type: 'visualization', + visualization: { + visState: JSON.stringify({ + type: 'vega', + params: { + spec: '{"$schema": "https://vega.github.io/schema/vega/v5.json" }', + }, + }), + }, + }, + }, + // map layout + { + _id: 'visualization:vega-3', + _source: { + type: 'visualization', + visualization: { + visState: JSON.stringify({ + type: 'vega', + params: { + spec: + '{"$schema": "https://vega.github.io/schema/vega/v3.json" \n "config": { "kibana" : { "type": "map" }} }', + }, + }), + }, + }, + }, +]; + +const getMockCallCluster = (hits?: unknown[]) => + jest.fn().mockReturnValue(Promise.resolve({ hits: { hits } }) as unknown) as LegacyAPICaller; + +describe('Vega visualization usage collector', () => { + const configMock = of({ kibana: { index: '' } }); + const usageCollector = getUsageCollector(configMock, { + home: ({ + sampleData: { + getSampleDatasets: jest.fn().mockReturnValue([ + { + savedObjects: [ + { + type: 'visualization', + attributes: { + visState: JSON.stringify({ + type: 'vega', + title: 'sample vega visualization', + params: { + spec: '{"$schema": "https://vega.github.io/schema/vega/v5.json" }', + }, + }), + }, + }, + ], + }, + ]), + }, + } as unknown) as HomeServerPluginSetup, + }); + + test('Should fit the shape', () => { + expect(usageCollector.type).toBe('vis_type_vega'); + expect(usageCollector.isReady()).toBe(true); + expect(usageCollector.fetch).toEqual(expect.any(Function)); + }); + + test('Returns undefined when no results found (undefined)', async () => { + const result = await usageCollector.fetch(getMockCallCluster()); + + expect(result).toBeUndefined(); + }); + + test('Returns undefined when no results found (0 results)', async () => { + const result = await usageCollector.fetch(getMockCallCluster([])); + + expect(result).toBeUndefined(); + }); + + test('Returns undefined when no vega saved objects found', async () => { + const result = await usageCollector.fetch( + getMockCallCluster([ + { + _id: 'visualization:myvis-123', + _source: { + type: 'visualization', + visualization: { visState: '{"type": "area"}' }, + }, + }, + ]) + ); + + expect(result).toBeUndefined(); + }); + + test('Should ingnore sample data visualizations', async () => { + const callCluster = getMockCallCluster([ + { + _id: 'visualization:sampledata-123', + _source: { + type: 'visualization', + visualization: { + visState: JSON.stringify({ + type: 'vega', + title: 'sample vega visualization', + params: { + spec: '{"$schema": "https://vega.github.io/schema/vega/v5.json" }', + }, + }), + }, + }, + }, + ]); + + const result = await usageCollector.fetch(callCluster); + + expect(result).toBeUndefined(); + }); + + test('Summarizes visualizations response data', async () => { + const result = await usageCollector.fetch(getMockCallCluster(mockedSavedObjects)); + + expect(result).toMatchObject({ + vega_lib_specs_total: 2, + vega_lite_lib_specs_total: 1, + vega_use_map_total: 1, + }); + }); +}); diff --git a/src/plugins/vis_type_vega/server/usage_collector/get_usage_collector.ts b/src/plugins/vis_type_vega/server/usage_collector/get_usage_collector.ts new file mode 100644 index 0000000000000..d5e691ca48301 --- /dev/null +++ b/src/plugins/vis_type_vega/server/usage_collector/get_usage_collector.ts @@ -0,0 +1,147 @@ +/* + * 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 { parse } from 'hjson'; +import { first } from 'rxjs/operators'; +import { SearchResponse } from 'elasticsearch'; +import { LegacyAPICaller, SavedObject } from 'src/core/server'; + +import { + ConfigObservable, + VegaSavedObjectAttributes, + VisTypeVegaPluginSetupDependencies, +} from '../types'; + +type UsageCollectorDependencies = Pick; + +type ESResponse = SearchResponse<{ visualization: { visState: string } }>; +type VegaType = 'vega' | 'vega-lite'; + +const VEGA_USAGE_TYPE = 'vis_type_vega'; + +function isVegaType(attributes: any): attributes is VegaSavedObjectAttributes { + return attributes && attributes.type === 'vega' && attributes.params?.spec; +} + +const checkVegaSchemaType = (schemaURL: string, type: VegaType) => + schemaURL.includes(`//vega.github.io/schema/${type}/`); + +const getDefaultVegaVisualizations = (home: UsageCollectorDependencies['home']) => { + const titles: string[] = []; + const sampleDataSets = home?.sampleData.getSampleDatasets() ?? []; + + sampleDataSets.forEach((sampleDataSet) => + sampleDataSet.savedObjects.forEach((savedObject: SavedObject) => { + try { + if (savedObject.type === 'visualization') { + const visState = JSON.parse(savedObject.attributes?.visState); + + if (isVegaType(visState)) { + titles.push(visState.title); + } + } + } catch (e) { + // Let it go, visState is invalid and we'll don't need to handle it + } + }) + ); + + return titles; +}; + +const getStats = async ( + callCluster: LegacyAPICaller, + index: string, + { home }: UsageCollectorDependencies +) => { + const searchParams = { + size: 10000, + index, + ignoreUnavailable: true, + filterPath: ['hits.hits._id', 'hits.hits._source.visualization'], + body: { + query: { + bool: { + filter: { term: { type: 'visualization' } }, + }, + }, + }, + }; + const esResponse: ESResponse = await callCluster('search', searchParams); + const size = esResponse?.hits?.hits?.length ?? 0; + let shouldPublishTelemetry = false; + + if (!size) { + return; + } + + // we want to exclude the Vega Sample Data visualizations from the stats + // in order to have more accurate results + const excludedFromStatsVisualizations = getDefaultVegaVisualizations(home); + + const finalTelemetry = esResponse.hits.hits.reduce( + (telemetry, hit) => { + const visualization = hit._source?.visualization; + const visState = JSON.parse(visualization?.visState ?? '{}'); + + if (isVegaType(visState) && !excludedFromStatsVisualizations.includes(visState.title)) + try { + const spec = parse(visState.params.spec, { legacyRoot: false }); + + if (spec) { + shouldPublishTelemetry = true; + if (checkVegaSchemaType(spec.$schema, 'vega')) { + telemetry.vega_lib_specs_total++; + } + if (checkVegaSchemaType(spec.$schema, 'vega-lite')) { + telemetry.vega_lite_lib_specs_total++; + } + if (spec.config?.kibana?.type === 'map') { + telemetry.vega_use_map_total++; + } + } + } catch (e) { + // Let it go, the data is invalid and we'll don't need to handle it + } + + return telemetry; + }, + { + vega_lib_specs_total: 0, + vega_lite_lib_specs_total: 0, + vega_use_map_total: 0, + } + ); + + return shouldPublishTelemetry ? finalTelemetry : undefined; +}; + +export function getUsageCollector( + config: ConfigObservable, + dependencies: UsageCollectorDependencies +) { + return { + type: VEGA_USAGE_TYPE, + isReady: () => true, + fetch: async (callCluster: LegacyAPICaller) => { + const { index } = (await config.pipe(first()).toPromise()).kibana; + + return await getStats(callCluster, index, dependencies); + }, + }; +} diff --git a/src/plugins/vis_type_vega/server/usage_collector/index.ts b/src/plugins/vis_type_vega/server/usage_collector/index.ts new file mode 100644 index 0000000000000..4fc12a14054ec --- /dev/null +++ b/src/plugins/vis_type_vega/server/usage_collector/index.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. + */ + +import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; +import { getUsageCollector } from './get_usage_collector'; +import { ConfigObservable, VisTypeVegaPluginSetupDependencies } from '../types'; + +export function registerVegaUsageCollector( + collectorSet: UsageCollectionSetup, + config: ConfigObservable, + dependencies: Pick +) { + const collector = collectorSet.makeUsageCollector(getUsageCollector(config, dependencies)); + + collectorSet.registerCollector(collector); +} diff --git a/src/plugins/vis_type_vislib/public/vis_controller.tsx b/src/plugins/vis_type_vislib/public/vis_controller.tsx index c422e9f4f3a0a..3a05030f804ca 100644 --- a/src/plugins/vis_type_vislib/public/vis_controller.tsx +++ b/src/plugins/vis_type_vislib/public/vis_controller.tsx @@ -20,8 +20,6 @@ import $ from 'jquery'; import React, { RefObject } from 'react'; -// @ts-ignore -import { Vis as Vislib } from './vislib/vis'; import { Positions } from './utils/collections'; import { VisTypeVislibDependencies } from './plugin'; import { mountReactNode } from '../../../core/public/utils'; @@ -80,6 +78,9 @@ export const createVislibVisController = (deps: VisTypeVislibDependencies) => { return resolve(); } + // @ts-expect-error + const { Vis: Vislib } = await import('./vislib/vis'); + this.vislibVis = new Vislib(this.chartEl, visParams, deps); this.vislibVis.on('brush', this.vis.API.events.brush); this.vislibVis.on('click', this.vis.API.events.filter); diff --git a/src/plugins/visualizations/kibana.json b/src/plugins/visualizations/kibana.json index 0bd5de1d9ee15..bf36bb35d0563 100644 --- a/src/plugins/visualizations/kibana.json +++ b/src/plugins/visualizations/kibana.json @@ -3,6 +3,7 @@ "version": "kibana", "server": true, "ui": true, - "requiredPlugins": ["data", "expressions", "uiActions", "embeddable", "usageCollection", "inspector", "dashboard"], + "requiredPlugins": ["data", "expressions", "uiActions", "embeddable", "inspector", "dashboard"], + "optionalPlugins": ["usageCollection"], "requiredBundles": ["kibanaUtils", "discover", "savedObjects"] } diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts b/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts index c091d396b4924..fe8a9adff4052 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts @@ -167,7 +167,7 @@ export class VisualizeEmbeddable typeof inspectorAdapters === 'function' ? inspectorAdapters() : inspectorAdapters; } } - public getVisualizationDescription() { + public getDescription() { return this.vis.description; } diff --git a/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap b/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap index 654ac78cdaa02..c0c37e2262f9c 100644 --- a/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap +++ b/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap @@ -24,6 +24,4 @@ exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunct exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles tile_map function 1`] = `"tilemap visConfig='{\\"metric\\":{},\\"dimensions\\":{\\"metric\\":{\\"accessor\\":0,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"},\\"geohash\\":1,\\"geocentroid\\":3}}' "`; -exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles timelion function 1`] = `"timelion_vis expression='foo' interval='bar' "`; - exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles vega function 1`] = `"vega spec='this is a test' "`; diff --git a/src/plugins/visualizations/public/legacy/build_pipeline.test.ts b/src/plugins/visualizations/public/legacy/build_pipeline.test.ts index 8cac76726b13b..a1fea45f51781 100644 --- a/src/plugins/visualizations/public/legacy/build_pipeline.test.ts +++ b/src/plugins/visualizations/public/legacy/build_pipeline.test.ts @@ -117,12 +117,6 @@ describe('visualize loader pipeline helpers: build pipeline', () => { expect(actual).toMatchSnapshot(); }); - it('handles timelion function', () => { - const params = { expression: 'foo', interval: 'bar' }; - const actual = buildPipelineVisFunction.timelion(params, schemasDef, uiState); - expect(actual).toMatchSnapshot(); - }); - describe('handles table function', () => { it('without splits or buckets', () => { const params = { foo: 'bar' }; diff --git a/src/plugins/visualizations/public/legacy/build_pipeline.ts b/src/plugins/visualizations/public/legacy/build_pipeline.ts index dcc384a191858..79e1c1cca2155 100644 --- a/src/plugins/visualizations/public/legacy/build_pipeline.ts +++ b/src/plugins/visualizations/public/legacy/build_pipeline.ts @@ -263,11 +263,6 @@ export const buildPipelineVisFunction: BuildPipelineVisFunction = { const paramsArray = [paramsJson, uiStateJson].filter((param) => Boolean(param)); return `tsvb ${paramsArray.join(' ')}`; }, - timelion: (params) => { - const expression = prepareString('expression', params.expression); - const interval = prepareString('interval', params.interval); - return `timelion_vis ${expression}${interval}`; - }, table: (params, schemas) => { const visConfig = { ...params, diff --git a/src/plugins/visualizations/public/vis_types/base_vis_type.ts b/src/plugins/visualizations/public/vis_types/base_vis_type.ts index 149146bf77e73..de1afc254e0d3 100644 --- a/src/plugins/visualizations/public/vis_types/base_vis_type.ts +++ b/src/plugins/visualizations/public/vis_types/base_vis_type.ts @@ -44,7 +44,7 @@ interface CommonBaseVisTypeOptions { useCustomNoDataScreen?: boolean; inspectorAdapters?: Adapters | (() => Adapters); isDeprecated?: boolean; - getDeprecationMessage?: (vis: Vis) => ReactElement; + getDeprecationMessage?: (vis: Vis) => ReactElement<{}>; } interface ExpressionBaseVisTypeOptions extends CommonBaseVisTypeOptions { @@ -84,8 +84,7 @@ export class BaseVisType { useCustomNoDataScreen: boolean; inspectorAdapters?: Adapters | (() => Adapters); toExpressionAst?: VisToExpressionAst; - isDeprecated: boolean; - getDeprecationMessage?: (vis: Vis) => ReactElement; + getDeprecationMessage?: (vis: Vis) => ReactElement<{}>; constructor(opts: BaseVisTypeOptions) { if (!opts.icon && !opts.image) { @@ -123,7 +122,6 @@ export class BaseVisType { this.useCustomNoDataScreen = opts.useCustomNoDataScreen || false; this.inspectorAdapters = opts.inspectorAdapters; this.toExpressionAst = opts.toExpressionAst; - this.isDeprecated = opts.isDeprecated || false; this.getDeprecationMessage = opts.getDeprecationMessage; } diff --git a/src/plugins/visualizations/public/wizard/__snapshots__/new_vis_modal.test.tsx.snap b/src/plugins/visualizations/public/wizard/__snapshots__/new_vis_modal.test.tsx.snap index 0925d1c7cc0c9..c2a2b27457f8d 100644 --- a/src/plugins/visualizations/public/wizard/__snapshots__/new_vis_modal.test.tsx.snap +++ b/src/plugins/visualizations/public/wizard/__snapshots__/new_vis_modal.test.tsx.snap @@ -147,7 +147,6 @@ exports[`NewVisModal filter for visualization types should render as expected 1`
`; diff --git a/x-pack/plugins/canvas/common/lib/index.ts b/x-pack/plugins/canvas/common/lib/index.ts index 055f6ce7739b7..c8ae53917c9e4 100644 --- a/x-pack/plugins/canvas/common/lib/index.ts +++ b/x-pack/plugins/canvas/common/lib/index.ts @@ -20,8 +20,6 @@ export * from './get_colors_from_palette'; export * from './get_field_type'; // @ts-expect-error missing local definition export * from './get_legend_config'; -// @ts-expect-error missing local definition -export * from './handlebars'; export * from './hex_to_rgb'; export * from './httpurl'; export * from './missing_asset'; diff --git a/x-pack/plugins/canvas/i18n/templates/template_strings.test.ts b/x-pack/plugins/canvas/i18n/templates/template_strings.test.ts index 4185ad00e7ed7..f27b3554cacd6 100644 --- a/x-pack/plugins/canvas/i18n/templates/template_strings.test.ts +++ b/x-pack/plugins/canvas/i18n/templates/template_strings.test.ts @@ -5,13 +5,13 @@ */ import { getTemplateStrings } from './template_strings'; -import { templates } from '../../server/templates'; // eslint-disable-line +import { loadTemplates } from '../../server/templates'; // eslint-disable-line import { TagStrings } from '../tags'; describe('TemplateStrings', () => { const templateStrings = getTemplateStrings(); - const templateNames = templates.map((template) => template.name); + const templateNames = loadTemplates().map((template) => template.name); const stringKeys = Object.keys(templateStrings); test('All template names should exist in the strings definition', () => { @@ -39,7 +39,7 @@ describe('TemplateStrings', () => { test('All templates should have tags that are defined', () => { const tagNames = Object.keys(TagStrings); - templates.forEach((template) => { + loadTemplates().forEach((template) => { template.tags.forEach((tagName: string) => expect(tagNames).toContain(tagName)); }); }); diff --git a/x-pack/plugins/canvas/public/expression_types/arg_types/container_style/__stories__/__snapshots__/simple_template.stories.storyshot b/x-pack/plugins/canvas/public/expression_types/arg_types/container_style/__stories__/__snapshots__/simple_template.stories.storyshot index 401e7bf1e937d..495bf5262476c 100644 --- a/x-pack/plugins/canvas/public/expression_types/arg_types/container_style/__stories__/__snapshots__/simple_template.stories.storyshot +++ b/x-pack/plugins/canvas/public/expression_types/arg_types/container_style/__stories__/__snapshots__/simple_template.stories.storyshot @@ -13,50 +13,60 @@ exports[`Storyshots arguments/ContainerStyle simple 1`] = `
- + /> +
+ +
@@ -76,50 +86,60 @@ exports[`Storyshots arguments/ContainerStyle/components simple template 1`] = `
- + /> +
+ +
diff --git a/x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__stories__/__snapshots__/simple_template.stories.storyshot b/x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__stories__/__snapshots__/simple_template.stories.storyshot index f8583d7cd0dc0..b242d90cd7361 100644 --- a/x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__stories__/__snapshots__/simple_template.stories.storyshot +++ b/x-pack/plugins/canvas/public/expression_types/arg_types/series_style/__stories__/__snapshots__/simple_template.stories.storyshot @@ -11,31 +11,41 @@ exports[`Storyshots arguments/SeriesStyle simple 1`] = ` } >
- Color +
+ Color +
-
-
- + +
@@ -53,31 +63,41 @@ exports[`Storyshots arguments/SeriesStyle/components simple: defaults 1`] = ` } >
- Color +
+ Color +
-
-
- + +
@@ -95,31 +115,41 @@ exports[`Storyshots arguments/SeriesStyle/components simple: no labels 1`] = ` } >
- Color +
+ Color +
-
-
- + +
@@ -137,51 +167,61 @@ exports[`Storyshots arguments/SeriesStyle/components simple: no series 1`] = ` } >
- Color +
+ Color +
-
-
- + +
-
-
- -
- + +
+ +
@@ -198,31 +238,41 @@ exports[`Storyshots arguments/SeriesStyle/components simple: with series 1`] = ` } >
- Color +
+ Color +
-
-
- + +
diff --git a/x-pack/plugins/canvas/scripts/storybook_new.js b/x-pack/plugins/canvas/scripts/storybook_new.js deleted file mode 100644 index 4871898b73a45..0000000000000 --- a/x-pack/plugins/canvas/scripts/storybook_new.js +++ /dev/null @@ -1,13 +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 { join } from 'path'; - -// eslint-disable-next-line -require('@kbn/storybook').runStorybookCli({ - name: 'canvas', - storyGlobs: [join(__dirname, '..', '**', '*.stories.tsx')], -}); diff --git a/x-pack/plugins/canvas/server/collectors/collector.ts b/x-pack/plugins/canvas/server/collectors/collector.ts index eb650ca5ad152..39a8262a5deec 100644 --- a/x-pack/plugins/canvas/server/collectors/collector.ts +++ b/x-pack/plugins/canvas/server/collectors/collector.ts @@ -5,11 +5,16 @@ */ import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; -import { LegacyAPICaller } from 'kibana/server'; import { TelemetryCollector } from '../../types'; -import { workpadCollector } from './workpad_collector'; -import { customElementCollector } from './custom_element_collector'; +import { workpadCollector, workpadSchema, WorkpadTelemetry } from './workpad_collector'; +import { + customElementCollector, + CustomElementTelemetry, + customElementSchema, +} from './custom_element_collector'; + +type CanvasUsage = WorkpadTelemetry & CustomElementTelemetry; const collectors: TelemetryCollector[] = [workpadCollector, customElementCollector]; @@ -29,18 +34,19 @@ export function registerCanvasUsageCollector( return; } - const canvasCollector = usageCollection.makeUsageCollector({ + const canvasCollector = usageCollection.makeUsageCollector({ type: 'canvas', isReady: () => true, - fetch: async (callCluster: LegacyAPICaller) => { + fetch: async (callCluster) => { const collectorResults = await Promise.all( collectors.map((collector) => collector(kibanaIndex, callCluster)) ); return collectorResults.reduce((reduction, usage) => { return { ...reduction, ...usage }; - }, {}); + }, {}) as CanvasUsage; // We need the casting because `TelemetryCollector` claims it returns `Record` }, + schema: { ...workpadSchema, ...customElementSchema }, }); usageCollection.registerCollector(canvasCollector); diff --git a/x-pack/plugins/canvas/server/collectors/custom_element_collector.ts b/x-pack/plugins/canvas/server/collectors/custom_element_collector.ts index 7b39e8b83b045..d3ed1e17785ee 100644 --- a/x-pack/plugins/canvas/server/collectors/custom_element_collector.ts +++ b/x-pack/plugins/canvas/server/collectors/custom_element_collector.ts @@ -6,6 +6,7 @@ import { SearchParams } from 'elasticsearch'; import { get } from 'lodash'; +import { MakeSchemaFrom } from 'src/plugins/usage_collection/server'; import { collectFns } from './collector_helpers'; import { TelemetryCollector, @@ -19,7 +20,7 @@ interface CustomElementSearch { [CUSTOM_ELEMENT_TYPE]: TelemetryCustomElementDocument; } -interface CustomElementTelemetry { +export interface CustomElementTelemetry { custom_elements?: { count: number; elements: { @@ -31,6 +32,18 @@ interface CustomElementTelemetry { }; } +export const customElementSchema: MakeSchemaFrom = { + custom_elements: { + count: { type: 'long' }, + elements: { + min: { type: 'long' }, + max: { type: 'long' }, + avg: { type: 'float' }, + }, + functions_in_use: { type: 'array', items: { type: 'keyword' } }, + }, +}; + function isCustomElement(maybeCustomElement: any): maybeCustomElement is TelemetryCustomElement { return ( maybeCustomElement !== null && diff --git a/x-pack/plugins/canvas/server/collectors/workpad_collector.ts b/x-pack/plugins/canvas/server/collectors/workpad_collector.ts index 9fa39c580962d..0479411528802 100644 --- a/x-pack/plugins/canvas/server/collectors/workpad_collector.ts +++ b/x-pack/plugins/canvas/server/collectors/workpad_collector.ts @@ -6,6 +6,7 @@ import { SearchParams } from 'elasticsearch'; import { sum as arraySum, min as arrayMin, max as arrayMax, get } from 'lodash'; +import { MakeSchemaFrom } from 'src/plugins/usage_collection/server'; import { CANVAS_TYPE } from '../../common/lib/constants'; import { collectFns } from './collector_helpers'; import { TelemetryCollector, CanvasWorkpad } from '../../types'; @@ -15,7 +16,7 @@ interface WorkpadSearch { [CANVAS_TYPE]: CanvasWorkpad; } -interface WorkpadTelemetry { +export interface WorkpadTelemetry { workpads?: { total: number; }; @@ -54,6 +55,43 @@ interface WorkpadTelemetry { }; } +export const workpadSchema: MakeSchemaFrom = { + workpads: { total: { type: 'long' } }, + pages: { + total: { type: 'long' }, + per_workpad: { + avg: { type: 'float' }, + min: { type: 'long' }, + max: { type: 'long' }, + }, + }, + elements: { + total: { type: 'long' }, + per_page: { + avg: { type: 'float' }, + min: { type: 'long' }, + max: { type: 'long' }, + }, + }, + functions: { + total: { type: 'long' }, + in_use: { type: 'array', items: { type: 'keyword' } }, + per_element: { + avg: { type: 'float' }, + min: { type: 'long' }, + max: { type: 'long' }, + }, + }, + variables: { + total: { type: 'long' }, + per_workpad: { + avg: { type: 'float' }, + min: { type: 'long' }, + max: { type: 'long' }, + }, + }, +}; + /** Gather statistic about the given workpads @param workpadDocs a collection of workpad documents diff --git a/x-pack/plugins/canvas/server/templates/index.ts b/x-pack/plugins/canvas/server/templates/index.ts index c2723fbc87e17..800ac10fb9cd4 100644 --- a/x-pack/plugins/canvas/server/templates/index.ts +++ b/x-pack/plugins/canvas/server/templates/index.ts @@ -5,15 +5,24 @@ */ import { SavedObjectsRepository } from 'src/core/server'; -import { pitch } from './pitch_presentation'; -import { status } from './status_report'; -import { summary } from './summary_report'; -import { dark } from './theme_dark'; -import { light } from './theme_light'; import { TEMPLATE_TYPE } from '../../common/lib/constants'; -export const templates = [status, summary, dark, light, pitch]; +// only load templates when requested to reduce require() cost on startup +export function loadTemplates() { + return [ + // eslint-disable-next-line @typescript-eslint/no-var-requires + require('./pitch_presentation').pitch, + // eslint-disable-next-line @typescript-eslint/no-var-requires + require('./status_report').status, + // eslint-disable-next-line @typescript-eslint/no-var-requires + require('./summary_report').summary, + // eslint-disable-next-line @typescript-eslint/no-var-requires + require('./theme_dark').dark, + // eslint-disable-next-line @typescript-eslint/no-var-requires + require('./theme_light').light, + ]; +} export async function initializeTemplates( client: Pick @@ -26,7 +35,7 @@ export async function initializeTemplates( // So, rather than doing a bulk create of templates, we're going to fire off individual // creates and catch and throw-away any errors that happen. // Once packages are ready, we should probably move that pitch that is so large to a package - for (const template of templates) { + for (const template of loadTemplates()) { client.create(TEMPLATE_TYPE, template, { id: template.id }).catch((err) => undefined); } } diff --git a/x-pack/plugins/canvas/shareable_runtime/components/__tests__/app.test.tsx b/x-pack/plugins/canvas/shareable_runtime/components/__tests__/app.test.tsx index 4b4f8f7d4de66..eaf45db0a0b93 100644 --- a/x-pack/plugins/canvas/shareable_runtime/components/__tests__/app.test.tsx +++ b/x-pack/plugins/canvas/shareable_runtime/components/__tests__/app.test.tsx @@ -4,10 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -/* - One test relies on react-dom at a version of 16.9... it can be enabled - once renovate completes the upgrade. Relevant code has been commented out - in the meantime. +/* + One test relies on react-dom at a version of 16.9... it can be enabled + once renovate completes the upgrade. Relevant code has been commented out + in the meantime. */ import { mount, ReactWrapper } from 'enzyme'; @@ -40,7 +40,7 @@ jest.mock('@elastic/eui/lib/components/portal/portal', () => { // Local constants are not supported in Jest mocks-- they must be // imported within the mock. // eslint-disable-next-line no-shadow - const React = require.requireActual('react'); + const React = jest.requireActual('react'); return { EuiPortal: (props: any) =>
{props.children}
, }; diff --git a/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__tests__/settings.test.tsx b/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__tests__/settings.test.tsx index 34dacc7956253..28aa6ef90aedb 100644 --- a/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__tests__/settings.test.tsx +++ b/x-pack/plugins/canvas/shareable_runtime/components/footer/settings/__tests__/settings.test.tsx @@ -26,7 +26,7 @@ jest.mock('@elastic/eui/lib/services/accessibility', () => { }); jest.mock('@elastic/eui/lib/components/portal/portal', () => { // eslint-disable-next-line no-shadow - const React = require.requireActual('react'); + const React = jest.requireActual('react'); return { EuiPortal: (props: any) =>
{props.children}
, }; diff --git a/x-pack/plugins/canvas/shareable_runtime/test/index.ts b/x-pack/plugins/canvas/shareable_runtime/test/index.ts index e07d94a6e1054..288dd0dc3a5be 100644 --- a/x-pack/plugins/canvas/shareable_runtime/test/index.ts +++ b/x-pack/plugins/canvas/shareable_runtime/test/index.ts @@ -11,4 +11,11 @@ import test from './workpads/test.json'; export * from './utils'; export type WorkpadNames = keyof typeof sharedWorkpads; -export const sharedWorkpads = { hello, austin, test }; +export const sharedWorkpads = { + // TODO: the automatic types for these JSON files are insufficient, and "austin" is so massive + // that Typescript refuses to type it. These should be converted to TypeScript and typed to fit + // the requirements. "austin" should also be reduced to the necessary data + hello: hello as any, + austin: austin as any, + test: test as any, +}; diff --git a/x-pack/plugins/canvas/storybook/addon/src/register.tsx b/x-pack/plugins/canvas/storybook/addon/src/register.tsx index 4934438789b94..7fcb8832b1ed8 100644 --- a/x-pack/plugins/canvas/storybook/addon/src/register.tsx +++ b/x-pack/plugins/canvas/storybook/addon/src/register.tsx @@ -24,7 +24,7 @@ addons.register(ADDON_ID, (api) => { type: types.PANEL, render: ({ active, key }) => { return ( - + ); diff --git a/x-pack/plugins/canvas/storybook/decorators/index.ts b/x-pack/plugins/canvas/storybook/decorators/index.ts index 8cd716cf7e3f1..c518e7e0daaa3 100644 --- a/x-pack/plugins/canvas/storybook/decorators/index.ts +++ b/x-pack/plugins/canvas/storybook/decorators/index.ts @@ -5,14 +5,6 @@ */ import { addDecorator } from '@storybook/react'; -// @ts-expect-error -import { withInfo } from '@storybook/addon-info'; -import { Provider as ReduxProvider } from 'react-redux'; - -import { ServicesProvider } from '../../public/services'; -import { RouterContext } from '../../public/components/router'; -import { KibanaContextProvider } from '../../../../../src/plugins/kibana_react/public'; - import { routerContextDecorator } from './router_decorator'; import { kibanaContextDecorator } from './kibana_decorator'; import { servicesContextDecorator } from './services_decorator'; @@ -23,22 +15,6 @@ export const addDecorators = () => { if (process.env.NODE_ENV === 'test') { // eslint-disable-next-line @typescript-eslint/no-var-requires require('babel-plugin-require-context-hook/register')(); - } else { - // Customize the info for each story. - addDecorator( - withInfo({ - inline: true, - styles: { - infoBody: { - margin: 20, - }, - infoStory: { - margin: '40px 60px', - }, - }, - propTablesExclude: [ReduxProvider, ServicesProvider, RouterContext, KibanaContextProvider], - }) - ); } addDecorator(kibanaContextDecorator); diff --git a/x-pack/plugins/canvas/storybook/main.ts b/x-pack/plugins/canvas/storybook/main.ts index ad6d10f9bc75f..29952d22e44df 100644 --- a/x-pack/plugins/canvas/storybook/main.ts +++ b/x-pack/plugins/canvas/storybook/main.ts @@ -4,11 +4,20 @@ * you may not use this file except in compliance with the Elastic License. */ +/* eslint-disable @typescript-eslint/no-var-requires */ +const { existsSync } = require('fs'); +const { join } = require('path'); + +// Check for DLL +if (!existsSync(join(__dirname, '../../../../built_assets/canvas_storybook_dll/manifest.json'))) { + // eslint-disable-next-line no-console + console.error( + 'No DLL found. Run `node scripts/storybook --dll` from the Canvas plugin directory.' + ); + process.exit(1); +} + module.exports = { stories: ['../**/*.stories.tsx'], - addons: [ - '@storybook/addon-actions', - '@storybook/addon-knobs', - './storybook/addon/target/register', - ], + addons: ['@storybook/addon-actions', '@storybook/addon-knobs', './addon/target/register'], }; diff --git a/x-pack/plugins/canvas/storybook/storyshots.test.tsx b/x-pack/plugins/canvas/storybook/storyshots.test.tsx index 85ec7baf18c62..44420159c328a 100644 --- a/x-pack/plugins/canvas/storybook/storyshots.test.tsx +++ b/x-pack/plugins/canvas/storybook/storyshots.test.tsx @@ -11,7 +11,7 @@ import moment from 'moment'; import 'moment-timezone'; import ReactDOM from 'react-dom'; -import initStoryshots, { multiSnapshotWithOptions } from '@storybook/addon-storyshots'; +// import initStoryshots, { multiSnapshotWithOptions } from '@storybook/addon-storyshots'; // @ts-expect-error untyped library import styleSheetSerializer from 'jest-styled-components/src/styleSheetSerializer'; import { addSerializer } from 'jest-specific-snapshot'; @@ -104,9 +104,12 @@ if (!fs.existsSync(cssDir)) { addSerializer(styleSheetSerializer); // Initialize Storyshots and build the Jest Snapshots -initStoryshots({ - configPath: path.resolve(__dirname, './../storybook'), - test: multiSnapshotWithOptions({}), - // Don't snapshot tests that start with 'redux' - storyNameRegex: /^((?!.*?redux).)*$/, -}); +// Commenting this out until after #75357 is merged and Jest gets updated. +// initStoryshots({ +// configPath: path.resolve(__dirname, './../storybook'), +// test: multiSnapshotWithOptions({}), +// // Don't snapshot tests that start with 'redux' +// storyNameRegex: /^((?!.*?redux).)*$/, +// }); + +test.todo('Storyshots'); diff --git a/x-pack/plugins/dashboard_enhanced/.storybook/main.js b/x-pack/plugins/dashboard_enhanced/.storybook/main.js new file mode 100644 index 0000000000000..1818aa44a9399 --- /dev/null +++ b/x-pack/plugins/dashboard_enhanced/.storybook/main.js @@ -0,0 +1,7 @@ +/* + * 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. + */ + +module.exports = require('@kbn/storybook').defaultConfig; diff --git a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/menu_item.test.tsx b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/menu_item.test.tsx index 771b15e46ad25..27a8d73f32944 100644 --- a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/menu_item.test.tsx +++ b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/actions/flyout_edit_drilldown/menu_item.test.tsx @@ -5,14 +5,12 @@ */ import React from 'react'; -import { render, cleanup, act } from '@testing-library/react/pure'; +import { render, act } from '@testing-library/react'; import { MenuItem } from './menu_item'; import { createStateContainer } from '../../../../../../../../src/plugins/kibana_utils/public'; import { UiActionsEnhancedDynamicActionManager as DynamicActionManager } from '../../../../../../ui_actions_enhanced/public'; import { EnhancedEmbeddable } from '../../../../../../embeddable_enhanced/public'; -afterEach(cleanup); - test('', () => { const state = createStateContainer<{ events: object[] }>({ events: [] }); const { getByText, queryByText } = render( diff --git a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/components/dashboard_drilldown_config/dashboard_drilldown_config.story.tsx b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/components/dashboard_drilldown_config/dashboard_drilldown_config.stories.tsx similarity index 100% rename from x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/components/dashboard_drilldown_config/dashboard_drilldown_config.story.tsx rename to x-pack/plugins/dashboard_enhanced/public/services/drilldowns/dashboard_to_dashboard_drilldown/components/dashboard_drilldown_config/dashboard_drilldown_config.stories.tsx diff --git a/x-pack/plugins/dashboard_enhanced/scripts/storybook.js b/x-pack/plugins/dashboard_enhanced/scripts/storybook.js deleted file mode 100644 index 5d95c56c31e3b..0000000000000 --- a/x-pack/plugins/dashboard_enhanced/scripts/storybook.js +++ /dev/null @@ -1,13 +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 { join } from 'path'; - -// eslint-disable-next-line -require('@kbn/storybook').runStorybookCli({ - name: 'dashboard_enhanced', - storyGlobs: [join(__dirname, '..', 'public', '**', '*.story.tsx')], -}); diff --git a/x-pack/plugins/data_enhanced/public/autocomplete/providers/kql_query_suggestion/value.ts b/x-pack/plugins/data_enhanced/public/autocomplete/providers/kql_query_suggestion/value.ts index 6f9ba4d00109d..441e5a6f775dd 100644 --- a/x-pack/plugins/data_enhanced/public/autocomplete/providers/kql_query_suggestion/value.ts +++ b/x-pack/plugins/data_enhanced/public/autocomplete/providers/kql_query_suggestion/value.ts @@ -9,6 +9,8 @@ import { escapeQuotes } from './lib/escape_kuery'; import { KqlQuerySuggestionProvider } from './types'; import { getAutocompleteService } from '../../../services'; import { + IFieldType, + IIndexPattern, QuerySuggestion, QuerySuggestionTypes, } from '../../../../../../../src/plugins/data/public'; @@ -23,29 +25,27 @@ const wrapAsSuggestions = (start: number, end: number, query: string, values: st end, })); -export const setupGetValueSuggestions: KqlQuerySuggestionProvider = (core) => { +export const setupGetValueSuggestions: KqlQuerySuggestionProvider = () => { return async ( { indexPatterns, boolFilter, signal }, { start, end, prefix, suffix, fieldName, nestedPath } ): Promise => { - const allFields = flatten( - indexPatterns.map((indexPattern) => - indexPattern.fields.map((field) => ({ - ...field, - indexPattern, - })) - ) - ); - const fullFieldName = nestedPath ? `${nestedPath}.${fieldName}` : fieldName; - const fields = allFields.filter((field) => field.name === fullFieldName); + + const indexPatternFieldEntries: Array<[IIndexPattern, IFieldType]> = []; + indexPatterns.forEach((indexPattern) => { + indexPattern.fields + .filter((field) => field.name === fullFieldName) + .forEach((field) => indexPatternFieldEntries.push([indexPattern, field])); + }); + const query = `${prefix}${suffix}`.trim(); const { getValueSuggestions } = getAutocompleteService(); const data = await Promise.all( - fields.map((field) => + indexPatternFieldEntries.map(([indexPattern, field]) => getValueSuggestions({ - indexPattern: field.indexPattern, + indexPattern, field, query, boolFilter, diff --git a/x-pack/plugins/encrypted_saved_objects/server/config.test.ts b/x-pack/plugins/encrypted_saved_objects/server/config.test.ts index 3f8074eb15c0c..cbe987830717f 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/config.test.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/config.test.ts @@ -6,9 +6,8 @@ jest.mock('crypto', () => ({ randomBytes: jest.fn() })); -import { first } from 'rxjs/operators'; -import { loggingSystemMock, coreMock } from 'src/core/server/mocks'; -import { createConfig$, ConfigSchema } from './config'; +import { loggingSystemMock } from 'src/core/server/mocks'; +import { createConfig, ConfigSchema } from './config'; describe('config schema', () => { it('generates proper defaults', () => { @@ -16,6 +15,9 @@ describe('config schema', () => { Object { "enabled": true, "encryptionKey": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "keyRotation": Object { + "decryptionOnlyKeys": Array [], + }, } `); @@ -23,12 +25,41 @@ describe('config schema', () => { Object { "enabled": true, "encryptionKey": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "keyRotation": Object { + "decryptionOnlyKeys": Array [], + }, } `); expect(ConfigSchema.validate({}, { dist: true })).toMatchInlineSnapshot(` Object { "enabled": true, + "keyRotation": Object { + "decryptionOnlyKeys": Array [], + }, + } + `); + }); + + it('properly validates config', () => { + expect( + ConfigSchema.validate( + { + encryptionKey: 'a'.repeat(32), + keyRotation: { decryptionOnlyKeys: ['b'.repeat(32), 'c'.repeat(32)] }, + }, + { dist: true } + ) + ).toMatchInlineSnapshot(` + Object { + "enabled": true, + "encryptionKey": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "keyRotation": Object { + "decryptionOnlyKeys": Array [ + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "cccccccccccccccccccccccccccccccc", + ], + }, } `); }); @@ -46,21 +77,65 @@ describe('config schema', () => { `"[encryptionKey]: value has length [3] but it must have a minimum length of [32]."` ); }); + + it('should throw error if any of the xpack.encryptedSavedObjects.keyRotation.decryptionOnlyKeys is less than 32 characters', () => { + expect(() => + ConfigSchema.validate({ + keyRotation: { decryptionOnlyKeys: ['a'.repeat(32), 'b'.repeat(31)] }, + }) + ).toThrowErrorMatchingInlineSnapshot( + `"[keyRotation.decryptionOnlyKeys.1]: value has length [31] but it must have a minimum length of [32]."` + ); + + expect(() => + ConfigSchema.validate( + { keyRotation: { decryptionOnlyKeys: ['a'.repeat(32), 'b'.repeat(31)] } }, + { dist: true } + ) + ).toThrowErrorMatchingInlineSnapshot( + `"[keyRotation.decryptionOnlyKeys.1]: value has length [31] but it must have a minimum length of [32]."` + ); + }); + + it('should throw error if any of the xpack.encryptedSavedObjects.keyRotation.decryptionOnlyKeys is equal to xpack.encryptedSavedObjects.encryptionKey', () => { + expect(() => + ConfigSchema.validate({ + encryptionKey: 'a'.repeat(32), + keyRotation: { decryptionOnlyKeys: ['a'.repeat(32)] }, + }) + ).toThrowErrorMatchingInlineSnapshot( + `"\`keyRotation.decryptionOnlyKeys\` cannot contain primary encryption key specified in \`encryptionKey\`."` + ); + + expect(() => + ConfigSchema.validate( + { + encryptionKey: 'a'.repeat(32), + keyRotation: { decryptionOnlyKeys: ['a'.repeat(32)] }, + }, + { dist: true } + ) + ).toThrowErrorMatchingInlineSnapshot( + `"\`keyRotation.decryptionOnlyKeys\` cannot contain primary encryption key specified in \`encryptionKey\`."` + ); + }); }); -describe('createConfig$()', () => { - it('should log a warning, set xpack.encryptedSavedObjects.encryptionKey and usingEphemeralEncryptionKey=true when encryptionKey is not set', async () => { +describe('createConfig()', () => { + it('should log a warning, set xpack.encryptedSavedObjects.encryptionKey and usingEphemeralEncryptionKey=true when encryptionKey is not set', () => { const mockRandomBytes = jest.requireMock('crypto').randomBytes; mockRandomBytes.mockReturnValue('ab'.repeat(16)); - const contextMock = coreMock.createPluginInitializerContext({}); - const config = await createConfig$(contextMock).pipe(first()).toPromise(); + const logger = loggingSystemMock.create().get(); + const config = createConfig(ConfigSchema.validate({}, { dist: true }), logger); expect(config).toEqual({ - config: { encryptionKey: 'ab'.repeat(16) }, + enabled: true, + encryptionKey: 'ab'.repeat(16), + keyRotation: { decryptionOnlyKeys: [] }, usingEphemeralEncryptionKey: true, }); - expect(loggingSystemMock.collect(contextMock.logger).warn).toMatchInlineSnapshot(` + expect(loggingSystemMock.collect(logger).warn).toMatchInlineSnapshot(` Array [ Array [ "Generating a random key for xpack.encryptedSavedObjects.encryptionKey. To be able to decrypt encrypted saved objects attributes after restart, please set xpack.encryptedSavedObjects.encryptionKey in kibana.yml", @@ -70,15 +145,18 @@ describe('createConfig$()', () => { }); it('should not log a warning and set usingEphemeralEncryptionKey=false when encryptionKey is set', async () => { - const contextMock = coreMock.createPluginInitializerContext({ - encryptionKey: 'supersecret', - }); - const config = await createConfig$(contextMock).pipe(first()).toPromise(); + const logger = loggingSystemMock.create().get(); + const config = createConfig( + ConfigSchema.validate({ encryptionKey: 'supersecret'.repeat(3) }, { dist: true }), + logger + ); expect(config).toEqual({ - config: { encryptionKey: 'supersecret' }, + enabled: true, + encryptionKey: 'supersecret'.repeat(3), + keyRotation: { decryptionOnlyKeys: [] }, usingEphemeralEncryptionKey: false, }); - expect(loggingSystemMock.collect(contextMock.logger).warn).toEqual([]); + expect(loggingSystemMock.collect(logger).warn).toEqual([]); }); }); diff --git a/x-pack/plugins/encrypted_saved_objects/server/config.ts b/x-pack/plugins/encrypted_saved_objects/server/config.ts index 9c751a9c67f52..f06c6fa1823ba 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/config.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/config.ts @@ -5,41 +5,50 @@ */ import crypto from 'crypto'; -import { map } from 'rxjs/operators'; import { schema, TypeOf } from '@kbn/config-schema'; -import { PluginInitializerContext } from 'src/core/server'; +import { Logger } from 'src/core/server'; -export const ConfigSchema = schema.object({ - enabled: schema.boolean({ defaultValue: true }), - encryptionKey: schema.conditional( - schema.contextRef('dist'), - true, - schema.maybe(schema.string({ minLength: 32 })), - schema.string({ minLength: 32, defaultValue: 'a'.repeat(32) }) - ), -}); +export type ConfigType = ReturnType; -export function createConfig$(context: PluginInitializerContext) { - return context.config.create>().pipe( - map((config) => { - const logger = context.logger.get('config'); +export const ConfigSchema = schema.object( + { + enabled: schema.boolean({ defaultValue: true }), + encryptionKey: schema.conditional( + schema.contextRef('dist'), + true, + schema.maybe(schema.string({ minLength: 32 })), + schema.string({ minLength: 32, defaultValue: 'a'.repeat(32) }) + ), + keyRotation: schema.object({ + decryptionOnlyKeys: schema.arrayOf(schema.string({ minLength: 32 }), { defaultValue: [] }), + }), + }, + { + validate(value) { + const decryptionOnlyKeys = value.keyRotation?.decryptionOnlyKeys ?? []; + if (value.encryptionKey && decryptionOnlyKeys.includes(value.encryptionKey)) { + return '`keyRotation.decryptionOnlyKeys` cannot contain primary encryption key specified in `encryptionKey`.'; + } + }, + } +); - let encryptionKey = config.encryptionKey; - const usingEphemeralEncryptionKey = encryptionKey === undefined; - if (encryptionKey === undefined) { - logger.warn( - 'Generating a random key for xpack.encryptedSavedObjects.encryptionKey. ' + - 'To be able to decrypt encrypted saved objects attributes after restart, ' + - 'please set xpack.encryptedSavedObjects.encryptionKey in kibana.yml' - ); +export function createConfig(config: TypeOf, logger: Logger) { + let encryptionKey = config.encryptionKey; + const usingEphemeralEncryptionKey = encryptionKey === undefined; + if (encryptionKey === undefined) { + logger.warn( + 'Generating a random key for xpack.encryptedSavedObjects.encryptionKey. ' + + 'To be able to decrypt encrypted saved objects attributes after restart, ' + + 'please set xpack.encryptedSavedObjects.encryptionKey in kibana.yml' + ); - encryptionKey = crypto.randomBytes(16).toString('hex'); - } + encryptionKey = crypto.randomBytes(16).toString('hex'); + } - return { - config: { ...config, encryptionKey }, - usingEphemeralEncryptionKey, - }; - }) - ); + return { + ...config, + encryptionKey, + usingEphemeralEncryptionKey, + }; } diff --git a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.test.ts b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.test.ts index 42d2e2ffd1516..88d57072697fe 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.test.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.test.ts @@ -14,40 +14,44 @@ import { EncryptionError } from './encryption_error'; import { loggingSystemMock } from 'src/core/server/mocks'; import { encryptedSavedObjectsAuditLoggerMock } from '../audit/index.mock'; -const crypto = nodeCrypto({ encryptionKey: 'encryption-key-abc' }); +function createNodeCryptMock(encryptionKey: string) { + const crypto = nodeCrypto({ encryptionKey }); + const nodeCryptoMock: jest.Mocked = { + encrypt: jest.fn(), + decrypt: jest.fn(), + encryptSync: jest.fn(), + decryptSync: jest.fn(), + }; -const mockNodeCrypto: jest.Mocked = { - encrypt: jest.fn(), - decrypt: jest.fn(), - encryptSync: jest.fn(), - decryptSync: jest.fn(), -}; - -let service: EncryptedSavedObjectsService; -let mockAuditLogger: jest.Mocked; - -beforeEach(() => { // Call actual `@elastic/node-crypto` by default, but allow to override implementation in tests. - mockNodeCrypto.encrypt.mockImplementation(async (input: any, aad?: string) => + nodeCryptoMock.encrypt.mockImplementation(async (input: any, aad?: string) => crypto.encrypt(input, aad) ); - mockNodeCrypto.decrypt.mockImplementation( + nodeCryptoMock.decrypt.mockImplementation( async (encryptedOutput: string | Buffer, aad?: string) => crypto.decrypt(encryptedOutput, aad) ); - mockNodeCrypto.encryptSync.mockImplementation((input: any, aad?: string) => + nodeCryptoMock.encryptSync.mockImplementation((input: any, aad?: string) => crypto.encryptSync(input, aad) ); - mockNodeCrypto.decryptSync.mockImplementation((encryptedOutput: string | Buffer, aad?: string) => + nodeCryptoMock.decryptSync.mockImplementation((encryptedOutput: string | Buffer, aad?: string) => crypto.decryptSync(encryptedOutput, aad) ); + return nodeCryptoMock; +} + +let mockNodeCrypto: jest.Mocked; +let service: EncryptedSavedObjectsService; +let mockAuditLogger: jest.Mocked; +beforeEach(() => { + mockNodeCrypto = createNodeCryptMock('encryption-key-abc'); mockAuditLogger = encryptedSavedObjectsAuditLoggerMock.create(); - service = new EncryptedSavedObjectsService( - mockNodeCrypto, - loggingSystemMock.create().get(), - mockAuditLogger - ); + service = new EncryptedSavedObjectsService({ + primaryCrypto: mockNodeCrypto, + logger: loggingSystemMock.create().get(), + audit: mockAuditLogger, + }); }); afterEach(() => jest.resetAllMocks()); @@ -229,11 +233,11 @@ describe('#encryptAttributes', () => { async (valueToEncrypt, aad) => `|${valueToEncrypt}|${aad}|` ); - service = new EncryptedSavedObjectsService( - mockNodeCrypto, - loggingSystemMock.create().get(), - mockAuditLogger - ); + service = new EncryptedSavedObjectsService({ + primaryCrypto: mockNodeCrypto, + logger: loggingSystemMock.create().get(), + audit: mockAuditLogger, + }); }); it('does not encrypt attributes for unknown types', async () => { @@ -304,6 +308,34 @@ describe('#encryptAttributes', () => { ); }); + it('encrypts only using primary crypto', async () => { + const attributes = { attrOne: 'one', attrTwo: 'two', attrThree: 'three', attrFour: null }; + + const decryptionOnlyCrypto = createNodeCryptMock('some-key'); + service = new EncryptedSavedObjectsService({ + primaryCrypto: mockNodeCrypto, + decryptionOnlyCryptos: [decryptionOnlyCrypto], + logger: loggingSystemMock.create().get(), + audit: mockAuditLogger, + }); + service.registerType({ + type: 'known-type-1', + attributesToEncrypt: new Set(['attrOne', 'attrThree', 'attrFour']), + }); + + await expect( + service.encryptAttributes({ type: 'known-type-1', id: 'object-id' }, attributes) + ).resolves.toEqual({ + attrOne: '|one|["known-type-1","object-id",{"attrTwo":"two"}]|', + attrTwo: 'two', + attrThree: '|three|["known-type-1","object-id",{"attrTwo":"two"}]|', + attrFour: null, + }); + + expect(decryptionOnlyCrypto.encrypt).not.toHaveBeenCalled(); + expect(decryptionOnlyCrypto.encryptSync).not.toHaveBeenCalled(); + }); + it('encrypts only attributes that are supposed to be encrypted even if not all provided', async () => { const attributes = { attrTwo: 'two', attrThree: 'three' }; @@ -923,11 +955,11 @@ describe('#decryptAttributes', () => { }); it('fails if encrypted with another encryption key', async () => { - service = new EncryptedSavedObjectsService( - nodeCrypto({ encryptionKey: 'encryption-key-abc*' }), - loggingSystemMock.create().get(), - mockAuditLogger - ); + service = new EncryptedSavedObjectsService({ + primaryCrypto: nodeCrypto({ encryptionKey: 'encryption-key-abc*' }), + logger: loggingSystemMock.create().get(), + audit: mockAuditLogger, + }); service.registerType({ type: 'known-type-1', @@ -949,6 +981,123 @@ describe('#decryptAttributes', () => { ); }); }); + + describe('with decryption only keys', () => { + function getService(primaryCrypto: Crypto, decryptionOnlyCryptos?: Readonly) { + const esoService = new EncryptedSavedObjectsService({ + primaryCrypto, + decryptionOnlyCryptos, + logger: loggingSystemMock.create().get(), + audit: mockAuditLogger, + }); + + esoService.registerType({ + type: 'known-type-1', + attributesToEncrypt: new Set(['attrOne', 'attrThree', 'attrFour']), + }); + + return esoService; + } + + const attributes = { attrOne: 'one', attrTwo: 'two', attrThree: 'three', attrFour: null }; + + let decryptionOnlyCryptoOne: jest.Mocked; + let decryptionOnlyCryptoTwo: jest.Mocked; + beforeEach(() => { + decryptionOnlyCryptoOne = createNodeCryptMock('old-key-one'); + decryptionOnlyCryptoTwo = createNodeCryptMock('old-key-two'); + + service = getService(mockNodeCrypto, [decryptionOnlyCryptoOne, decryptionOnlyCryptoTwo]); + }); + + it('does not use decryption only keys if we can decrypt using primary key', async () => { + const encryptedAttributes = await service.encryptAttributes( + { type: 'known-type-1', id: 'object-id' }, + attributes + ); + + await expect( + service.decryptAttributes({ type: 'known-type-1', id: 'object-id' }, encryptedAttributes) + ).resolves.toEqual({ attrOne: 'one', attrTwo: 'two', attrThree: 'three', attrFour: null }); + expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); + expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( + ['attrOne', 'attrThree'], + { type: 'known-type-1', id: 'object-id' }, + undefined + ); + + expect(decryptionOnlyCryptoOne.decrypt).not.toHaveBeenCalled(); + expect(decryptionOnlyCryptoTwo.decrypt).not.toHaveBeenCalled(); + }); + + it('uses decryption only keys if cannot decrypt using primary key', async () => { + const encryptedAttributes = await getService(decryptionOnlyCryptoOne).encryptAttributes( + { type: 'known-type-1', id: 'object-id' }, + attributes + ); + + await expect( + service.decryptAttributes({ type: 'known-type-1', id: 'object-id' }, encryptedAttributes) + ).resolves.toEqual({ attrOne: 'one', attrTwo: 'two', attrThree: 'three', attrFour: null }); + expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); + expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( + ['attrOne', 'attrThree'], + { type: 'known-type-1', id: 'object-id' }, + undefined + ); + + // One call per attributes, we have 2 of them. + expect(mockNodeCrypto.decrypt).toHaveBeenCalledTimes(2); + expect(decryptionOnlyCryptoOne.decrypt).toHaveBeenCalledTimes(2); + expect(decryptionOnlyCryptoTwo.decrypt).not.toHaveBeenCalled(); + }); + + it('uses all available decryption only keys if needed', async () => { + const encryptedAttributes = await getService(decryptionOnlyCryptoTwo).encryptAttributes( + { type: 'known-type-1', id: 'object-id' }, + attributes + ); + + await expect( + service.decryptAttributes({ type: 'known-type-1', id: 'object-id' }, encryptedAttributes) + ).resolves.toEqual({ attrOne: 'one', attrTwo: 'two', attrThree: 'three', attrFour: null }); + expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); + expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( + ['attrOne', 'attrThree'], + { type: 'known-type-1', id: 'object-id' }, + undefined + ); + + // One call per attributes, we have 2 of them. + expect(mockNodeCrypto.decrypt).toHaveBeenCalledTimes(2); + expect(decryptionOnlyCryptoOne.decrypt).toHaveBeenCalledTimes(2); + expect(decryptionOnlyCryptoTwo.decrypt).toHaveBeenCalledTimes(2); + }); + + it('does not use primary encryption key if `omitPrimaryEncryptionKey` is specified', async () => { + const encryptedAttributes = await getService(decryptionOnlyCryptoOne).encryptAttributes( + { type: 'known-type-1', id: 'object-id' }, + attributes + ); + + await expect( + service.decryptAttributes({ type: 'known-type-1', id: 'object-id' }, encryptedAttributes, { + omitPrimaryEncryptionKey: true, + }) + ).resolves.toEqual({ attrOne: 'one', attrTwo: 'two', attrThree: 'three', attrFour: null }); + expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); + expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( + ['attrOne', 'attrThree'], + { type: 'known-type-1', id: 'object-id' }, + undefined + ); + + // One call per attributes, we have 2 of them. + expect(mockNodeCrypto.decrypt).not.toHaveBeenCalled(); + expect(decryptionOnlyCryptoOne.decrypt).toHaveBeenCalledTimes(2); + expect(decryptionOnlyCryptoTwo.decrypt).not.toHaveBeenCalled(); + }); + }); }); describe('#encryptAttributesSync', () => { @@ -957,11 +1106,11 @@ describe('#encryptAttributesSync', () => { (valueToEncrypt, aad) => `|${valueToEncrypt}|${aad}|` ); - service = new EncryptedSavedObjectsService( - mockNodeCrypto, - loggingSystemMock.create().get(), - mockAuditLogger - ); + service = new EncryptedSavedObjectsService({ + primaryCrypto: mockNodeCrypto, + logger: loggingSystemMock.create().get(), + audit: mockAuditLogger, + }); }); it('does not encrypt attributes that are not supposed to be encrypted', () => { @@ -996,6 +1145,34 @@ describe('#encryptAttributesSync', () => { }); }); + it('encrypts only using primary crypto', async () => { + const attributes = { attrOne: 'one', attrTwo: 'two', attrThree: 'three', attrFour: null }; + + const decryptionOnlyCrypto = createNodeCryptMock('some-key'); + service = new EncryptedSavedObjectsService({ + primaryCrypto: mockNodeCrypto, + decryptionOnlyCryptos: [decryptionOnlyCrypto], + logger: loggingSystemMock.create().get(), + audit: mockAuditLogger, + }); + service.registerType({ + type: 'known-type-1', + attributesToEncrypt: new Set(['attrOne', 'attrThree', 'attrFour']), + }); + + expect( + service.encryptAttributesSync({ type: 'known-type-1', id: 'object-id' }, attributes) + ).toEqual({ + attrOne: '|one|["known-type-1","object-id",{"attrTwo":"two"}]|', + attrTwo: 'two', + attrThree: '|three|["known-type-1","object-id",{"attrTwo":"two"}]|', + attrFour: null, + }); + + expect(decryptionOnlyCrypto.encrypt).not.toHaveBeenCalled(); + expect(decryptionOnlyCrypto.encryptSync).not.toHaveBeenCalled(); + }); + it('encrypts only attributes that are supposed to be encrypted even if not all provided', () => { const attributes = { attrTwo: 'two', attrThree: 'three' }; @@ -1459,11 +1636,11 @@ describe('#decryptAttributesSync', () => { }); it('fails if encrypted with another encryption key', () => { - service = new EncryptedSavedObjectsService( - nodeCrypto({ encryptionKey: 'encryption-key-abc*' }), - loggingSystemMock.create().get(), - mockAuditLogger - ); + service = new EncryptedSavedObjectsService({ + primaryCrypto: nodeCrypto({ encryptionKey: 'encryption-key-abc*' }), + logger: loggingSystemMock.create().get(), + audit: mockAuditLogger, + }); service.registerType({ type: 'known-type-1', @@ -1478,4 +1655,132 @@ describe('#decryptAttributesSync', () => { ).toThrowError(EncryptionError); }); }); + + describe('with decryption only keys', () => { + function getService(primaryCrypto: Crypto, decryptionOnlyCryptos?: Readonly) { + const esoService = new EncryptedSavedObjectsService({ + primaryCrypto, + decryptionOnlyCryptos, + logger: loggingSystemMock.create().get(), + audit: mockAuditLogger, + }); + + esoService.registerType({ + type: 'known-type-1', + attributesToEncrypt: new Set(['attrOne', 'attrThree', 'attrFour']), + }); + + return esoService; + } + + const attributes = { attrOne: 'one', attrTwo: 'two', attrThree: 'three', attrFour: null }; + + let decryptionOnlyCryptoOne: jest.Mocked; + let decryptionOnlyCryptoTwo: jest.Mocked; + beforeEach(() => { + decryptionOnlyCryptoOne = createNodeCryptMock('old-key-one'); + decryptionOnlyCryptoTwo = createNodeCryptMock('old-key-two'); + + service = getService(mockNodeCrypto, [decryptionOnlyCryptoOne, decryptionOnlyCryptoTwo]); + }); + + it('does not use decryption only keys if we can decrypt using primary key', () => { + const encryptedAttributes = service.encryptAttributesSync( + { type: 'known-type-1', id: 'object-id' }, + attributes + ); + + expect( + service.decryptAttributesSync( + { type: 'known-type-1', id: 'object-id' }, + encryptedAttributes + ) + ).toEqual({ attrOne: 'one', attrTwo: 'two', attrThree: 'three', attrFour: null }); + expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); + expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( + ['attrOne', 'attrThree'], + { type: 'known-type-1', id: 'object-id' }, + undefined + ); + + expect(decryptionOnlyCryptoOne.decryptSync).not.toHaveBeenCalled(); + expect(decryptionOnlyCryptoTwo.decryptSync).not.toHaveBeenCalled(); + }); + + it('uses decryption only keys if cannot decrypt using primary key', () => { + const encryptedAttributes = getService(decryptionOnlyCryptoOne).encryptAttributesSync( + { type: 'known-type-1', id: 'object-id' }, + attributes + ); + + expect( + service.decryptAttributesSync( + { type: 'known-type-1', id: 'object-id' }, + encryptedAttributes + ) + ).toEqual({ attrOne: 'one', attrTwo: 'two', attrThree: 'three', attrFour: null }); + expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); + expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( + ['attrOne', 'attrThree'], + { type: 'known-type-1', id: 'object-id' }, + undefined + ); + + // One call per attributes, we have 2 of them. + expect(mockNodeCrypto.decryptSync).toHaveBeenCalledTimes(2); + expect(decryptionOnlyCryptoOne.decryptSync).toHaveBeenCalledTimes(2); + expect(decryptionOnlyCryptoTwo.decryptSync).not.toHaveBeenCalled(); + }); + + it('uses all available decryption only keys if needed', () => { + const encryptedAttributes = getService(decryptionOnlyCryptoTwo).encryptAttributesSync( + { type: 'known-type-1', id: 'object-id' }, + attributes + ); + + expect( + service.decryptAttributesSync( + { type: 'known-type-1', id: 'object-id' }, + encryptedAttributes + ) + ).toEqual({ attrOne: 'one', attrTwo: 'two', attrThree: 'three', attrFour: null }); + expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); + expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( + ['attrOne', 'attrThree'], + { type: 'known-type-1', id: 'object-id' }, + undefined + ); + + // One call per attributes, we have 2 of them. + expect(mockNodeCrypto.decryptSync).toHaveBeenCalledTimes(2); + expect(decryptionOnlyCryptoOne.decryptSync).toHaveBeenCalledTimes(2); + expect(decryptionOnlyCryptoTwo.decryptSync).toHaveBeenCalledTimes(2); + }); + + it('does not use primary encryption key if `omitPrimaryEncryptionKey` is specified', () => { + const encryptedAttributes = getService(decryptionOnlyCryptoOne).encryptAttributesSync( + { type: 'known-type-1', id: 'object-id' }, + attributes + ); + + expect( + service.decryptAttributesSync( + { type: 'known-type-1', id: 'object-id' }, + encryptedAttributes, + { omitPrimaryEncryptionKey: true } + ) + ).toEqual({ attrOne: 'one', attrTwo: 'two', attrThree: 'three', attrFour: null }); + expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledTimes(1); + expect(mockAuditLogger.decryptAttributesSuccess).toHaveBeenCalledWith( + ['attrOne', 'attrThree'], + { type: 'known-type-1', id: 'object-id' }, + undefined + ); + + // One call per attributes, we have 2 of them. + expect(mockNodeCrypto.decryptSync).not.toHaveBeenCalled(); + expect(decryptionOnlyCryptoOne.decryptSync).toHaveBeenCalledTimes(2); + expect(decryptionOnlyCryptoTwo.decryptSync).not.toHaveBeenCalled(); + }); + }); }); diff --git a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.ts b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.ts index 82d6bb9be15f6..1f1093a179538 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/crypto/encrypted_saved_objects_service.ts @@ -52,6 +52,38 @@ interface CommonParameters { user?: AuthenticatedUser; } +/** + * Describes parameters for the decrypt methods. + */ +interface DecryptParameters extends CommonParameters { + /** + * Indicates whether decryption should only be performed using secondary decryption-only keys. + */ + omitPrimaryEncryptionKey?: boolean; +} + +interface EncryptedSavedObjectsServiceOptions { + /** + * Service logger instance. + */ + logger: Logger; + + /** + * Audit logger instance. + */ + audit: EncryptedSavedObjectsAuditLogger; + + /** + * NodeCrypto instance used for both encryption and decryption. + */ + primaryCrypto: Crypto; + + /** + * NodeCrypto instances used ONLY for decryption (i.e. rotated encryption keys). + */ + decryptionOnlyCryptos?: Readonly; +} + /** * Utility function that gives array representation of the saved object descriptor respecting * optional `namespace` property. @@ -79,16 +111,7 @@ export class EncryptedSavedObjectsService { EncryptedSavedObjectAttributesDefinition > = new Map(); - /** - * @param crypto nodeCrypto instance. - * @param logger Ordinary logger instance. - * @param audit Audit logger instance. - */ - constructor( - private readonly crypto: Readonly, - private readonly logger: Logger, - private readonly audit: EncryptedSavedObjectsAuditLogger - ) {} + constructor(private readonly options: EncryptedSavedObjectsServiceOptions) {} /** * Registers saved object type as the one that contains attributes that should be encrypted. @@ -136,7 +159,7 @@ export class EncryptedSavedObjectsService { descriptor: SavedObjectDescriptor, attributes: T, originalAttributes?: T, - params?: CommonParameters + params?: DecryptParameters ) { const typeDefinition = this.typeDefinitions.get(descriptor.type); if (typeDefinition === undefined) { @@ -174,7 +197,7 @@ export class EncryptedSavedObjectsService { Object.fromEntries( Object.entries(attributes).filter(([key]) => !typeDefinition.shouldBeStripped(key)) ) as T, - { user: params?.user } + params ); } catch (err) { decryptionError = err; @@ -210,10 +233,10 @@ export class EncryptedSavedObjectsService { try { encryptedAttributes[attributeName] = (yield [attributeValue, encryptionAAD])!; } catch (err) { - this.logger.error( + this.options.logger.error( `Failed to encrypt "${attributeName}" attribute: ${err.message || err}` ); - this.audit.encryptAttributeFailure(attributeName, descriptor, params?.user); + this.options.audit.encryptAttributeFailure(attributeName, descriptor, params?.user); throw new EncryptionError( `Unable to encrypt attribute "${attributeName}"`, @@ -229,7 +252,7 @@ export class EncryptedSavedObjectsService { // not the case we should collect and log them to make troubleshooting easier. const encryptedAttributesKeys = Object.keys(encryptedAttributes); if (encryptedAttributesKeys.length !== typeDefinition.attributesToEncrypt.size) { - this.logger.debug( + this.options.logger.debug( `The following attributes of saved object "${descriptorToArray( descriptor )}" should have been encrypted: ${Array.from( @@ -242,7 +265,7 @@ export class EncryptedSavedObjectsService { return attributes; } - this.audit.encryptAttributesSuccess(encryptedAttributesKeys, descriptor, params?.user); + this.options.audit.encryptAttributesSuccess(encryptedAttributesKeys, descriptor, params?.user); return { ...attributes, @@ -270,7 +293,9 @@ export class EncryptedSavedObjectsService { while (!iteratorResult.done) { const [attributeValue, encryptionAAD] = iteratorResult.value; try { - iteratorResult = iterator.next(await this.crypto.encrypt(attributeValue, encryptionAAD)); + iteratorResult = iterator.next( + await this.options.primaryCrypto.encrypt(attributeValue, encryptionAAD) + ); } catch (err) { iterator.throw!(err); } @@ -299,7 +324,9 @@ export class EncryptedSavedObjectsService { while (!iteratorResult.done) { const [attributeValue, encryptionAAD] = iteratorResult.value; try { - iteratorResult = iterator.next(this.crypto.encryptSync(attributeValue, encryptionAAD)); + iteratorResult = iterator.next( + this.options.primaryCrypto.encryptSync(attributeValue, encryptionAAD) + ); } catch (err) { iterator.throw!(err); } @@ -321,19 +348,31 @@ export class EncryptedSavedObjectsService { public async decryptAttributes>( descriptor: SavedObjectDescriptor, attributes: T, - params?: CommonParameters + params?: DecryptParameters ): Promise { + const decrypters = this.getDecrypters(params?.omitPrimaryEncryptionKey); const iterator = this.attributesToDecryptIterator(descriptor, attributes, params); let iteratorResult = iterator.next(); while (!iteratorResult.done) { const [attributeValue, encryptionAAD] = iteratorResult.value; - try { - iteratorResult = iterator.next( - (await this.crypto.decrypt(attributeValue, encryptionAAD)) as string - ); - } catch (err) { - iterator.throw!(err); + + let decryptionError; + for (const decrypter of decrypters) { + try { + iteratorResult = iterator.next(await decrypter.decrypt(attributeValue, encryptionAAD)); + decryptionError = undefined; + break; + } catch (err) { + // Remember the error thrown when we tried to decrypt with the primary key. + if (!decryptionError) { + decryptionError = err; + } + } + } + + if (decryptionError) { + iterator.throw!(decryptionError); } } @@ -353,17 +392,31 @@ export class EncryptedSavedObjectsService { public decryptAttributesSync>( descriptor: SavedObjectDescriptor, attributes: T, - params?: CommonParameters + params?: DecryptParameters ): T { + const decrypters = this.getDecrypters(params?.omitPrimaryEncryptionKey); const iterator = this.attributesToDecryptIterator(descriptor, attributes, params); let iteratorResult = iterator.next(); while (!iteratorResult.done) { const [attributeValue, encryptionAAD] = iteratorResult.value; - try { - iteratorResult = iterator.next(this.crypto.decryptSync(attributeValue, encryptionAAD)); - } catch (err) { - iterator.throw!(err); + + let decryptionError; + for (const decrypter of decrypters) { + try { + iteratorResult = iterator.next(decrypter.decryptSync(attributeValue, encryptionAAD)); + decryptionError = undefined; + break; + } catch (err) { + // Remember the error thrown when we tried to decrypt with the primary key. + if (!decryptionError) { + decryptionError = err; + } + } + } + + if (decryptionError) { + iterator.throw!(decryptionError); } } @@ -388,7 +441,7 @@ export class EncryptedSavedObjectsService { } if (typeof attributeValue !== 'string') { - this.audit.decryptAttributeFailure(attributeName, descriptor, params?.user); + this.options.audit.decryptAttributeFailure(attributeName, descriptor, params?.user); throw new Error( `Encrypted "${attributeName}" attribute should be a string, but found ${typeDetect( attributeValue @@ -401,8 +454,10 @@ export class EncryptedSavedObjectsService { try { decryptedAttributes[attributeName] = (yield [attributeValue, encryptionAAD])!; } catch (err) { - this.logger.error(`Failed to decrypt "${attributeName}" attribute: ${err.message || err}`); - this.audit.decryptAttributeFailure(attributeName, descriptor, params?.user); + this.options.logger.error( + `Failed to decrypt "${attributeName}" attribute: ${err.message || err}` + ); + this.options.audit.decryptAttributeFailure(attributeName, descriptor, params?.user); throw new EncryptionError( `Unable to decrypt attribute "${attributeName}"`, @@ -417,7 +472,7 @@ export class EncryptedSavedObjectsService { // not the case we should collect and log them to make troubleshooting easier. const decryptedAttributesKeys = Object.keys(decryptedAttributes); if (decryptedAttributesKeys.length !== typeDefinition.attributesToEncrypt.size) { - this.logger.debug( + this.options.logger.debug( `The following attributes of saved object "${descriptorToArray( descriptor )}" should have been decrypted: ${Array.from( @@ -430,7 +485,7 @@ export class EncryptedSavedObjectsService { return attributes; } - this.audit.decryptAttributesSuccess(decryptedAttributesKeys, descriptor, params?.user); + this.options.audit.decryptAttributesSuccess(decryptedAttributesKeys, descriptor, params?.user); return { ...attributes, @@ -459,7 +514,7 @@ export class EncryptedSavedObjectsService { } if (Object.keys(attributesAAD).length === 0) { - this.logger.debug( + this.options.logger.debug( `The AAD for saved object "${descriptorToArray( descriptor )}" does not include any attributes.` @@ -468,4 +523,23 @@ export class EncryptedSavedObjectsService { return stringify([...descriptorToArray(descriptor), attributesAAD]); } + + /** + * Returns list of NodeCrypto instances used for decryption. + * @param omitPrimaryEncryptionKey Specifies whether returned decrypters shouldn't include primary + * encryption/decryption crypto. + */ + private getDecrypters(omitPrimaryEncryptionKey?: boolean) { + if (omitPrimaryEncryptionKey) { + if (!this.options.decryptionOnlyCryptos || this.options.decryptionOnlyCryptos.length === 0) { + throw new Error( + `"omitPrimaryEncryptionKey" cannot be set when secondary keys aren't configured.` + ); + } + + return this.options.decryptionOnlyCryptos; + } + + return [this.options.primaryCrypto, ...(this.options.decryptionOnlyCryptos ?? [])]; + } } diff --git a/x-pack/plugins/encrypted_saved_objects/server/crypto/encryption_key_rotation_service.mocks.ts b/x-pack/plugins/encrypted_saved_objects/server/crypto/encryption_key_rotation_service.mocks.ts new file mode 100644 index 0000000000000..2d14577f91567 --- /dev/null +++ b/x-pack/plugins/encrypted_saved_objects/server/crypto/encryption_key_rotation_service.mocks.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { EncryptionKeyRotationService } from './encryption_key_rotation_service'; + +function createEncryptionKeyRotationServiceMock() { + return ({ rotate: jest.fn() } as unknown) as jest.Mocked; +} + +export const encryptionKeyRotationServiceMock = { + create: createEncryptionKeyRotationServiceMock, +}; diff --git a/x-pack/plugins/encrypted_saved_objects/server/crypto/encryption_key_rotation_service.test.ts b/x-pack/plugins/encrypted_saved_objects/server/crypto/encryption_key_rotation_service.test.ts new file mode 100644 index 0000000000000..8607b81e7205e --- /dev/null +++ b/x-pack/plugins/encrypted_saved_objects/server/crypto/encryption_key_rotation_service.test.ts @@ -0,0 +1,502 @@ +/* + * 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 { + SavedObject, + SavedObjectsClientContract, + SavedObjectsServiceStart, +} from '../../../../../src/core/server'; +import { EncryptionError, EncryptionErrorOperation } from './encryption_error'; +import { EncryptionKeyRotationService } from './encryption_key_rotation_service'; +import { EncryptedSavedObjectsService } from './encrypted_saved_objects_service'; + +import { + coreMock, + httpServerMock, + loggingSystemMock, + savedObjectsClientMock, + savedObjectsTypeRegistryMock, +} from '../../../../../src/core/server/mocks'; +import { encryptedSavedObjectsServiceMock } from './index.mock'; + +function getMockSavedObject(savedObject?: Partial>) { + const id = savedObject?.id ?? `id-1`; + return { + id, + type: `type-${id}`, + references: [], + attributes: { attr: `attr-${id}` }, + score: 0, + ...savedObject, + }; +} + +let mockEncryptionService: jest.Mocked; +let mockRetrieveClient: jest.Mocked; +let mockUpdateClient: jest.Mocked; +let mockSavedObjects: jest.Mocked; +let service: EncryptionKeyRotationService; +beforeEach(() => { + mockEncryptionService = encryptedSavedObjectsServiceMock.create(); + mockEncryptionService.isRegistered.mockImplementation( + (type) => type !== 'type-id-3' && type !== 'type-id-6' + ); + mockEncryptionService.decryptAttributes.mockImplementation(async (descriptor, { attr }) => ({ + attr: `decrypted-${attr}`, + })); + + const coreSetupMock = coreMock.createSetup(); + const coreStartMock = coreMock.createStart(); + coreSetupMock.getStartServices.mockResolvedValue([coreStartMock, {}, {}]); + + mockSavedObjects = coreStartMock.savedObjects; + const typeRegistryMock = savedObjectsTypeRegistryMock.create(); + typeRegistryMock.getAllTypes.mockReturnValue([ + { name: 'type-id-1', namespaceType: 'single', mappings: { properties: {} }, hidden: false }, + { name: 'type-id-2', namespaceType: 'single', mappings: { properties: {} }, hidden: true }, + { name: 'type-id-3', namespaceType: 'single', mappings: { properties: {} }, hidden: false }, + { name: 'type-id-4', namespaceType: 'multiple', mappings: { properties: {} }, hidden: true }, + { name: 'type-id-5', namespaceType: 'single', mappings: { properties: {} }, hidden: false }, + { name: 'type-id-6', namespaceType: 'single', mappings: { properties: {} }, hidden: true }, + ]); + typeRegistryMock.isSingleNamespace.mockImplementation((type) => type !== 'type-id-4'); + mockSavedObjects.getTypeRegistry.mockReturnValue(typeRegistryMock); + + mockRetrieveClient = savedObjectsClientMock.create(); + mockRetrieveClient.find.mockResolvedValue({ total: 0, saved_objects: [], per_page: 0, page: 0 }); + mockUpdateClient = savedObjectsClientMock.create(); + mockSavedObjects.getScopedClient.mockImplementation((request, params) => + params?.excludedWrappers?.[0] === 'encryptedSavedObjects' + ? mockRetrieveClient + : mockUpdateClient + ); + + service = new EncryptionKeyRotationService({ + logger: loggingSystemMock.create().get(), + service: mockEncryptionService, + getStartServices: coreSetupMock.getStartServices, + }); +}); + +it('correctly setups Saved Objects clients', async () => { + const mockRequest = httpServerMock.createKibanaRequest(); + await service.rotate(mockRequest, { batchSize: 10000 }); + + expect(mockSavedObjects.getScopedClient).toHaveBeenCalledTimes(2); + expect(mockSavedObjects.getScopedClient).toHaveBeenCalledWith(mockRequest, { + includedHiddenTypes: ['type-id-2', 'type-id-4'], + excludedWrappers: ['encryptedSavedObjects'], + }); + expect(mockSavedObjects.getScopedClient).toHaveBeenCalledWith(mockRequest, { + includedHiddenTypes: ['type-id-2', 'type-id-4'], + }); +}); + +it('bails out if specified type is not registered', async () => { + mockEncryptionService.isRegistered.mockImplementation((type) => type !== 'type-unknown'); + + await expect( + service.rotate(httpServerMock.createKibanaRequest(), { + batchSize: 10000, + type: 'type-unknown', + }) + ).resolves.toEqual({ + total: 0, + successful: 0, + failed: 0, + }); + + expect(mockSavedObjects.getScopedClient).not.toHaveBeenCalled(); +}); + +it('does not perform rotation if there are no Saved Objects to process', async () => { + await expect( + service.rotate(httpServerMock.createKibanaRequest(), { batchSize: 12345 }) + ).resolves.toEqual({ + total: 0, + successful: 0, + failed: 0, + }); + + expect(mockRetrieveClient.find).toHaveBeenCalledTimes(1); + expect(mockRetrieveClient.find).toHaveBeenCalledWith({ + type: ['type-id-1', 'type-id-2', 'type-id-4', 'type-id-5'], + perPage: 12345, + namespaces: ['*'], + sortField: 'updated_at', + sortOrder: 'asc', + }); + + await expect( + service.rotate(httpServerMock.createKibanaRequest(), { batchSize: 54321, type: 'type-id-2' }) + ).resolves.toEqual({ + total: 0, + successful: 0, + failed: 0, + }); + + expect(mockRetrieveClient.find).toHaveBeenCalledTimes(2); + expect(mockRetrieveClient.find).toHaveBeenCalledWith({ + type: ['type-id-2'], + perPage: 54321, + namespaces: ['*'], + sortField: 'updated_at', + sortOrder: 'asc', + }); + + expect(mockEncryptionService.decryptAttributes).not.toHaveBeenCalled(); + expect(mockUpdateClient.bulkUpdate).not.toHaveBeenCalled(); +}); + +it('throws if Saved Object attributes cannot be decrypted because of unknown reason', async () => { + mockRetrieveClient.find.mockResolvedValue({ + total: 2, + saved_objects: [getMockSavedObject({ id: 'id-1' }), getMockSavedObject({ id: 'id-2' })], + per_page: 2, + page: 0, + }); + + const decryptionFailure = new Error('Oh no!'); + mockEncryptionService.decryptAttributes.mockRejectedValue(decryptionFailure); + + await expect( + service.rotate(httpServerMock.createKibanaRequest(), { batchSize: 12345 }) + ).rejects.toBe(decryptionFailure); + + expect(mockUpdateClient.bulkUpdate).not.toHaveBeenCalled(); +}); + +it('does not perform rotation if Saved Object attributes cannot be decrypted', async () => { + mockRetrieveClient.find.mockResolvedValue({ + total: 2, + saved_objects: [getMockSavedObject({ id: 'id-1' }), getMockSavedObject({ id: 'id-2' })], + per_page: 2, + page: 0, + }); + + mockEncryptionService.decryptAttributes.mockRejectedValue( + new EncryptionError('some-message', 'attr', EncryptionErrorOperation.Decryption) + ); + + await expect( + service.rotate(httpServerMock.createKibanaRequest(), { batchSize: 12345 }) + ).resolves.toEqual({ + total: 2, + successful: 0, + failed: 0, + }); + + expect(mockEncryptionService.decryptAttributes).toHaveBeenCalledTimes(2); + expect(mockUpdateClient.bulkUpdate).not.toHaveBeenCalled(); +}); + +it('properly rotates encryption key', async () => { + const savedObjects = [ + getMockSavedObject({ id: 'id-1' }), + getMockSavedObject({ id: 'id-2', namespaces: ['ns-1'] }), + getMockSavedObject({ id: 'id-4', namespaces: ['ns-2', 'ns-3'] }), + ]; + mockRetrieveClient.find.mockResolvedValue({ + total: 3, + saved_objects: savedObjects, + per_page: 3, + page: 0, + }); + mockUpdateClient.bulkUpdate.mockResolvedValue({ + saved_objects: savedObjects.map((object) => ({ ...object, attributes: {} })), + }); + + await expect( + service.rotate(httpServerMock.createKibanaRequest(), { batchSize: 12345 }) + ).resolves.toEqual({ + total: 3, + successful: 3, + failed: 0, + }); + + expect(mockEncryptionService.decryptAttributes).toHaveBeenCalledTimes(3); + expect(mockEncryptionService.decryptAttributes).toHaveBeenCalledWith( + { type: 'type-id-1', id: 'id-1' }, + { attr: 'attr-id-1' }, + { omitPrimaryEncryptionKey: true } + ); + expect(mockEncryptionService.decryptAttributes).toHaveBeenCalledWith( + { type: 'type-id-2', id: 'id-2', namespace: 'ns-1' }, + { attr: 'attr-id-2' }, + { omitPrimaryEncryptionKey: true } + ); + expect(mockEncryptionService.decryptAttributes).toHaveBeenCalledWith( + { type: 'type-id-4', id: 'id-4' }, + { attr: 'attr-id-4' }, + { omitPrimaryEncryptionKey: true } + ); + + expect(mockUpdateClient.bulkUpdate).toHaveBeenCalledTimes(1); + expect(mockUpdateClient.bulkUpdate).toHaveBeenCalledWith([ + { ...savedObjects[0], attributes: { attr: 'decrypted-attr-id-1' } }, + { ...savedObjects[1], namespace: 'ns-1', attributes: { attr: 'decrypted-attr-id-2' } }, + { ...savedObjects[2], namespace: 'ns-2', attributes: { attr: 'decrypted-attr-id-4' } }, + ]); +}); + +it('skips objects that cannot be decrypted', async () => { + const savedObjects = [ + getMockSavedObject({ id: 'id-1' }), + getMockSavedObject({ id: 'id-2', namespaces: ['ns-1'] }), + getMockSavedObject({ id: 'id-4', namespaces: ['ns-2', 'ns-3'] }), + ]; + mockRetrieveClient.find.mockResolvedValue({ + total: 3, + saved_objects: savedObjects, + per_page: 3, + page: 0, + }); + mockUpdateClient.bulkUpdate.mockResolvedValue({ + saved_objects: [ + { ...savedObjects[0], attributes: {} }, + { ...savedObjects[2], attributes: {} }, + ], + }); + + mockEncryptionService.decryptAttributes.mockImplementation(async ({ type }, { attr }) => { + if (type === 'type-id-2') { + throw new EncryptionError('some-message', 'attr', EncryptionErrorOperation.Decryption); + } + + return { attr: `decrypted-${attr}` }; + }); + + await expect( + service.rotate(httpServerMock.createKibanaRequest(), { batchSize: 12345 }) + ).resolves.toEqual({ + total: 3, + successful: 2, + failed: 0, + }); + + expect(mockEncryptionService.decryptAttributes).toHaveBeenCalledTimes(3); + expect(mockUpdateClient.bulkUpdate).toHaveBeenCalledTimes(1); + expect(mockUpdateClient.bulkUpdate).toHaveBeenCalledWith([ + { ...savedObjects[0], attributes: { attr: 'decrypted-attr-id-1' } }, + { ...savedObjects[2], namespace: 'ns-2', attributes: { attr: 'decrypted-attr-id-4' } }, + ]); +}); + +it('marks object that we could not update as failed', async () => { + const savedObjects = [ + getMockSavedObject({ id: 'id-1' }), + getMockSavedObject({ id: 'id-2', namespaces: ['ns-1'] }), + getMockSavedObject({ id: 'id-4', namespaces: ['ns-2', 'ns-3'] }), + ]; + mockRetrieveClient.find.mockResolvedValue({ + total: 3, + saved_objects: savedObjects, + per_page: 3, + page: 0, + }); + mockUpdateClient.bulkUpdate.mockResolvedValue({ + saved_objects: [{ ...savedObjects[0], attributes: {} }, { error: new Error('Oh no!') } as any], + }); + + mockEncryptionService.decryptAttributes.mockImplementation(async ({ type }, { attr }) => { + if (type === 'type-id-2') { + throw new EncryptionError('some-message', 'attr', EncryptionErrorOperation.Decryption); + } + + return { attr: `decrypted-${attr}` }; + }); + + await expect( + service.rotate(httpServerMock.createKibanaRequest(), { batchSize: 12345 }) + ).resolves.toEqual({ + total: 3, + successful: 1, + failed: 1, + }); + + expect(mockEncryptionService.decryptAttributes).toHaveBeenCalledTimes(3); + expect(mockUpdateClient.bulkUpdate).toHaveBeenCalledTimes(1); + expect(mockUpdateClient.bulkUpdate).toHaveBeenCalledWith([ + { ...savedObjects[0], attributes: { attr: 'decrypted-attr-id-1' } }, + { ...savedObjects[2], namespace: 'ns-2', attributes: { attr: 'decrypted-attr-id-4' } }, + ]); +}); + +it('iterates until number of returned results less than batch size', async () => { + const savedObjectsBatch0 = [ + getMockSavedObject({ id: 'id-1', type: 'type-id-1' }), + getMockSavedObject({ id: 'id-2', type: 'type-id-1' }), + getMockSavedObject({ id: 'id-3', type: 'type-id-1' }), + ]; + + const savedObjectsBatch1 = [ + getMockSavedObject({ id: 'id-4', type: 'type-id-1' }), + getMockSavedObject({ id: 'id-5', type: 'type-id-1' }), + ]; + + // During first request we had 100 objects in total. + mockRetrieveClient.find.mockResolvedValueOnce({ + total: 100, + saved_objects: savedObjectsBatch0, + per_page: 3, + page: 0, + }); + mockUpdateClient.bulkUpdate.mockResolvedValueOnce({ + saved_objects: [ + { ...savedObjectsBatch0[0], attributes: {} }, + { ...savedObjectsBatch0[1], attributes: {} }, + { ...savedObjectsBatch0[2], attributes: {} }, + ], + }); + + // But when we fetch data for the second time we have just two objects left (e.g. they were removed). + mockRetrieveClient.find.mockResolvedValueOnce({ + total: 2, + saved_objects: savedObjectsBatch1, + per_page: 2, + page: 0, + }); + mockUpdateClient.bulkUpdate.mockResolvedValueOnce({ + saved_objects: [ + { ...savedObjectsBatch1[0], attributes: {} }, + { ...savedObjectsBatch1[1], attributes: {} }, + ], + }); + + await expect( + service.rotate(httpServerMock.createKibanaRequest(), { batchSize: 3 }) + ).resolves.toEqual({ + total: 100, + successful: 5, + failed: 0, + }); + + expect(mockRetrieveClient.find).toHaveBeenCalledTimes(2); + expect(mockEncryptionService.decryptAttributes).toHaveBeenCalledTimes(5); + expect(mockUpdateClient.bulkUpdate).toHaveBeenCalledTimes(2); + expect(mockUpdateClient.bulkUpdate).toHaveBeenCalledWith([ + { ...savedObjectsBatch0[0], attributes: { attr: 'decrypted-attr-id-1' } }, + { ...savedObjectsBatch0[1], attributes: { attr: 'decrypted-attr-id-2' } }, + { ...savedObjectsBatch0[2], attributes: { attr: 'decrypted-attr-id-3' } }, + ]); + expect(mockUpdateClient.bulkUpdate).toHaveBeenCalledWith([ + { ...savedObjectsBatch1[0], attributes: { attr: 'decrypted-attr-id-4' } }, + { ...savedObjectsBatch1[1], attributes: { attr: 'decrypted-attr-id-5' } }, + ]); +}); + +it('iterates until no new objects are returned', async () => { + const savedObjectBatches = [ + [ + getMockSavedObject({ id: 'id-1', type: 'type-id-1' }), + getMockSavedObject({ id: 'id-2', type: 'type-id-1' }), + getMockSavedObject({ id: 'id-3', type: 'type-id-1' }), + ], + [ + getMockSavedObject({ id: 'id-4', type: 'type-id-1' }), + getMockSavedObject({ id: 'id-5', type: 'type-id-1' }), + getMockSavedObject({ id: 'id-6', type: 'type-id-1' }), + ], + [ + getMockSavedObject({ id: 'id-7', type: 'type-id-1' }), + getMockSavedObject({ id: 'id-8', type: 'type-id-1' }), + getMockSavedObject({ id: 'id-9', type: 'type-id-1' }), + ], + [ + getMockSavedObject({ id: 'id-1', type: 'type-id-1' }), + getMockSavedObject({ id: 'id-2', type: 'type-id-1' }), + getMockSavedObject({ id: 'id-3', type: 'type-id-1' }), + ], + ]; + + for (const batch of savedObjectBatches) { + mockRetrieveClient.find.mockResolvedValueOnce({ + total: 100, + saved_objects: batch, + per_page: 3, + page: 0, + }); + mockUpdateClient.bulkUpdate.mockResolvedValueOnce({ + saved_objects: batch.map((object) => ({ ...object, attributes: {} })), + }); + } + + await expect( + service.rotate(httpServerMock.createKibanaRequest(), { batchSize: 3 }) + ).resolves.toEqual({ + total: 100, + successful: 9, + failed: 0, + }); + + expect(mockRetrieveClient.find).toHaveBeenCalledTimes(4); + // We don't decrypt\update same object twice, so neither object from the last batch is decrypted or updated. + expect(mockEncryptionService.decryptAttributes).toHaveBeenCalledTimes(9); + expect(mockUpdateClient.bulkUpdate).toHaveBeenCalledTimes(3); + for (const batch of savedObjectBatches.slice(0, 3)) { + expect(mockUpdateClient.bulkUpdate).toHaveBeenCalledWith( + batch.map((object) => ({ + ...object, + attributes: { attr: `decrypted-${object.attributes.attr}` }, + })) + ); + } +}); + +it('iterates until max number of batches is reached', async () => { + // Simulate the scenario when we're getting more records then was indicated by the `total` field + // returned with the first batch, and every such batch includes documents we haven't processed yet. + const savedObjectBatches = [ + [ + getMockSavedObject({ id: 'id-1', type: 'type-id-1' }), + getMockSavedObject({ id: 'id-2', type: 'type-id-1' }), + ], + [ + getMockSavedObject({ id: 'id-3', type: 'type-id-1' }), + getMockSavedObject({ id: 'id-4', type: 'type-id-1' }), + ], + [ + getMockSavedObject({ id: 'id-5', type: 'type-id-1' }), + getMockSavedObject({ id: 'id-6', type: 'type-id-1' }), + ], + [ + getMockSavedObject({ id: 'id-7', type: 'type-id-1' }), + getMockSavedObject({ id: 'id-8', type: 'type-id-1' }), + ], + ]; + + for (const batch of savedObjectBatches) { + mockRetrieveClient.find.mockResolvedValueOnce({ + total: 3, + saved_objects: batch, + per_page: 2, + page: 0, + }); + mockUpdateClient.bulkUpdate.mockResolvedValueOnce({ + saved_objects: batch.map((object) => ({ ...object, attributes: {} })), + }); + } + + await expect( + service.rotate(httpServerMock.createKibanaRequest(), { batchSize: 2 }) + ).resolves.toEqual({ + total: 3, + successful: 6, + failed: 0, + }); + + expect(mockRetrieveClient.find).toHaveBeenCalledTimes(3); + expect(mockEncryptionService.decryptAttributes).toHaveBeenCalledTimes(6); + expect(mockUpdateClient.bulkUpdate).toHaveBeenCalledTimes(3); + for (const batch of savedObjectBatches.slice(0, 3)) { + expect(mockUpdateClient.bulkUpdate).toHaveBeenCalledWith( + batch.map((object) => ({ + ...object, + attributes: { attr: `decrypted-${object.attributes.attr}` }, + })) + ); + } +}); diff --git a/x-pack/plugins/encrypted_saved_objects/server/crypto/encryption_key_rotation_service.ts b/x-pack/plugins/encrypted_saved_objects/server/crypto/encryption_key_rotation_service.ts new file mode 100644 index 0000000000000..fb1b6db45e762 --- /dev/null +++ b/x-pack/plugins/encrypted_saved_objects/server/crypto/encryption_key_rotation_service.ts @@ -0,0 +1,268 @@ +/* + * 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 { + ISavedObjectTypeRegistry, + KibanaRequest, + Logger, + SavedObject, + SavedObjectsBulkUpdateObject, + StartServicesAccessor, +} from 'src/core/server'; +import { AuthenticatedUser, SecurityPluginSetup } from '../../../security/server'; +import { getDescriptorNamespace } from '../saved_objects/get_descriptor_namespace'; +import { EncryptedSavedObjectsService } from './encrypted_saved_objects_service'; +import { EncryptionError } from './encryption_error'; + +interface EncryptionKeyRotationServiceOptions { + logger: Logger; + service: PublicMethodsOf; + getStartServices: StartServicesAccessor; + security?: SecurityPluginSetup; +} + +interface EncryptionKeyRotationParams { + /** + * The maximum number of the objects we fetch and process in one iteration. + */ + batchSize: number; + + /** + * Optionally allows to limit key rotation to only specified Saved Object type. + */ + type?: string; +} + +interface EncryptionKeyRotationResult { + /** + * The total number of the Saved Objects encrypted by the Encrypted Saved Objects plugin. + */ + total: number; + + /** + * The number of the Saved Objects that were still encrypted with one of the secondary encryption + * keys and were successfully re-encrypted with the primary key. + */ + successful: number; + + /** + * The number of the Saved Objects that were still encrypted with one of the secondary encryption + * keys that we failed to re-encrypt with the primary key. + */ + failed: number; +} + +/** + * Service that deals with encryption key rotation matters. + */ +export class EncryptionKeyRotationService { + constructor(private readonly options: EncryptionKeyRotationServiceOptions) {} + + public async rotate( + request: KibanaRequest, + { batchSize, type }: EncryptionKeyRotationParams + ): Promise { + const [{ savedObjects }] = await this.options.getStartServices(); + const typeRegistry = savedObjects.getTypeRegistry(); + + // We need to retrieve all SavedObject types which have encrypted attributes, specifically + // collecting those that are hidden as they are ignored by the Saved Objects client by default. + this.options.logger.debug('Retrieving Saved Object types that require encryption.'); + const registeredSavedObjectTypes = []; + const registeredHiddenSavedObjectTypes = []; + for (const knownType of typeRegistry.getAllTypes()) { + if (this.options.service.isRegistered(knownType.name) && (!type || knownType.name === type)) { + registeredSavedObjectTypes.push(knownType.name); + + if (knownType.hidden) { + registeredHiddenSavedObjectTypes.push(knownType.name); + } + } + } + + const result = { total: 0, successful: 0, failed: 0 }; + if (registeredSavedObjectTypes.length === 0) { + this.options.logger.info( + type + ? `Saved Object type "${type}" is not registered, encryption key rotation is not needed.` + : 'There are no registered Saved Object types that can have encrypted attributes, encryption key rotation is not needed.' + ); + return result; + } + + this.options.logger.info( + `Saved Objects with the following types [${registeredSavedObjectTypes}] will be processed.` + ); + + // We need two separate Saved Objects clients for the retrieval and update. For retrieval we + // don't want to have Encrypted Saved Objects wrapper so that it doesn't strip encrypted + // attributes. But for the update we want to have it so that it automatically re-encrypts + // attributes with the new primary encryption key. + const user = this.options.security?.authc.getCurrentUser(request) ?? undefined; + const retrieveClient = savedObjects.getScopedClient(request, { + includedHiddenTypes: registeredHiddenSavedObjectTypes, + excludedWrappers: ['encryptedSavedObjects'], + }); + const updateClient = savedObjects.getScopedClient(request, { + includedHiddenTypes: registeredHiddenSavedObjectTypes, + }); + + // Keeps track of object IDs that have been processed already. + const processedObjectIDs = new Set(); + + // Until we get scroll/search_after support in Saved Objects client we have to retrieve as much objects as allowed + // by the `batchSize` parameter. Instead of using paging functionality (size/from or page/perPage parameters) that + // has certain performance issues and is also limited by the maximum result window setting on .kibana index + // (10,000 by default) we always fetch the first page of the results sorted by the `updated_at` field. This way we + // can prioritize "old" objects that have a higher chance to have been encrypted with the old encryption keys, since + // all newly created or updated objects are always encrypted with the current primary key. Re-encryption of the + // "old" objects with the primary key implicitly bumps up their `updated_at` field so that these objects won't be + // included into the first page of the results during next iteration. Additionally we track IDs of all processed + // objects so that eventually we can detect that first page consists of only objects encrypted with the current + // primary key and stop iterating. + // + // LIMITATION: if we have a lot of "old" objects encrypted with the _unknown_ encryption key it may either + // significantly slow down rotation or prevent it from happening completely since such objects will be included into + // every batch we fetch and if their number is equal to or greater than `batchSize` we won't be able to process any + // object. Another and more complex case when we can be hit by this limitation is when users have multiple Kibana + // instances configured with different primary encryption keys, these time even "new" objects may require rotation, + // but they may be included into 2+ page of the results. We can potentially detect such cases and issue a warning, + // but it's not an easy task: if we detect a case when none of the objects from the very first batch cannot be + // decrypted with the decryption only keys we'll need to check how many of them can be decrypted at all using all + // available keys including the current primary one. + // + // Also theoretically if `batchSize` is less than `index.max_result_window` we could try to rely on the paging + // functionality and switch to the second page, but the issue here is that objects can be deleted in the meantime + // so that unprocessed objects may get into the first page and we'll miss them. We can of course oscillate between + // the first and the second pages or do multiple rotation passes, but it'd complicate code significantly. + let batch = 0; + let maxBatches = 0; + while (true) { + this.options.logger.debug(`Fetching ${batchSize} objects (batch #${batch}).`); + const savedObjectsToDecrypt = await retrieveClient.find({ + type: registeredSavedObjectTypes, + perPage: batchSize, + namespaces: ['*'], + sortField: 'updated_at', + sortOrder: 'asc', + }); + + // We use `total` only from the first batch just as an approximate indicator for the consumer since total number + // can change from batch to batch, but it won't affect the actual processing logic. + if (batch === 0) { + this.options.logger.debug(`Found ${savedObjectsToDecrypt.total} objects.`); + result.total = savedObjectsToDecrypt.total; + // Since we process live data there is a theoretical chance that we may be getting new + // objects in every batch effectively making this loop infinite. To prevent this we want to + // limit a number of batches we process during single rotation request giving enough room + // for the Saved Objects occasionally created during rotation. + maxBatches = Math.ceil((savedObjectsToDecrypt.total * 2) / batchSize); + } + + this.options.logger.debug( + `Decrypting ${savedObjectsToDecrypt.saved_objects.length} objects (batch #${batch}).` + ); + const savedObjectsToEncrypt = await this.getSavedObjectsToReEncrypt( + savedObjectsToDecrypt.saved_objects, + processedObjectIDs, + typeRegistry, + user + ); + if (savedObjectsToEncrypt.length === 0) { + break; + } + + this.options.logger.debug( + `Re-encrypting ${savedObjectsToEncrypt.length} objects (batch #${batch}).` + ); + try { + const succeeded = ( + await updateClient.bulkUpdate(savedObjectsToEncrypt) + ).saved_objects.filter((savedObject) => !savedObject.error).length; + + this.options.logger.debug( + `Successfully re-encrypted ${succeeded} out of ${savedObjectsToEncrypt.length} objects (batch #${batch}).` + ); + + result.successful += succeeded; + result.failed += savedObjectsToEncrypt.length - succeeded; + } catch (err) { + this.options.logger.error( + `Failed to re-encrypt saved objects (batch #${batch}): ${err.message}` + ); + result.failed += savedObjectsToEncrypt.length; + } + + if (savedObjectsToDecrypt.total <= batchSize || ++batch >= maxBatches) { + break; + } + } + + this.options.logger.info( + `Encryption key rotation is completed. ${result.successful} objects out ouf ${result.total} were successfully re-encrypted with the primary encryption key and ${result.failed} objects failed.` + ); + + return result; + } + + /** + * Takes a list of Saved Objects and tries to decrypt their attributes with the secondary encryption + * keys, silently skipping those that cannot be decrypted. The objects that were decrypted with the + * decryption-only keys will be returned and grouped by the namespace. + * @param savedObjects Saved Objects to decrypt attributes for. + * @param processedObjectIDs Set of Saved Object IDs that were already processed. + * @param typeRegistry Saved Objects type registry. + * @param user The user that initiated decryption. + */ + private async getSavedObjectsToReEncrypt( + savedObjects: SavedObject[], + processedObjectIDs: Set, + typeRegistry: ISavedObjectTypeRegistry, + user?: AuthenticatedUser + ) { + const decryptedSavedObjects: SavedObjectsBulkUpdateObject[] = []; + for (const savedObject of savedObjects) { + // We shouldn't process objects that we already processed during previous iterations. + if (processedObjectIDs.has(savedObject.id)) { + continue; + } else { + processedObjectIDs.add(savedObject.id); + } + + let decryptedAttributes; + try { + decryptedAttributes = await this.options.service.decryptAttributes( + { + type: savedObject.type, + id: savedObject.id, + namespace: getDescriptorNamespace( + typeRegistry, + savedObject.type, + savedObject.namespaces + ), + }, + savedObject.attributes as Record, + { omitPrimaryEncryptionKey: true, user } + ); + } catch (err) { + if (!(err instanceof EncryptionError)) { + throw err; + } + + continue; + } + + decryptedSavedObjects.push({ + ...savedObject, + attributes: decryptedAttributes, + // `bulkUpdate` expects objects with a single `namespace`. + namespace: savedObject.namespaces?.[0], + }); + } + + return decryptedSavedObjects; + } +} diff --git a/x-pack/plugins/encrypted_saved_objects/server/crypto/index.mock.ts b/x-pack/plugins/encrypted_saved_objects/server/crypto/index.mock.ts index 3e4983deca625..4410cbac7beb9 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/crypto/index.mock.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/crypto/index.mock.ts @@ -5,3 +5,4 @@ */ export { encryptedSavedObjectsServiceMock } from './encrypted_saved_objects_service.mocks'; +export { encryptionKeyRotationServiceMock } from './encryption_key_rotation_service.mocks'; diff --git a/x-pack/plugins/encrypted_saved_objects/server/crypto/index.ts b/x-pack/plugins/encrypted_saved_objects/server/crypto/index.ts index 75445bd24eba8..ff5e5fdc01059 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/crypto/index.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/crypto/index.ts @@ -12,3 +12,4 @@ export { } from './encrypted_saved_objects_service'; export { EncryptionError } from './encryption_error'; export { EncryptedSavedObjectAttributesDefinition } from './encrypted_saved_object_type_definition'; +export { EncryptionKeyRotationService } from './encryption_key_rotation_service'; diff --git a/x-pack/plugins/encrypted_saved_objects/server/plugin.test.ts b/x-pack/plugins/encrypted_saved_objects/server/plugin.test.ts index 57108954f2568..8d8f1a51f6802 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/plugin.test.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/plugin.test.ts @@ -5,6 +5,7 @@ */ import { Plugin } from './plugin'; +import { ConfigSchema } from './config'; import { coreMock } from 'src/core/server/mocks'; import { securityMock } from '../../security/server/mocks'; @@ -12,7 +13,9 @@ import { securityMock } from '../../security/server/mocks'; describe('EncryptedSavedObjects Plugin', () => { describe('setup()', () => { it('exposes proper contract', async () => { - const plugin = new Plugin(coreMock.createPluginInitializerContext()); + const plugin = new Plugin( + coreMock.createPluginInitializerContext(ConfigSchema.validate({}, { dist: true })) + ); await expect(plugin.setup(coreMock.createSetup(), { security: securityMock.createSetup() })) .resolves.toMatchInlineSnapshot(` Object { @@ -26,7 +29,9 @@ describe('EncryptedSavedObjects Plugin', () => { describe('start()', () => { it('exposes proper contract', async () => { - const plugin = new Plugin(coreMock.createPluginInitializerContext()); + const plugin = new Plugin( + coreMock.createPluginInitializerContext(ConfigSchema.validate({}, { dist: true })) + ); await plugin.setup(coreMock.createSetup(), { security: securityMock.createSetup() }); const startContract = plugin.start(); diff --git a/x-pack/plugins/encrypted_saved_objects/server/plugin.ts b/x-pack/plugins/encrypted_saved_objects/server/plugin.ts index 69777798ddf19..6e3724fa3fe58 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/plugin.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/plugin.ts @@ -4,19 +4,22 @@ * you may not use this file except in compliance with the Elastic License. */ +import { first, map } from 'rxjs/operators'; import nodeCrypto from '@elastic/node-crypto'; import { Logger, PluginInitializerContext, CoreSetup } from 'src/core/server'; -import { first } from 'rxjs/operators'; +import { TypeOf } from '@kbn/config-schema'; import { SecurityPluginSetup } from '../../security/server'; -import { createConfig$ } from './config'; +import { createConfig, ConfigSchema } from './config'; import { EncryptedSavedObjectsService, EncryptedSavedObjectTypeRegistration, EncryptionError, + EncryptionKeyRotationService, } from './crypto'; import { EncryptedSavedObjectsAuditLogger } from './audit'; import { setupSavedObjects, ClientInstanciator } from './saved_objects'; import { getCreateMigration, CreateEncryptedSavedObjectsMigrationFn } from './create_migration'; +import { defineRoutes } from './routes'; export interface PluginsSetup { security?: SecurityPluginSetup; @@ -48,18 +51,29 @@ export class Plugin { core: CoreSetup, deps: PluginsSetup ): Promise { - const { - config: { encryptionKey }, - usingEphemeralEncryptionKey, - } = await createConfig$(this.initializerContext).pipe(first()).toPromise(); - - const crypto = nodeCrypto({ encryptionKey }); - + const config = await this.initializerContext.config + .create>() + .pipe( + map((rawConfig) => createConfig(rawConfig, this.initializerContext.logger.get('config'))) + ) + .pipe(first()) + .toPromise(); const auditLogger = new EncryptedSavedObjectsAuditLogger( deps.security?.audit.getLogger('encryptedSavedObjects') ); + + const primaryCrypto = nodeCrypto({ encryptionKey: config.encryptionKey }); + const decryptionOnlyCryptos = config.keyRotation.decryptionOnlyKeys.map((decryptionKey) => + nodeCrypto({ encryptionKey: decryptionKey }) + ); + const service = Object.freeze( - new EncryptedSavedObjectsService(crypto, this.logger, auditLogger) + new EncryptedSavedObjectsService({ + primaryCrypto, + decryptionOnlyCryptos, + logger: this.logger, + audit: auditLogger, + }) ); this.savedObjectsSetup = setupSavedObjects({ @@ -69,18 +83,33 @@ export class Plugin { getStartServices: core.getStartServices, }); + defineRoutes({ + router: core.http.createRouter(), + logger: this.initializerContext.logger.get('routes'), + encryptionKeyRotationService: Object.freeze( + new EncryptionKeyRotationService({ + logger: this.logger.get('key-rotation-service'), + service, + getStartServices: core.getStartServices, + security: deps.security, + }) + ), + config, + }); + return { registerType: (typeRegistration: EncryptedSavedObjectTypeRegistration) => service.registerType(typeRegistration), - usingEphemeralEncryptionKey, + usingEphemeralEncryptionKey: config.usingEphemeralEncryptionKey, createMigration: getCreateMigration( service, (typeRegistration: EncryptedSavedObjectTypeRegistration) => { - const serviceForMigration = new EncryptedSavedObjectsService( - crypto, - this.logger, - auditLogger - ); + const serviceForMigration = new EncryptedSavedObjectsService({ + primaryCrypto, + decryptionOnlyCryptos, + logger: this.logger, + audit: auditLogger, + }); serviceForMigration.registerType(typeRegistration); return serviceForMigration; } diff --git a/x-pack/plugins/encrypted_saved_objects/server/routes/index.mock.ts b/x-pack/plugins/encrypted_saved_objects/server/routes/index.mock.ts new file mode 100644 index 0000000000000..b3d54c7f1ecac --- /dev/null +++ b/x-pack/plugins/encrypted_saved_objects/server/routes/index.mock.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { ConfigSchema, createConfig } from '../config'; + +import { httpServiceMock, loggingSystemMock } from '../../../../../src/core/server/mocks'; +import { encryptionKeyRotationServiceMock } from '../crypto/index.mock'; + +export const routeDefinitionParamsMock = { + create: (config: Record = {}) => ({ + router: httpServiceMock.createRouter(), + logger: loggingSystemMock.create().get(), + config: createConfig(ConfigSchema.validate(config), loggingSystemMock.create().get()), + encryptionKeyRotationService: encryptionKeyRotationServiceMock.create(), + }), +}; diff --git a/x-pack/plugins/encrypted_saved_objects/server/routes/index.ts b/x-pack/plugins/encrypted_saved_objects/server/routes/index.ts new file mode 100644 index 0000000000000..72af8060de827 --- /dev/null +++ b/x-pack/plugins/encrypted_saved_objects/server/routes/index.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { IRouter, Logger } from '../../../../../src/core/server'; +import { ConfigType } from '../config'; +import { EncryptionKeyRotationService } from '../crypto'; + +import { defineKeyRotationRoutes } from './key_rotation'; + +/** + * Describes parameters used to define HTTP routes. + */ +export interface RouteDefinitionParams { + router: IRouter; + logger: Logger; + config: ConfigType; + encryptionKeyRotationService: PublicMethodsOf; +} + +export function defineRoutes(params: RouteDefinitionParams) { + defineKeyRotationRoutes(params); +} diff --git a/x-pack/plugins/encrypted_saved_objects/server/routes/key_rotation.test.ts b/x-pack/plugins/encrypted_saved_objects/server/routes/key_rotation.test.ts new file mode 100644 index 0000000000000..ced4dda48fcd2 --- /dev/null +++ b/x-pack/plugins/encrypted_saved_objects/server/routes/key_rotation.test.ts @@ -0,0 +1,172 @@ +/* + * 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 { Type } from '@kbn/config-schema'; +import { + IRouter, + kibanaResponseFactory, + RequestHandler, + RequestHandlerContext, + RouteConfig, +} from '../../../../../src/core/server'; +import { defineKeyRotationRoutes } from './key_rotation'; + +import { httpServerMock } from '../../../../../src/core/server/mocks'; +import { routeDefinitionParamsMock } from './index.mock'; +import { EncryptionKeyRotationService } from '../crypto'; + +describe('Key rotation routes', () => { + let router: jest.Mocked; + let mockContext: RequestHandlerContext; + let mockEncryptionKeyRotationService: jest.Mocked; + beforeEach(() => { + const routeParamsMock = routeDefinitionParamsMock.create({ + keyRotation: { decryptionOnlyKeys: ['b'.repeat(32)] }, + }); + router = routeParamsMock.router; + mockEncryptionKeyRotationService = routeParamsMock.encryptionKeyRotationService; + + mockContext = ({} as unknown) as RequestHandlerContext; + + defineKeyRotationRoutes(routeParamsMock); + }); + + describe('rotate', () => { + let routeHandler: RequestHandler; + let routeConfig: RouteConfig; + beforeEach(() => { + const [rotateRouteConfig, rotateRouteHandler] = router.post.mock.calls.find( + ([{ path }]) => path === '/api/encrypted_saved_objects/_rotate_key' + )!; + + routeConfig = rotateRouteConfig; + routeHandler = rotateRouteHandler; + }); + + it('correctly defines route.', () => { + expect(routeConfig.options).toEqual({ tags: ['access:rotateEncryptionKey'] }); + expect(routeConfig.validate).toEqual({ + body: undefined, + query: expect.any(Type), + params: undefined, + }); + + const queryValidator = (routeConfig.validate as any).query as Type; + expect( + queryValidator.validate({ + batchSize: 100, + type: 'some-type', + }) + ).toEqual({ + batchSize: 100, + type: 'some-type', + }); + expect(queryValidator.validate({ batchSize: 1 })).toEqual({ batchSize: 1 }); + expect(queryValidator.validate({ batchSize: 10000 })).toEqual({ batchSize: 10000 }); + expect(queryValidator.validate({})).toEqual({ batchSize: 10000 }); + + expect(() => queryValidator.validate({ batchSize: 0 })).toThrowErrorMatchingInlineSnapshot( + `"[batchSize]: Value must be equal to or greater than [1]."` + ); + expect(() => + queryValidator.validate({ batchSize: 10001 }) + ).toThrowErrorMatchingInlineSnapshot( + `"[batchSize]: Value must be equal to or lower than [10000]."` + ); + + expect(() => queryValidator.validate({ type: 100 })).toThrowErrorMatchingInlineSnapshot( + `"[type]: expected value of type [string] but got [number]"` + ); + }); + + it('returns 400 if decryption only keys are not specified.', async () => { + const routeParamsMock = routeDefinitionParamsMock.create(); + defineKeyRotationRoutes(routeParamsMock); + const [, rotateRouteHandler] = routeParamsMock.router.post.mock.calls.find( + ([{ path }]) => path === '/api/encrypted_saved_objects/_rotate_key' + )!; + + await expect( + rotateRouteHandler(mockContext, httpServerMock.createKibanaRequest(), kibanaResponseFactory) + ).resolves.toEqual({ + status: 400, + payload: + 'Kibana is not configured to support encryption key rotation. Update `kibana.yml` to include `xpack.encryptedSavedObjects.keyRotation.decryptionOnlyKeys` to rotate your encryption keys.', + options: { + body: + 'Kibana is not configured to support encryption key rotation. Update `kibana.yml` to include `xpack.encryptedSavedObjects.keyRotation.decryptionOnlyKeys` to rotate your encryption keys.', + }, + }); + }); + + it('returns 500 if `rotate` throws unhandled exception.', async () => { + const unhandledException = new Error('Something went wrong.'); + mockEncryptionKeyRotationService.rotate.mockRejectedValue(unhandledException); + + const mockRequest = httpServerMock.createKibanaRequest({ query: { batchSize: 1234 } }); + const response = await routeHandler(mockContext, mockRequest, kibanaResponseFactory); + + expect(response.status).toBe(500); + expect(response.payload).toEqual(unhandledException); + expect(mockEncryptionKeyRotationService.rotate).toHaveBeenCalledWith(mockRequest, { + batchSize: 1234, + }); + }); + + it('returns whatever `rotate` returns.', async () => { + const mockRequest = httpServerMock.createKibanaRequest({ query: { batchSize: 1234 } }); + mockEncryptionKeyRotationService.rotate.mockResolvedValue({ + total: 3, + successful: 6, + failed: 0, + }); + + await expect(routeHandler(mockContext, mockRequest, kibanaResponseFactory)).resolves.toEqual({ + status: 200, + payload: { total: 3, successful: 6, failed: 0 }, + options: { body: { total: 3, successful: 6, failed: 0 } }, + }); + }); + + it('returns 429 if called while rotation is in progress.', async () => { + const mockRequest = httpServerMock.createKibanaRequest({ query: { batchSize: 1234 } }); + mockEncryptionKeyRotationService.rotate.mockResolvedValue({ + total: 3, + successful: 6, + failed: 0, + }); + + // Run rotation, but don't wait until it's complete. + const firstRequestPromise = routeHandler(mockContext, mockRequest, kibanaResponseFactory); + + // Try to run rotation once again. + await expect(routeHandler(mockContext, mockRequest, kibanaResponseFactory)).resolves.toEqual({ + status: 429, + payload: + 'Encryption key rotation is in progress already. Please wait until it is completed and try again.', + options: { + statusCode: 429, + body: + 'Encryption key rotation is in progress already. Please wait until it is completed and try again.', + }, + }); + + // Initial request properly resolves. + await expect(firstRequestPromise).resolves.toEqual({ + status: 200, + payload: { total: 3, successful: 6, failed: 0 }, + options: { body: { total: 3, successful: 6, failed: 0 } }, + }); + + // And subsequent requests resolve properly too. + await expect(routeHandler(mockContext, mockRequest, kibanaResponseFactory)).resolves.toEqual({ + status: 200, + payload: { total: 3, successful: 6, failed: 0 }, + options: { body: { total: 3, successful: 6, failed: 0 } }, + }); + }); + }); +}); diff --git a/x-pack/plugins/encrypted_saved_objects/server/routes/key_rotation.ts b/x-pack/plugins/encrypted_saved_objects/server/routes/key_rotation.ts new file mode 100644 index 0000000000000..48b29387106ee --- /dev/null +++ b/x-pack/plugins/encrypted_saved_objects/server/routes/key_rotation.ts @@ -0,0 +1,75 @@ +/* + * 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 { schema } from '@kbn/config-schema'; +import { RouteDefinitionParams } from '.'; + +/** + * The default maximum value of from + size for searches to .kibana index. Since we cannot use scroll + * or search_after functionality with the .kibana index we limit maximum batch size with this value. + */ +const DEFAULT_MAX_RESULT_WINDOW = 10000; + +/** + * Defines routes that are used for encryption key rotation. + */ +export function defineKeyRotationRoutes({ + encryptionKeyRotationService, + router, + logger, + config, +}: RouteDefinitionParams) { + let rotationInProgress = false; + router.post( + { + path: '/api/encrypted_saved_objects/_rotate_key', + validate: { + query: schema.object({ + batchSize: schema.number({ + min: 1, + max: DEFAULT_MAX_RESULT_WINDOW, + defaultValue: DEFAULT_MAX_RESULT_WINDOW, + }), + type: schema.maybe(schema.string()), + }), + }, + options: { + tags: ['access:rotateEncryptionKey'], + }, + }, + async (context, request, response) => { + if (config.keyRotation.decryptionOnlyKeys.length === 0) { + return response.badRequest({ + body: + 'Kibana is not configured to support encryption key rotation. Update `kibana.yml` to include `xpack.encryptedSavedObjects.keyRotation.decryptionOnlyKeys` to rotate your encryption keys.', + }); + } + + if (rotationInProgress) { + return response.customError({ + body: + 'Encryption key rotation is in progress already. Please wait until it is completed and try again.', + statusCode: 429, + }); + } + + rotationInProgress = true; + try { + return response.ok({ + body: await encryptionKeyRotationService.rotate(request, { + batchSize: request.query.batchSize, + type: request.query.type, + }), + }); + } catch (err) { + logger.error(err); + return response.customError({ body: err, statusCode: 500 }); + } finally { + rotationInProgress = false; + } + } + ); +} diff --git a/x-pack/plugins/encrypted_saved_objects/server/saved_objects/get_descriptor_namespace.test.ts b/x-pack/plugins/encrypted_saved_objects/server/saved_objects/get_descriptor_namespace.test.ts index 7ba90a5a76ab3..33ea1d8c3acec 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/saved_objects/get_descriptor_namespace.test.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/saved_objects/get_descriptor_namespace.test.ts @@ -66,5 +66,16 @@ describe('getDescriptorNamespace', () => { 'foo-namespace' ); }); + + it('returns the provided namespace if it is in array format', () => { + const mockBaseTypeRegistry = savedObjectsTypeRegistryMock.create(); + mockBaseTypeRegistry.isSingleNamespace.mockReturnValue(true); + mockBaseTypeRegistry.isMultiNamespace.mockReturnValue(false); + mockBaseTypeRegistry.isNamespaceAgnostic.mockReturnValue(false); + + expect(getDescriptorNamespace(mockBaseTypeRegistry, 'singletype', ['foo-namespace'])).toEqual( + 'foo-namespace' + ); + }); }); }); diff --git a/x-pack/plugins/encrypted_saved_objects/server/saved_objects/get_descriptor_namespace.ts b/x-pack/plugins/encrypted_saved_objects/server/saved_objects/get_descriptor_namespace.ts index 7201f13fb930b..7c237b82cbb15 100644 --- a/x-pack/plugins/encrypted_saved_objects/server/saved_objects/get_descriptor_namespace.ts +++ b/x-pack/plugins/encrypted_saved_objects/server/saved_objects/get_descriptor_namespace.ts @@ -9,9 +9,13 @@ import { ISavedObjectTypeRegistry, SavedObjectsUtils } from '../../../../../src/ export const getDescriptorNamespace = ( typeRegistry: ISavedObjectTypeRegistry, type: string, - namespace?: string + namespace?: string | string[] ) => { - const descriptorNamespace = typeRegistry.isSingleNamespace(type) ? namespace : undefined; + const descriptorNamespace = typeRegistry.isSingleNamespace(type) + ? Array.isArray(namespace) + ? namespace[0] + : namespace + : undefined; return normalizeNamespace(descriptorNamespace); }; diff --git a/x-pack/plugins/enterprise_search/README.md b/x-pack/plugins/enterprise_search/README.md index ba14be5564be1..711c7c7b065d2 100644 --- a/x-pack/plugins/enterprise_search/README.md +++ b/x-pack/plugins/enterprise_search/README.md @@ -17,6 +17,10 @@ This plugin's goal is to provide a Kibana user interface to the Enterprise Searc Enterprise Search uses [Kea.js](https://github.com/keajs/kea) to manage our React/Redux state for us. Kea state is handled in our `*Logic` files and exposes [values](https://kea.js.org/docs/guide/concepts#values) and [actions](https://kea.js.org/docs/guide/concepts#actions) for our components to get and set state with. +#### Advanced Kea usage + +For the most part, we stick to the functionality described in Kea's [core concepts](https://kea.js.org/docs/guide/concepts). However, in some files, we also take advantage of [props](https://kea.js.org/docs/guide/additional#props) and [events](https://kea.js.org/docs/guide/additional#events), as well as [manually mounting](https://kea.js.org/docs/guide/advanced#mounting-and-unmounting) some shared logic files on plugin init outside of React. + #### Debugging Kea To debug Kea state in-browser, Kea recommends [Redux Devtools](https://kea.js.org/docs/guide/debugging). To facilitate debugging, we use the [path](https://kea.js.org/docs/guide/debugging/#setting-the-path-manually) key with `snake_case`d paths. The path key should always end with the logic filename (e.g. `['enterprise_search', 'some_logic']`) to make it easy for devs to quickly find/jump to files via IDE tooling. diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/index.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/index.ts index 88a900f69c5ec..22bb556e6d602 100644 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/index.ts @@ -5,17 +5,13 @@ */ export { mockHistory, mockLocation } from './react_router_history.mock'; -export { mockKibanaContext } from './kibana_context.mock'; +export { mockKibanaValues } from './kibana_logic.mock'; export { mockLicensingValues } from './licensing_logic.mock'; export { mockHttpValues } from './http_logic.mock'; export { mockFlashMessagesValues, mockFlashMessagesActions } from './flash_messages_logic.mock'; -export { mockAllValues, mockAllActions, setMockValues } from './kea.mock'; +export { mockAllValues, mockAllActions, setMockValues, setMockActions } from './kea.mock'; -export { - mountWithContext, - mountWithKibanaContext, - mountWithAsyncContext, -} from './mount_with_context.mock'; +export { mountAsync } from './mount_async.mock'; +export { mountWithIntl } from './mount_with_i18n.mock'; export { shallowWithIntl } from './shallow_with_i18n.mock'; - -// Note: shallow_usecontext must be imported directly as a file +// Note: shallow_useeffect must be imported directly as a file diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts index bad6beaa1652e..ffbbaaf794bcc 100644 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kea.mock.ts @@ -10,11 +10,13 @@ * NOTE: These variable names MUST start with 'mock*' in order for * Jest to accept its use within a jest.mock() */ +import { mockKibanaValues } from './kibana_logic.mock'; import { mockLicensingValues } from './licensing_logic.mock'; import { mockHttpValues } from './http_logic.mock'; import { mockFlashMessagesValues, mockFlashMessagesActions } from './flash_messages_logic.mock'; export const mockAllValues = { + ...mockKibanaValues, ...mockLicensingValues, ...mockHttpValues, ...mockFlashMessagesValues, @@ -46,8 +48,11 @@ jest.mock('kea', () => ({ * setMockValues({ someValue: 'hello' }); * }); */ -import { useValues } from 'kea'; +import { useValues, useActions } from 'kea'; export const setMockValues = (values: object) => { (useValues as jest.Mock).mockImplementation(() => ({ ...mockAllValues, ...values })); }; +export const setMockActions = (actions: object) => { + (useActions as jest.Mock).mockImplementation(() => ({ ...mockAllActions, ...actions })); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_context.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_context.mock.ts deleted file mode 100644 index ee77b0937cd82..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_context.mock.ts +++ /dev/null @@ -1,16 +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. - */ - -/** - * A set of default Kibana context values to use across component tests. - * @see enterprise_search/public/index.tsx for the KibanaContext definition/import - */ -export const mockKibanaContext = { - navigateToUrl: jest.fn(), - setBreadcrumbs: jest.fn(), - setDocTitle: jest.fn(), - config: { host: 'http://localhost:3002' }, -}; diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_logic.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_logic.mock.ts new file mode 100644 index 0000000000000..ab91666d4acb6 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_logic.mock.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 { mockHistory } from './'; + +export const mockKibanaValues = { + config: { host: 'http://localhost:3002' }, + history: mockHistory, + navigateToUrl: jest.fn(), + setBreadcrumbs: jest.fn(), + setDocTitle: jest.fn(), + renderHeaderActions: jest.fn(), +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_async.mock.tsx b/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_async.mock.tsx new file mode 100644 index 0000000000000..a33e116c7ca72 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_async.mock.tsx @@ -0,0 +1,46 @@ +/* + * 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 { act } from 'react-dom/test-utils'; +import { mount, ReactWrapper } from 'enzyme'; + +import { mountWithIntl } from './'; + +/** + * This helper is intended for components that have async effects + * (e.g. http fetches) on mount. It mostly adds act/update boilerplate + * that's needed for the wrapper to play nice with Enzyme/Jest + * + * Example usage: + * + * const wrapper = mountAsync(); + */ + +interface IOptions { + i18n?: boolean; +} + +export const mountAsync = async ( + children: React.ReactElement, + options: IOptions +): Promise => { + let wrapper: ReactWrapper | undefined; + + // We get a lot of act() warning/errors in the terminal without this. + // TBH, I don't fully understand why since Enzyme's mount is supposed to + // have act() baked in - could be because of the wrapping context provider? + await act(async () => { + wrapper = options.i18n ? mountWithIntl(children) : mount(children); + }); + if (wrapper) { + wrapper.update(); // This seems to be required for the DOM to actually update + + return wrapper; + } else { + throw new Error('Could not mount wrapper'); + } +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_with_context.mock.tsx b/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_with_context.mock.tsx deleted file mode 100644 index 646c3104c286f..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_with_context.mock.tsx +++ /dev/null @@ -1,83 +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 { act } from 'react-dom/test-utils'; -import { mount, ReactWrapper } from 'enzyme'; - -import { Provider } from 'react-redux'; -import { Store } from 'redux'; -import { getContext, resetContext } from 'kea'; - -import { I18nProvider } from '@kbn/i18n/react'; -import { KibanaContext } from '../'; -import { mockKibanaContext } from './kibana_context.mock'; - -/** - * This helper mounts a component with all the contexts/providers used - * by the production app, while allowing custom context to be - * passed in via a second arg - * - * Example usage: - * - * const wrapper = mountWithContext(, { config: { host: 'someOverride' } }); - */ -export const mountWithContext = (children: React.ReactNode, context?: object) => { - resetContext({ createStore: true }); - const store = getContext().store as Store; - - return mount( - - - {children} - - - ); -}; - -/** - * This helper mounts a component with just the default KibanaContext - - * useful for isolated / helper components that only need this context - * - * Same usage/override functionality as mountWithContext - */ -export const mountWithKibanaContext = (children: React.ReactNode, context?: object) => { - return mount( - - {children} - - ); -}; - -/** - * This helper is intended for components that have async effects - * (e.g. http fetches) on mount. It mostly adds act/update boilerplate - * that's needed for the wrapper to play nice with Enzyme/Jest - * - * Example usage: - * - * const wrapper = mountWithAsyncContext(, { http: { get: () => someData } }); - */ -export const mountWithAsyncContext = async ( - children: React.ReactNode, - context?: object -): Promise => { - let wrapper: ReactWrapper | undefined; - - // We get a lot of act() warning/errors in the terminal without this. - // TBH, I don't fully understand why since Enzyme's mount is supposed to - // have act() baked in - could be because of the wrapping context provider? - await act(async () => { - wrapper = mountWithContext(children, context); - }); - if (wrapper) { - wrapper.update(); // This seems to be required for the DOM to actually update - - return wrapper; - } else { - throw new Error('Could not mount wrapper'); - } -}; diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_with_i18n.mock.tsx b/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_with_i18n.mock.tsx new file mode 100644 index 0000000000000..55abe1030544f --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/mount_with_i18n.mock.tsx @@ -0,0 +1,21 @@ +/* + * 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 { mount } from 'enzyme'; +import { I18nProvider } from '@kbn/i18n/react'; + +/** + * This helper wraps a component with react-intl's which + * fixes "Could not find required `intl` object" console errors when running tests + * + * Example usage (should be the same as mount()): + * + * const wrapper = mountWithI18n(); + */ +export const mountWithIntl = (children: React.ReactElement) => { + return mount({children}); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/react_router_history.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/react_router_history.mock.ts index 7b3ac86ad0ab1..2c833bcfeaf4c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/react_router_history.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/react_router_history.mock.ts @@ -15,7 +15,7 @@ export const mockHistory = { pathname: '/current-path', }, listen: jest.fn(() => jest.fn()), -}; +} as any; export const mockLocation = { key: 'someKey', pathname: '/current-path', @@ -25,6 +25,7 @@ export const mockLocation = { }; jest.mock('react-router-dom', () => ({ + ...(jest.requireActual('react-router-dom') as object), useHistory: jest.fn(() => mockHistory), useLocation: jest.fn(() => mockLocation), })); diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/shallow_usecontext.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/shallow_usecontext.mock.ts deleted file mode 100644 index df9e58994e36b..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/shallow_usecontext.mock.ts +++ /dev/null @@ -1,40 +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. - */ - -/** - * NOTE: These variable names MUST start with 'mock*' in order for - * Jest to accept its use within a jest.mock() - */ -import { mockKibanaContext } from './kibana_context.mock'; - -jest.mock('react', () => ({ - ...(jest.requireActual('react') as object), - useContext: jest.fn(() => ({ ...mockKibanaContext })), - useEffect: jest.fn((fn) => fn()), // Calls on mount/every update - use mount for more complex behavior -})); - -/** - * Example usage within a component test using shallow(): - * - * import '../../../__mocks__/shallow_usecontext'; // Must come before React's import, adjust relative path as needed - * - * import React from 'react'; - * import { shallow } from 'enzyme'; - * - * // ... etc. - */ - -/** - * If you need to override the default mock context values, you can do so via jest.mockImplementation: - * - * import React, { useContext } from 'react'; - * - * // ... etc. - * - * it('some test', () => { - * useContext.mockImplementationOnce(() => ({ config: { host: 'someOverride' } })); - * }); - */ diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/shallow_useeffect.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/shallow_useeffect.mock.ts new file mode 100644 index 0000000000000..732786b5f9249 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/shallow_useeffect.mock.ts @@ -0,0 +1,21 @@ +/* + * 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. + */ + +jest.mock('react', () => ({ + ...(jest.requireActual('react') as object), + useEffect: jest.fn((fn) => fn()), // Calls on mount/every update - use mount for more complex behavior +})); + +/** + * Example usage within a component test using shallow(): + * + * import '../../../__mocks__/shallow_useeffect.mock'; // Must come before React's import, adjust relative path as needed + * + * import React from 'react'; + * import { shallow } from 'enzyme'; + * + * // ... etc. + */ diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_logic.test.ts index c5cb8a2c61759..56fc825493b80 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_logic.test.ts @@ -27,7 +27,7 @@ describe('CredentialsLogic', () => { write: true, access_all_engines: true, }, - activeApiTokenIsExisting: false, + activeApiTokenExists: false, activeApiTokenRawName: '', apiTokens: [], dataLoading: true, @@ -37,7 +37,7 @@ describe('CredentialsLogic', () => { isCredentialsDetailsComplete: false, meta: {}, nameInputBlurred: false, - showCredentialsForm: false, + shouldShowCredentialsForm: false, }; const mount = (defaults?: object) => { @@ -85,710 +85,499 @@ describe('CredentialsLogic', () => { expect(CredentialsLogic.values).toEqual(DEFAULT_VALUES); }); - describe('addEngineName', () => { - const values = { - ...DEFAULT_VALUES, - activeApiToken: expect.any(Object), - }; - - describe('activeApiToken', () => { - it("should add an engine to the active api token's engine list", () => { - mount({ - activeApiToken: { - ...newToken, - engines: ['someEngine'], - }, - }); - - CredentialsLogic.actions.addEngineName('newEngine'); - expect(CredentialsLogic.values).toEqual({ - ...values, - activeApiToken: { ...newToken, engines: ['someEngine', 'newEngine'] }, - }); - }); - - it("should create a new engines list if one doesn't exist", () => { - mount({ - activeApiToken: { - ...newToken, - engines: undefined, - }, - }); - - CredentialsLogic.actions.addEngineName('newEngine'); - expect(CredentialsLogic.values).toEqual({ - ...values, - activeApiToken: { ...newToken, engines: ['newEngine'] }, - }); - }); - }); - }); - - describe('removeEngineName', () => { - describe('activeApiToken', () => { + describe('actions', () => { + describe('addEngineName', () => { const values = { ...DEFAULT_VALUES, activeApiToken: expect.any(Object), + activeApiTokenExists: expect.any(Boolean), }; - it("should remove an engine from the active api token's engine list", () => { - mount({ - activeApiToken: { - ...newToken, - engines: ['someEngine', 'anotherEngine'], - }, - }); - - CredentialsLogic.actions.removeEngineName('someEngine'); - expect(CredentialsLogic.values).toEqual({ - ...values, - activeApiToken: { ...newToken, engines: ['anotherEngine'] }, - }); - }); + describe('activeApiToken', () => { + it("should add an engine to the active api token's engine list", () => { + mount({ + activeApiToken: { + ...newToken, + engines: ['someEngine'], + }, + }); - it('will not remove the engine if it is not found', () => { - mount({ - activeApiToken: { - ...newToken, - engines: ['someEngine', 'anotherEngine'], - }, + CredentialsLogic.actions.addEngineName('newEngine'); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiToken: { ...newToken, engines: ['someEngine', 'newEngine'] }, + }); }); - CredentialsLogic.actions.removeEngineName('notfound'); - expect(CredentialsLogic.values).toEqual({ - ...values, - activeApiToken: { ...newToken, engines: ['someEngine', 'anotherEngine'] }, - }); - }); + it("should create a new engines list if one doesn't exist", () => { + mount({ + activeApiToken: { + ...newToken, + engines: undefined, + }, + }); - it('does not throw a type error if no engines are stored in state', () => { - mount({ - activeApiToken: {}, - }); - CredentialsLogic.actions.removeEngineName(''); - expect(CredentialsLogic.values).toEqual({ - ...values, - activeApiToken: { engines: [] }, + CredentialsLogic.actions.addEngineName('newEngine'); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiToken: { ...newToken, engines: ['newEngine'] }, + }); }); }); }); - }); - - describe('setAccessAllEngines', () => { - const values = { - ...DEFAULT_VALUES, - activeApiToken: expect.any(Object), - }; - - describe('activeApiToken', () => { - it('should set the value of access_all_engines and clear out engines list if true', () => { - mount({ - activeApiToken: { - ...newToken, - access_all_engines: false, - engines: ['someEngine', 'anotherEngine'], - }, - }); - - CredentialsLogic.actions.setAccessAllEngines(true); - expect(CredentialsLogic.values).toEqual({ - ...values, - activeApiToken: { ...newToken, engines: [], access_all_engines: true }, - }); - }); - - it('should set the value of access_all_engines and but maintain engines list if false', () => { - mount({ - activeApiToken: { - ...newToken, - access_all_engines: true, - engines: ['someEngine', 'anotherEngine'], - }, - }); - CredentialsLogic.actions.setAccessAllEngines(false); - expect(CredentialsLogic.values).toEqual({ - ...values, - activeApiToken: { - ...newToken, - access_all_engines: false, - engines: ['someEngine', 'anotherEngine'], - }, - }); - }); - }); - }); + describe('removeEngineName', () => { + describe('activeApiToken', () => { + const values = { + ...DEFAULT_VALUES, + activeApiToken: expect.any(Object), + activeApiTokenExists: expect.any(Boolean), + }; - describe('onApiKeyDelete', () => { - const values = { - ...DEFAULT_VALUES, - apiTokens: expect.any(Array), - }; + it("should remove an engine from the active api token's engine list", () => { + mount({ + activeApiToken: { + ...newToken, + engines: ['someEngine', 'anotherEngine'], + }, + }); - describe('apiTokens', () => { - it('should remove specified token from apiTokens if name matches', () => { - mount({ - apiTokens: [newToken], + CredentialsLogic.actions.removeEngineName('someEngine'); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiToken: { ...newToken, engines: ['anotherEngine'] }, + }); }); - CredentialsLogic.actions.onApiKeyDelete(newToken.name); - expect(CredentialsLogic.values).toEqual({ - ...values, - apiTokens: [], - }); - }); + it('will not remove the engine if it is not found', () => { + mount({ + activeApiToken: { + ...newToken, + engines: ['someEngine', 'anotherEngine'], + }, + }); - it('should not remove specified token from apiTokens if name does not match', () => { - mount({ - apiTokens: [newToken], + CredentialsLogic.actions.removeEngineName('notfound'); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiToken: { ...newToken, engines: ['someEngine', 'anotherEngine'] }, + }); }); - CredentialsLogic.actions.onApiKeyDelete('foo'); - expect(CredentialsLogic.values).toEqual({ - ...values, - apiTokens: [newToken], + it('does not throw a type error if no engines are stored in state', () => { + mount({ + activeApiToken: {}, + }); + CredentialsLogic.actions.removeEngineName(''); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiToken: { engines: [] }, + }); }); }); }); - }); - describe('onApiTokenCreateSuccess', () => { - const values = { - ...DEFAULT_VALUES, - apiTokens: expect.any(Array), - activeApiToken: expect.any(Object), - activeApiTokenRawName: expect.any(String), - showCredentialsForm: expect.any(Boolean), - formErrors: expect.any(Array), - }; - - describe('apiTokens', () => { - const existingToken = { - name: 'some_token', - type: PRIVATE, + describe('setAccessAllEngines', () => { + const values = { + ...DEFAULT_VALUES, + activeApiToken: expect.any(Object), + activeApiTokenExists: expect.any(Boolean), }; - it('should add the provided token to the apiTokens list', () => { - mount({ - apiTokens: [existingToken], - }); - - CredentialsLogic.actions.onApiTokenCreateSuccess(newToken); - expect(CredentialsLogic.values).toEqual({ - ...values, - apiTokens: [existingToken, newToken], - }); - }); - }); - - describe('activeApiToken', () => { - // TODO It is weird that methods like this update activeApiToken but not activeApiTokenIsExisting... - it('should reset to the default value, which effectively clears out the current form', () => { - mount({ - activeApiToken: newToken, - }); + describe('activeApiToken', () => { + it('should set the value of access_all_engines and clear out engines list if true', () => { + mount({ + activeApiToken: { + ...newToken, + access_all_engines: false, + engines: ['someEngine', 'anotherEngine'], + }, + }); - CredentialsLogic.actions.onApiTokenCreateSuccess(newToken); - expect(CredentialsLogic.values).toEqual({ - ...values, - activeApiToken: DEFAULT_VALUES.activeApiToken, + CredentialsLogic.actions.setAccessAllEngines(true); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiToken: { ...newToken, engines: [], access_all_engines: true }, + }); }); - }); - }); - describe('activeApiTokenRawName', () => { - it('should reset to the default value, which effectively clears out the current form', () => { - mount({ - activeApiTokenRawName: 'foo', - }); + it('should set the value of access_all_engines and but maintain engines list if false', () => { + mount({ + activeApiToken: { + ...newToken, + access_all_engines: true, + engines: ['someEngine', 'anotherEngine'], + }, + }); - CredentialsLogic.actions.onApiTokenCreateSuccess(newToken); - expect(CredentialsLogic.values).toEqual({ - ...values, - activeApiTokenRawName: DEFAULT_VALUES.activeApiTokenRawName, + CredentialsLogic.actions.setAccessAllEngines(false); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiToken: { + ...newToken, + access_all_engines: false, + engines: ['someEngine', 'anotherEngine'], + }, + }); }); }); }); - describe('showCredentialsForm', () => { - it('should reset to the default value, which closes the credentials form', () => { - mount({ - showCredentialsForm: true, - }); - - CredentialsLogic.actions.onApiTokenCreateSuccess(newToken); - expect(CredentialsLogic.values).toEqual({ - ...values, - showCredentialsForm: false, - }); - }); - }); + describe('onApiKeyDelete', () => { + const values = { + ...DEFAULT_VALUES, + apiTokens: expect.any(Array), + }; - describe('formErrors', () => { - it('should reset `formErrors`', () => { - mount({ - formErrors: ['I am an error'], - }); + describe('apiTokens', () => { + it('should remove specified token from apiTokens if name matches', () => { + mount({ + apiTokens: [newToken], + }); - CredentialsLogic.actions.onApiTokenCreateSuccess(newToken); - expect(CredentialsLogic.values).toEqual({ - ...values, - formErrors: [], + CredentialsLogic.actions.onApiKeyDelete(newToken.name); + expect(CredentialsLogic.values).toEqual({ + ...values, + apiTokens: [], + }); }); - }); - }); - }); - - describe('onApiTokenError', () => { - const values = { - ...DEFAULT_VALUES, - formErrors: expect.any(Array), - }; - describe('formErrors', () => { - it('should set `formErrors`', () => { - mount({ - formErrors: ['I am an error'], - }); + it('should not remove specified token from apiTokens if name does not match', () => { + mount({ + apiTokens: [newToken], + }); - CredentialsLogic.actions.onApiTokenError(['I am the NEW error']); - expect(CredentialsLogic.values).toEqual({ - ...values, - formErrors: ['I am the NEW error'], + CredentialsLogic.actions.onApiKeyDelete('foo'); + expect(CredentialsLogic.values).toEqual({ + ...values, + apiTokens: [newToken], + }); }); }); }); - }); - describe('onApiTokenUpdateSuccess', () => { - const values = { - ...DEFAULT_VALUES, - apiTokens: expect.any(Array), - activeApiToken: expect.any(Object), - activeApiTokenRawName: expect.any(String), - showCredentialsForm: expect.any(Boolean), - }; - - describe('apiTokens', () => { - const existingToken = { - name: 'some_token', - type: PRIVATE, + describe('onApiTokenCreateSuccess', () => { + const values = { + ...DEFAULT_VALUES, + activeApiTokenExists: expect.any(Boolean), + apiTokens: expect.any(Array), + activeApiToken: expect.any(Object), + activeApiTokenRawName: expect.any(String), + shouldShowCredentialsForm: expect.any(Boolean), + formErrors: expect.any(Array), }; - it('should replace the existing token with the new token by name', () => { - mount({ - apiTokens: [newToken, existingToken], - }); - const updatedExistingToken = { - ...existingToken, - type: ADMIN, - }; - - CredentialsLogic.actions.onApiTokenUpdateSuccess(updatedExistingToken); - expect(CredentialsLogic.values).toEqual({ - ...values, - apiTokens: [newToken, updatedExistingToken], - }); - }); - - // TODO Not sure if this is a good behavior or not - it('if for some reason the existing token is not found, it adds a new token...', () => { - mount({ - apiTokens: [newToken, existingToken], - }); - const brandNewToken = { - name: 'brand new token', - type: ADMIN, + describe('apiTokens', () => { + const existingToken = { + name: 'some_token', + type: PRIVATE, }; - CredentialsLogic.actions.onApiTokenUpdateSuccess(brandNewToken); - expect(CredentialsLogic.values).toEqual({ - ...values, - apiTokens: [newToken, existingToken, brandNewToken], - }); - }); - }); - - describe('activeApiToken', () => { - it('should reset to the default value, which effectively clears out the current form', () => { - mount({ - activeApiToken: newToken, - }); - - CredentialsLogic.actions.onApiTokenUpdateSuccess({ ...newToken, type: ADMIN }); - expect(CredentialsLogic.values).toEqual({ - ...values, - activeApiToken: DEFAULT_VALUES.activeApiToken, - }); - }); - }); - - describe('activeApiTokenRawName', () => { - it('should reset to the default value, which effectively clears out the current form', () => { - mount({ - activeApiTokenRawName: 'foo', - }); + it('should add the provided token to the apiTokens list', () => { + mount({ + apiTokens: [existingToken], + }); - CredentialsLogic.actions.onApiTokenUpdateSuccess({ ...newToken, type: ADMIN }); - expect(CredentialsLogic.values).toEqual({ - ...values, - activeApiTokenRawName: DEFAULT_VALUES.activeApiTokenRawName, + CredentialsLogic.actions.onApiTokenCreateSuccess(newToken); + expect(CredentialsLogic.values).toEqual({ + ...values, + apiTokens: [existingToken, newToken], + }); }); }); - }); - describe('showCredentialsForm', () => { - it('should reset to the default value, which closes the credentials form', () => { - mount({ - showCredentialsForm: true, - }); + describe('activeApiToken', () => { + it('should reset to the default value, which effectively clears out the current form', () => { + mount({ + activeApiToken: newToken, + }); - CredentialsLogic.actions.onApiTokenUpdateSuccess({ ...newToken, type: ADMIN }); - expect(CredentialsLogic.values).toEqual({ - ...values, - showCredentialsForm: false, + CredentialsLogic.actions.onApiTokenCreateSuccess(newToken); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiToken: DEFAULT_VALUES.activeApiToken, + }); }); }); - }); - }); - describe('setCredentialsData', () => { - const meta = { - page: { - current: 1, - size: 1, - total_pages: 1, - total_results: 1, - }, - }; - - const values = { - ...DEFAULT_VALUES, - apiTokens: expect.any(Array), - meta: expect.any(Object), - isCredentialsDataComplete: expect.any(Boolean), - }; - - describe('apiTokens', () => { - it('should be set', () => { - mount(); + describe('activeApiTokenRawName', () => { + it('should reset to the default value, which effectively clears out the current form', () => { + mount({ + activeApiTokenRawName: 'foo', + }); - CredentialsLogic.actions.setCredentialsData(meta, [newToken, newToken]); - expect(CredentialsLogic.values).toEqual({ - ...values, - apiTokens: [newToken, newToken], + CredentialsLogic.actions.onApiTokenCreateSuccess(newToken); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiTokenRawName: DEFAULT_VALUES.activeApiTokenRawName, + }); }); }); - }); - describe('meta', () => { - it('should be set', () => { - mount(); + describe('shouldShowCredentialsForm', () => { + it('should reset to the default value, which closes the credentials form', () => { + mount({ + shouldShowCredentialsForm: true, + }); - CredentialsLogic.actions.setCredentialsData(meta, [newToken, newToken]); - expect(CredentialsLogic.values).toEqual({ - ...values, - meta, + CredentialsLogic.actions.onApiTokenCreateSuccess(newToken); + expect(CredentialsLogic.values).toEqual({ + ...values, + shouldShowCredentialsForm: false, + }); }); }); - }); - describe('isCredentialsDataComplete', () => { - it('should be set to true so we know that data fetching has completed', () => { - mount({ - isCredentialsDataComplete: false, - }); + describe('formErrors', () => { + it('should reset `formErrors`', () => { + mount({ + formErrors: ['I am an error'], + }); - CredentialsLogic.actions.setCredentialsData(meta, [newToken, newToken]); - expect(CredentialsLogic.values).toEqual({ - ...values, - isCredentialsDataComplete: true, + CredentialsLogic.actions.onApiTokenCreateSuccess(newToken); + expect(CredentialsLogic.values).toEqual({ + ...values, + formErrors: [], + }); }); }); }); - }); - describe('setCredentialsDetails', () => { - const values = { - ...DEFAULT_VALUES, - engines: expect.any(Array), - isCredentialsDetailsComplete: expect.any(Boolean), - }; + describe('onApiTokenError', () => { + const values = { + ...DEFAULT_VALUES, + formErrors: expect.any(Array), + }; - describe('isCredentialsDataComplete', () => { - it('should be set to true so that we know data fetching has been completed', () => { - mount({ - isCredentialsDetailsComplete: false, - }); + describe('formErrors', () => { + it('should set `formErrors`', () => { + mount({ + formErrors: ['I am an error'], + }); - CredentialsLogic.actions.setCredentialsDetails(credentialsDetails); - expect(CredentialsLogic.values).toEqual({ - ...values, - isCredentialsDetailsComplete: true, + CredentialsLogic.actions.onApiTokenError(['I am the NEW error']); + expect(CredentialsLogic.values).toEqual({ + ...values, + formErrors: ['I am the NEW error'], + }); }); }); }); - describe('engines', () => { - it('should set `engines` from the provided details object', () => { - mount({ - engines: [], - }); - - CredentialsLogic.actions.setCredentialsDetails(credentialsDetails); - expect(CredentialsLogic.values).toEqual({ - ...values, - engines: credentialsDetails.engines, - }); - }); - }); - }); + describe('onApiTokenUpdateSuccess', () => { + const values = { + ...DEFAULT_VALUES, + apiTokens: expect.any(Array), + activeApiToken: expect.any(Object), + activeApiTokenRawName: expect.any(String), + shouldShowCredentialsForm: expect.any(Boolean), + }; - describe('setNameInputBlurred', () => { - const values = { - ...DEFAULT_VALUES, - nameInputBlurred: expect.any(Boolean), - }; + describe('apiTokens', () => { + const existingToken = { + name: 'some_token', + type: PRIVATE, + }; - describe('nameInputBlurred', () => { - it('should set this value', () => { - mount({ - nameInputBlurred: false, - }); + it('should replace the existing token with the new token by name', () => { + mount({ + apiTokens: [newToken, existingToken], + }); + const updatedExistingToken = { + ...existingToken, + type: ADMIN, + }; - CredentialsLogic.actions.setNameInputBlurred(true); - expect(CredentialsLogic.values).toEqual({ - ...values, - nameInputBlurred: true, + CredentialsLogic.actions.onApiTokenUpdateSuccess(updatedExistingToken); + expect(CredentialsLogic.values).toEqual({ + ...values, + apiTokens: [newToken, updatedExistingToken], + }); }); - }); - }); - }); - - describe('setTokenReadWrite', () => { - const values = { - ...DEFAULT_VALUES, - activeApiToken: expect.any(Object), - }; - describe('activeApiToken', () => { - it('should set "read" or "write" values', () => { - mount({ - activeApiToken: { - ...newToken, - read: false, - }, - }); + // TODO Not sure if this is a good behavior or not + it('if for some reason the existing token is not found, it adds a new token...', () => { + mount({ + apiTokens: [newToken, existingToken], + }); + const brandNewToken = { + name: 'brand new token', + type: ADMIN, + }; - CredentialsLogic.actions.setTokenReadWrite({ name: 'read', checked: true }); - expect(CredentialsLogic.values).toEqual({ - ...values, - activeApiToken: { - ...newToken, - read: true, - }, + CredentialsLogic.actions.onApiTokenUpdateSuccess(brandNewToken); + expect(CredentialsLogic.values).toEqual({ + ...values, + apiTokens: [newToken, existingToken, brandNewToken], + }); }); }); - }); - }); - - describe('setTokenName', () => { - const values = { - ...DEFAULT_VALUES, - activeApiToken: expect.any(Object), - activeApiTokenRawName: expect.any(String), - }; - describe('activeApiToken', () => { - it('update the name property on the activeApiToken, formatted correctly', () => { - mount({ - activeApiToken: { - ...newToken, - name: 'bar', - }, - }); + describe('activeApiToken', () => { + it('should reset to the default value, which effectively clears out the current form', () => { + mount({ + activeApiToken: newToken, + }); - CredentialsLogic.actions.setTokenName('New Name'); - expect(CredentialsLogic.values).toEqual({ - ...values, - activeApiToken: { ...newToken, name: 'new-name' }, + CredentialsLogic.actions.onApiTokenUpdateSuccess({ ...newToken, type: ADMIN }); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiToken: DEFAULT_VALUES.activeApiToken, + }); }); }); - }); - describe('activeApiTokenRawName', () => { - it('updates the raw name, with no formatting applied', () => { - mount(); + describe('activeApiTokenRawName', () => { + it('should reset to the default value, which effectively clears out the current form', () => { + mount({ + activeApiTokenRawName: 'foo', + }); - CredentialsLogic.actions.setTokenName('New Name'); - expect(CredentialsLogic.values).toEqual({ - ...values, - activeApiTokenRawName: 'New Name', + CredentialsLogic.actions.onApiTokenUpdateSuccess({ ...newToken, type: ADMIN }); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiTokenRawName: DEFAULT_VALUES.activeApiTokenRawName, + }); }); }); - }); - }); - describe('setTokenType', () => { - const values = { - ...DEFAULT_VALUES, - activeApiToken: { - ...newToken, - type: expect.any(String), - read: expect.any(Boolean), - write: expect.any(Boolean), - access_all_engines: expect.any(Boolean), - engines: expect.any(Array), - }, - }; - - describe('activeApiToken.access_all_engines', () => { - describe('when value is ADMIN', () => { - it('updates access_all_engines to false', () => { + describe('shouldShowCredentialsForm', () => { + it('should reset to the default value, which closes the credentials form', () => { mount({ - activeApiToken: { - ...newToken, - access_all_engines: true, - }, + shouldShowCredentialsForm: true, }); - CredentialsLogic.actions.setTokenType(ADMIN); + CredentialsLogic.actions.onApiTokenUpdateSuccess({ ...newToken, type: ADMIN }); expect(CredentialsLogic.values).toEqual({ ...values, - activeApiToken: { - ...values.activeApiToken, - access_all_engines: false, - }, + shouldShowCredentialsForm: false, }); }); }); + }); - describe('when value is not ADMIN', () => { - it('will maintain access_all_engines value when true', () => { - mount({ - activeApiToken: { - ...newToken, - access_all_engines: true, - }, - }); + describe('setCredentialsData', () => { + const meta = { + page: { + current: 1, + size: 1, + total_pages: 1, + total_results: 1, + }, + }; - CredentialsLogic.actions.setTokenType(PRIVATE); + const values = { + ...DEFAULT_VALUES, + apiTokens: expect.any(Array), + meta: expect.any(Object), + isCredentialsDataComplete: expect.any(Boolean), + }; + + describe('apiTokens', () => { + it('should be set', () => { + mount(); + + CredentialsLogic.actions.setCredentialsData(meta, [newToken, newToken]); expect(CredentialsLogic.values).toEqual({ ...values, - activeApiToken: { - ...values.activeApiToken, - access_all_engines: true, - }, + apiTokens: [newToken, newToken], }); }); + }); - it('will maintain access_all_engines value when false', () => { - mount({ - activeApiToken: { - ...newToken, - access_all_engines: false, - }, - }); + describe('meta', () => { + it('should be set', () => { + mount(); - CredentialsLogic.actions.setTokenType(PRIVATE); + CredentialsLogic.actions.setCredentialsData(meta, [newToken, newToken]); expect(CredentialsLogic.values).toEqual({ ...values, - activeApiToken: { - ...values.activeApiToken, - access_all_engines: false, - }, + meta, }); }); }); - }); - describe('activeApiToken.engines', () => { - describe('when value is ADMIN', () => { - it('clears the array', () => { + describe('isCredentialsDataComplete', () => { + it('should be set to true so we know that data fetching has completed', () => { mount({ - activeApiToken: { - ...newToken, - engines: [{}, {}], - }, + isCredentialsDataComplete: false, }); - CredentialsLogic.actions.setTokenType(ADMIN); + CredentialsLogic.actions.setCredentialsData(meta, [newToken, newToken]); expect(CredentialsLogic.values).toEqual({ ...values, - activeApiToken: { - ...values.activeApiToken, - engines: [], - }, + isCredentialsDataComplete: true, }); }); }); + }); + + describe('setCredentialsDetails', () => { + const values = { + ...DEFAULT_VALUES, + engines: expect.any(Array), + isCredentialsDetailsComplete: expect.any(Boolean), + }; - describe('when value is not ADMIN', () => { - it('will maintain engines array', () => { + describe('isCredentialsDataComplete', () => { + it('should be set to true so that we know data fetching has been completed', () => { mount({ - activeApiToken: { - ...newToken, - engines: [{}, {}], - }, + isCredentialsDetailsComplete: false, }); - CredentialsLogic.actions.setTokenType(PRIVATE); + CredentialsLogic.actions.setCredentialsDetails(credentialsDetails); expect(CredentialsLogic.values).toEqual({ ...values, - activeApiToken: { - ...values.activeApiToken, - engines: [{}, {}], - }, + isCredentialsDetailsComplete: true, }); }); }); - }); - describe('activeApiToken.write', () => { - describe('when value is PRIVATE', () => { - it('sets this to true', () => { + describe('engines', () => { + it('should set `engines` from the provided details object', () => { mount({ - activeApiToken: { - ...newToken, - write: false, - }, + engines: [], }); - CredentialsLogic.actions.setTokenType(PRIVATE); + CredentialsLogic.actions.setCredentialsDetails(credentialsDetails); expect(CredentialsLogic.values).toEqual({ ...values, - activeApiToken: { - ...values.activeApiToken, - write: true, - }, + engines: credentialsDetails.engines, }); }); }); + }); + + describe('setNameInputBlurred', () => { + const values = { + ...DEFAULT_VALUES, + nameInputBlurred: expect.any(Boolean), + }; - describe('when value is not PRIVATE', () => { - it('sets this to false', () => { + describe('nameInputBlurred', () => { + it('should set this value', () => { mount({ - activeApiToken: { - ...newToken, - write: true, - }, + nameInputBlurred: false, }); - CredentialsLogic.actions.setTokenType(ADMIN); + CredentialsLogic.actions.setNameInputBlurred(true); expect(CredentialsLogic.values).toEqual({ ...values, - activeApiToken: { - ...values.activeApiToken, - write: false, - }, + nameInputBlurred: true, }); }); }); }); - describe('activeApiToken.read', () => { - describe('when value is PRIVATE', () => { - it('sets this to true', () => { + describe('setTokenReadWrite', () => { + const values = { + ...DEFAULT_VALUES, + activeApiToken: expect.any(Object), + activeApiTokenExists: expect.any(Boolean), + }; + + describe('activeApiToken', () => { + it('should set "read" or "write" values', () => { mount({ activeApiToken: { ...newToken, @@ -796,401 +585,594 @@ describe('CredentialsLogic', () => { }, }); - CredentialsLogic.actions.setTokenType(PRIVATE); + CredentialsLogic.actions.setTokenReadWrite({ name: 'read', checked: true }); expect(CredentialsLogic.values).toEqual({ ...values, activeApiToken: { - ...values.activeApiToken, + ...newToken, read: true, }, }); }); }); + }); + + describe('setTokenName', () => { + const values = { + ...DEFAULT_VALUES, + activeApiToken: expect.any(Object), + activeApiTokenRawName: expect.any(String), + activeApiTokenExists: expect.any(Boolean), + }; - describe('when value is not PRIVATE', () => { - it('sets this to false', () => { + describe('activeApiToken', () => { + it('update the name property on the activeApiToken, formatted correctly', () => { mount({ activeApiToken: { ...newToken, - read: true, + name: 'bar', }, }); - CredentialsLogic.actions.setTokenType(ADMIN); + CredentialsLogic.actions.setTokenName('New Name'); expect(CredentialsLogic.values).toEqual({ ...values, - activeApiToken: { - ...values.activeApiToken, - read: false, - }, + activeApiToken: { ...newToken, name: 'new-name' }, }); }); }); - }); - describe('activeApiToken.type', () => { - it('sets the type value', () => { - mount({ - activeApiToken: { - ...newToken, - type: ADMIN, - }, - }); + describe('activeApiTokenRawName', () => { + it('updates the raw name, with no formatting applied', () => { + mount(); - CredentialsLogic.actions.setTokenType(PRIVATE); - expect(CredentialsLogic.values).toEqual({ - ...values, - activeApiToken: { - ...values.activeApiToken, - type: PRIVATE, - }, + CredentialsLogic.actions.setTokenName('New Name'); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiTokenRawName: 'New Name', + }); }); }); }); - }); - describe('toggleCredentialsForm', () => { - const values = { - ...DEFAULT_VALUES, - activeApiTokenIsExisting: expect.any(Boolean), - activeApiToken: expect.any(Object), - activeApiTokenRawName: expect.any(String), - formErrors: expect.any(Array), - showCredentialsForm: expect.any(Boolean), - }; + describe('setTokenType', () => { + const values = { + ...DEFAULT_VALUES, + activeApiToken: { + ...newToken, + type: expect.any(String), + read: expect.any(Boolean), + write: expect.any(Boolean), + access_all_engines: expect.any(Boolean), + engines: expect.any(Array), + }, + activeApiTokenExists: expect.any(Boolean), + }; - describe('showCredentialsForm', () => { - it('should toggle `showCredentialsForm`', () => { - mount({ - showCredentialsForm: false, + describe('activeApiToken.access_all_engines', () => { + describe('when value is ADMIN', () => { + it('updates access_all_engines to false', () => { + mount({ + activeApiToken: { + ...newToken, + access_all_engines: true, + }, + }); + + CredentialsLogic.actions.setTokenType(ADMIN); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiToken: { + ...values.activeApiToken, + access_all_engines: false, + }, + }); + }); }); - CredentialsLogic.actions.toggleCredentialsForm(); - expect(CredentialsLogic.values).toEqual({ - ...values, - showCredentialsForm: true, - }); + describe('when value is not ADMIN', () => { + it('will maintain access_all_engines value when true', () => { + mount({ + activeApiToken: { + ...newToken, + access_all_engines: true, + }, + }); + + CredentialsLogic.actions.setTokenType(PRIVATE); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiToken: { + ...values.activeApiToken, + access_all_engines: true, + }, + }); + }); - CredentialsLogic.actions.toggleCredentialsForm(); - expect(CredentialsLogic.values).toEqual({ - ...values, - showCredentialsForm: false, + it('will maintain access_all_engines value when false', () => { + mount({ + activeApiToken: { + ...newToken, + access_all_engines: false, + }, + }); + + CredentialsLogic.actions.setTokenType(PRIVATE); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiToken: { + ...values.activeApiToken, + access_all_engines: false, + }, + }); + }); }); }); - }); - describe('formErrors', () => { - it('should reset `formErrors`', () => { - mount({ - formErrors: ['I am an error'], + describe('activeApiToken.engines', () => { + describe('when value is ADMIN', () => { + it('clears the array', () => { + mount({ + activeApiToken: { + ...newToken, + engines: [{}, {}], + }, + }); + + CredentialsLogic.actions.setTokenType(ADMIN); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiToken: { + ...values.activeApiToken, + engines: [], + }, + }); + }); }); - CredentialsLogic.actions.toggleCredentialsForm(); - expect(CredentialsLogic.values).toEqual({ - ...values, - formErrors: [], + describe('when value is not ADMIN', () => { + it('will maintain engines array', () => { + mount({ + activeApiToken: { + ...newToken, + engines: [{}, {}], + }, + }); + + CredentialsLogic.actions.setTokenType(PRIVATE); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiToken: { + ...values.activeApiToken, + engines: [{}, {}], + }, + }); + }); }); }); - }); - describe('activeApiTokenRawName', () => { - it('should set `activeApiTokenRawName` to the name of the provided token', () => { - mount(); + describe('activeApiToken.write', () => { + describe('when value is PRIVATE', () => { + it('sets this to true', () => { + mount({ + activeApiToken: { + ...newToken, + write: false, + }, + }); + + CredentialsLogic.actions.setTokenType(PRIVATE); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiToken: { + ...values.activeApiToken, + write: true, + }, + }); + }); + }); - CredentialsLogic.actions.toggleCredentialsForm(newToken); - expect(CredentialsLogic.values).toEqual({ - ...values, - activeApiTokenRawName: 'myToken', + describe('when value is not PRIVATE', () => { + it('sets this to false', () => { + mount({ + activeApiToken: { + ...newToken, + write: true, + }, + }); + + CredentialsLogic.actions.setTokenType(ADMIN); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiToken: { + ...values.activeApiToken, + write: false, + }, + }); + }); }); }); - it('should set `activeApiTokenRawName` to the default value if no token is provided', () => { - mount(); + describe('activeApiToken.read', () => { + describe('when value is PRIVATE', () => { + it('sets this to true', () => { + mount({ + activeApiToken: { + ...newToken, + read: false, + }, + }); + + CredentialsLogic.actions.setTokenType(PRIVATE); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiToken: { + ...values.activeApiToken, + read: true, + }, + }); + }); + }); - CredentialsLogic.actions.toggleCredentialsForm(); - expect(CredentialsLogic.values).toEqual({ - ...values, - activeApiTokenRawName: DEFAULT_VALUES.activeApiTokenRawName, + describe('when value is not PRIVATE', () => { + it('sets this to false', () => { + mount({ + activeApiToken: { + ...newToken, + read: true, + }, + }); + + CredentialsLogic.actions.setTokenType(ADMIN); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiToken: { + ...values.activeApiToken, + read: false, + }, + }); + }); }); }); - // TODO: This fails, is this an issue? Instead of reseting back to the default value, it sets it to the previously - // used value... to be honest, this should probably just be a selector - // it('should set `activeApiTokenRawName` back to the default value if no token is provided', () => { - // mount(); - // CredentialsLogic.actions.toggleCredentialsForm(newToken); - // CredentialsLogic.actions.toggleCredentialsForm(); - // expect(CredentialsLogic.values).toEqual({ - // ...values, - // activeApiTokenRawName: DEFAULT_VALUES.activeApiTokenRawName, - // }); - // }); - }); - - describe('activeApiToken', () => { - it('should set `activeApiToken` to the provided token', () => { - mount(); + describe('activeApiToken.type', () => { + it('sets the type value', () => { + mount({ + activeApiToken: { + ...newToken, + type: ADMIN, + }, + }); - CredentialsLogic.actions.toggleCredentialsForm(newToken); - expect(CredentialsLogic.values).toEqual({ - ...values, - activeApiToken: newToken, + CredentialsLogic.actions.setTokenType(PRIVATE); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiToken: { + ...values.activeApiToken, + type: PRIVATE, + }, + }); }); }); + }); - it('should set `activeApiToken` to the default value if no token is provided', () => { - mount({ - activeApiToken: newToken, - }); + describe('showCredentialsForm', () => { + const values = { + ...DEFAULT_VALUES, + activeApiTokenExists: expect.any(Boolean), + activeApiToken: expect.any(Object), + activeApiTokenRawName: expect.any(String), + formErrors: expect.any(Array), + shouldShowCredentialsForm: expect.any(Boolean), + }; + + describe('shouldShowCredentialsForm', () => { + it('should toggle `shouldShowCredentialsForm`', () => { + mount({ + shouldShowCredentialsForm: false, + }); - CredentialsLogic.actions.toggleCredentialsForm(); - expect(CredentialsLogic.values).toEqual({ - ...values, - activeApiToken: DEFAULT_VALUES.activeApiToken, + CredentialsLogic.actions.showCredentialsForm(); + expect(CredentialsLogic.values).toEqual({ + ...values, + shouldShowCredentialsForm: true, + }); }); }); - }); - // TODO: This should probably just be a selector... - describe('activeApiTokenIsExisting', () => { - it('should set `activeApiTokenIsExisting` to true when the provided token has an id', () => { - mount({ - activeApiTokenIsExisting: false, - }); + describe('formErrors', () => { + it('should reset `formErrors`', () => { + mount({ + formErrors: ['I am an error'], + }); - CredentialsLogic.actions.toggleCredentialsForm(newToken); - expect(CredentialsLogic.values).toEqual({ - ...values, - activeApiTokenIsExisting: true, + CredentialsLogic.actions.showCredentialsForm(); + expect(CredentialsLogic.values).toEqual({ + ...values, + formErrors: [], + }); }); }); - it('should set `activeApiTokenIsExisting` to false when the provided token has no id', () => { - mount({ - activeApiTokenIsExisting: true, + describe('activeApiTokenRawName', () => { + it('should set `activeApiTokenRawName` to the name of the provided token', () => { + mount({ + activeApiTokenRawName: 'Some Name', + }); + + CredentialsLogic.actions.showCredentialsForm(newToken); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiTokenRawName: 'myToken', + }); }); - const { id, ...newTokenWithoutId } = newToken; - CredentialsLogic.actions.toggleCredentialsForm(newTokenWithoutId); - expect(CredentialsLogic.values).toEqual({ - ...values, - activeApiTokenIsExisting: false, + it('should set `activeApiTokenRawName` to the default value if no token is provided', () => { + mount({ + activeApiTokenRawName: 'Some Name', + }); + + CredentialsLogic.actions.showCredentialsForm(); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiTokenRawName: DEFAULT_VALUES.activeApiTokenRawName, + }); }); }); - it('should set `activeApiTokenIsExisting` to false when no token is provided', () => { - mount({ - activeApiTokenIsExisting: true, + describe('activeApiToken', () => { + it('should set `activeApiToken` to the provided token', () => { + mount(); + + CredentialsLogic.actions.showCredentialsForm(newToken); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiToken: newToken, + }); }); - CredentialsLogic.actions.toggleCredentialsForm(); - expect(CredentialsLogic.values).toEqual({ - ...values, - activeApiTokenIsExisting: false, + it('should set `activeApiToken` to the default value if no token is provided', () => { + mount({ + activeApiToken: newToken, + }); + + CredentialsLogic.actions.showCredentialsForm(); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiToken: DEFAULT_VALUES.activeApiToken, + }); }); }); }); - }); - describe('hideCredentialsForm', () => { - const values = { - ...DEFAULT_VALUES, - showCredentialsForm: expect.any(Boolean), - activeApiTokenRawName: expect.any(String), - }; + describe('hideCredentialsForm', () => { + const values = { + ...DEFAULT_VALUES, + shouldShowCredentialsForm: expect.any(Boolean), + activeApiTokenRawName: expect.any(String), + }; - describe('activeApiTokenRawName', () => { - it('resets this value', () => { - mount({ - activeApiTokenRawName: 'foo', - }); + describe('activeApiTokenRawName', () => { + it('resets this value', () => { + mount({ + activeApiTokenRawName: 'foo', + }); - CredentialsLogic.actions.hideCredentialsForm(); - expect(CredentialsLogic.values).toEqual({ - ...values, - activeApiTokenRawName: '', + CredentialsLogic.actions.hideCredentialsForm(); + expect(CredentialsLogic.values).toEqual({ + ...values, + activeApiTokenRawName: '', + }); }); }); - }); - describe('showCredentialsForm', () => { - it('resets this value', () => { - mount({ - showCredentialsForm: true, - }); + describe('shouldShowCredentialsForm', () => { + it('resets this value', () => { + mount({ + shouldShowCredentialsForm: true, + }); - CredentialsLogic.actions.hideCredentialsForm(); - expect(CredentialsLogic.values).toEqual({ - ...values, - showCredentialsForm: false, + CredentialsLogic.actions.hideCredentialsForm(); + expect(CredentialsLogic.values).toEqual({ + ...values, + shouldShowCredentialsForm: false, + }); }); }); }); - }); - describe('resetCredentials', () => { - const values = { - ...DEFAULT_VALUES, - isCredentialsDetailsComplete: expect.any(Boolean), - isCredentialsDataComplete: expect.any(Boolean), - formErrors: expect.any(Array), - }; + describe('resetCredentials', () => { + const values = { + ...DEFAULT_VALUES, + isCredentialsDetailsComplete: expect.any(Boolean), + isCredentialsDataComplete: expect.any(Boolean), + formErrors: expect.any(Array), + }; - describe('isCredentialsDetailsComplete', () => { - it('should reset to false', () => { - mount({ - isCredentialsDetailsComplete: true, - }); + describe('isCredentialsDetailsComplete', () => { + it('should reset to false', () => { + mount({ + isCredentialsDetailsComplete: true, + }); - CredentialsLogic.actions.resetCredentials(); - expect(CredentialsLogic.values).toEqual({ - ...values, - isCredentialsDetailsComplete: false, + CredentialsLogic.actions.resetCredentials(); + expect(CredentialsLogic.values).toEqual({ + ...values, + isCredentialsDetailsComplete: false, + }); }); }); - }); - describe('isCredentialsDataComplete', () => { - it('should reset to false', () => { - mount({ - isCredentialsDataComplete: true, - }); + describe('isCredentialsDataComplete', () => { + it('should reset to false', () => { + mount({ + isCredentialsDataComplete: true, + }); - CredentialsLogic.actions.resetCredentials(); - expect(CredentialsLogic.values).toEqual({ - ...values, - isCredentialsDataComplete: false, + CredentialsLogic.actions.resetCredentials(); + expect(CredentialsLogic.values).toEqual({ + ...values, + isCredentialsDataComplete: false, + }); }); }); - }); - describe('formErrors', () => { - it('should reset', () => { - mount({ - formErrors: ['I am an error'], - }); + describe('formErrors', () => { + it('should reset', () => { + mount({ + formErrors: ['I am an error'], + }); - CredentialsLogic.actions.resetCredentials(); - expect(CredentialsLogic.values).toEqual({ - ...values, - formErrors: [], + CredentialsLogic.actions.resetCredentials(); + expect(CredentialsLogic.values).toEqual({ + ...values, + formErrors: [], + }); }); }); }); - }); - describe('initializeCredentialsData', () => { - it('should call fetchCredentials and fetchDetails', () => { - mount(); - jest.spyOn(CredentialsLogic.actions, 'fetchCredentials').mockImplementationOnce(() => {}); - jest.spyOn(CredentialsLogic.actions, 'fetchDetails').mockImplementationOnce(() => {}); + describe('initializeCredentialsData', () => { + it('should call fetchCredentials and fetchDetails', () => { + mount(); + jest.spyOn(CredentialsLogic.actions, 'fetchCredentials').mockImplementationOnce(() => {}); + jest.spyOn(CredentialsLogic.actions, 'fetchDetails').mockImplementationOnce(() => {}); - CredentialsLogic.actions.initializeCredentialsData(); - expect(CredentialsLogic.actions.fetchCredentials).toHaveBeenCalled(); - expect(CredentialsLogic.actions.fetchDetails).toHaveBeenCalled(); + CredentialsLogic.actions.initializeCredentialsData(); + expect(CredentialsLogic.actions.fetchCredentials).toHaveBeenCalled(); + expect(CredentialsLogic.actions.fetchDetails).toHaveBeenCalled(); + }); }); - }); - describe('fetchCredentials', () => { - const meta = { - page: { - current: 1, - size: 1, - total_pages: 1, - total_results: 1, - }, - }; - const results: object[] = []; - - it('will call an API endpoint and set the results with the `setCredentialsData` action', async () => { - mount(); - jest.spyOn(CredentialsLogic.actions, 'setCredentialsData').mockImplementationOnce(() => {}); - const promise = Promise.resolve({ meta, results }); - (HttpLogic.values.http.get as jest.Mock).mockReturnValue(promise); - - CredentialsLogic.actions.fetchCredentials(2); - expect(HttpLogic.values.http.get).toHaveBeenCalledWith('/api/app_search/credentials', { - query: { - 'page[current]': 2, + describe('fetchCredentials', () => { + const meta = { + page: { + current: 1, + size: 1, + total_pages: 1, + total_results: 1, }, + }; + const results: object[] = []; + + it('will call an API endpoint and set the results with the `setCredentialsData` action', async () => { + mount(); + jest.spyOn(CredentialsLogic.actions, 'setCredentialsData').mockImplementationOnce(() => {}); + const promise = Promise.resolve({ meta, results }); + (HttpLogic.values.http.get as jest.Mock).mockReturnValue(promise); + + CredentialsLogic.actions.fetchCredentials(2); + expect(HttpLogic.values.http.get).toHaveBeenCalledWith('/api/app_search/credentials', { + query: { + 'page[current]': 2, + }, + }); + await promise; + expect(CredentialsLogic.actions.setCredentialsData).toHaveBeenCalledWith(meta, results); }); - await promise; - expect(CredentialsLogic.actions.setCredentialsData).toHaveBeenCalledWith(meta, results); - }); - it('handles errors', async () => { - mount(); - const promise = Promise.reject('An error occured'); - (HttpLogic.values.http.get as jest.Mock).mockReturnValue(promise); + it('handles errors', async () => { + mount(); + const promise = Promise.reject('An error occured'); + (HttpLogic.values.http.get as jest.Mock).mockReturnValue(promise); + + CredentialsLogic.actions.fetchCredentials(); + try { + await promise; + } catch { + expect(flashAPIErrors).toHaveBeenCalledWith('An error occured'); + } + }); + }); - CredentialsLogic.actions.fetchCredentials(); - try { + describe('fetchDetails', () => { + it('will call an API endpoint and set the results with the `setCredentialsDetails` action', async () => { + mount(); + jest + .spyOn(CredentialsLogic.actions, 'setCredentialsDetails') + .mockImplementationOnce(() => {}); + const promise = Promise.resolve(credentialsDetails); + (HttpLogic.values.http.get as jest.Mock).mockReturnValue(promise); + + CredentialsLogic.actions.fetchDetails(); + expect(HttpLogic.values.http.get).toHaveBeenCalledWith( + '/api/app_search/credentials/details' + ); await promise; - } catch { - expect(flashAPIErrors).toHaveBeenCalledWith('An error occured'); - } - }); - }); + expect(CredentialsLogic.actions.setCredentialsDetails).toHaveBeenCalledWith( + credentialsDetails + ); + }); - describe('fetchDetails', () => { - it('will call an API endpoint and set the results with the `setCredentialsDetails` action', async () => { - mount(); - jest - .spyOn(CredentialsLogic.actions, 'setCredentialsDetails') - .mockImplementationOnce(() => {}); - const promise = Promise.resolve(credentialsDetails); - (HttpLogic.values.http.get as jest.Mock).mockReturnValue(promise); - - CredentialsLogic.actions.fetchDetails(); - expect(HttpLogic.values.http.get).toHaveBeenCalledWith('/api/app_search/credentials/details'); - await promise; - expect(CredentialsLogic.actions.setCredentialsDetails).toHaveBeenCalledWith( - credentialsDetails - ); + it('handles errors', async () => { + mount(); + const promise = Promise.reject('An error occured'); + (HttpLogic.values.http.get as jest.Mock).mockReturnValue(promise); + + CredentialsLogic.actions.fetchDetails(); + try { + await promise; + } catch { + expect(flashAPIErrors).toHaveBeenCalledWith('An error occured'); + } + }); }); - it('handles errors', async () => { - mount(); - const promise = Promise.reject('An error occured'); - (HttpLogic.values.http.get as jest.Mock).mockReturnValue(promise); + describe('deleteApiKey', () => { + const tokenName = 'abc123'; - CredentialsLogic.actions.fetchDetails(); - try { + it('will call an API endpoint and set the results with the `onApiKeyDelete` action', async () => { + mount(); + jest.spyOn(CredentialsLogic.actions, 'onApiKeyDelete').mockImplementationOnce(() => {}); + const promise = Promise.resolve(); + (HttpLogic.values.http.delete as jest.Mock).mockReturnValue(promise); + + CredentialsLogic.actions.deleteApiKey(tokenName); + expect(HttpLogic.values.http.delete).toHaveBeenCalledWith( + `/api/app_search/credentials/${tokenName}` + ); await promise; - } catch { - expect(flashAPIErrors).toHaveBeenCalledWith('An error occured'); - } + expect(CredentialsLogic.actions.onApiKeyDelete).toHaveBeenCalledWith(tokenName); + }); + + it('handles errors', async () => { + mount(); + const promise = Promise.reject('An error occured'); + (HttpLogic.values.http.delete as jest.Mock).mockReturnValue(promise); + + CredentialsLogic.actions.deleteApiKey(tokenName); + try { + await promise; + } catch { + expect(flashAPIErrors).toHaveBeenCalledWith('An error occured'); + } + }); }); }); - describe('deleteApiKey', () => { - const tokenName = 'abc123'; - - it('will call an API endpoint and set the results with the `onApiKeyDelete` action', async () => { - mount(); - jest.spyOn(CredentialsLogic.actions, 'onApiKeyDelete').mockImplementationOnce(() => {}); - const promise = Promise.resolve(); - (HttpLogic.values.http.delete as jest.Mock).mockReturnValue(promise); - - CredentialsLogic.actions.deleteApiKey(tokenName); - expect(HttpLogic.values.http.delete).toHaveBeenCalledWith( - `/api/app_search/credentials/${tokenName}` - ); - await promise; - expect(CredentialsLogic.actions.onApiKeyDelete).toHaveBeenCalledWith(tokenName); - }); + describe('selectors', () => { + describe('activeApiTokenExists', () => { + it('should be false if the token has no id', () => { + mount({ + activeApiToken: { + ...DEFAULT_VALUES.activeApiToken, + id: undefined, + }, + }); - it('handles errors', async () => { - mount(); - const promise = Promise.reject('An error occured'); - (HttpLogic.values.http.delete as jest.Mock).mockReturnValue(promise); + expect(CredentialsLogic.values.activeApiTokenExists).toEqual(false); + }); - CredentialsLogic.actions.deleteApiKey(tokenName); - try { - await promise; - } catch { - expect(flashAPIErrors).toHaveBeenCalledWith('An error occured'); - } + it('should be true if the token has an id', () => { + mount({ + activeApiToken: { + ...DEFAULT_VALUES.activeApiToken, + id: '123', + }, + }); + + expect(CredentialsLogic.values.activeApiTokenExists).toEqual(true); + }); }); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_logic.ts index 43f2731711823..41897b8edbc1e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/credentials_logic.ts @@ -13,12 +13,7 @@ import { HttpLogic } from '../../../shared/http'; import { IMeta } from '../../../../../common/types'; import { flashAPIErrors } from '../../../shared/flash_messages'; import { IEngine } from '../../types'; -import { IApiToken, ICredentialsDetails } from './types'; - -interface ITokenReadWrite { - name: 'read' | 'write'; - checked: boolean; -} +import { IApiToken, ICredentialsDetails, ITokenReadWrite } from './types'; const defaultApiToken: IApiToken = { name: '', @@ -44,7 +39,7 @@ export interface ICredentialsLogicActions { setTokenReadWrite(tokenReadWrite: ITokenReadWrite): ITokenReadWrite; setTokenName(name: string): string; setTokenType(tokenType: string): string; - toggleCredentialsForm(apiToken?: IApiToken): IApiToken; + showCredentialsForm(apiToken?: IApiToken): IApiToken; hideCredentialsForm(): { value: boolean }; resetCredentials(): { value: boolean }; initializeCredentialsData(): { value: boolean }; @@ -55,7 +50,7 @@ export interface ICredentialsLogicActions { export interface ICredentialsLogicValues { activeApiToken: IApiToken; - activeApiTokenIsExisting: boolean; + activeApiTokenExists: boolean; activeApiTokenRawName: string; apiTokens: IApiToken[]; dataLoading: boolean; @@ -66,7 +61,7 @@ export interface ICredentialsLogicValues { fullEngineAccessChecked: boolean; meta: Partial; nameInputBlurred: boolean; - showCredentialsForm: boolean; + shouldShowCredentialsForm: boolean; } export const CredentialsLogic = kea< @@ -90,7 +85,7 @@ export const CredentialsLogic = kea< }), setTokenName: (name) => name, setTokenType: (tokenType) => tokenType, - toggleCredentialsForm: (apiToken = { ...defaultApiToken }) => apiToken, + showCredentialsForm: (apiToken = { ...defaultApiToken }) => apiToken, hideCredentialsForm: false, resetCredentials: false, initializeCredentialsData: true, @@ -175,30 +170,23 @@ export const CredentialsLogic = kea< read: tokenType === PRIVATE, type: tokenType, }), - toggleCredentialsForm: (_, activeApiToken) => activeApiToken, + showCredentialsForm: (_, activeApiToken) => activeApiToken, }, ], activeApiTokenRawName: [ '', { setTokenName: (_, activeApiTokenRawName) => activeApiTokenRawName, - toggleCredentialsForm: (activeApiTokenRawName, activeApiToken) => - activeApiToken.name || activeApiTokenRawName, + showCredentialsForm: (_, activeApiToken) => activeApiToken.name, hideCredentialsForm: () => '', onApiTokenCreateSuccess: () => '', onApiTokenUpdateSuccess: () => '', }, ], - activeApiTokenIsExisting: [ + shouldShowCredentialsForm: [ false, { - toggleCredentialsForm: (_, activeApiToken) => !!activeApiToken.id, - }, - ], - showCredentialsForm: [ - false, - { - toggleCredentialsForm: (showCredentialsForm) => !showCredentialsForm, + showCredentialsForm: () => true, hideCredentialsForm: () => false, onApiTokenCreateSuccess: () => false, onApiTokenUpdateSuccess: () => false, @@ -209,7 +197,7 @@ export const CredentialsLogic = kea< { onApiTokenError: (_, formErrors) => formErrors, onApiTokenCreateSuccess: () => [], - toggleCredentialsForm: () => [], + showCredentialsForm: () => [], resetCredentials: () => [], }, ], @@ -222,6 +210,10 @@ export const CredentialsLogic = kea< return isCredentialsDetailsComplete === false || isCredentialsDataComplete === false; }, ], + activeApiTokenExists: [ + () => [selectors.activeApiToken], + (activeApiToken) => !!activeApiToken.id, + ], }), listeners: ({ actions, values }) => ({ initializeCredentialsData: () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/types.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/types.ts index 9b09bd13a9086..bbf7a54da10da 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/types.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/credentials/types.ts @@ -20,3 +20,8 @@ export interface IApiToken { type: string; write?: boolean; } + +export interface ITokenReadWrite { + name: 'read' | 'write'; + checked: boolean; +} diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview.test.tsx index 44afce96c1a6c..f87ea2d422780 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_overview.test.tsx @@ -11,7 +11,7 @@ import React from 'react'; import { act } from 'react-dom/test-utils'; import { shallow, ReactWrapper } from 'enzyme'; -import { mountWithAsyncContext, mockHttpValues, setMockValues } from '../../../__mocks__'; +import { mountAsync, mockHttpValues, setMockValues } from '../../../__mocks__'; import { LoadingState, EmptyState } from './components'; import { EngineTable } from './engine_table'; @@ -36,7 +36,7 @@ describe('EngineOverview', () => { }), }, }); - const wrapper = await mountWithAsyncContext(); + const wrapper = await mountAsync(, { i18n: true }); expect(wrapper.find(EmptyState)).toHaveLength(1); }); @@ -69,7 +69,7 @@ describe('EngineOverview', () => { }); it('renders and calls the engines API', async () => { - const wrapper = await mountWithAsyncContext(); + const wrapper = await mountAsync(, { i18n: true }); expect(wrapper.find(EngineTable)).toHaveLength(1); expect(mockApi).toHaveBeenNthCalledWith(1, '/api/app_search/engines', { @@ -86,7 +86,7 @@ describe('EngineOverview', () => { hasPlatinumLicense: true, http: { ...mockHttpValues.http, get: mockApi }, }); - const wrapper = await mountWithAsyncContext(); + const wrapper = await mountAsync(, { i18n: true }); expect(wrapper.find(EngineTable)).toHaveLength(2); expect(mockApi).toHaveBeenNthCalledWith(2, '/api/app_search/engines', { @@ -103,7 +103,7 @@ describe('EngineOverview', () => { wrapper.find(EngineTable).prop('pagination'); it('passes down page data from the API', async () => { - const wrapper = await mountWithAsyncContext(); + const wrapper = await mountAsync(, { i18n: true }); const pagination = getTablePagination(wrapper); expect(pagination.totalEngines).toEqual(100); @@ -111,7 +111,7 @@ describe('EngineOverview', () => { }); it('re-polls the API on page change', async () => { - const wrapper = await mountWithAsyncContext(); + const wrapper = await mountAsync(, { i18n: true }); await act(async () => getTablePagination(wrapper).onPaginate(5)); wrapper.update(); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_table.test.tsx index c66fd24fee12a..4d97a16991b71 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_table.test.tsx @@ -6,11 +6,9 @@ import '../../../__mocks__/kea.mock'; import '../../../__mocks__/enterprise_search_url.mock'; -import { mockHttpValues } from '../../../__mocks__/'; +import { mockHttpValues, mountWithIntl } from '../../../__mocks__/'; import React from 'react'; -import { mount } from 'enzyme'; -import { I18nProvider } from '@kbn/i18n/react'; import { EuiBasicTable, EuiPagination, EuiButtonEmpty, EuiLink } from '@elastic/eui'; jest.mock('../../../shared/telemetry', () => ({ sendTelemetry: jest.fn() })); @@ -21,24 +19,22 @@ import { EngineTable } from './engine_table'; describe('EngineTable', () => { const onPaginate = jest.fn(); // onPaginate updates the engines API call upstream - const wrapper = mount( - - - + const wrapper = mountWithIntl( + ); const table = wrapper.find(EuiBasicTable); @@ -78,13 +74,8 @@ describe('EngineTable', () => { }); it('handles empty data', () => { - const emptyWrapper = mount( - - {} }} - /> - + const emptyWrapper = mountWithIntl( + {} }} /> ); const emptyTable = emptyWrapper.find(EuiBasicTable); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx index 052f4446e4409..ab5b3c9faeea7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx @@ -4,14 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../__mocks__/shallow_usecontext.mock'; +import '../__mocks__/shallow_useeffect.mock'; import '../__mocks__/kea.mock'; import '../__mocks__/enterprise_search_url.mock'; +import { setMockValues, setMockActions } from '../__mocks__'; -import React, { useContext } from 'react'; +import React from 'react'; import { Redirect } from 'react-router-dom'; import { shallow } from 'enzyme'; -import { useValues, useActions } from 'kea'; import { Layout, SideNav, SideNavLink } from '../shared/layout'; import { SetupGuide } from './components/setup_guide'; @@ -21,14 +21,14 @@ import { AppSearch, AppSearchUnconfigured, AppSearchConfigured, AppSearchNav } f describe('AppSearch', () => { it('renders AppSearchUnconfigured when config.host is not set', () => { - (useContext as jest.Mock).mockImplementationOnce(() => ({ config: { host: '' } })); + setMockValues({ config: { host: '' } }); const wrapper = shallow(); expect(wrapper.find(AppSearchUnconfigured)).toHaveLength(1); }); it('renders AppSearchConfigured when config.host set', () => { - (useContext as jest.Mock).mockImplementationOnce(() => ({ config: { host: 'some.url' } })); + setMockValues({ config: { host: 'some.url' } }); const wrapper = shallow(); expect(wrapper.find(AppSearchConfigured)).toHaveLength(1); @@ -47,8 +47,8 @@ describe('AppSearchUnconfigured', () => { describe('AppSearchConfigured', () => { beforeEach(() => { // Mock resets - (useValues as jest.Mock).mockImplementation(() => ({ myRole: {} })); - (useActions as jest.Mock).mockImplementation(() => ({ initializeAppData: () => {} })); + setMockValues({ myRole: {} }); + setMockActions({ initializeAppData: () => {} }); }); it('renders with layout', () => { @@ -61,7 +61,7 @@ describe('AppSearchConfigured', () => { it('initializes app data with passed props', () => { const initializeAppData = jest.fn(); - (useActions as jest.Mock).mockImplementation(() => ({ initializeAppData })); + setMockActions({ initializeAppData }); shallow(); @@ -70,8 +70,8 @@ describe('AppSearchConfigured', () => { it('does not re-initialize app data', () => { const initializeAppData = jest.fn(); - (useActions as jest.Mock).mockImplementation(() => ({ initializeAppData })); - (useValues as jest.Mock).mockImplementation(() => ({ myRole: {}, hasInitialized: true })); + setMockActions({ initializeAppData }); + setMockValues({ myRole: {}, hasInitialized: true }); shallow(); @@ -79,7 +79,7 @@ describe('AppSearchConfigured', () => { }); it('renders ErrorConnecting', () => { - (useValues as jest.Mock).mockImplementation(() => ({ myRole: {}, errorConnecting: true })); + setMockValues({ myRole: {}, errorConnecting: true }); const wrapper = shallow(); @@ -87,7 +87,7 @@ describe('AppSearchConfigured', () => { }); it('passes readOnlyMode state', () => { - (useValues as jest.Mock).mockImplementation(() => ({ myRole: {}, readOnlyMode: true })); + setMockValues({ myRole: {}, readOnlyMode: true }); const wrapper = shallow(); @@ -109,9 +109,7 @@ describe('AppSearchNav', () => { }); it('renders the Settings link', () => { - (useValues as jest.Mock).mockImplementation(() => ({ - myRole: { canViewSettings: true }, - })); + setMockValues({ myRole: { canViewSettings: true } }); const wrapper = shallow(); expect(wrapper.find(SideNavLink).last().prop('to')).toEqual( @@ -120,9 +118,7 @@ describe('AppSearchNav', () => { }); it('renders the Credentials link', () => { - (useValues as jest.Mock).mockImplementation(() => ({ - myRole: { canViewAccountCredentials: true }, - })); + setMockValues({ myRole: { canViewAccountCredentials: true } }); const wrapper = shallow(); expect(wrapper.find(SideNavLink).last().prop('to')).toEqual( @@ -131,9 +127,7 @@ describe('AppSearchNav', () => { }); it('renders the Role Mappings link', () => { - (useValues as jest.Mock).mockImplementation(() => ({ - myRole: { canViewRoleMappings: true }, - })); + setMockValues({ myRole: { canViewRoleMappings: true } }); const wrapper = shallow(); expect(wrapper.find(SideNavLink).last().prop('to')).toEqual( diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx index 410f6eb524822..9aa2cce9c74df 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx @@ -4,14 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext, useEffect } from 'react'; +import React, { useEffect } from 'react'; import { Route, Redirect, Switch } from 'react-router-dom'; import { useActions, useValues } from 'kea'; import { i18n } from '@kbn/i18n'; -import { KibanaContext, IKibanaContext } from '../index'; import { getAppSearchUrl } from '../shared/enterprise_search_url'; +import { KibanaLogic } from '../shared/kibana'; import { HttpLogic } from '../shared/http'; import { AppLogic } from './app_logic'; import { IInitialAppData } from '../../../common/types'; @@ -34,7 +34,7 @@ import { NotFound } from '../shared/not_found'; import { EngineOverview } from './components/engine_overview'; export const AppSearch: React.FC = (props) => { - const { config } = useContext(KibanaContext) as IKibanaContext; + const { config } = useValues(KibanaLogic); return !config.host ? : ; }; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.test.tsx index 35301af44b413..b2030ec910cd8 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.test.tsx @@ -5,9 +5,9 @@ */ import '../../../__mocks__/kea.mock'; -import '../../../__mocks__/shallow_usecontext.mock'; -import React, { useContext } from 'react'; +import React from 'react'; +import { useValues } from 'kea'; import { shallow } from 'enzyme'; import { EuiCard } from '@elastic/eui'; @@ -27,7 +27,6 @@ describe('ProductCard', () => { }); it('renders an App Search card', () => { - (useContext as jest.Mock).mockImplementationOnce(() => ({ config: { host: 'localhost' } })); const wrapper = shallow(); const card = wrapper.find(EuiCard).dive().shallow(); @@ -43,7 +42,6 @@ describe('ProductCard', () => { }); it('renders a Workplace Search card', () => { - (useContext as jest.Mock).mockImplementationOnce(() => ({ config: { host: 'localhost' } })); const wrapper = shallow(); const card = wrapper.find(EuiCard).dive().shallow(); @@ -61,7 +59,7 @@ describe('ProductCard', () => { }); it('renders correct button text when host not present', () => { - (useContext as jest.Mock).mockImplementation(() => ({ config: { host: '' } })); + (useValues as jest.Mock).mockImplementation(() => ({ config: { host: '' } })); const wrapper = shallow(); const card = wrapper.find(EuiCard).dive().shallow(); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.tsx index 482d68736af01..1d05128adc2e3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_card/product_card.tsx @@ -4,17 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext } from 'react'; +import React from 'react'; import { useValues } from 'kea'; import { snakeCase } from 'lodash'; import { i18n } from '@kbn/i18n'; import { EuiCard, EuiTextColor } from '@elastic/eui'; -import { KibanaContext, IKibanaContext } from '../../../index'; - import { EuiButton } from '../../../shared/react_router_helpers'; import { sendTelemetry } from '../../../shared/telemetry'; import { HttpLogic } from '../../../shared/http'; +import { KibanaLogic } from '../../../shared/kibana'; import './product_card.scss'; @@ -31,9 +30,7 @@ interface IProductCard { export const ProductCard: React.FC = ({ product, image }) => { const { http } = useValues(HttpLogic); - const { - config: { host }, - } = useContext(KibanaContext) as IKibanaContext; + const { config } = useValues(KibanaLogic); const LAUNCH_BUTTON_TEXT = i18n.translate( 'xpack.enterpriseSearch.overview.productCard.launchButton', @@ -80,7 +77,7 @@ export const ProductCard: React.FC = ({ product, image }) => { }) } > - {host ? LAUNCH_BUTTON_TEXT : SETUP_BUTTON_TEXT} + {config.host ? LAUNCH_BUTTON_TEXT : SETUP_BUTTON_TEXT} } /> diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.test.tsx index 44efa57db897f..f1f16d1a6f7a4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.test.tsx @@ -4,9 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../__mocks__/shallow_usecontext.mock'; +import '../../../__mocks__/kea.mock'; -import React, { useContext } from 'react'; +import React from 'react'; +import { useValues } from 'kea'; import { shallow } from 'enzyme'; import { EuiPage } from '@elastic/eui'; @@ -15,7 +16,7 @@ import { ProductCard } from '../product_card'; describe('ProductSelector', () => { it('renders the overview page and product cards with no host set', () => { - (useContext as jest.Mock).mockImplementationOnce(() => ({ config: { host: '' } })); + (useValues as jest.Mock).mockImplementationOnce(() => ({ config: { host: '' } })); const wrapper = shallow(); expect(wrapper.find(EuiPage).hasClass('enterpriseSearchOverview')).toBe(true); @@ -24,7 +25,7 @@ describe('ProductSelector', () => { describe('access checks when host is set', () => { beforeEach(() => { - (useContext as jest.Mock).mockImplementationOnce(() => ({ config: { host: 'localhost' } })); + (useValues as jest.Mock).mockImplementationOnce(() => ({ config: { host: 'localhost' } })); }); it('does not render the App Search card if the user does not have access to AS', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.tsx index 07b8d4b9926d7..5c2d105e69c40 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/components/product_selector/product_selector.tsx @@ -9,8 +9,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext } from 'react'; - +import React from 'react'; +import { useValues } from 'kea'; import { EuiPage, EuiPageBody, @@ -24,10 +24,8 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { KibanaContext, IKibanaContext } from '../../../index'; - import { APP_SEARCH_PLUGIN, WORKPLACE_SEARCH_PLUGIN } from '../../../../../common/constants'; - +import { KibanaLogic } from '../../../shared/kibana'; import { SetEnterpriseSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; import { SendEnterpriseSearchTelemetry as SendTelemetry } from '../../../shared/telemetry'; @@ -45,12 +43,11 @@ interface IProductSelectorProps { export const ProductSelector: React.FC = ({ access }) => { const { hasAppSearchAccess, hasWorkplaceSearchAccess } = access; - const { - config: { host }, - } = useContext(KibanaContext) as IKibanaContext; + const { config } = useValues(KibanaLogic); - const shouldShowAppSearchCard = !host || hasAppSearchAccess; - const shouldShowWorkplaceSearchCard = !host || hasWorkplaceSearchAccess; + // If Enterprise Search hasn't been set up yet, show all products. Otherwise, only show products the user has access to + const shouldShowAppSearchCard = !config.host || hasAppSearchAccess; + const shouldShowWorkplaceSearchCard = !config.host || hasWorkplaceSearchAccess; return ( diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.test.tsx index 2c0902163e3d6..803d2c8462b1b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.test.tsx @@ -4,9 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../__mocks__/shallow_usecontext.mock'; - -import React, { useContext } from 'react'; +import React from 'react'; import { shallow } from 'enzyme'; import { EuiPage } from '@elastic/eui'; @@ -19,12 +17,11 @@ import { ErrorConnecting } from './components/error_connecting'; import { ProductSelector } from './components/product_selector'; describe('EnterpriseSearch', () => { - beforeEach(() => { - (useValues as jest.Mock).mockReturnValue({ errorConnecting: false }); - (useContext as jest.Mock).mockImplementationOnce(() => ({ config: { host: 'localhost' } })); - }); - it('renders the Setup Guide and Product Selector', () => { + (useValues as jest.Mock).mockReturnValue({ + errorConnecting: false, + config: { host: 'localhost' }, + }); const wrapper = shallow(); expect(wrapper.find(SetupGuide)).toHaveLength(1); @@ -32,9 +29,10 @@ describe('EnterpriseSearch', () => { }); it('renders the error connecting prompt when host is not configured', () => { - (useValues as jest.Mock).mockReturnValueOnce({ errorConnecting: true }); - (useContext as jest.Mock).mockImplementationOnce(() => ({ config: { host: '' } })); - + (useValues as jest.Mock).mockReturnValueOnce({ + errorConnecting: true, + config: { host: '' }, + }); const wrapper = shallow(); expect(wrapper.find(ErrorConnecting)).toHaveLength(1); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.tsx index e2c05434dd0bb..7b97c6c9e58b6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search/index.tsx @@ -4,11 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext } from 'react'; +import React from 'react'; import { Route, Switch } from 'react-router-dom'; import { useValues } from 'kea'; -import { KibanaContext, IKibanaContext } from '../index'; +import { KibanaLogic } from '../shared/kibana'; import { IInitialAppData } from '../../../common/types'; import { HttpLogic } from '../shared/http'; @@ -23,7 +23,7 @@ import './index.scss'; export const EnterpriseSearch: React.FC = ({ access = {} }) => { const { errorConnecting } = useValues(HttpLogic); - const { config } = useContext(KibanaContext) as IKibanaContext; + const { config } = useValues(KibanaLogic); const showErrorConnecting = config.host && errorConnecting; diff --git a/x-pack/plugins/enterprise_search/public/applications/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/index.test.tsx index 66772f96671e8..d5b9513d0dbb3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/index.test.tsx @@ -5,13 +5,16 @@ */ import React from 'react'; +import { getContext } from 'kea'; import { coreMock } from 'src/core/public/mocks'; import { licensingMock } from '../../../licensing/public/mocks'; import { renderApp, renderHeaderActions } from './'; +import { EnterpriseSearch } from './enterprise_search'; import { AppSearch } from './app_search'; import { WorkplaceSearch } from './workplace_search'; +import { KibanaLogic } from './shared/kibana'; describe('renderApp', () => { const kibanaDeps = { @@ -28,36 +31,70 @@ describe('renderApp', () => { jest.clearAllMocks(); }); - it('mounts and unmounts UI', () => { - const MockApp = () =>
Hello world!
; + const mockContainer = kibanaDeps.params.element; + const MockApp = () =>
Hello world!
; + it('mounts and unmounts UI', () => { const unmount = renderApp(MockApp, kibanaDeps, pluginData); - expect(kibanaDeps.params.element.querySelector('.hello-world')).not.toBeNull(); + expect(mockContainer.querySelector('.hello-world')).not.toBeNull(); unmount(); - expect(kibanaDeps.params.element.innerHTML).toEqual(''); + expect(mockContainer.innerHTML).toEqual(''); }); - it('renders AppSearch', () => { - renderApp(AppSearch, kibanaDeps, pluginData); - expect(kibanaDeps.params.element.querySelector('.setupGuide')).not.toBeNull(); - }); + /** + * Helper for automatically mounting and unmounting future tests + */ + let unmount: any; + const mount = (App: React.FC) => { + unmount = renderApp(App, kibanaDeps, pluginData); + }; + + describe('Enterprise Search apps', () => { + afterEach(() => unmount()); + + it('renders EnterpriseSearch', () => { + mount(EnterpriseSearch); + expect(mockContainer.querySelector('.enterpriseSearchOverview')).not.toBeNull(); + }); + + it('renders AppSearch', () => { + mount(AppSearch); + expect(mockContainer.querySelector('.setupGuide')).not.toBeNull(); + }); - it('renders WorkplaceSearch', () => { - renderApp(WorkplaceSearch, kibanaDeps, pluginData); - expect(kibanaDeps.params.element.querySelector('.setupGuide')).not.toBeNull(); + it('renders WorkplaceSearch', () => { + mount(WorkplaceSearch); + expect(mockContainer.querySelector('.setupGuide')).not.toBeNull(); + }); }); -}); -describe('renderHeaderActions', () => { - it('mounts and unmounts any HeaderActions component', () => { + describe('renderHeaderActions', () => { const mockHeaderEl = document.createElement('header'); const MockHeaderActions = () => ; - const unmount = renderHeaderActions(MockHeaderActions, mockHeaderEl); - expect(mockHeaderEl.querySelector('.hello-world')).not.toBeNull(); + it('mounts and unmounts any HeaderActions component', () => { + const store = getContext().store; - unmount(); - expect(mockHeaderEl.innerHTML).toEqual(''); + const unmountHeader = renderHeaderActions(MockHeaderActions, store, mockHeaderEl); + expect(mockHeaderEl.querySelector('.hello-world')).not.toBeNull(); + + unmountHeader(); + expect(mockHeaderEl.innerHTML).toEqual(''); + }); + + it('passes a renderHeaderActions helper to KibanaLogic, which can be used by our apps to render HeaderActions', () => { + // Setup + kibanaDeps.params.setHeaderActionMenu.mockImplementationOnce((cb: any) => cb(mockHeaderEl)); + mount(MockApp); + + // Call KibanaLogic's renderHeaderActions, which should call params.setHeaderActionMenu + KibanaLogic.values.renderHeaderActions(MockHeaderActions); + expect(kibanaDeps.params.setHeaderActionMenu).toHaveBeenCalled(); + + // renderHeaderActions should have been called and generated the correct DOM + expect(mockHeaderEl.querySelector('.hello-world')).not.toBeNull(); + unmount(); + }); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/index.tsx b/x-pack/plugins/enterprise_search/public/applications/index.tsx index 2c6bc787923e3..b9c94e351089d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/index.tsx @@ -7,28 +7,20 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { Router } from 'react-router-dom'; - import { Provider } from 'react-redux'; import { Store } from 'redux'; import { getContext, resetContext } from 'kea'; - import { I18nProvider } from '@kbn/i18n/react'; -import { AppMountParameters, CoreStart, ApplicationStart, ChromeBreadcrumb } from 'src/core/public'; + +import { AppMountParameters, CoreStart } from 'src/core/public'; import { PluginsStart, ClientConfigType, ClientData } from '../plugin'; +import { IInitialAppData } from '../../common/types'; + +import { mountKibanaLogic } from './shared/kibana'; import { mountLicensingLogic } from './shared/licensing'; import { mountHttpLogic } from './shared/http'; import { mountFlashMessagesLogic } from './shared/flash_messages'; import { externalUrl } from './shared/enterprise_search_url'; -import { IInitialAppData } from '../../common/types'; - -export interface IKibanaContext { - config: { host?: string }; - navigateToUrl: ApplicationStart['navigateToUrl']; - setBreadcrumbs(crumbs: ChromeBreadcrumb[]): void; - setDocTitle(title: string): void; -} - -export const KibanaContext = React.createContext({}); /** * This file serves as a reusable wrapper to share Kibana-level context and other helpers @@ -45,41 +37,40 @@ export const renderApp = ( externalUrl.enterpriseSearchUrl = publicUrl || config.host || ''; resetContext({ createStore: true }); - const store = getContext().store as Store; + const store = getContext().store; + const unmountKibanaLogic = mountKibanaLogic({ + config, + history: params.history, + navigateToUrl: core.application.navigateToUrl, + setBreadcrumbs: core.chrome.setBreadcrumbs, + setDocTitle: core.chrome.docTitle.change, + renderHeaderActions: (HeaderActions) => + params.setHeaderActionMenu((el) => renderHeaderActions(HeaderActions, store, el)), + }); const unmountLicensingLogic = mountLicensingLogic({ license$: plugins.licensing.license$, }); - const unmountHttpLogic = mountHttpLogic({ http: core.http, errorConnecting, readOnlyMode: initialData.readOnlyMode, }); - - const unmountFlashMessagesLogic = mountFlashMessagesLogic({ history: params.history }); + const unmountFlashMessagesLogic = mountFlashMessagesLogic(); ReactDOM.render( - - - - - - - + + + + + , params.element ); return () => { ReactDOM.unmountComponentAtNode(params.element); + unmountKibanaLogic(); unmountLicensingLogic(); unmountHttpLogic(); unmountFlashMessagesLogic(); @@ -93,7 +84,16 @@ export const renderApp = ( * @see https://github.com/elastic/kibana/blob/master/docs/development/core/public/kibana-plugin-core-public.appmountparameters.setheaderactionmenu.md */ -export const renderHeaderActions = (HeaderActions: React.FC, kibanaHeaderEl: HTMLElement) => { - ReactDOM.render(, kibanaHeaderEl); +export const renderHeaderActions = ( + HeaderActions: React.FC, + store: Store, + kibanaHeaderEl: HTMLElement +) => { + ReactDOM.render( + + + , + kibanaHeaderEl + ); return () => ReactDOM.unmountComponentAtNode(kibanaHeaderEl); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.test.tsx index 29b773b80158a..25a02e847ccbd 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.test.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../__mocks__/shallow_usecontext.mock'; +import '../../__mocks__/kea.mock'; import React from 'react'; import { shallow } from 'enzyme'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.tsx index a2cb424dadee8..b92a5bbf1c64e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/error_state/error_state_prompt.tsx @@ -4,17 +4,18 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext } from 'react'; +import React from 'react'; +import { useValues } from 'kea'; import { EuiEmptyPrompt, EuiCode } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiButton } from '../react_router_helpers'; -import { KibanaContext, IKibanaContext } from '../../index'; +import { KibanaLogic } from '../../shared/kibana'; import './error_state_prompt.scss'; export const ErrorStatePrompt: React.FC = () => { - const { config } = useContext(KibanaContext) as IKibanaContext; + const { config } = useValues(KibanaLogic); return ( ({ + KibanaLogic: { values: { history: mockHistory } }, +})); import { FlashMessagesLogic, mountFlashMessagesLogic, IFlashMessage } from './'; describe('FlashMessagesLogic', () => { - const mount = () => mountFlashMessagesLogic({ history: mockHistory as any }); + const mount = () => mountFlashMessagesLogic(); beforeEach(() => { jest.clearAllMocks(); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages_logic.ts b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages_logic.ts index 1735cc8ac7228..5a05a03adeb6b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/flash_messages_logic.ts @@ -6,7 +6,8 @@ import { kea, MakeLogicType } from 'kea'; import { ReactNode } from 'react'; -import { History } from 'history'; + +import { KibanaLogic } from '../kibana'; export interface IFlashMessage { type: 'success' | 'info' | 'warning' | 'error'; @@ -61,10 +62,10 @@ export const FlashMessagesLogic = kea ({ + events: ({ values, actions }) => ({ afterMount: () => { // On React Router navigation, clear previous flash messages and load any queued messages - const unlisten = props.history.listen(() => { + const unlisten = KibanaLogic.values.history.listen(() => { actions.clearFlashMessages(); actions.setFlashMessages(values.queuedMessages); actions.clearQueuedMessages(); @@ -81,11 +82,7 @@ export const FlashMessagesLogic = kea { - FlashMessagesLogic(props); +export const mountFlashMessagesLogic = () => { const unmount = FlashMessagesLogic.mount(); return unmount; }; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/set_message_helpers.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/set_message_helpers.test.ts index f2ddd560ac9c1..46027fdfb22b1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/set_message_helpers.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/flash_messages/set_message_helpers.test.ts @@ -5,6 +5,9 @@ */ import { mockHistory } from '../../__mocks__'; +jest.mock('../kibana', () => ({ + KibanaLogic: { values: { history: mockHistory } }, +})); import { FlashMessagesLogic, @@ -18,7 +21,7 @@ describe('Flash Message Helpers', () => { const message = 'I am a message'; beforeEach(() => { - mountFlashMessagesLogic({ history: mockHistory as any }); + mountFlashMessagesLogic(); }); it('setSuccessMessage()', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana/index.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana/index.ts new file mode 100644 index 0000000000000..5751dd3a47de2 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana/index.ts @@ -0,0 +1,7 @@ +/* + * 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 { KibanaLogic, mountKibanaLogic } from './kibana_logic'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.test.ts new file mode 100644 index 0000000000000..4d51362a7e11b --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.test.ts @@ -0,0 +1,51 @@ +/* + * 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 { resetContext } from 'kea'; + +import { mockKibanaValues } from '../../__mocks__'; + +import { KibanaLogic, mountKibanaLogic } from './kibana_logic'; + +describe('KibanaLogic', () => { + beforeEach(() => { + jest.clearAllMocks(); + resetContext({}); + }); + + describe('mounts', () => { + it('sets values from props', () => { + mountKibanaLogic(mockKibanaValues); + + expect(KibanaLogic.values).toEqual({ + ...mockKibanaValues, + navigateToUrl: expect.any(Function), + }); + }); + + it('gracefully handles missing configs', () => { + mountKibanaLogic({ ...mockKibanaValues, config: undefined } as any); + + expect(KibanaLogic.values.config).toEqual({}); + }); + }); + + describe('navigateToUrl()', () => { + beforeEach(() => mountKibanaLogic(mockKibanaValues)); + + it('runs paths through createHref before calling navigateToUrl', () => { + KibanaLogic.values.navigateToUrl('/test'); + + expect(mockKibanaValues.navigateToUrl).toHaveBeenCalledWith('/app/enterprise_search/test'); + }); + + it('does not run paths through createHref if the shouldNotCreateHref option is passed', () => { + KibanaLogic.values.navigateToUrl('/test', { shouldNotCreateHref: true }); + + expect(mockKibanaValues.navigateToUrl).toHaveBeenCalledWith('/test'); + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.ts new file mode 100644 index 0000000000000..9519a62ac352b --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana/kibana_logic.ts @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { kea, MakeLogicType } from 'kea'; + +import { FC } from 'react'; +import { History } from 'history'; +import { ApplicationStart, ChromeBreadcrumb } from 'src/core/public'; + +import { createHref, ICreateHrefOptions } from '../react_router_helpers'; + +interface IKibanaLogicProps { + config: { host?: string }; + history: History; + navigateToUrl: ApplicationStart['navigateToUrl']; + setBreadcrumbs(crumbs: ChromeBreadcrumb[]): void; + setDocTitle(title: string): void; + renderHeaderActions(HeaderActions: FC): void; +} +export interface IKibanaValues extends IKibanaLogicProps { + navigateToUrl(path: string, options?: ICreateHrefOptions): Promise; +} + +export const KibanaLogic = kea>({ + path: ['enterprise_search', 'kibana_logic'], + reducers: ({ props }) => ({ + config: [props.config || {}, {}], + history: [props.history, {}], + navigateToUrl: [ + (url: string, options?: ICreateHrefOptions) => { + const href = createHref(url, props.history, options); + return props.navigateToUrl(href); + }, + {}, + ], + setBreadcrumbs: [props.setBreadcrumbs, {}], + setDocTitle: [props.setDocTitle, {}], + renderHeaderActions: [props.renderHeaderActions, {}], + }), +}); + +export const mountKibanaLogic = (props: IKibanaLogicProps) => { + KibanaLogic(props); + const unmount = KibanaLogic.mount(); + return unmount; +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts index 3c8b3a7218862..61a4397486346 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.test.ts @@ -4,11 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../__mocks__/shallow_usecontext.mock'; -import '../../__mocks__/react_router_history.mock'; -import { mockKibanaContext, mockHistory } from '../../__mocks__'; +import '../../__mocks__/kea.mock'; +import { mockKibanaValues, mockHistory } from '../../__mocks__'; -jest.mock('../react_router_helpers', () => ({ letBrowserHandleEvent: jest.fn(() => false) })); +jest.mock('../react_router_helpers', () => ({ + letBrowserHandleEvent: jest.fn(() => false), + createHref: jest.requireActual('../react_router_helpers').createHref, +})); import { letBrowserHandleEvent } from '../react_router_helpers'; import { @@ -50,21 +52,23 @@ describe('useBreadcrumbs', () => { it('prevents default navigation and uses React Router history on click', () => { const breadcrumb = useBreadcrumbs([{ text: '', path: '/test' }])[0] as any; + + expect(breadcrumb.href).toEqual('/app/enterprise_search/test'); + expect(mockHistory.createHref).toHaveBeenCalled(); + const event = { preventDefault: jest.fn() }; breadcrumb.onClick(event); - expect(mockKibanaContext.navigateToUrl).toHaveBeenCalledWith('/app/enterprise_search/test'); - expect(mockHistory.createHref).toHaveBeenCalled(); expect(event.preventDefault).toHaveBeenCalled(); + expect(mockKibanaValues.navigateToUrl).toHaveBeenCalled(); }); it('does not call createHref if shouldNotCreateHref is passed', () => { const breadcrumb = useBreadcrumbs([ { text: '', path: '/test', shouldNotCreateHref: true }, ])[0] as any; - breadcrumb.onClick({ preventDefault: () => null }); - expect(mockKibanaContext.navigateToUrl).toHaveBeenCalledWith('/test'); + expect(breadcrumb.href).toEqual('/test'); expect(mockHistory.createHref).not.toHaveBeenCalled(); }); @@ -74,7 +78,7 @@ describe('useBreadcrumbs', () => { (letBrowserHandleEvent as jest.Mock).mockImplementationOnce(() => true); breadcrumb.onClick(); - expect(mockKibanaContext.navigateToUrl).not.toHaveBeenCalled(); + expect(mockKibanaValues.navigateToUrl).not.toHaveBeenCalled(); }); it('does not generate link behavior if path is excluded', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts index 19714608e73e9..9ef23e6b176d9 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/generate_breadcrumbs.ts @@ -4,11 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import { useContext } from 'react'; -import { useHistory } from 'react-router-dom'; +import { useValues } from 'kea'; import { EuiBreadcrumb } from '@elastic/eui'; -import { KibanaContext, IKibanaContext } from '../../index'; +import { KibanaLogic } from '../../shared/kibana'; import { ENTERPRISE_SEARCH_PLUGIN, @@ -16,7 +15,7 @@ import { WORKPLACE_SEARCH_PLUGIN, } from '../../../../common/constants'; -import { letBrowserHandleEvent } from '../react_router_helpers'; +import { letBrowserHandleEvent, createHref } from '../react_router_helpers'; /** * Generate React-Router-friendly EUI breadcrumb objects @@ -33,20 +32,17 @@ interface IBreadcrumb { export type TBreadcrumbs = IBreadcrumb[]; export const useBreadcrumbs = (breadcrumbs: TBreadcrumbs) => { - const history = useHistory(); - const { navigateToUrl } = useContext(KibanaContext) as IKibanaContext; + const { navigateToUrl, history } = useValues(KibanaLogic); return breadcrumbs.map(({ text, path, shouldNotCreateHref }) => { const breadcrumb = { text } as EuiBreadcrumb; if (path) { - const href = shouldNotCreateHref ? path : (history.createHref({ pathname: path }) as string); - - breadcrumb.href = href; + breadcrumb.href = createHref(path, history, { shouldNotCreateHref }); breadcrumb.onClick = (event) => { if (letBrowserHandleEvent(event)) return; event.preventDefault(); - navigateToUrl(href); + navigateToUrl(path, { shouldNotCreateHref }); }; } diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx index 61a066bb92216..2aee224304f89 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.test.tsx @@ -4,12 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../__mocks__/shallow_usecontext.mock'; +import '../../__mocks__/kea.mock'; +import '../../__mocks__/shallow_useeffect.mock'; import '../../__mocks__/react_router_history.mock'; +import { mockKibanaValues } from '../../__mocks__'; import React from 'react'; - -import { mockKibanaContext, mountWithKibanaContext } from '../../__mocks__'; +import { shallow } from 'enzyme'; jest.mock('./generate_breadcrumbs', () => ({ useEnterpriseSearchBreadcrumbs: jest.fn(() => (crumbs: any) => crumbs), @@ -37,13 +38,13 @@ describe('Set Kibana Chrome helpers', () => { }); afterEach(() => { - expect(mockKibanaContext.setBreadcrumbs).toHaveBeenCalled(); - expect(mockKibanaContext.setDocTitle).toHaveBeenCalled(); + expect(mockKibanaValues.setBreadcrumbs).toHaveBeenCalled(); + expect(mockKibanaValues.setDocTitle).toHaveBeenCalled(); }); describe('SetEnterpriseSearchChrome', () => { it('sets breadcrumbs and document title', () => { - mountWithKibanaContext(); + shallow(); expect(enterpriseSearchTitle).toHaveBeenCalledWith(['Hello World']); expect(useEnterpriseSearchBreadcrumbs).toHaveBeenCalledWith([ @@ -55,7 +56,7 @@ describe('Set Kibana Chrome helpers', () => { }); it('sets empty breadcrumbs and document title when isRoot is true', () => { - mountWithKibanaContext(); + shallow(); expect(enterpriseSearchTitle).toHaveBeenCalledWith([]); expect(useEnterpriseSearchBreadcrumbs).toHaveBeenCalledWith([]); @@ -64,7 +65,7 @@ describe('Set Kibana Chrome helpers', () => { describe('SetAppSearchChrome', () => { it('sets breadcrumbs and document title', () => { - mountWithKibanaContext(); + shallow(); expect(appSearchTitle).toHaveBeenCalledWith(['Engines']); expect(useAppSearchBreadcrumbs).toHaveBeenCalledWith([ @@ -76,7 +77,7 @@ describe('Set Kibana Chrome helpers', () => { }); it('sets empty breadcrumbs and document title when isRoot is true', () => { - mountWithKibanaContext(); + shallow(); expect(appSearchTitle).toHaveBeenCalledWith([]); expect(useAppSearchBreadcrumbs).toHaveBeenCalledWith([]); @@ -85,7 +86,7 @@ describe('Set Kibana Chrome helpers', () => { describe('SetWorkplaceSearchChrome', () => { it('sets breadcrumbs and document title', () => { - mountWithKibanaContext(); + shallow(); expect(workplaceSearchTitle).toHaveBeenCalledWith(['Sources']); expect(useWorkplaceSearchBreadcrumbs).toHaveBeenCalledWith([ @@ -97,7 +98,7 @@ describe('Set Kibana Chrome helpers', () => { }); it('sets empty breadcrumbs and document title when isRoot is true', () => { - mountWithKibanaContext(); + shallow(); expect(workplaceSearchTitle).toHaveBeenCalledWith([]); expect(useWorkplaceSearchBreadcrumbs).toHaveBeenCalledWith([]); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx index 5e8d972e1a135..2ae3ca0137d54 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/kibana_chrome/set_chrome.tsx @@ -4,11 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext, useEffect } from 'react'; +import React, { useEffect } from 'react'; +import { useValues } from 'kea'; import { useHistory } from 'react-router-dom'; import { EuiBreadcrumb } from '@elastic/eui'; -import { KibanaContext, IKibanaContext } from '../../index'; +import { KibanaLogic } from '../kibana'; + import { useEnterpriseSearchBreadcrumbs, useAppSearchBreadcrumbs, @@ -41,7 +43,7 @@ type TBreadcrumbsProps = IBreadcrumbsProps | IRootBreadcrumbsProps; export const SetEnterpriseSearchChrome: React.FC = ({ text, isRoot }) => { const history = useHistory(); - const { setBreadcrumbs, setDocTitle } = useContext(KibanaContext) as IKibanaContext; + const { setBreadcrumbs, setDocTitle } = useValues(KibanaLogic); const title = isRoot ? [] : [text]; const docTitle = enterpriseSearchTitle(title as TTitle | []); @@ -59,7 +61,7 @@ export const SetEnterpriseSearchChrome: React.FC = ({ text, i export const SetAppSearchChrome: React.FC = ({ text, isRoot }) => { const history = useHistory(); - const { setBreadcrumbs, setDocTitle } = useContext(KibanaContext) as IKibanaContext; + const { setBreadcrumbs, setDocTitle } = useValues(KibanaLogic); const title = isRoot ? [] : [text]; const docTitle = appSearchTitle(title as TTitle | []); @@ -77,7 +79,7 @@ export const SetAppSearchChrome: React.FC = ({ text, isRoot } export const SetWorkplaceSearchChrome: React.FC = ({ text, isRoot }) => { const history = useHistory(); - const { setBreadcrumbs, setDocTitle } = useContext(KibanaContext) as IKibanaContext; + const { setBreadcrumbs, setDocTitle } = useValues(KibanaLogic); const title = isRoot ? [] : [text]; const docTitle = workplaceSearchTitle(title as TTitle | []); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/create_href.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/create_href.test.ts new file mode 100644 index 0000000000000..5f96beeb42ae4 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/create_href.test.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { mockHistory } from '../../__mocks__'; + +import { createHref } from './'; + +describe('createHref', () => { + it('generates a path with the React Router basename included', () => { + expect(createHref('/test', mockHistory)).toEqual('/app/enterprise_search/test'); + }); + + it('does not include the basename if shouldNotCreateHref is passed', () => { + expect(createHref('/test', mockHistory, { shouldNotCreateHref: true })).toEqual('/test'); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/create_href.ts b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/create_href.ts new file mode 100644 index 0000000000000..cc8279c80a092 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/create_href.ts @@ -0,0 +1,27 @@ +/* + * 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 } from 'history'; + +/** + * This helper uses React Router's createHref function to generate links with router basenames accounted for. + * For example, if we perform navigateToUrl('/engines') within App Search, we expect the app basename + * to be taken into account to be intelligently routed to '/app/enterprise_search/app_search/engines'. + * + * This helper accomplishes that, while still giving us an escape hatch for navigation *between* apps. + * For example, if we want to navigate the user from App Search to Enterprise Search we could + * navigateToUrl('/app/enterprise_search', { shouldNotCreateHref: true }) + */ +export interface ICreateHrefOptions { + shouldNotCreateHref?: boolean; +} +export const createHref = ( + path: string, + history: History, + options?: ICreateHrefOptions +): string => { + return options?.shouldNotCreateHref ? path : history.createHref({ pathname: path }); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.test.tsx index 0c7bac99085dd..82fbb8940d460 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.test.tsx @@ -4,14 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../__mocks__/shallow_usecontext.mock'; -import '../../__mocks__/react_router_history.mock'; +import '../../__mocks__/kea.mock'; import React from 'react'; import { shallow, mount } from 'enzyme'; import { EuiLink, EuiButton } from '@elastic/eui'; -import { mockKibanaContext, mockHistory } from '../../__mocks__'; +import { mockKibanaValues, mockHistory } from '../../__mocks__'; import { EuiReactRouterLink, EuiReactRouterButton } from './eui_link'; @@ -69,7 +68,7 @@ describe('EUI & React Router Component Helpers', () => { wrapper.find(EuiLink).simulate('click', simulatedEvent); expect(simulatedEvent.preventDefault).toHaveBeenCalled(); - expect(mockKibanaContext.navigateToUrl).toHaveBeenCalled(); + expect(mockKibanaValues.navigateToUrl).toHaveBeenCalled(); }); it('does not prevent default browser behavior on new tab/window clicks', () => { @@ -81,7 +80,7 @@ describe('EUI & React Router Component Helpers', () => { }; wrapper.find(EuiLink).simulate('click', simulatedEvent); - expect(mockKibanaContext.navigateToUrl).not.toHaveBeenCalled(); + expect(mockKibanaValues.navigateToUrl).not.toHaveBeenCalled(); }); it('calls inherited onClick actions in addition to default navigation', () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.tsx index e3b46632ddf9e..e0aa5afdf38c1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/eui_link.tsx @@ -4,12 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext } from 'react'; -import { useHistory } from 'react-router-dom'; +import React from 'react'; +import { useValues } from 'kea'; import { EuiLink, EuiButton, EuiButtonProps, EuiLinkAnchorProps } from '@elastic/eui'; -import { KibanaContext, IKibanaContext } from '../../index'; -import { letBrowserHandleEvent } from './link_events'; +import { KibanaLogic } from '../../shared/kibana'; +import { letBrowserHandleEvent, createHref } from './'; /** * Generates either an EuiLink or EuiButton with a React-Router-ified link @@ -32,11 +32,10 @@ export const EuiReactRouterHelper: React.FC = ({ shouldNotCreateHref, children, }) => { - const history = useHistory(); - const { navigateToUrl } = useContext(KibanaContext) as IKibanaContext; + const { navigateToUrl, history } = useValues(KibanaLogic); // Generate the correct link href (with basename etc. accounted for) - const href = shouldNotCreateHref ? to : history.createHref({ pathname: to }); + const href = createHref(to, history, { shouldNotCreateHref }); const reactRouterLinkClick = (event: React.MouseEvent) => { if (onClick) onClick(); // Run any passed click events (e.g. telemetry) @@ -46,7 +45,7 @@ export const EuiReactRouterHelper: React.FC = ({ event.preventDefault(); // Perform SPA navigation. - navigateToUrl(href); + navigateToUrl(to, { shouldNotCreateHref }); }; const reactRouterProps = { href, onClick: reactRouterLinkClick }; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/index.ts b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/index.ts index 46dc328633153..6915d3222c45c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/react_router_helpers/index.ts @@ -5,5 +5,6 @@ */ export { letBrowserHandleEvent } from './link_events'; +export { createHref, ICreateHrefOptions } from './create_href'; export { EuiReactRouterLink as EuiLink } from './eui_link'; export { EuiReactRouterButton as EuiButton } from './eui_link'; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/setup_guide.test.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/setup_guide.test.tsx index 0423ae61779af..802a10e3b3db7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/setup_guide.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/setup_guide/setup_guide.test.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { shallow } from 'enzyme'; import { EuiSteps, EuiIcon, EuiLink } from '@elastic/eui'; -import { mountWithContext } from '../../__mocks__'; +import { mountWithIntl } from '../../__mocks__'; import { SetupGuide } from './'; @@ -27,7 +27,7 @@ describe('SetupGuide', () => { }); it('renders with optional auth links', () => { - const wrapper = mountWithContext( + const wrapper = mountWithIntl( { it('renders WorkplaceSearchUnconfigured when config.host is not set', () => { - (useContext as jest.Mock).mockImplementationOnce(() => ({ config: { host: '' } })); + setMockValues({ config: { host: '' } }); const wrapper = shallow(); expect(wrapper.find(WorkplaceSearchUnconfigured)).toHaveLength(1); }); it('renders WorkplaceSearchConfigured when config.host set', () => { - (useContext as jest.Mock).mockImplementationOnce(() => ({ config: { host: 'some.url' } })); + setMockValues({ config: { host: 'some.url' } }); const wrapper = shallow(); expect(wrapper.find(WorkplaceSearchConfigured)).toHaveLength(1); @@ -46,39 +47,40 @@ describe('WorkplaceSearchUnconfigured', () => { describe('WorkplaceSearchConfigured', () => { beforeEach(() => { - // Mock resets - (useValues as jest.Mock).mockImplementation(() => ({})); - (useActions as jest.Mock).mockImplementation(() => ({ initializeAppData: () => {} })); + jest.clearAllMocks(); + setMockActions({ initializeAppData: () => {} }); }); - it('renders with layout', () => { + it('renders layout and header actions', () => { const wrapper = shallow(); expect(wrapper.find(Layout).prop('readOnlyMode')).toBeFalsy(); expect(wrapper.find(Overview)).toHaveLength(1); + expect(mockKibanaValues.renderHeaderActions).toHaveBeenCalledWith(WorkplaceSearchHeaderActions); }); it('initializes app data with passed props', () => { const initializeAppData = jest.fn(); - (useActions as jest.Mock).mockImplementation(() => ({ initializeAppData })); + setMockActions({ initializeAppData }); shallow(); expect(initializeAppData).toHaveBeenCalledWith({ isFederatedAuth: true }); }); - it('does not re-initialize app data', () => { + it('does not re-initialize app data or re-render header actions', () => { const initializeAppData = jest.fn(); - (useActions as jest.Mock).mockImplementation(() => ({ initializeAppData })); - (useValues as jest.Mock).mockImplementation(() => ({ hasInitialized: true })); + setMockActions({ initializeAppData }); + setMockValues({ hasInitialized: true }); shallow(); expect(initializeAppData).not.toHaveBeenCalled(); + expect(mockKibanaValues.renderHeaderActions).not.toHaveBeenCalled(); }); it('renders ErrorState', () => { - (useValues as jest.Mock).mockImplementation(() => ({ errorConnecting: true })); + setMockValues({ errorConnecting: true }); const wrapper = shallow(); @@ -86,7 +88,7 @@ describe('WorkplaceSearchConfigured', () => { }); it('passes readOnlyMode state', () => { - (useValues as jest.Mock).mockImplementation(() => ({ readOnlyMode: true })); + setMockValues({ readOnlyMode: true }); const wrapper = shallow(); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx index a68dfaf8ea471..b4c4217659043 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/index.tsx @@ -4,17 +4,17 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext, useEffect } from 'react'; +import React, { useEffect } from 'react'; import { Route, Redirect, Switch } from 'react-router-dom'; import { useActions, useValues } from 'kea'; import { WORKPLACE_SEARCH_PLUGIN } from '../../../common/constants'; import { IInitialAppData } from '../../../common/types'; -import { KibanaContext, IKibanaContext } from '../index'; +import { KibanaLogic } from '../shared/kibana'; import { HttpLogic } from '../shared/http'; import { AppLogic } from './app_logic'; import { Layout } from '../shared/layout'; -import { WorkplaceSearchNav } from './components/layout/nav'; +import { WorkplaceSearchNav, WorkplaceSearchHeaderActions } from './components/layout'; import { SETUP_GUIDE_PATH } from './routes'; @@ -24,17 +24,21 @@ import { NotFound } from '../shared/not_found'; import { Overview } from './views/overview'; export const WorkplaceSearch: React.FC = (props) => { - const { config } = useContext(KibanaContext) as IKibanaContext; + const { config } = useValues(KibanaLogic); return !config.host ? : ; }; export const WorkplaceSearchConfigured: React.FC = (props) => { const { hasInitialized } = useValues(AppLogic); const { initializeAppData } = useActions(AppLogic); + const { renderHeaderActions } = useValues(KibanaLogic); const { errorConnecting, readOnlyMode } = useValues(HttpLogic); useEffect(() => { - if (!hasInitialized) initializeAppData(props); + if (!hasInitialized) { + initializeAppData(props); + renderHeaderActions(WorkplaceSearchHeaderActions); + } }, [hasInitialized]); return ( diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.test.tsx index ab5cd7f0de90f..a757e187da098 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/error_state/error_state.test.tsx @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../__mocks__/shallow_usecontext.mock'; - import React from 'react'; import { shallow } from 'enzyme'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/organization_stats.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/organization_stats.test.tsx index d9b05c5da777d..d9d03245f6141 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/organization_stats.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/organization_stats.test.tsx @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../__mocks__/shallow_usecontext.mock'; import './__mocks__/overview_logic.mock'; import { setMockValues } from './__mocks__'; diff --git a/x-pack/plugins/enterprise_search/public/plugin.ts b/x-pack/plugins/enterprise_search/public/plugin.ts index d870127f297b4..e054a49ef1f74 100644 --- a/x-pack/plugins/enterprise_search/public/plugin.ts +++ b/x-pack/plugins/enterprise_search/public/plugin.ts @@ -23,7 +23,6 @@ import { WORKPLACE_SEARCH_PLUGIN, } from '../common/constants'; import { IInitialAppData } from '../common/types'; -import { externalUrl } from './applications/shared/enterprise_search_url'; export interface ClientConfigType { host?: string; @@ -101,21 +100,14 @@ export class EnterpriseSearchPlugin implements Plugin { mount: async (params: AppMountParameters) => { const kibanaDeps = await this.getKibanaDeps(core, params); const { chrome, http } = kibanaDeps.core; - chrome.docTitle.change(APP_SEARCH_PLUGIN.NAME); + chrome.docTitle.change(WORKPLACE_SEARCH_PLUGIN.NAME); await this.getInitialData(http); const pluginData = this.getPluginData(); - const { renderApp, renderHeaderActions } = await import('./applications'); + const { renderApp } = await import('./applications'); const { WorkplaceSearch } = await import('./applications/workplace_search'); - const { WorkplaceSearchHeaderActions } = await import( - './applications/workplace_search/components/layout' - ); - params.setHeaderActionMenu((element) => - renderHeaderActions(WorkplaceSearchHeaderActions, element) - ); - return renderApp(WorkplaceSearch, kibanaDeps, pluginData); }, }); @@ -175,10 +167,6 @@ export class EnterpriseSearchPlugin implements Plugin { try { this.data = await http.get('/api/enterprise_search/config_data'); this.hasInitialized = true; - - // TODO: This is a temporary workaround to keep the WorkplaceSearchHeaderActions working. - // We'll solve this shortly by ensuring the main app store loads before the header actions. - externalUrl.enterpriseSearchUrl = this.data.publicUrl || this.config.host; } catch { this.data.errorConnecting = true; } diff --git a/x-pack/plugins/event_log/server/lib/ready_signal.test.ts b/x-pack/plugins/event_log/server/lib/ready_signal.test.ts index c216651ee94b1..d23d81861acc4 100644 --- a/x-pack/plugins/event_log/server/lib/ready_signal.test.ts +++ b/x-pack/plugins/event_log/server/lib/ready_signal.test.ts @@ -13,28 +13,9 @@ describe('ReadySignal', () => { readySignal = createReadySignal(); }); - test('works as expected', async (done) => { - let value = 41; - - timeoutSet(100, async () => { - expect(value).toBe(41); - }); - - timeoutSet(250, async () => readySignal.signal(42)); - - timeoutSet(400, async () => { - expect(value).toBe(42); - - const innerValue = await readySignal.wait(); - expect(innerValue).toBe(42); - done(); - }); - - value = await readySignal.wait(); - expect(value).toBe(42); + test('works as expected', async () => { + readySignal.signal(42); + const ready = await readySignal.wait(); + expect(ready).toBe(42); }); }); - -function timeoutSet(ms: number, fn: () => Promise): void { - setTimeout(fn, ms); -} diff --git a/x-pack/plugins/global_search_bar/public/assets/illustration_product_no_search_results_dark.svg b/x-pack/plugins/global_search_bar/public/assets/illustration_product_no_search_results_dark.svg new file mode 100644 index 0000000000000..3a87f06b7bcc8 --- /dev/null +++ b/x-pack/plugins/global_search_bar/public/assets/illustration_product_no_search_results_dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/x-pack/plugins/global_search_bar/public/assets/illustration_product_no_search_results_light.svg b/x-pack/plugins/global_search_bar/public/assets/illustration_product_no_search_results_light.svg new file mode 100644 index 0000000000000..ac5298be17cca --- /dev/null +++ b/x-pack/plugins/global_search_bar/public/assets/illustration_product_no_search_results_light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/x-pack/plugins/global_search_bar/public/components/search_bar.test.tsx b/x-pack/plugins/global_search_bar/public/components/search_bar.test.tsx index 11fbc7931e620..6fad3335c5efc 100644 --- a/x-pack/plugins/global_search_bar/public/components/search_bar.test.tsx +++ b/x-pack/plugins/global_search_bar/public/components/search_bar.test.tsx @@ -8,6 +8,7 @@ import React from 'react'; import { wait } from '@testing-library/react'; import { of } from 'rxjs'; import { mountWithIntl } from 'test_utils/enzyme_helpers'; +import { httpServiceMock, uiSettingsServiceMock } from '../../../../../src/core/public/mocks'; import { GlobalSearchBatchedResults, GlobalSearchPluginStart, @@ -47,6 +48,10 @@ const getSearchProps: any = (component: any) => component.find('EuiFieldSearch') describe('SearchBar', () => { let searchService: GlobalSearchPluginStart; let findSpy: jest.SpyInstance; + const http = httpServiceMock.createSetupContract({ basePath: '/test' }); + const basePathUrl = http.basePath.prepend('/plugins/globalSearchBar/assets/'); + const uiSettings = uiSettingsServiceMock.createStartContract(); + const darkMode = uiSettings.get('theme:darkMode'); beforeEach(() => { searchService = globalSearchPluginMock.createStartContract(); @@ -66,7 +71,12 @@ describe('SearchBar', () => { .mockReturnValueOnce(of(createBatch('Discover', { id: 'My Dashboard', type: 'test' }))); const component = mountWithIntl( - + ); expect(findSpy).toHaveBeenCalledTimes(0); @@ -85,7 +95,14 @@ describe('SearchBar', () => { }); it('supports keyboard shortcuts', () => { - mountWithIntl(); + mountWithIntl( + + ); const searchEvent = new KeyboardEvent('keydown', { key: '/', diff --git a/x-pack/plugins/global_search_bar/public/components/search_bar.tsx b/x-pack/plugins/global_search_bar/public/components/search_bar.tsx index 54066cee414d8..4ca0f8cf81b7b 100644 --- a/x-pack/plugins/global_search_bar/public/components/search_bar.tsx +++ b/x-pack/plugins/global_search_bar/public/components/search_bar.tsx @@ -12,6 +12,7 @@ import { EuiSelectableTemplateSitewideOption, EuiText, EuiIcon, + EuiImage, EuiHeaderSectionItemButton, EuiSelectableMessage, } from '@elastic/eui'; @@ -27,6 +28,8 @@ import { GlobalSearchPluginStart, GlobalSearchResult } from '../../../global_sea interface Props { globalSearch: GlobalSearchPluginStart['find']; navigateToUrl: ApplicationStart['navigateToUrl']; + basePathUrl: string; + darkMode: boolean; } const clearField = (field: HTMLInputElement) => { @@ -42,7 +45,7 @@ const clearField = (field: HTMLInputElement) => { const cleanMeta = (str: string) => (str.charAt(0).toUpperCase() + str.slice(1)).replace(/-/g, ' '); const blurEvent = new FocusEvent('blur'); -export function SearchBar({ globalSearch, navigateToUrl }: Props) { +export function SearchBar({ globalSearch, navigateToUrl, basePathUrl, darkMode }: Props) { const isMounted = useMountedState(); const [searchValue, setSearchValue] = useState(''); const [searchRef, setSearchRef] = useState(null); @@ -109,7 +112,7 @@ export function SearchBar({ globalSearch, navigateToUrl }: Props) { complete: () => {}, }); }, - 250, + 350, [searchValue] ); @@ -134,6 +137,34 @@ export function SearchBar({ globalSearch, navigateToUrl }: Props) { } }; + const emptyMessage = ( + + + +

+ +

+
+

+ +

+
+ ); + useEvent('keydown', onKeyDown); return ( @@ -161,22 +192,11 @@ export function SearchBar({ globalSearch, navigateToUrl }: Props) { defaultMessage: 'Search Elastic', }), }} - emptyMessage={ - -

- -

-

- -

-
- } + popoverProps={{ + repositionOnScroll: true, + }} + emptyMessage={emptyMessage} + noMatchesMessage={emptyMessage} popoverFooter={ { public start(core: CoreStart, { globalSearch }: GlobalSearchBarPluginStartDeps) { core.chrome.navControls.registerCenter({ order: 1000, - mount: (target) => this.mount(target, globalSearch, core.application.navigateToUrl), + mount: (target) => + this.mount( + target, + globalSearch, + core.application.navigateToUrl, + core.http.basePath.prepend('/plugins/globalSearchBar/assets/'), + core.uiSettings.get('theme:darkMode') + ), }); return {}; } @@ -32,11 +39,18 @@ export class GlobalSearchBarPlugin implements Plugin<{}, {}> { private mount( targetDomElement: HTMLElement, globalSearch: GlobalSearchPluginStart, - navigateToUrl: ApplicationStart['navigateToUrl'] + navigateToUrl: ApplicationStart['navigateToUrl'], + basePathUrl: string, + darkMode: boolean ) { ReactDOM.render( - + , targetDomElement ); diff --git a/x-pack/plugins/index_lifecycle_management/README.md b/x-pack/plugins/index_lifecycle_management/README.md index 3b72ac85810c6..28b2a4637da89 100644 --- a/x-pack/plugins/index_lifecycle_management/README.md +++ b/x-pack/plugins/index_lifecycle_management/README.md @@ -1,6 +1,8 @@ # Index Lifecycle Management -## Quick steps for testing ILM in Index Management +## Testing + +### Quick steps for testing ILM in Index Management You can test that the `Frozen` badge, phase filtering, and lifecycle information is surfaced in Index Management by running this series of requests in Console: @@ -92,4 +94,26 @@ After about a minute, there should be an error on this index. When you click the ILM information in the detail panel as well as an error. You can dismiss the error by clicking `Manage > Retry lifecycle step`. -![image](https://user-images.githubusercontent.com/1238659/78087984-a6811000-7377-11ea-880e-1a7b182c14f1.png) \ No newline at end of file +![image](https://user-images.githubusercontent.com/1238659/78087984-a6811000-7377-11ea-880e-1a7b182c14f1.png) + +### Data tier notifications + +When creating or editing an ILM policy the UI should notify users that under certain conditions their data will not be +moved to a tier corresponding to a phase. For instance, when a cluster only has hot-tier nodes. We test the UI +with this cluster state by starting an ES node with the `data_hot` role. Using this command: + +```bash +yarn es snapshot --license=trial -E node.roles=data_hot,master,data_content +``` + +This will create a cluster where we have a single node that belongs to the hot-tier. In the data allocation section of +both the warm and cold phase you should see notice like the following: + +![image](https://user-images.githubusercontent.com/8155004/94132944-4b306600-fe60-11ea-9c3d-02229e3055b8.png) + +Default configuration for a node is that it belongs to all tiers, in which case you should not see this notice. Test +this by running: + +```bash +yarn es snapshot --license=trial +``` \ No newline at end of file diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.tsx b/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.tsx index f195228775772..dfbe19ba21a94 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.tsx +++ b/x-pack/plugins/index_lifecycle_management/__jest__/components/edit_policy.test.tsx @@ -503,6 +503,30 @@ describe('edit policy', () => { expect(rendered.find('.euiLoadingSpinner').exists()).toBeFalsy(); expect(findTestSubject(rendered, 'defaultAllocationWarning').exists()).toBeTruthy(); }); + test('should show default allocation notice when hot tier exists, but not warm tier', async () => { + http.setupNodeListResponse({ + nodesByAttributes: {}, + nodesByRoles: { data_hot: ['test'], data_cold: ['test'] }, + }); + const rendered = mountWithIntl(component); + noRollover(rendered); + setPolicyName(rendered, 'mypolicy'); + await activatePhase(rendered, 'warm'); + expect(rendered.find('.euiLoadingSpinner').exists()).toBeFalsy(); + expect(findTestSubject(rendered, 'defaultAllocationNotice').exists()).toBeTruthy(); + }); + test('should not show default allocation notice when node with "data" role exists', async () => { + http.setupNodeListResponse({ + nodesByAttributes: {}, + nodesByRoles: { data: ['test'] }, + }); + const rendered = mountWithIntl(component); + noRollover(rendered); + setPolicyName(rendered, 'mypolicy'); + await activatePhase(rendered, 'warm'); + expect(rendered.find('.euiLoadingSpinner').exists()).toBeFalsy(); + expect(findTestSubject(rendered, 'defaultAllocationNotice').exists()).toBeFalsy(); + }); }); describe('cold phase', () => { beforeEach(() => { @@ -610,6 +634,30 @@ describe('edit policy', () => { expect(rendered.find('.euiLoadingSpinner').exists()).toBeFalsy(); expect(findTestSubject(rendered, 'defaultAllocationWarning').exists()).toBeTruthy(); }); + test('should show default allocation notice when warm or hot tiers exists, but not cold tier', async () => { + http.setupNodeListResponse({ + nodesByAttributes: {}, + nodesByRoles: { data_hot: ['test'], data_warm: ['test'] }, + }); + const rendered = mountWithIntl(component); + noRollover(rendered); + setPolicyName(rendered, 'mypolicy'); + await activatePhase(rendered, 'cold'); + expect(rendered.find('.euiLoadingSpinner').exists()).toBeFalsy(); + expect(findTestSubject(rendered, 'defaultAllocationNotice').exists()).toBeTruthy(); + }); + test('should not show default allocation notice when node with "data" role exists', async () => { + http.setupNodeListResponse({ + nodesByAttributes: {}, + nodesByRoles: { data: ['test'] }, + }); + const rendered = mountWithIntl(component); + noRollover(rendered); + setPolicyName(rendered, 'mypolicy'); + await activatePhase(rendered, 'cold'); + expect(rendered.find('.euiLoadingSpinner').exists()).toBeFalsy(); + expect(findTestSubject(rendered, 'defaultAllocationNotice').exists()).toBeFalsy(); + }); }); describe('delete phase', () => { test('should allow 0 for phase timing', async () => { diff --git a/x-pack/plugins/index_lifecycle_management/common/constants/data_tiers.ts b/x-pack/plugins/index_lifecycle_management/common/constants/data_tiers.ts new file mode 100644 index 0000000000000..8a1acf72949e6 --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/common/constants/data_tiers.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +// Order of node roles matters here, the warm phase prefers allocating data +// to the data_warm role. +import { NodeDataRole, PhaseWithAllocation } from '../types'; + +const WARM_PHASE_NODE_PREFERENCE: NodeDataRole[] = ['data_warm', 'data_hot']; + +const COLD_PHASE_NODE_PREFERENCE: NodeDataRole[] = ['data_cold', 'data_warm', 'data_hot']; + +export const phaseToNodePreferenceMap: Record = Object.freeze({ + warm: WARM_PHASE_NODE_PREFERENCE, + cold: COLD_PHASE_NODE_PREFERENCE, +}); diff --git a/x-pack/plugins/index_lifecycle_management/common/constants/index.ts b/x-pack/plugins/index_lifecycle_management/common/constants/index.ts index 5c89b917163d8..522dc6d82a4e9 100644 --- a/x-pack/plugins/index_lifecycle_management/common/constants/index.ts +++ b/x-pack/plugins/index_lifecycle_management/common/constants/index.ts @@ -7,6 +7,8 @@ import { i18n } from '@kbn/i18n'; import { LicenseType } from '../../../licensing/common/types'; +export { phaseToNodePreferenceMap } from './data_tiers'; + const basicLicense: LicenseType = 'basic'; export const PLUGIN = { diff --git a/x-pack/plugins/index_lifecycle_management/common/types/api.ts b/x-pack/plugins/index_lifecycle_management/common/types/api.ts index 16b8fbd127ab6..fcdbdf2c9cc90 100644 --- a/x-pack/plugins/index_lifecycle_management/common/types/api.ts +++ b/x-pack/plugins/index_lifecycle_management/common/types/api.ts @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -export type NodeDataRole = 'data' | 'data_hot' | 'data_warm' | 'data_cold' | 'data_frozen'; +import { NodeDataRoleWithCatchAll } from '.'; export interface ListNodesRouteResponse { nodesByAttributes: { [attributePair: string]: string[] }; - nodesByRoles: { [role in NodeDataRole]?: string[] }; + nodesByRoles: { [role in NodeDataRoleWithCatchAll]?: string[] }; } diff --git a/x-pack/plugins/index_lifecycle_management/common/types/index.ts b/x-pack/plugins/index_lifecycle_management/common/types/index.ts index a23dc647f1f65..1f41370e48f18 100644 --- a/x-pack/plugins/index_lifecycle_management/common/types/index.ts +++ b/x-pack/plugins/index_lifecycle_management/common/types/index.ts @@ -7,3 +7,10 @@ export * from './api'; export * from './policies'; + +/** + * These roles reflect how nodes are stratified into different data tiers. The "data" role + * is a catch-all that can be used to store data in any phase. + */ +export type NodeDataRole = 'data_hot' | 'data_warm' | 'data_cold'; +export type NodeDataRoleWithCatchAll = 'data' | NodeDataRole; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/lib/data_tiers/check_phase_compatibility.ts b/x-pack/plugins/index_lifecycle_management/public/application/lib/data_tiers/check_phase_compatibility.ts deleted file mode 100644 index 2ef0fb145551f..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/lib/data_tiers/check_phase_compatibility.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. - */ - -import { - NodeDataRole, - ListNodesRouteResponse, - PhaseWithAllocation, -} from '../../../../common/types'; - -/** - * Given a phase and current node roles, determine whether the phase - * can use default data tier allocation. - * - * This can only be checked for phases that have an allocate action. - */ -export const isPhaseDefaultDataAllocationCompatible = ( - phase: PhaseWithAllocation, - nodesByRoles: ListNodesRouteResponse['nodesByRoles'] -): boolean => { - // The 'data' role covers all node roles, so if we have at least one node with the data role - // we can use default allocation. - if (nodesByRoles.data?.length) { - return true; - } - - // Otherwise we need to check whether a node role for the specific phase exists - if (nodesByRoles[`data_${phase}` as NodeDataRole]?.length) { - return true; - } - - // Otherwise default allocation has nowhere to allocate new shards to in this phase. - return false; -}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/lib/data_tiers/get_available_node_roles_for_phase.ts b/x-pack/plugins/index_lifecycle_management/public/application/lib/data_tiers/get_available_node_roles_for_phase.ts new file mode 100644 index 0000000000000..6daae57330886 --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/public/application/lib/data_tiers/get_available_node_roles_for_phase.ts @@ -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 { + NodeDataRole, + ListNodesRouteResponse, + PhaseWithAllocation, +} from '../../../../common/types'; + +import { phaseToNodePreferenceMap } from '../../../../common/constants'; + +export type AllocationNodeRole = NodeDataRole | 'none'; + +/** + * Given a phase and current cluster node roles, determine which nodes the phase + * will allocate data to. For instance, for the warm phase, with warm + * tier nodes, we would expect "data_warm". + * + * If no nodes can be identified for allocation (very special case) then + * we return "none". + */ +export const getAvailableNodeRoleForPhase = ( + phase: PhaseWithAllocation, + nodesByRoles: ListNodesRouteResponse['nodesByRoles'] +): AllocationNodeRole => { + const preferredNodeRoles = phaseToNodePreferenceMap[phase]; + + // The 'data' role covers all node roles, so if we have at least one node with the data role + // we can allocate to our first preference. + if (nodesByRoles.data?.length) { + return preferredNodeRoles[0]; + } + + return preferredNodeRoles.find((role) => Boolean(nodesByRoles[role]?.length)) ?? 'none'; +}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/lib/data_tiers/index.ts b/x-pack/plugins/index_lifecycle_management/public/application/lib/data_tiers/index.ts index 67a512cefe00c..87f2cbc08ecc0 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/lib/data_tiers/index.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/lib/data_tiers/index.ts @@ -6,4 +6,4 @@ export * from './determine_allocation_type'; -export * from './check_phase_compatibility'; +export * from './get_available_node_roles_for_phase'; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/lib/data_tiers/is_node_role_first_preference.ts b/x-pack/plugins/index_lifecycle_management/public/application/lib/data_tiers/is_node_role_first_preference.ts new file mode 100644 index 0000000000000..872efa740b131 --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/public/application/lib/data_tiers/is_node_role_first_preference.ts @@ -0,0 +1,12 @@ +/* + * 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 { NodeDataRole, PhaseWithAllocation } from '../../../../common/types'; +import { phaseToNodePreferenceMap } from '../../../../common/constants'; + +export const isNodeRoleFirstPreference = (phase: PhaseWithAllocation, nodeRole: NodeDataRole) => { + return phaseToNodePreferenceMap[phase][0] === nodeRole; +}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/default_allocation_notice.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/default_allocation_notice.tsx new file mode 100644 index 0000000000000..8faa9bb2972c2 --- /dev/null +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/default_allocation_notice.tsx @@ -0,0 +1,111 @@ +/* + * 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 React, { FunctionComponent } from 'react'; +import { EuiCallOut, EuiSpacer } from '@elastic/eui'; + +import { PhaseWithAllocation, NodeDataRole } from '../../../../../../common/types'; + +import { AllocationNodeRole } from '../../../../lib'; + +const i18nTextsNodeRoleToDataTier: Record = { + data_hot: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.dataTierHotLabel', { + defaultMessage: 'hot', + }), + data_warm: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.dataTierWarmLabel', { + defaultMessage: 'warm', + }), + data_cold: i18n.translate('xpack.indexLifecycleMgmt.editPolicy.dataTierColdLabel', { + defaultMessage: 'cold', + }), +}; + +const i18nTexts = { + notice: { + warm: { + title: i18n.translate( + 'xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.warm.title', + { defaultMessage: 'No nodes assigned to the warm tier' } + ), + body: (nodeRole: NodeDataRole) => + i18n.translate('xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.warm', { + defaultMessage: + 'This policy will move data in the warm phase to {tier} tier nodes instead.', + values: { tier: i18nTextsNodeRoleToDataTier[nodeRole] }, + }), + }, + cold: { + title: i18n.translate( + 'xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.cold.title', + { defaultMessage: 'No nodes assigned to the cold tier' } + ), + body: (nodeRole: NodeDataRole) => + i18n.translate('xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotice.cold', { + defaultMessage: + 'This policy will move data in the cold phase to {tier} tier nodes instead.', + values: { tier: i18nTextsNodeRoleToDataTier[nodeRole] }, + }), + }, + }, + warning: { + warm: { + title: i18n.translate( + 'xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotAvailableTitle', + { defaultMessage: 'No nodes assigned to the warm tier' } + ), + body: i18n.translate( + 'xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotAvailableBody', + { + defaultMessage: + 'Assign at least one node to the warm or hot tier to use role-based allocation. The policy will fail to complete allocation if there are no available nodes.', + } + ), + }, + cold: { + title: i18n.translate( + 'xpack.indexLifecycleMgmt.coldPhase.dataTier.defaultAllocationNotAvailableTitle', + { defaultMessage: 'No nodes assigned to the cold tier' } + ), + body: i18n.translate( + 'xpack.indexLifecycleMgmt.coldPhase.dataTier.defaultAllocationNotAvailableBody', + { + defaultMessage: + 'Assign at least one node to the cold, warm, or hot tier to use role-based allocation. The policy will fail to complete allocation if there are no available nodes.', + } + ), + }, + }, +}; + +interface Props { + phase: PhaseWithAllocation; + targetNodeRole: AllocationNodeRole; +} + +export const DefaultAllocationNotice: FunctionComponent = ({ phase, targetNodeRole }) => { + const content = + targetNodeRole === 'none' ? ( + + {i18nTexts.warning[phase].body} + + ) : ( + + {i18nTexts.notice[phase].body(targetNodeRole)} + + ); + + return ( + <> + + {content} + + ); +}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/default_allocation_warning.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/default_allocation_warning.tsx deleted file mode 100644 index 5aba411b6fe53..0000000000000 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/default_allocation_warning.tsx +++ /dev/null @@ -1,59 +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 { i18n } from '@kbn/i18n'; -import React, { FunctionComponent } from 'react'; -import { EuiCallOut, EuiSpacer } from '@elastic/eui'; - -import { PhaseWithAllocation } from '../../../../../../common/types'; - -const i18nTexts = { - warm: { - title: i18n.translate( - 'xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotAvailableTitle', - { defaultMessage: 'No nodes assigned to the warm tier' } - ), - body: i18n.translate( - 'xpack.indexLifecycleMgmt.warmPhase.dataTier.defaultAllocationNotAvailableBody', - { - defaultMessage: - 'Assign at least one node to the warm tier to use role-based allocation. The policy will fail to complete allocation if there are no warm nodes.', - } - ), - }, - cold: { - title: i18n.translate( - 'xpack.indexLifecycleMgmt.coldPhase.dataTier.defaultAllocationNotAvailableTitle', - { defaultMessage: 'No nodes assigned to the cold tier' } - ), - body: i18n.translate( - 'xpack.indexLifecycleMgmt.coldPhase.dataTier.defaultAllocationNotAvailableBody', - { - defaultMessage: - 'Assign at least one node to the cold tier to use role-based allocation. The policy will fail to complete allocation if there are no cold nodes.', - } - ), - }, -}; - -interface Props { - phase: PhaseWithAllocation; -} - -export const DefaultAllocationWarning: FunctionComponent = ({ phase }) => { - return ( - <> - - - {i18nTexts[phase].body} - - - ); -}; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/index.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/index.ts index 26464a75ae14c..dcbdf960fd380 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/index.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/data_tier_allocation/index.ts @@ -8,5 +8,5 @@ export { NodesDataProvider } from './node_data_provider'; export { NodeAllocation } from './node_allocation'; export { NodeAttrsDetails } from './node_attrs_details'; export { DataTierAllocation } from './data_tier_allocation'; -export { DefaultAllocationWarning } from './default_allocation_warning'; +export { DefaultAllocationNotice } from './default_allocation_notice'; export { NoNodeAttributesWarning } from './no_node_attributes_warning'; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/index.ts b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/index.ts index 2428cade0898e..c39545112ee52 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/index.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/index.ts @@ -18,7 +18,7 @@ export { NodeAllocation, NodeAttrsDetails, NodesDataProvider, - DefaultAllocationWarning, + DefaultAllocationNotice, } from './data_tier_allocation'; export { DescribedFormField } from './described_form_field'; export { Forcemerge } from './forcemerge'; diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/phases/cold_phase.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/phases/cold_phase.tsx index 241a98fffa6df..b9b1b8b663ec8 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/phases/cold_phase.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/phases/cold_phase.tsx @@ -33,7 +33,7 @@ const i18nTexts = { dataTierAllocation: { description: i18n.translate('xpack.indexLifecycleMgmt.coldPhase.dataTier.description', { defaultMessage: - 'Move data to data nodes optimized for less frequent, read-only access. Store cold data on less-expensive hardware.', + 'Move data to nodes optimized for less frequent, read-only access. Store data in the cold phase on less-expensive hardware.', }), }, }; @@ -192,8 +192,7 @@ export const ColdPhase: FunctionComponent = ({ {' '} diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/phases/shared/data_tier_allocation_field.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/phases/shared/data_tier_allocation_field.tsx index 6475e5286a778..623d443a1db01 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/phases/shared/data_tier_allocation_field.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/phases/shared/data_tier_allocation_field.tsx @@ -9,15 +9,16 @@ import { i18n } from '@kbn/i18n'; import { EuiDescribedFormGroup, EuiFormRow } from '@elastic/eui'; import { PhaseWithAllocationAction, PhaseWithAllocation } from '../../../../../../common/types'; +import { PhaseValidationErrors } from '../../../../services/policies/policy_validation'; +import { getAvailableNodeRoleForPhase } from '../../../../lib/data_tiers'; +import { isNodeRoleFirstPreference } from '../../../../lib/data_tiers/is_node_role_first_preference'; import { DataTierAllocation, - DefaultAllocationWarning, + DefaultAllocationNotice, NoNodeAttributesWarning, NodesDataProvider, } from '../../components/data_tier_allocation'; -import { PhaseValidationErrors } from '../../../../services/policies/policy_validation'; -import { isPhaseDefaultDataAllocationCompatible } from '../../../../lib/data_tiers'; const i18nTexts = { title: i18n.translate('xpack.indexLifecycleMgmt.common.dataTier.title', { @@ -48,9 +49,34 @@ export const DataTierAllocationField: FunctionComponent = ({ return ( {(nodesData) => { - const isCompatible = isPhaseDefaultDataAllocationCompatible(phase, nodesData.nodesByRoles); const hasNodeAttrs = Boolean(Object.keys(nodesData.nodesByAttributes ?? {}).length); + const renderDefaultAllocationNotice = () => { + if (phaseData.dataTierAllocationType !== 'default') { + return null; + } + + const allocationNodeRole = getAvailableNodeRoleForPhase(phase, nodesData.nodesByRoles); + if ( + allocationNodeRole !== 'none' && + isNodeRoleFirstPreference(phase, allocationNodeRole) + ) { + return null; + } + + return ; + }; + + const renderNodeAttributesWarning = () => { + if (phaseData.dataTierAllocationType !== 'custom') { + return null; + } + if (hasNodeAttrs) { + return null; + } + return ; + }; + return ( {i18nTexts.title}} @@ -70,14 +96,8 @@ export const DataTierAllocationField: FunctionComponent = ({ /> {/* Data tier related warnings */} - - {phaseData.dataTierAllocationType === 'default' && !isCompatible && ( - - )} - - {phaseData.dataTierAllocationType === 'custom' && !hasNodeAttrs && ( - - )} + {renderDefaultAllocationNotice()} + {renderNodeAttributesWarning()} diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/phases/warm_phase.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/phases/warm_phase.tsx index 16a740b1171c9..b837eed1256c5 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/phases/warm_phase.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/phases/warm_phase.tsx @@ -45,8 +45,7 @@ const i18nTexts = { ), dataTierAllocation: { description: i18n.translate('xpack.indexLifecycleMgmt.warmPhase.dataTier.description', { - defaultMessage: - 'Move warm data to nodes optimized for read-only access. Store warm data on less-expensive hardware.', + defaultMessage: 'Move data to nodes optimized for less-frequent, read-only access.', }), }, }; diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/version_datatype.test.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/version_datatype.test.tsx new file mode 100644 index 0000000000000..61f67b04ec3cd --- /dev/null +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/datatypes/version_datatype.test.tsx @@ -0,0 +1,95 @@ +/* + * 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 { act } from 'react-dom/test-utils'; + +import { componentHelpers, MappingsEditorTestBed } from '../helpers'; + +const { setup, getMappingsEditorDataFactory } = componentHelpers.mappingsEditor; + +// Parameters automatically added to the version datatype when saved (with the default values) +export const defaultVersionParameters = { + type: 'version', +}; + +describe('Mappings editor: version datatype', () => { + /** + * Variable to store the mappings data forwarded to the consumer component + */ + let data: any; + let onChangeHandler: jest.Mock = jest.fn(); + let getMappingsEditorData = getMappingsEditorDataFactory(onChangeHandler); + let testBed: MappingsEditorTestBed; + + beforeAll(() => { + jest.useFakeTimers(); + }); + + afterAll(() => { + jest.useRealTimers(); + }); + + beforeEach(() => { + onChangeHandler = jest.fn(); + getMappingsEditorData = getMappingsEditorDataFactory(onChangeHandler); + }); + + test('supports meta parameter', async () => { + const defaultMappings = { + properties: { + myField: { + type: 'version', + }, + }, + }; + + const updatedMappings = { ...defaultMappings }; + + const metaParameter = { + meta: { + my_metadata: 'foobar', + }, + }; + + await act(async () => { + testBed = setup({ value: defaultMappings, onChange: onChangeHandler }); + }); + testBed.component.update(); + + const { + component, + actions: { + startEditField, + updateFieldAndCloseFlyout, + showAdvancedSettings, + toggleFormRow, + updateJsonEditor, + }, + } = testBed; + + // Open the flyout to edit the field + await startEditField('myField'); + await showAdvancedSettings(); + + // Enable the meta parameter and provide a valid object + toggleFormRow('metaParameter'); + await act(async () => { + updateJsonEditor('metaParameterEditor', metaParameter.meta); + }); + component.update(); + + // Save the field and close the flyout + await updateFieldAndCloseFlyout(); + + // It should have the default parameters values added, plus metadata + updatedMappings.properties.myField = { + ...defaultVersionParameters, + ...metaParameter, + }; + + ({ data } = await getMappingsEditorData(component)); + expect(data).toEqual(updatedMappings); + }); +}); diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/mappings_editor.test.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/mappings_editor.test.tsx index 68933ddc9a935..f5fcff9f96254 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/mappings_editor.test.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/__jest__/client_integration/mappings_editor.test.tsx @@ -223,6 +223,33 @@ describe('Mappings editor: core', () => { isNumericDetectionVisible = exists('advancedConfiguration.numericDetection'); expect(isNumericDetectionVisible).toBe(false); }); + + test('should keep default dynamic templates value when switching tabs', async () => { + await act(async () => { + testBed = setup({ + value: { ...defaultMappings, dynamic_templates: [] }, // by default, the UI will provide an empty array for dynamic templates + onChange: onChangeHandler, + }); + }); + testBed.component.update(); + + const { + actions: { selectTab, getJsonEditorValue }, + } = testBed; + + // Navigate to dynamic templates tab and verify empty array + await selectTab('templates'); + let templatesValue = getJsonEditorValue('dynamicTemplatesEditor'); + expect(templatesValue).toEqual([]); + + // Navigate to advanced tab + await selectTab('advanced'); + + // Navigate back to dynamic templates tab and verify empty array persists + await selectTab('templates'); + templatesValue = getJsonEditorValue('dynamicTemplatesEditor'); + expect(templatesValue).toEqual([]); + }); }); describe('component props', () => { diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/index.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/index.ts index 4d36b4dd2578d..d135d1b81419c 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/index.ts +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/index.ts @@ -34,6 +34,7 @@ import { RankFeatureType } from './rank_feature_type'; import { RuntimeType } from './runtime_type'; import { WildcardType } from './wildcard_type'; import { PointType } from './point_type'; +import { VersionType } from './version_type'; const typeToParametersFormMap: { [key in DataType]?: ComponentType } = { alias: AliasType, @@ -64,6 +65,7 @@ const typeToParametersFormMap: { [key in DataType]?: ComponentType } = { runtime: RuntimeType, wildcard: WildcardType, point: PointType, + version: VersionType, }; export const getParametersFormForType = ( diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/version_type.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/version_type.tsx new file mode 100644 index 0000000000000..24ee356c5db77 --- /dev/null +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/document_fields/fields/field_types/version_type.tsx @@ -0,0 +1,27 @@ +/* + * 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 { NormalizedField, Field as FieldType, ParameterName } from '../../../../types'; +import { getFieldConfig } from '../../../../lib'; +import { MetaParameter } from '../../field_parameters'; +import { AdvancedParametersSection } from '../edit_field'; + +interface Props { + field: NormalizedField; +} + +const getDefaultToggleValue = (param: ParameterName, field: FieldType) => { + return field[param] !== undefined && field[param] !== getFieldConfig(param).defaultValue; +}; + +export const VersionType = ({ field }: Props) => { + return ( + + + + ); +}; diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/templates_form/templates_form.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/templates_form/templates_form.tsx index 4b813b4edbabd..46e7bbd5e094a 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/components/templates_form/templates_form.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/components/templates_form/templates_form.tsx @@ -36,11 +36,10 @@ const formSerializer: SerializerFunc = (formData) // Silently swallow errors } - return Array.isArray(parsedTemplates) && parsedTemplates.length > 0 - ? { - dynamic_templates: parsedTemplates, - } - : undefined; + return { + dynamic_templates: + Array.isArray(parsedTemplates) && parsedTemplates.length > 0 ? parsedTemplates : [], + }; }; const formDeserializer = (formData: { [key: string]: any }) => { diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/data_types_definition.tsx b/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/data_types_definition.tsx index 7bcd8f32f1a7d..07ca0a69afefb 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/data_types_definition.tsx +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/constants/data_types_definition.tsx @@ -860,6 +860,35 @@ export const TYPE_DEFINITION: { [key in DataType]: DataTypeDefinition } = {

), }, + version: { + label: i18n.translate('xpack.idxMgmt.mappingsEditor.dataType.versionDescription', { + defaultMessage: 'Version', + }), + value: 'version', + documentation: { + main: '/version.html', + }, + description: () => ( +

+ + {i18n.translate( + 'xpack.idxMgmt.mappingsEditor.dataType.versionLongDescription.keywordTypeLink', + { + defaultMessage: 'keyword data type', + } + )} + + ), + }} + /> +

+ ), + }, wildcard: { label: i18n.translate('xpack.idxMgmt.mappingsEditor.dataType.wildcardDescription', { defaultMessage: 'Wildcard', @@ -923,6 +952,7 @@ export const MAIN_TYPES: MainType[] = [ 'histogram', 'wildcard', 'point', + 'version', 'other', ]; diff --git a/x-pack/plugins/index_management/public/application/components/mappings_editor/types/document_fields.ts b/x-pack/plugins/index_management/public/application/components/mappings_editor/types/document_fields.ts index 48282abd1d799..926b4c9d12bee 100644 --- a/x-pack/plugins/index_management/public/application/components/mappings_editor/types/document_fields.ts +++ b/x-pack/plugins/index_management/public/application/components/mappings_editor/types/document_fields.ts @@ -64,6 +64,7 @@ export type MainType = | 'point' | 'histogram' | 'constant_keyword' + | 'version' | 'wildcard' /** * 'other' is a special type that only exists inside of MappingsEditor as a placeholder diff --git a/x-pack/plugins/infra/.storybook/main.js b/x-pack/plugins/infra/.storybook/main.js new file mode 100644 index 0000000000000..1818aa44a9399 --- /dev/null +++ b/x-pack/plugins/infra/.storybook/main.js @@ -0,0 +1,7 @@ +/* + * 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. + */ + +module.exports = require('@kbn/storybook').defaultConfig; diff --git a/x-pack/plugins/infra/common/alerting/logs/log_threshold/types.ts b/x-pack/plugins/infra/common/alerting/logs/log_threshold/types.ts new file mode 100644 index 0000000000000..c505a234c7b2b --- /dev/null +++ b/x-pack/plugins/infra/common/alerting/logs/log_threshold/types.ts @@ -0,0 +1,262 @@ +/* + * 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 * as rt from 'io-ts'; +import { commonSearchSuccessResponseFieldsRT } from '../../../utils/elasticsearch_runtime_types'; + +export const LOG_DOCUMENT_COUNT_ALERT_TYPE_ID = 'logs.alert.document.count'; + +const ThresholdTypeRT = rt.keyof({ + count: null, + ratio: null, +}); + +export type ThresholdType = rt.TypeOf; + +// Comparators // +export enum Comparator { + GT = 'more than', + GT_OR_EQ = 'more than or equals', + LT = 'less than', + LT_OR_EQ = 'less than or equals', + EQ = 'equals', + NOT_EQ = 'does not equal', + MATCH = 'matches', + NOT_MATCH = 'does not match', + MATCH_PHRASE = 'matches phrase', + NOT_MATCH_PHRASE = 'does not match phrase', +} + +const ComparatorRT = rt.keyof({ + [Comparator.GT]: null, + [Comparator.GT_OR_EQ]: null, + [Comparator.LT]: null, + [Comparator.LT_OR_EQ]: null, + [Comparator.EQ]: null, + [Comparator.NOT_EQ]: null, + [Comparator.MATCH]: null, + [Comparator.NOT_MATCH]: null, + [Comparator.MATCH_PHRASE]: null, + [Comparator.NOT_MATCH_PHRASE]: null, +}); + +// Maps our comparators to i18n strings, some comparators have more specific wording +// depending on the field type the comparator is being used with. +export const ComparatorToi18nMap = { + [Comparator.GT]: i18n.translate('xpack.infra.logs.alerting.comparator.gt', { + defaultMessage: 'more than', + }), + [Comparator.GT_OR_EQ]: i18n.translate('xpack.infra.logs.alerting.comparator.gtOrEq', { + defaultMessage: 'more than or equals', + }), + [Comparator.LT]: i18n.translate('xpack.infra.logs.alerting.comparator.lt', { + defaultMessage: 'less than', + }), + [Comparator.LT_OR_EQ]: i18n.translate('xpack.infra.logs.alerting.comparator.ltOrEq', { + defaultMessage: 'less than or equals', + }), + [Comparator.EQ]: i18n.translate('xpack.infra.logs.alerting.comparator.eq', { + defaultMessage: 'is', + }), + [Comparator.NOT_EQ]: i18n.translate('xpack.infra.logs.alerting.comparator.notEq', { + defaultMessage: 'is not', + }), + [`${Comparator.EQ}:number`]: i18n.translate('xpack.infra.logs.alerting.comparator.eqNumber', { + defaultMessage: 'equals', + }), + [`${Comparator.NOT_EQ}:number`]: i18n.translate( + 'xpack.infra.logs.alerting.comparator.notEqNumber', + { + defaultMessage: 'does not equal', + } + ), + [Comparator.MATCH]: i18n.translate('xpack.infra.logs.alerting.comparator.match', { + defaultMessage: 'matches', + }), + [Comparator.NOT_MATCH]: i18n.translate('xpack.infra.logs.alerting.comparator.notMatch', { + defaultMessage: 'does not match', + }), + [Comparator.MATCH_PHRASE]: i18n.translate('xpack.infra.logs.alerting.comparator.matchPhrase', { + defaultMessage: 'matches phrase', + }), + [Comparator.NOT_MATCH_PHRASE]: i18n.translate( + 'xpack.infra.logs.alerting.comparator.notMatchPhrase', + { + defaultMessage: 'does not match phrase', + } + ), +}; + +// Alert parameters // +export enum AlertStates { + OK, + ALERT, + NO_DATA, + ERROR, +} + +const ThresholdRT = rt.type({ + comparator: ComparatorRT, + value: rt.number, +}); + +export type Threshold = rt.TypeOf; + +export const CriterionRT = rt.type({ + field: rt.string, + comparator: ComparatorRT, + value: rt.union([rt.string, rt.number]), +}); + +export type Criterion = rt.TypeOf; +export const criteriaRT = rt.array(CriterionRT); +export type Criteria = rt.TypeOf; + +export const countCriteriaRT = criteriaRT; +export type CountCriteria = rt.TypeOf; + +export const ratioCriteriaRT = rt.tuple([criteriaRT, criteriaRT]); +export type RatioCriteria = rt.TypeOf; + +export const TimeUnitRT = rt.union([ + rt.literal('s'), + rt.literal('m'), + rt.literal('h'), + rt.literal('d'), +]); +export type TimeUnit = rt.TypeOf; + +export const timeSizeRT = rt.number; +export const groupByRT = rt.array(rt.string); + +const RequiredAlertParamsRT = rt.type({ + // NOTE: "count" would be better named as "threshold", but this would require a + // migration of encrypted saved objects, so we'll keep "count" until it's problematic. + count: ThresholdRT, + timeUnit: TimeUnitRT, + timeSize: timeSizeRT, +}); + +const OptionalAlertParamsRT = rt.partial({ + groupBy: groupByRT, +}); + +export const alertParamsRT = rt.intersection([ + rt.type({ + criteria: countCriteriaRT, + ...RequiredAlertParamsRT.props, + }), + rt.partial({ + ...OptionalAlertParamsRT.props, + }), +]); + +export type CountAlertParams = rt.TypeOf; + +export const ratioAlertParamsRT = rt.intersection([ + rt.type({ + criteria: ratioCriteriaRT, + ...RequiredAlertParamsRT.props, + }), + rt.partial({ + ...OptionalAlertParamsRT.props, + }), +]); + +export type RatioAlertParams = rt.TypeOf; + +export const AlertParamsRT = rt.union([alertParamsRT, ratioAlertParamsRT]); +export type AlertParams = rt.TypeOf; + +export const isRatioAlert = (criteria: AlertParams['criteria']): criteria is RatioCriteria => { + return criteria.length > 0 && Array.isArray(criteria[0]) ? true : false; +}; + +export const isRatioAlertParams = (params: AlertParams): params is RatioAlertParams => { + return isRatioAlert(params.criteria); +}; + +export const getNumerator = (criteria: RatioCriteria): Criteria => { + return criteria[0]; +}; + +export const getDenominator = (criteria: RatioCriteria): Criteria => { + return criteria[1]; +}; + +export const hasGroupBy = (alertParams: AlertParams) => { + const { groupBy } = alertParams; + return groupBy && groupBy.length > 0 ? true : false; +}; + +// Chart previews // +const chartPreviewHistogramBucket = rt.type({ + key: rt.number, + doc_count: rt.number, +}); + +// ES query responses // +export const UngroupedSearchQueryResponseRT = rt.intersection([ + commonSearchSuccessResponseFieldsRT, + rt.intersection([ + rt.type({ + hits: rt.type({ + total: rt.type({ + value: rt.number, + }), + }), + }), + // Chart preview buckets + rt.partial({ + aggregations: rt.type({ + histogramBuckets: rt.type({ + buckets: rt.array(chartPreviewHistogramBucket), + }), + }), + }), + ]), +]); + +export type UngroupedSearchQueryResponse = rt.TypeOf; + +export const GroupedSearchQueryResponseRT = rt.intersection([ + commonSearchSuccessResponseFieldsRT, + rt.type({ + aggregations: rt.type({ + groups: rt.intersection([ + rt.type({ + buckets: rt.array( + rt.type({ + key: rt.record(rt.string, rt.string), + doc_count: rt.number, + filtered_results: rt.intersection([ + rt.type({ + doc_count: rt.number, + }), + // Chart preview buckets + rt.partial({ + histogramBuckets: rt.type({ + buckets: rt.array(chartPreviewHistogramBucket), + }), + }), + ]), + }) + ), + }), + rt.partial({ + after_key: rt.record(rt.string, rt.string), + }), + ]), + }), + hits: rt.type({ + total: rt.type({ + value: rt.number, + }), + }), + }), +]); + +export type GroupedSearchQueryResponse = rt.TypeOf; diff --git a/x-pack/plugins/infra/common/alerting/logs/types.ts b/x-pack/plugins/infra/common/alerting/logs/types.ts deleted file mode 100644 index 1b736f52aa7e2..0000000000000 --- a/x-pack/plugins/infra/common/alerting/logs/types.ts +++ /dev/null @@ -1,198 +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 { i18n } from '@kbn/i18n'; -import * as rt from 'io-ts'; -import { commonSearchSuccessResponseFieldsRT } from '../../utils/elasticsearch_runtime_types'; - -export const LOG_DOCUMENT_COUNT_ALERT_TYPE_ID = 'logs.alert.document.count'; - -export enum Comparator { - GT = 'more than', - GT_OR_EQ = 'more than or equals', - LT = 'less than', - LT_OR_EQ = 'less than or equals', - EQ = 'equals', - NOT_EQ = 'does not equal', - MATCH = 'matches', - NOT_MATCH = 'does not match', - MATCH_PHRASE = 'matches phrase', - NOT_MATCH_PHRASE = 'does not match phrase', -} - -const ComparatorRT = rt.keyof({ - [Comparator.GT]: null, - [Comparator.GT_OR_EQ]: null, - [Comparator.LT]: null, - [Comparator.LT_OR_EQ]: null, - [Comparator.EQ]: null, - [Comparator.NOT_EQ]: null, - [Comparator.MATCH]: null, - [Comparator.NOT_MATCH]: null, - [Comparator.MATCH_PHRASE]: null, - [Comparator.NOT_MATCH_PHRASE]: null, -}); - -// Maps our comparators to i18n strings, some comparators have more specific wording -// depending on the field type the comparator is being used with. -export const ComparatorToi18nMap = { - [Comparator.GT]: i18n.translate('xpack.infra.logs.alerting.comparator.gt', { - defaultMessage: 'more than', - }), - [Comparator.GT_OR_EQ]: i18n.translate('xpack.infra.logs.alerting.comparator.gtOrEq', { - defaultMessage: 'more than or equals', - }), - [Comparator.LT]: i18n.translate('xpack.infra.logs.alerting.comparator.lt', { - defaultMessage: 'less than', - }), - [Comparator.LT_OR_EQ]: i18n.translate('xpack.infra.logs.alerting.comparator.ltOrEq', { - defaultMessage: 'less than or equals', - }), - [Comparator.EQ]: i18n.translate('xpack.infra.logs.alerting.comparator.eq', { - defaultMessage: 'is', - }), - [Comparator.NOT_EQ]: i18n.translate('xpack.infra.logs.alerting.comparator.notEq', { - defaultMessage: 'is not', - }), - [`${Comparator.EQ}:number`]: i18n.translate('xpack.infra.logs.alerting.comparator.eqNumber', { - defaultMessage: 'equals', - }), - [`${Comparator.NOT_EQ}:number`]: i18n.translate( - 'xpack.infra.logs.alerting.comparator.notEqNumber', - { - defaultMessage: 'does not equal', - } - ), - [Comparator.MATCH]: i18n.translate('xpack.infra.logs.alerting.comparator.match', { - defaultMessage: 'matches', - }), - [Comparator.NOT_MATCH]: i18n.translate('xpack.infra.logs.alerting.comparator.notMatch', { - defaultMessage: 'does not match', - }), - [Comparator.MATCH_PHRASE]: i18n.translate('xpack.infra.logs.alerting.comparator.matchPhrase', { - defaultMessage: 'matches phrase', - }), - [Comparator.NOT_MATCH_PHRASE]: i18n.translate( - 'xpack.infra.logs.alerting.comparator.notMatchPhrase', - { - defaultMessage: 'does not match phrase', - } - ), -}; - -export enum AlertStates { - OK, - ALERT, - NO_DATA, - ERROR, -} - -const DocumentCountRT = rt.type({ - comparator: ComparatorRT, - value: rt.number, -}); - -export type DocumentCount = rt.TypeOf; - -export const CriterionRT = rt.type({ - field: rt.string, - comparator: ComparatorRT, - value: rt.union([rt.string, rt.number]), -}); - -export type Criterion = rt.TypeOf; -export const criteriaRT = rt.array(CriterionRT); - -export const TimeUnitRT = rt.union([ - rt.literal('s'), - rt.literal('m'), - rt.literal('h'), - rt.literal('d'), -]); -export type TimeUnit = rt.TypeOf; - -export const timeSizeRT = rt.number; -export const groupByRT = rt.array(rt.string); - -export const LogDocumentCountAlertParamsRT = rt.intersection([ - rt.type({ - count: DocumentCountRT, - criteria: criteriaRT, - timeUnit: TimeUnitRT, - timeSize: timeSizeRT, - }), - rt.partial({ - groupBy: groupByRT, - }), -]); - -export type LogDocumentCountAlertParams = rt.TypeOf; - -const chartPreviewHistogramBucket = rt.type({ - key: rt.number, - doc_count: rt.number, -}); - -export const UngroupedSearchQueryResponseRT = rt.intersection([ - commonSearchSuccessResponseFieldsRT, - rt.intersection([ - rt.type({ - hits: rt.type({ - total: rt.type({ - value: rt.number, - }), - }), - }), - // Chart preview buckets - rt.partial({ - aggregations: rt.type({ - histogramBuckets: rt.type({ - buckets: rt.array(chartPreviewHistogramBucket), - }), - }), - }), - ]), -]); - -export type UngroupedSearchQueryResponse = rt.TypeOf; - -export const GroupedSearchQueryResponseRT = rt.intersection([ - commonSearchSuccessResponseFieldsRT, - rt.type({ - aggregations: rt.type({ - groups: rt.intersection([ - rt.type({ - buckets: rt.array( - rt.type({ - key: rt.record(rt.string, rt.string), - doc_count: rt.number, - filtered_results: rt.intersection([ - rt.type({ - doc_count: rt.number, - }), - // Chart preview buckets - rt.partial({ - histogramBuckets: rt.type({ - buckets: rt.array(chartPreviewHistogramBucket), - }), - }), - ]), - }) - ), - }), - rt.partial({ - after_key: rt.record(rt.string, rt.string), - }), - ]), - }), - hits: rt.type({ - total: rt.type({ - value: rt.number, - }), - }), - }), -]); - -export type GroupedSearchQueryResponse = rt.TypeOf; diff --git a/x-pack/plugins/infra/common/http_api/infra_ml/results/common.ts b/x-pack/plugins/infra/common/http_api/infra_ml/results/common.ts index 0474fbd1cfc2f..deb8e6401008d 100644 --- a/x-pack/plugins/infra/common/http_api/infra_ml/results/common.ts +++ b/x-pack/plugins/infra/common/http_api/infra_ml/results/common.ts @@ -57,3 +57,11 @@ export const sortRT = rt.type({ }); export type Sort = rt.TypeOf; + +export const metricRT = rt.keyof({ + memory_usage: null, + network_in: null, + network_out: null, +}); + +export type Metric = rt.TypeOf; diff --git a/x-pack/plugins/infra/common/http_api/infra_ml/results/metrics_hosts_anomalies.ts b/x-pack/plugins/infra/common/http_api/infra_ml/results/metrics_hosts_anomalies.ts index 9fdac09fec20e..a08dd438a32c8 100644 --- a/x-pack/plugins/infra/common/http_api/infra_ml/results/metrics_hosts_anomalies.ts +++ b/x-pack/plugins/infra/common/http_api/infra_ml/results/metrics_hosts_anomalies.ts @@ -7,7 +7,7 @@ import * as rt from 'io-ts'; import { timeRangeRT, routeTimingMetadataRT } from '../../shared'; -import { anomalyTypeRT, paginationCursorRT, sortRT, paginationRT } from './common'; +import { anomalyTypeRT, paginationCursorRT, sortRT, paginationRT, metricRT } from './common'; export const INFA_ML_GET_METRICS_HOSTS_ANOMALIES_PATH = '/api/infra/infra_ml/results/metrics_hosts_anomalies'; @@ -18,6 +18,7 @@ const metricsHostAnomalyCommonFieldsRT = rt.type({ typical: rt.number, actual: rt.number, type: anomalyTypeRT, + influencers: rt.array(rt.string), duration: rt.number, startTime: rt.number, jobId: rt.string, @@ -64,12 +65,11 @@ export const getMetricsHostsAnomaliesRequestPayloadRT = rt.type({ timeRange: timeRangeRT, }), rt.partial({ + metric: metricRT, // Pagination properties pagination: paginationRT, // Sort properties sort: sortRT, - // // Dataset filters - // datasets: rt.array(rt.string), }), ]), }); diff --git a/x-pack/plugins/infra/common/http_api/infra_ml/results/metrics_k8s_anomalies.ts b/x-pack/plugins/infra/common/http_api/infra_ml/results/metrics_k8s_anomalies.ts index ab1f245a74c0c..7450bb39276ac 100644 --- a/x-pack/plugins/infra/common/http_api/infra_ml/results/metrics_k8s_anomalies.ts +++ b/x-pack/plugins/infra/common/http_api/infra_ml/results/metrics_k8s_anomalies.ts @@ -7,7 +7,7 @@ import * as rt from 'io-ts'; import { timeRangeRT, routeTimingMetadataRT } from '../../shared'; -import { paginationCursorRT, anomalyTypeRT, sortRT, paginationRT } from './common'; +import { paginationCursorRT, anomalyTypeRT, sortRT, paginationRT, metricRT } from './common'; export const INFA_ML_GET_METRICS_K8S_ANOMALIES_PATH = '/api/infra/infra_ml/results/metrics_k8s_anomalies'; @@ -18,6 +18,7 @@ const metricsK8sAnomalyCommonFieldsRT = rt.type({ typical: rt.number, actual: rt.number, type: anomalyTypeRT, + influencers: rt.array(rt.string), duration: rt.number, startTime: rt.number, jobId: rt.string, @@ -64,6 +65,7 @@ export const getMetricsK8sAnomaliesRequestPayloadRT = rt.type({ timeRange: timeRangeRT, }), rt.partial({ + metric: metricRT, // Pagination properties pagination: paginationRT, // Sort properties diff --git a/x-pack/plugins/infra/common/http_api/log_alerts/chart_preview_data.ts b/x-pack/plugins/infra/common/http_api/log_alerts/chart_preview_data.ts index 15914bd1b2209..3226287d4cbde 100644 --- a/x-pack/plugins/infra/common/http_api/log_alerts/chart_preview_data.ts +++ b/x-pack/plugins/infra/common/http_api/log_alerts/chart_preview_data.ts @@ -5,7 +5,12 @@ */ import * as rt from 'io-ts'; -import { criteriaRT, TimeUnitRT, timeSizeRT, groupByRT } from '../../alerting/logs/types'; +import { + criteriaRT, + TimeUnitRT, + timeSizeRT, + groupByRT, +} from '../../alerting/logs/log_threshold/types'; export const LOG_ALERTS_CHART_PREVIEW_DATA_PATH = '/api/infra/log_alerts/chart_preview_data'; diff --git a/x-pack/plugins/infra/public/alerting/common/components/get_alert_preview.ts b/x-pack/plugins/infra/public/alerting/common/components/get_alert_preview.ts index 207d8a722a8c6..ea50ea6f11f3a 100644 --- a/x-pack/plugins/infra/public/alerting/common/components/get_alert_preview.ts +++ b/x-pack/plugins/infra/public/alerting/common/components/get_alert_preview.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { HttpSetup } from 'src/core/public'; +import type { HttpHandler } from 'src/core/public'; import { INFRA_ALERT_PREVIEW_PATH, METRIC_THRESHOLD_ALERT_TYPE_ID, @@ -22,7 +22,7 @@ export async function getAlertPreview({ params, alertType, }: { - fetch: HttpSetup['fetch']; + fetch: HttpHandler; params: AlertPreviewRequestParams; alertType: PreviewableAlertTypes; }): Promise { diff --git a/x-pack/plugins/infra/public/alerting/common/criterion_preview_chart/criterion_preview_chart.tsx b/x-pack/plugins/infra/public/alerting/common/criterion_preview_chart/criterion_preview_chart.tsx new file mode 100644 index 0000000000000..9003e13869e60 --- /dev/null +++ b/x-pack/plugins/infra/public/alerting/common/criterion_preview_chart/criterion_preview_chart.tsx @@ -0,0 +1,136 @@ +/* + * 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, { useMemo } from 'react'; +import { niceTimeFormatter, TooltipValue } from '@elastic/charts'; +import { Theme, LIGHT_THEME, DARK_THEME } from '@elastic/charts'; +import { sum, min as getMin, max as getMax } from 'lodash'; +import moment from 'moment'; +import { i18n } from '@kbn/i18n'; +import { EuiText } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { formatNumber } from '../../../../common/formatters/number'; +import { GetLogAlertsChartPreviewDataSuccessResponsePayload } from '../../../../common/http_api'; + +type Series = GetLogAlertsChartPreviewDataSuccessResponsePayload['data']['series']; + +export const tooltipProps = { + headerFormatter: (tooltipValue: TooltipValue) => + moment(tooltipValue.value).format('Y-MM-DD HH:mm:ss'), +}; + +export const NUM_BUCKETS = 20; + +export const TIME_LABELS = { + s: i18n.translate('xpack.infra.alerts.timeLabels.seconds', { defaultMessage: 'seconds' }), + m: i18n.translate('xpack.infra.alerts.timeLabels.minutes', { defaultMessage: 'minutes' }), + h: i18n.translate('xpack.infra.alerts.timeLabels.hours', { defaultMessage: 'hours' }), + d: i18n.translate('xpack.infra.alerts.timeLabels.days', { defaultMessage: 'days' }), +}; + +export const useDateFormatter = (xMin?: number, xMax?: number) => { + const dateFormatter = useMemo(() => { + if (typeof xMin === 'number' && typeof xMax === 'number') { + return niceTimeFormatter([xMin, xMax]); + } else { + return (value: number) => `${value}`; + } + }, [xMin, xMax]); + return dateFormatter; +}; + +export const yAxisFormatter = formatNumber; + +export const getDomain = (series: Series, stacked: boolean = false) => { + let min: number | null = null; + let max: number | null = null; + const valuesByTimestamp = series.reduce<{ [timestamp: number]: number[] }>((acc, serie) => { + serie.points.forEach((point) => { + const valuesForTimestamp = acc[point.timestamp] || []; + acc[point.timestamp] = [...valuesForTimestamp, point.value]; + }); + return acc; + }, {}); + const pointValues = Object.values(valuesByTimestamp); + pointValues.forEach((results) => { + const maxResult = stacked ? sum(results) : getMax(results); + const minResult = getMin(results); + if (maxResult && (!max || maxResult > max)) { + max = maxResult; + } + if (minResult && (!min || minResult < min)) { + min = minResult; + } + }); + const timestampValues = Object.keys(valuesByTimestamp).map(Number); + const minTimestamp = getMin(timestampValues) || 0; + const maxTimestamp = getMax(timestampValues) || 0; + return { yMin: min || 0, yMax: max || 0, xMin: minTimestamp, xMax: maxTimestamp }; +}; + +export const getChartTheme = (isDarkMode: boolean): Theme => { + return isDarkMode ? DARK_THEME : LIGHT_THEME; +}; + +export const EmptyContainer: React.FC = ({ children }) => ( +
+ {children} +
+); + +export const ChartContainer: React.FC = ({ children }) => ( +
+ {children} +
+); + +export const NoDataState = () => { + return ( + + + + + + ); +}; + +export const LoadingState = () => { + return ( + + + + + + ); +}; + +export const ErrorState = () => { + return ( + + + + + + ); +}; diff --git a/x-pack/plugins/infra/public/components/alerting/shared/group_by_expression/group_by_expression.tsx b/x-pack/plugins/infra/public/alerting/common/group_by_expression/group_by_expression.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/alerting/shared/group_by_expression/group_by_expression.tsx rename to x-pack/plugins/infra/public/alerting/common/group_by_expression/group_by_expression.tsx diff --git a/x-pack/plugins/infra/public/components/alerting/shared/group_by_expression/selector.tsx b/x-pack/plugins/infra/public/alerting/common/group_by_expression/selector.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/alerting/shared/group_by_expression/selector.tsx rename to x-pack/plugins/infra/public/alerting/common/group_by_expression/selector.tsx diff --git a/x-pack/plugins/infra/public/components/alerting/logs/alert_dropdown.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/alerting/logs/alert_dropdown.tsx rename to x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx diff --git a/x-pack/plugins/infra/public/components/alerting/logs/alert_flyout.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_flyout.tsx similarity index 97% rename from x-pack/plugins/infra/public/components/alerting/logs/alert_flyout.tsx rename to x-pack/plugins/infra/public/alerting/log_threshold/components/alert_flyout.tsx index 45e4f8576892c..cd69fe02c5846 100644 --- a/x-pack/plugins/infra/public/components/alerting/logs/alert_flyout.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_flyout.tsx @@ -6,11 +6,10 @@ import React, { useContext } from 'react'; import { ApplicationStart, DocLinksStart, HttpStart, NotificationsStart } from 'src/core/public'; - import { AlertsContextProvider, AlertAdd } from '../../../../../triggers_actions_ui/public'; import { TriggerActionsContext } from '../../../utils/triggers_actions_context'; import { useKibana } from '../../../../../../../src/plugins/kibana_react/public'; -import { LOG_DOCUMENT_COUNT_ALERT_TYPE_ID } from '../../../../common/alerting/logs/types'; +import { LOG_DOCUMENT_COUNT_ALERT_TYPE_ID } from '../../../../common/alerting/logs/log_threshold/types'; interface Props { visible?: boolean; diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criteria.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criteria.tsx new file mode 100644 index 0000000000000..c35e7141efc9d --- /dev/null +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criteria.tsx @@ -0,0 +1,284 @@ +/* + * 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, { useCallback } from 'react'; +import { EuiFlexItem, EuiFlexGroup, EuiButtonEmpty, EuiAccordion, EuiSpacer } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { i18n } from '@kbn/i18n'; +import { IFieldType } from 'src/plugins/data/public'; +import { Criterion } from './criterion'; +import { + AlertParams, + Comparator, + Criteria as CriteriaType, + Criterion as CriterionType, + CountCriteria as CountCriteriaType, + RatioCriteria as RatioCriteriaType, + isRatioAlert, + getNumerator, + getDenominator, +} from '../../../../../common/alerting/logs/log_threshold/types'; +import { Errors, CriterionErrors } from '../../validation'; +import { AlertsContext, ExpressionLike } from './editor'; +import { CriterionPreview } from './criterion_preview_chart'; + +const DEFAULT_CRITERIA = { field: 'log.level', comparator: Comparator.EQ, value: 'error' }; + +const QueryAText = i18n.translate('xpack.infra.logs.alerting.threshold.ratioCriteriaQueryAText', { + defaultMessage: 'Query A', +}); + +const QueryBText = i18n.translate('xpack.infra.logs.alerting.threshold.ratioCriteriaQueryBText', { + defaultMessage: 'Query B', +}); + +interface SharedProps { + fields: IFieldType[]; + criteria?: AlertParams['criteria']; + errors: Errors['criteria']; + alertParams: Partial; + context: AlertsContext; + sourceId: string; + updateCriteria: (criteria: AlertParams['criteria']) => void; +} + +type CriteriaProps = SharedProps; + +export const Criteria: React.FC = (props) => { + const { criteria, errors } = props; + if (!criteria || criteria.length === 0) return null; + + return !isRatioAlert(criteria) ? ( + + ) : ( + + ); +}; + +interface CriteriaWrapperProps { + alertParams: SharedProps['alertParams']; + fields: SharedProps['fields']; + updateCriterion: (idx: number, params: Partial) => void; + removeCriterion: (idx: number) => void; + addCriterion: () => void; + criteria: CriteriaType; + errors: CriterionErrors; + context: SharedProps['context']; + sourceId: SharedProps['sourceId']; + isRatio?: boolean; +} + +const CriteriaWrapper: React.FC = (props) => { + const { + updateCriterion, + removeCriterion, + addCriterion, + criteria, + fields, + errors, + alertParams, + context, + sourceId, + isRatio = false, + } = props; + + return ( + + + {criteria.map((criterion, idx) => { + return ( + 1} + errors={errors[idx]} + /> + } + key={idx} + arrowDisplay="right" + > + + + ); + })} + + + + ); +}; + +interface RatioCriteriaProps { + alertParams: SharedProps['alertParams']; + fields: SharedProps['fields']; + criteria: RatioCriteriaType; + errors: Errors['criteria']; + context: SharedProps['context']; + sourceId: SharedProps['sourceId']; + updateCriteria: (criteria: AlertParams['criteria']) => void; +} + +const RatioCriteria: React.FC = (props) => { + const { criteria, errors, updateCriteria } = props; + + const handleUpdateNumeratorCriteria = useCallback( + (criteriaParam: CriteriaType) => { + const nextCriteria: RatioCriteriaType = [criteriaParam, getDenominator(criteria)]; + updateCriteria(nextCriteria); + }, + [updateCriteria, criteria] + ); + + const handleUpdateDenominatorCriteria = useCallback( + (criteriaParam: CriteriaType) => { + const nextCriteria: RatioCriteriaType = [getNumerator(criteria), criteriaParam]; + updateCriteria(nextCriteria); + }, + [updateCriteria, criteria] + ); + + const { + updateCriterion: updateNumeratorCriterion, + addCriterion: addNumeratorCriterion, + removeCriterion: removeNumeratorCriterion, + } = useCriteriaState(getNumerator(criteria), handleUpdateNumeratorCriteria); + + const { + updateCriterion: updateDenominatorCriterion, + addCriterion: addDenominatorCriterion, + removeCriterion: removeDenominatorCriterion, + } = useCriteriaState(getDenominator(criteria), handleUpdateDenominatorCriteria); + + return ( + <> + + + + + + + + + + + + + ); +}; + +interface CountCriteriaProps { + alertParams: SharedProps['alertParams']; + fields: SharedProps['fields']; + criteria: CountCriteriaType; + errors: Errors['criteria']; + context: SharedProps['context']; + sourceId: SharedProps['sourceId']; + updateCriteria: (criteria: AlertParams['criteria']) => void; +} + +const CountCriteria: React.FC = (props) => { + const { criteria, updateCriteria, errors } = props; + + const handleUpdateCriteria = useCallback( + (criteriaParam: CriteriaType) => { + updateCriteria(criteriaParam); + }, + [updateCriteria] + ); + + const { updateCriterion, addCriterion, removeCriterion } = useCriteriaState( + criteria, + handleUpdateCriteria + ); + + return ( + + ); +}; + +const useCriteriaState = ( + criteria: CriteriaType, + onUpdateCriteria: (criteria: CriteriaType) => void +) => { + const updateCriterion = useCallback( + (idx, criterionParams) => { + const nextCriteria = criteria.map((criterion, index) => { + return idx === index ? { ...criterion, ...criterionParams } : criterion; + }); + onUpdateCriteria(nextCriteria); + }, + [criteria, onUpdateCriteria] + ); + + const addCriterion = useCallback(() => { + const nextCriteria = criteria ? [...criteria, DEFAULT_CRITERIA] : [DEFAULT_CRITERIA]; + onUpdateCriteria(nextCriteria); + }, [criteria, onUpdateCriteria]); + + const removeCriterion = useCallback( + (idx) => { + const nextCriteria = criteria.filter((criterion, index) => { + return index !== idx; + }); + onUpdateCriteria(nextCriteria); + }, + [criteria, onUpdateCriteria] + ); + + return { updateCriterion, addCriterion, removeCriterion }; +}; + +const AddCriterionButton = ({ addCriterion }: { addCriterion: () => void }) => { + return ( +
+ + + +
+ ); +}; diff --git a/x-pack/plugins/infra/public/components/alerting/logs/expression_editor/criterion.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion.tsx similarity index 96% rename from x-pack/plugins/infra/public/components/alerting/logs/expression_editor/criterion.tsx rename to x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion.tsx index 9ee9373bd2c14..b2992ead3ea1b 100644 --- a/x-pack/plugins/infra/public/components/alerting/logs/expression_editor/criterion.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion.tsx @@ -18,6 +18,7 @@ import { EuiFormRow, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { isNumber, isFinite } from 'lodash'; import { IFieldType } from 'src/plugins/data/public'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { IErrorObject } from '../../../../../../triggers_actions_ui/public/types'; @@ -25,7 +26,7 @@ import { Comparator, Criterion as CriterionType, ComparatorToi18nMap, -} from '../../../../../common/alerting/logs/types'; +} from '../../../../../common/alerting/logs/log_threshold/types'; const firstCriterionFieldPrefix = i18n.translate( 'xpack.infra.logs.alertFlyout.firstCriterionFieldPrefix', @@ -239,8 +240,10 @@ export const Criterion: React.FC = ({ compressed value={criterion.value as number | undefined} onChange={(e) => { - const number = parseInt(e.target.value, 10); - updateCriterion(idx, { value: number ? number : undefined }); + const number = parseFloat(e.target.value); + updateCriterion(idx, { + value: isNumber(number) && isFinite(number) ? number : undefined, + }); }} /> ) : ( diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion_preview_chart.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion_preview_chart.tsx new file mode 100644 index 0000000000000..478d4b879a7e1 --- /dev/null +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion_preview_chart.tsx @@ -0,0 +1,336 @@ +/* + * 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, { useMemo } from 'react'; +import { useDebounce } from 'react-use'; +import { + ScaleType, + AnnotationDomainTypes, + Position, + Axis, + BarSeries, + Chart, + Settings, + RectAnnotation, + LineAnnotation, +} from '@elastic/charts'; +import { EuiText } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { + ChartContainer, + LoadingState, + NoDataState, + ErrorState, + TIME_LABELS, + getDomain, + tooltipProps, + useDateFormatter, + getChartTheme, + yAxisFormatter, + NUM_BUCKETS, +} from '../../../common/criterion_preview_chart/criterion_preview_chart'; +import { + AlertParams, + Threshold, + Criterion, + Comparator, +} from '../../../../../common/alerting/logs/log_threshold/types'; +import { Color, colorTransformer } from '../../../../../common/color_palette'; +import { + GetLogAlertsChartPreviewDataAlertParamsSubset, + getLogAlertsChartPreviewDataAlertParamsSubsetRT, +} from '../../../../../common/http_api/log_alerts/'; +import { AlertsContext } from './editor'; +import { useChartPreviewData } from './hooks/use_chart_preview_data'; +import { decodeOrThrow } from '../../../../../common/runtime_types'; + +const GROUP_LIMIT = 5; + +interface Props { + alertParams: Partial; + context: AlertsContext; + chartCriterion: Partial; + sourceId: string; + showThreshold: boolean; +} + +export const CriterionPreview: React.FC = ({ + alertParams, + context, + chartCriterion, + sourceId, + showThreshold, +}) => { + const chartAlertParams: GetLogAlertsChartPreviewDataAlertParamsSubset | null = useMemo(() => { + const { field, comparator, value } = chartCriterion; + const criteria = field && comparator && value ? [{ field, comparator, value }] : []; + const params = { + criteria, + timeSize: alertParams.timeSize, + timeUnit: alertParams.timeUnit, + groupBy: alertParams.groupBy, + }; + + try { + return decodeOrThrow(getLogAlertsChartPreviewDataAlertParamsSubsetRT)(params); + } catch (error) { + return null; + } + }, [alertParams.timeSize, alertParams.timeUnit, alertParams.groupBy, chartCriterion]); + + // Check for the existence of properties that are necessary for a meaningful chart. + if (chartAlertParams === null || chartAlertParams.criteria.length === 0) return null; + + return ( + + ); +}; + +interface ChartProps { + buckets: number; + context: AlertsContext; + sourceId: string; + threshold?: Threshold; + chartAlertParams: GetLogAlertsChartPreviewDataAlertParamsSubset; + showThreshold: boolean; +} + +const CriterionPreviewChart: React.FC = ({ + buckets, + context, + sourceId, + threshold, + chartAlertParams, + showThreshold, +}) => { + const isDarkMode = context.uiSettings?.get('theme:darkMode') || false; + + const { + getChartPreviewData, + isLoading, + hasError, + chartPreviewData: series, + } = useChartPreviewData({ + context, + sourceId, + alertParams: chartAlertParams, + buckets, + }); + + useDebounce( + () => { + getChartPreviewData(); + }, + 500, + [getChartPreviewData] + ); + + const isStacked = false; + + const { timeSize, timeUnit, groupBy } = chartAlertParams; + + const isGrouped = groupBy && groupBy.length > 0 ? true : false; + + const isAbove = + showThreshold && threshold && threshold.comparator + ? [Comparator.GT, Comparator.GT_OR_EQ].includes(threshold.comparator) + : false; + + const isBelow = + showThreshold && threshold && threshold.comparator + ? [Comparator.LT, Comparator.LT_OR_EQ].includes(threshold.comparator) + : false; + + // For grouped scenarios we want to limit the groups displayed, for "isAbove" thresholds we'll show + // groups with the highest doc counts. And for "isBelow" thresholds we'll show groups with the lowest doc counts. + // Ratio scenarios will just default to max. + const filteredSeries = useMemo(() => { + if (!isGrouped) { + return series; + } + + const sortedByMax = series.sort((a, b) => { + const aMax = Math.max(...a.points.map((point) => point.value)); + const bMax = Math.max(...b.points.map((point) => point.value)); + return bMax - aMax; + }); + const sortedSeries = (!isAbove && !isBelow) || isAbove ? sortedByMax : sortedByMax.reverse(); + return sortedSeries.slice(0, GROUP_LIMIT); + }, [series, isGrouped, isAbove, isBelow]); + + const barSeries = useMemo(() => { + return filteredSeries.reduce>( + (acc, serie) => { + const barPoints = serie.points.reduce< + Array<{ timestamp: number; value: number; groupBy: string }> + >((pointAcc, point) => { + return [...pointAcc, { ...point, groupBy: serie.id }]; + }, []); + return [...acc, ...barPoints]; + }, + [] + ); + }, [filteredSeries]); + + const lookback = timeSize * buckets; + const hasData = series.length > 0; + const { yMin, yMax, xMin, xMax } = getDomain(filteredSeries, isStacked); + const chartDomain = { + max: + showThreshold && threshold && threshold.value + ? Math.max(yMax, threshold.value) * 1.1 + : yMax * 1.1, // Add 10% headroom. + min: showThreshold && threshold && threshold.value ? Math.min(yMin, threshold.value) : yMin, + }; + + if (showThreshold && threshold && threshold.value && chartDomain.min === threshold.value) { + chartDomain.min = chartDomain.min * 0.9; // Allow some padding so the threshold annotation has better visibility + } + + const THRESHOLD_OPACITY = 0.3; + const groupByLabel = groupBy && groupBy.length > 0 ? groupBy.join(', ') : null; + const dateFormatter = useDateFormatter(xMin, xMax); + const timeLabel = TIME_LABELS[timeUnit as keyof typeof TIME_LABELS]; + + if (isLoading) { + return ; + } else if (hasError) { + return ; + } else if (!hasData) { + return ; + } + + return ( + <> + + + + {showThreshold && threshold && threshold.value ? ( + + ) : null} + {showThreshold && threshold && threshold.value && isBelow ? ( + + ) : null} + {showThreshold && threshold && threshold.value && isAbove ? ( + + ) : null} + + + + + +
+ {groupByLabel != null ? ( + + + + ) : ( + + + + )} +
+ + ); +}; diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx new file mode 100644 index 0000000000000..c5b0ed5844852 --- /dev/null +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx @@ -0,0 +1,285 @@ +/* + * 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, { useCallback, useMemo, useState } from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiLoadingSpinner, EuiSpacer, EuiButton, EuiCallOut } from '@elastic/eui'; +import { useMount } from 'react-use'; +import { GroupByExpression } from '../../../common/group_by_expression/group_by_expression'; +import { + ForLastExpression, + AlertsContextValue, +} from '../../../../../../triggers_actions_ui/public'; +import { + AlertParams, + Comparator, + ThresholdType, + isRatioAlert, +} from '../../../../../common/alerting/logs/log_threshold/types'; +import { Threshold } from './threshold'; +import { Criteria } from './criteria'; +import { TypeSwitcher } from './type_switcher'; +import { useSourceId } from '../../../../containers/source_id'; +import { LogSourceProvider, useLogSourceContext } from '../../../../containers/logs/log_source'; +import { Errors } from '../../validation'; + +export interface ExpressionCriteria { + field?: string; + comparator?: Comparator; + value?: string | number; +} + +interface LogsContextMeta { + isInternal?: boolean; +} + +export type AlertsContext = AlertsContextValue; +interface Props { + errors: Errors; + alertParams: Partial; + setAlertParams(key: string, value: any): void; + setAlertProperty(key: string, value: any): void; + alertsContext: AlertsContext; + sourceId: string; +} + +const DEFAULT_CRITERIA = { field: 'log.level', comparator: Comparator.EQ, value: 'error' }; + +const DEFAULT_BASE_EXPRESSION = { + timeSize: 5, + timeUnit: 'm', +}; + +const DEFAULT_COUNT_EXPRESSION = { + ...DEFAULT_BASE_EXPRESSION, + count: { + value: 75, + comparator: Comparator.GT, + }, + criteria: [DEFAULT_CRITERIA], +}; + +const DEFAULT_RATIO_EXPRESSION = { + ...DEFAULT_BASE_EXPRESSION, + count: { + value: 2, + comparator: Comparator.GT, + }, + criteria: [ + [DEFAULT_CRITERIA], + [{ field: 'log.level', comparator: Comparator.EQ, value: 'warning' }], + ], +}; + +export const ExpressionEditor: React.FC = (props) => { + const isInternal = props.alertsContext.metadata?.isInternal; + const [sourceId] = useSourceId(); + + return ( + <> + {isInternal ? ( + + + + ) : ( + + + + + + )} + + ); +}; + +export const SourceStatusWrapper: React.FC = (props) => { + const { + initialize, + isLoadingSourceStatus, + isUninitialized, + hasFailedLoadingSourceStatus, + loadSourceStatus, + } = useLogSourceContext(); + const { children } = props; + + useMount(() => { + initialize(); + }); + + return ( + <> + {isLoadingSourceStatus || isUninitialized ? ( +
+ + + +
+ ) : hasFailedLoadingSourceStatus ? ( + + + {i18n.translate('xpack.infra.logs.alertFlyout.sourceStatusErrorTryAgain', { + defaultMessage: 'Try again', + })} + + + ) : ( + children + )} + + ); +}; + +export const Editor: React.FC = (props) => { + const { setAlertParams, alertParams, errors, alertsContext, sourceId } = props; + const [hasSetDefaults, setHasSetDefaults] = useState(false); + const { sourceStatus } = useLogSourceContext(); + useMount(() => { + for (const [key, value] of Object.entries({ ...DEFAULT_COUNT_EXPRESSION, ...alertParams })) { + setAlertParams(key, value); + } + setHasSetDefaults(true); + }); + + const supportedFields = useMemo(() => { + if (sourceStatus?.logIndexFields) { + return sourceStatus.logIndexFields.filter((field) => { + return (field.type === 'string' || field.type === 'number') && field.searchable; + }); + } else { + return []; + } + /* eslint-disable-next-line react-hooks/exhaustive-deps */ + }, [sourceStatus]); + + const groupByFields = useMemo(() => { + if (sourceStatus?.logIndexFields) { + return sourceStatus.logIndexFields.filter((field) => { + return field.type === 'string' && field.aggregatable; + }); + } else { + return []; + } + /* eslint-disable-next-line react-hooks/exhaustive-deps */ + }, [sourceStatus]); + + const updateThreshold = useCallback( + (thresholdParams) => { + const nextThresholdParams = { ...alertParams.count, ...thresholdParams }; + setAlertParams('count', nextThresholdParams); + }, + [alertParams.count, setAlertParams] + ); + + const updateCriteria = useCallback( + (criteria: AlertParams['criteria']) => { + setAlertParams('criteria', criteria); + }, + [setAlertParams] + ); + + const updateTimeSize = useCallback( + (ts: number | undefined) => { + setAlertParams('timeSize', ts); + }, + [setAlertParams] + ); + + const updateTimeUnit = useCallback( + (tu: string) => { + setAlertParams('timeUnit', tu); + }, + [setAlertParams] + ); + + const updateGroupBy = useCallback( + (groups: string[]) => { + setAlertParams('groupBy', groups); + }, + [setAlertParams] + ); + + const updateType = useCallback( + (type: ThresholdType) => { + const defaults = type === 'count' ? DEFAULT_COUNT_EXPRESSION : DEFAULT_RATIO_EXPRESSION; + // Reset properties that don't make sense switching from one context to the other + for (const [key, value] of Object.entries({ + criteria: defaults.criteria, + count: defaults.count, + })) { + setAlertParams(key, value); + } + }, + [setAlertParams] + ); + + // Wait until the alert param defaults have been set + if (!hasSetDefaults) return null; + + const criteriaComponent = alertParams.criteria ? ( + + ) : null; + + return ( + <> + + + {alertParams.criteria && !isRatioAlert(alertParams.criteria) && criteriaComponent} + + + + + + + + {alertParams.criteria && isRatioAlert(alertParams.criteria) && criteriaComponent} + + + + ); +}; + +// required for dynamic import +// eslint-disable-next-line import/no-default-export +export default ExpressionEditor; + +// NOTE: Temporary until EUI allow empty values in EuiExpression +// components. +export const ExpressionLike = ({ text }: { text: string }) => { + return ( +
+ {text} +
+ ); +}; diff --git a/x-pack/plugins/infra/public/components/alerting/logs/expression_editor/hooks/use_chart_preview_data.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/hooks/use_chart_preview_data.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/alerting/logs/expression_editor/hooks/use_chart_preview_data.tsx rename to x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/hooks/use_chart_preview_data.tsx diff --git a/x-pack/plugins/infra/public/components/alerting/logs/expression_editor/index.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/index.tsx similarity index 100% rename from x-pack/plugins/infra/public/components/alerting/logs/expression_editor/index.tsx rename to x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/index.tsx diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/threshold.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/threshold.tsx new file mode 100644 index 0000000000000..da0c987bac85f --- /dev/null +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/threshold.tsx @@ -0,0 +1,111 @@ +/* + * 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, { useState } from 'react'; +import { i18n } from '@kbn/i18n'; +import { isNumber, isFinite } from 'lodash'; +import { + EuiPopoverTitle, + EuiFlexItem, + EuiFlexGroup, + EuiPopover, + EuiSelect, + EuiFieldNumber, + EuiExpression, + EuiFormRow, +} from '@elastic/eui'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { IErrorObject } from '../../../../../../triggers_actions_ui/public/types'; +import { + Comparator, + ComparatorToi18nMap, + AlertParams, +} from '../../../../../common/alerting/logs/log_threshold/types'; + +const thresholdPrefix = i18n.translate('xpack.infra.logs.alertFlyout.thresholdPrefix', { + defaultMessage: 'is', +}); + +const popoverTitle = i18n.translate('xpack.infra.logs.alertFlyout.thresholdPopoverTitle', { + defaultMessage: 'Threshold', +}); + +const getComparatorOptions = (): Array<{ + value: Comparator; + text: string; +}> => { + return [ + { value: Comparator.LT, text: ComparatorToi18nMap[Comparator.LT] }, + { value: Comparator.LT_OR_EQ, text: ComparatorToi18nMap[Comparator.LT_OR_EQ] }, + { value: Comparator.GT, text: ComparatorToi18nMap[Comparator.GT] }, + { value: Comparator.GT_OR_EQ, text: ComparatorToi18nMap[Comparator.GT_OR_EQ] }, + ]; +}; + +interface Props { + comparator?: Comparator; + value?: number; + updateThreshold: (params: Partial) => void; + errors: IErrorObject; +} + +export const Threshold: React.FC = ({ comparator, value, updateThreshold, errors }) => { + const [isThresholdPopoverOpen, setThresholdPopoverOpenState] = useState(false); + + return ( + + + setThresholdPopoverOpenState(true)} + /> + } + isOpen={isThresholdPopoverOpen} + closePopover={() => setThresholdPopoverOpenState(false)} + ownFocus + panelPaddingSize="s" + anchorPosition="downLeft" + > + <> + {popoverTitle} + + + + updateThreshold({ comparator: e.target.value as Comparator })} + options={getComparatorOptions()} + /> + + + + 0} error={errors.value}> + { + const number = parseFloat(e.target.value); + updateThreshold({ + value: isNumber(number) && isFinite(number) ? number : undefined, + }); + }} + /> + + + + + + + + ); +}; diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/type_switcher.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/type_switcher.tsx new file mode 100644 index 0000000000000..5f5078f8aa6e1 --- /dev/null +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/type_switcher.tsx @@ -0,0 +1,101 @@ +/* + * 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, { useState } from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiFlexItem, EuiFlexGroup, EuiPopover, EuiSelect, EuiExpression } from '@elastic/eui'; +import { + AlertParams, + ThresholdType, + isRatioAlert, +} from '../../../../../common/alerting/logs/log_threshold/types'; +import { ExpressionLike } from './editor'; + +const typePrefix = i18n.translate('xpack.infra.logs.alertFlyout.thresholdTypePrefix', { + defaultMessage: 'when the', +}); + +const countSuffix = i18n.translate('xpack.infra.logs.alertFlyout.thresholdTypeCountSuffix', { + defaultMessage: 'of log entries', +}); + +const ratioSuffix = i18n.translate('xpack.infra.logs.alertFlyout.thresholdTypeRatioSuffix', { + defaultMessage: 'of Query A to Query B', +}); + +const countI18n = i18n.translate('xpack.infra.logs.alertFlyout.thresholdTypeCount', { + defaultMessage: 'count', +}); + +const ratioI18n = i18n.translate('xpack.infra.logs.alertFlyout.thresholdTypeRatio', { + defaultMessage: 'ratio', +}); + +const getOptions = (): Array<{ + value: ThresholdType; + text: string; +}> => { + return [ + { value: 'ratio', text: ratioI18n }, + { value: 'count', text: countI18n }, + ]; +}; + +interface Props { + criteria: AlertParams['criteria']; + updateType: (type: ThresholdType) => void; +} + +const getThresholdType = (criteria: AlertParams['criteria']): ThresholdType => { + return isRatioAlert(criteria) ? 'ratio' : 'count'; +}; + +export const TypeSwitcher: React.FC = ({ criteria, updateType }) => { + const [isThresholdTypePopoverOpen, setThresholdTypePopoverOpenState] = useState(false); + const thresholdType = getThresholdType(criteria); + + return ( + + + + setThresholdTypePopoverOpenState(true)} + /> + + + } + isOpen={isThresholdTypePopoverOpen} + closePopover={() => setThresholdTypePopoverOpenState(false)} + ownFocus + panelPaddingSize="s" + anchorPosition="downLeft" + > + + + updateType(thresholdType === 'ratio' ? 'count' : 'ratio')} + options={getOptions()} + /> + + + + + + ); +}; diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/index.ts b/x-pack/plugins/infra/public/alerting/log_threshold/index.ts new file mode 100644 index 0000000000000..0974d00c4dffb --- /dev/null +++ b/x-pack/plugins/infra/public/alerting/log_threshold/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export { getAlertType } from './log_threshold_alert_type'; +export { AlertDropdown } from './components/alert_dropdown'; diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/log_threshold_alert_type.ts b/x-pack/plugins/infra/public/alerting/log_threshold/log_threshold_alert_type.ts new file mode 100644 index 0000000000000..29a58fc95f2be --- /dev/null +++ b/x-pack/plugins/infra/public/alerting/log_threshold/log_threshold_alert_type.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { i18n } from '@kbn/i18n'; +import React from 'react'; +import { AlertTypeModel } from '../../../../triggers_actions_ui/public'; +import { LOG_DOCUMENT_COUNT_ALERT_TYPE_ID } from '../../../common/alerting/logs/log_threshold/types'; +import { validateExpression } from './validation'; + +export function getAlertType(): AlertTypeModel { + return { + id: LOG_DOCUMENT_COUNT_ALERT_TYPE_ID, + name: i18n.translate('xpack.infra.logs.alertFlyout.alertName', { + defaultMessage: 'Log threshold', + }), + iconClass: 'bell', + alertParamsExpression: React.lazy(() => import('./components/expression_editor/editor')), + validate: validateExpression, + defaultActionMessage: i18n.translate( + 'xpack.infra.logs.alerting.threshold.defaultActionMessage', + { + defaultMessage: `\\{\\{^context.isRatio\\}\\}\\{\\{#context.group\\}\\}\\{\\{context.group\\}\\} - \\{\\{/context.group\\}\\}\\{\\{context.matchingDocuments\\}\\} log entries have matched the following conditions: \\{\\{context.conditions\\}\\}\\{\\{/context.isRatio\\}\\}\\{\\{#context.isRatio\\}\\}\\{\\{#context.group\\}\\}\\{\\{context.group\\}\\} - \\{\\{/context.group\\}\\} Ratio of the count of log entries matching \\{\\{context.numeratorConditions\\}\\} to the count of log entries matching \\{\\{context.denominatorConditions\\}\\} was \\{\\{context.ratio\\}\\}\\{\\{/context.isRatio\\}\\}`, + } + ), + requiresAppContext: false, + }; +} diff --git a/x-pack/plugins/infra/public/alerting/log_threshold/validation.ts b/x-pack/plugins/infra/public/alerting/log_threshold/validation.ts new file mode 100644 index 0000000000000..6630b3d079141 --- /dev/null +++ b/x-pack/plugins/infra/public/alerting/log_threshold/validation.ts @@ -0,0 +1,128 @@ +/* + * 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 { isNumber, isFinite } from 'lodash'; +import { ValidationResult } from '../../../../triggers_actions_ui/public'; +import { + AlertParams, + Criteria, + RatioCriteria, + isRatioAlert, + getNumerator, + getDenominator, +} from '../../../common/alerting/logs/log_threshold/types'; + +export interface CriterionErrors { + [id: string]: { + field: string[]; + comparator: string[]; + value: string[]; + }; +} + +export interface Errors { + threshold: { + value: string[]; + }; + // NOTE: The data structure for criteria errors isn't 100% + // ideal but we need to conform to the interfaces that the alerting + // framework expects. + criteria: { + [id: string]: CriterionErrors; + }; + timeWindowSize: string[]; + timeSizeUnit: string[]; +} + +export function validateExpression({ + count, + criteria, + timeSize, + timeUnit, +}: Partial): ValidationResult { + const validationResult = { errors: {} }; + + // NOTE: In the case of components provided by the Alerting framework the error property names + // must match what they expect. + const errors: Errors = { + threshold: { + value: [], + }, + criteria: {}, + timeSizeUnit: [], + timeWindowSize: [], + }; + + validationResult.errors = errors; + + // Threshold validation + if (!isNumber(count?.value) && !isFinite(count?.value)) { + errors.threshold.value.push( + i18n.translate('xpack.infra.logs.alertFlyout.error.thresholdRequired', { + defaultMessage: 'Numeric threshold value is Required.', + }) + ); + } + + // Time validation + if (!timeSize) { + errors.timeWindowSize.push( + i18n.translate('xpack.infra.logs.alertFlyout.error.timeSizeRequired', { + defaultMessage: 'Time size is Required.', + }) + ); + } + + // Criteria validation + if (criteria && criteria.length > 0) { + const getCriterionErrors = (_criteria: Criteria): CriterionErrors => { + const _errors: CriterionErrors = {}; + + _criteria.forEach((criterion, idx) => { + _errors[idx] = { + field: [], + comparator: [], + value: [], + }; + if (!criterion.field) { + _errors[idx].field.push( + i18n.translate('xpack.infra.logs.alertFlyout.error.criterionFieldRequired', { + defaultMessage: 'Field is required.', + }) + ); + } + if (!criterion.comparator) { + _errors[idx].comparator.push( + i18n.translate('xpack.infra.logs.alertFlyout.error.criterionComparatorRequired', { + defaultMessage: 'Comparator is required.', + }) + ); + } + if (criterion.value === undefined || criterion.value === null) { + _errors[idx].value.push( + i18n.translate('xpack.infra.logs.alertFlyout.error.criterionValueRequired', { + defaultMessage: 'Value is required.', + }) + ); + } + }); + return _errors; + }; + + if (!isRatioAlert(criteria)) { + const criteriaErrors = getCriterionErrors(criteria as Criteria); + errors.criteria[0] = criteriaErrors; + } else { + const numeratorErrors = getCriterionErrors(getNumerator(criteria as RatioCriteria)); + errors.criteria[0] = numeratorErrors; + const denominatorErrors = getCriterionErrors(getDenominator(criteria as RatioCriteria)); + errors.criteria[1] = denominatorErrors; + } + } + + return validationResult; +} diff --git a/x-pack/plugins/infra/public/components/alerting/logs/expression_editor/criteria.tsx b/x-pack/plugins/infra/public/components/alerting/logs/expression_editor/criteria.tsx deleted file mode 100644 index 627ea2bbef429..0000000000000 --- a/x-pack/plugins/infra/public/components/alerting/logs/expression_editor/criteria.tsx +++ /dev/null @@ -1,75 +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 { EuiFlexItem, EuiFlexGroup, EuiAccordion } from '@elastic/eui'; -import { IFieldType } from 'src/plugins/data/public'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { IErrorObject } from '../../../../../../triggers_actions_ui/public/types'; -import { Criterion } from './criterion'; -import { - LogDocumentCountAlertParams, - Criterion as CriterionType, -} from '../../../../../common/alerting/logs/types'; -import { AlertsContext } from './editor'; -import { CriterionPreview } from './criterion_preview_chart'; - -interface Props { - fields: IFieldType[]; - criteria?: LogDocumentCountAlertParams['criteria']; - updateCriterion: (idx: number, params: Partial) => void; - removeCriterion: (idx: number) => void; - errors: IErrorObject; - alertParams: Partial; - context: AlertsContext; - sourceId: string; -} - -export const Criteria: React.FC = ({ - fields, - criteria, - updateCriterion, - removeCriterion, - errors, - alertParams, - context, - sourceId, -}) => { - if (!criteria) return null; - return ( - - - {criteria.map((criterion, idx) => { - return ( - 1} - errors={errors[idx.toString()] as IErrorObject} - /> - } - key={idx} - arrowDisplay="right" - > - - - ); - })} - - - ); -}; diff --git a/x-pack/plugins/infra/public/components/alerting/logs/expression_editor/criterion_preview_chart.tsx b/x-pack/plugins/infra/public/components/alerting/logs/expression_editor/criterion_preview_chart.tsx deleted file mode 100644 index 31f9a64015c07..0000000000000 --- a/x-pack/plugins/infra/public/components/alerting/logs/expression_editor/criterion_preview_chart.tsx +++ /dev/null @@ -1,326 +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, { useMemo } from 'react'; -import { useDebounce } from 'react-use'; -import { - ScaleType, - AnnotationDomainTypes, - Position, - Axis, - BarSeries, - Chart, - Settings, - RectAnnotation, - LineAnnotation, -} from '@elastic/charts'; -import { EuiText } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { - ChartContainer, - LoadingState, - NoDataState, - ErrorState, - TIME_LABELS, - getDomain, - tooltipProps, - useDateFormatter, - getChartTheme, - yAxisFormatter, - NUM_BUCKETS, -} from '../../shared/criterion_preview_chart/criterion_preview_chart'; -import { - LogDocumentCountAlertParams, - Criterion, - Comparator, -} from '../../../../../common/alerting/logs/types'; -import { Color, colorTransformer } from '../../../../../common/color_palette'; -import { - GetLogAlertsChartPreviewDataAlertParamsSubset, - getLogAlertsChartPreviewDataAlertParamsSubsetRT, -} from '../../../../../common/http_api/log_alerts/'; -import { AlertsContext } from './editor'; -import { useChartPreviewData } from './hooks/use_chart_preview_data'; -import { decodeOrThrow } from '../../../../../common/runtime_types'; - -const GROUP_LIMIT = 5; - -interface Props { - alertParams: Partial; - context: AlertsContext; - chartCriterion: Partial; - sourceId: string; -} - -export const CriterionPreview: React.FC = ({ - alertParams, - context, - chartCriterion, - sourceId, -}) => { - const chartAlertParams: GetLogAlertsChartPreviewDataAlertParamsSubset | null = useMemo(() => { - const { field, comparator, value } = chartCriterion; - const criteria = field && comparator && value ? [{ field, comparator, value }] : []; - const params = { - criteria, - timeSize: alertParams.timeSize, - timeUnit: alertParams.timeUnit, - groupBy: alertParams.groupBy, - }; - - try { - return decodeOrThrow(getLogAlertsChartPreviewDataAlertParamsSubsetRT)(params); - } catch (error) { - return null; - } - }, [alertParams.timeSize, alertParams.timeUnit, alertParams.groupBy, chartCriterion]); - - // Check for the existence of properties that are necessary for a meaningful chart. - if (chartAlertParams === null || chartAlertParams.criteria.length === 0) return null; - - return ( - - ); -}; - -interface ChartProps { - buckets: number; - context: AlertsContext; - sourceId: string; - threshold?: LogDocumentCountAlertParams['count']; - chartAlertParams: GetLogAlertsChartPreviewDataAlertParamsSubset; -} - -const CriterionPreviewChart: React.FC = ({ - buckets, - context, - sourceId, - threshold, - chartAlertParams, -}) => { - const isDarkMode = context.uiSettings?.get('theme:darkMode') || false; - - const { - getChartPreviewData, - isLoading, - hasError, - chartPreviewData: series, - } = useChartPreviewData({ - context, - sourceId, - alertParams: chartAlertParams, - buckets, - }); - - useDebounce( - () => { - getChartPreviewData(); - }, - 500, - [getChartPreviewData] - ); - - const isStacked = false; - - const { timeSize, timeUnit, groupBy } = chartAlertParams; - - const isGrouped = groupBy && groupBy.length > 0 ? true : false; - - const isAbove = - threshold && threshold.comparator - ? [Comparator.GT, Comparator.GT_OR_EQ].includes(threshold.comparator) - : false; - - const isBelow = - threshold && threshold.comparator - ? [Comparator.LT, Comparator.LT_OR_EQ].includes(threshold.comparator) - : false; - - // For grouped scenarios we want to limit the groups displayed, for "isAbove" thresholds we'll show - // groups with the highest doc counts. And for "isBelow" thresholds we'll show groups with the lowest doc counts. - const filteredSeries = useMemo(() => { - if (!isGrouped) { - return series; - } - - const sortedByMax = series.sort((a, b) => { - const aMax = Math.max(...a.points.map((point) => point.value)); - const bMax = Math.max(...b.points.map((point) => point.value)); - return bMax - aMax; - }); - const sortedSeries = (!isAbove && !isBelow) || isAbove ? sortedByMax : sortedByMax.reverse(); - return sortedSeries.slice(0, GROUP_LIMIT); - }, [series, isGrouped, isAbove, isBelow]); - - const barSeries = useMemo(() => { - return filteredSeries.reduce>( - (acc, serie) => { - const barPoints = serie.points.reduce< - Array<{ timestamp: number; value: number; groupBy: string }> - >((pointAcc, point) => { - return [...pointAcc, { ...point, groupBy: serie.id }]; - }, []); - return [...acc, ...barPoints]; - }, - [] - ); - }, [filteredSeries]); - - const lookback = timeSize * buckets; - const hasData = series.length > 0; - const { yMin, yMax, xMin, xMax } = getDomain(filteredSeries, isStacked); - const chartDomain = { - max: threshold && threshold.value ? Math.max(yMax, threshold.value) * 1.1 : yMax * 1.1, // Add 10% headroom. - min: threshold && threshold.value ? Math.min(yMin, threshold.value) : yMin, - }; - - if (threshold && threshold.value && chartDomain.min === threshold.value) { - chartDomain.min = chartDomain.min * 0.9; // Allow some padding so the threshold annotation has better visibility - } - - const THRESHOLD_OPACITY = 0.3; - const groupByLabel = groupBy && groupBy.length > 0 ? groupBy.join(', ') : null; - const dateFormatter = useDateFormatter(xMin, xMax); - const timeLabel = TIME_LABELS[timeUnit as keyof typeof TIME_LABELS]; - - if (isLoading) { - return ; - } else if (hasError) { - return ; - } else if (!hasData) { - return ; - } - - return ( - <> - - - - {threshold && threshold.value ? ( - - ) : null} - {threshold && threshold.value && isBelow ? ( - - ) : null} - {threshold && threshold.value && isAbove ? ( - - ) : null} - - - - - -
- {groupByLabel != null ? ( - - - - ) : ( - - - - )} -
- - ); -}; diff --git a/x-pack/plugins/infra/public/components/alerting/logs/expression_editor/document_count.tsx b/x-pack/plugins/infra/public/components/alerting/logs/expression_editor/document_count.tsx deleted file mode 100644 index ff6a8e7e55fd6..0000000000000 --- a/x-pack/plugins/infra/public/components/alerting/logs/expression_editor/document_count.tsx +++ /dev/null @@ -1,136 +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, { useState } from 'react'; -import { i18n } from '@kbn/i18n'; -import { - EuiPopoverTitle, - EuiFlexItem, - EuiFlexGroup, - EuiPopover, - EuiSelect, - EuiFieldNumber, - EuiExpression, - EuiFormRow, -} from '@elastic/eui'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { IErrorObject } from '../../../../../../triggers_actions_ui/public/types'; -import { - Comparator, - ComparatorToi18nMap, - LogDocumentCountAlertParams, -} from '../../../../../common/alerting/logs/types'; - -const documentCountPrefix = i18n.translate('xpack.infra.logs.alertFlyout.documentCountPrefix', { - defaultMessage: 'when', -}); - -const getComparatorOptions = (): Array<{ - value: Comparator; - text: string; -}> => { - return [ - { value: Comparator.LT, text: ComparatorToi18nMap[Comparator.LT] }, - { value: Comparator.LT_OR_EQ, text: ComparatorToi18nMap[Comparator.LT_OR_EQ] }, - { value: Comparator.GT, text: ComparatorToi18nMap[Comparator.GT] }, - { value: Comparator.GT_OR_EQ, text: ComparatorToi18nMap[Comparator.GT_OR_EQ] }, - ]; -}; - -interface Props { - comparator?: Comparator; - value?: number; - updateCount: (params: Partial) => void; - errors: IErrorObject; -} - -export const DocumentCount: React.FC = ({ comparator, value, updateCount, errors }) => { - const [isComparatorPopoverOpen, setComparatorPopoverOpenState] = useState(false); - const [isValuePopoverOpen, setIsValuePopoverOpen] = useState(false); - - const documentCountValue = i18n.translate('xpack.infra.logs.alertFlyout.documentCountValue', { - defaultMessage: '{value, plural, one {log entry} other {log entries}}', - values: { value }, - }); - - const documentCountSuffix = i18n.translate('xpack.infra.logs.alertFlyout.documentCountSuffix', { - defaultMessage: '{value, plural, one {occurs} other {occur}}', - values: { value }, - }); - - return ( - - - setComparatorPopoverOpenState(true)} - /> - } - isOpen={isComparatorPopoverOpen} - closePopover={() => setComparatorPopoverOpenState(false)} - ownFocus - panelPaddingSize="s" - anchorPosition="downLeft" - > -
- {documentCountPrefix} - updateCount({ comparator: e.target.value as Comparator })} - options={getComparatorOptions()} - /> -
-
-
- - - setIsValuePopoverOpen(true)} - color={errors.value.length === 0 ? 'secondary' : 'danger'} - /> - } - isOpen={isValuePopoverOpen} - closePopover={() => setIsValuePopoverOpen(false)} - ownFocus - panelPaddingSize="s" - anchorPosition="downLeft" - > -
- {documentCountValue} - 0} error={errors.value}> - { - const number = parseInt(e.target.value, 10); - updateCount({ value: number ? number : undefined }); - }} - /> - -
-
-
- - - - -
- ); -}; diff --git a/x-pack/plugins/infra/public/components/alerting/logs/expression_editor/editor.tsx b/x-pack/plugins/infra/public/components/alerting/logs/expression_editor/editor.tsx deleted file mode 100644 index e063b880ab843..0000000000000 --- a/x-pack/plugins/infra/public/components/alerting/logs/expression_editor/editor.tsx +++ /dev/null @@ -1,271 +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, { useCallback, useMemo, useState } from 'react'; -import { i18n } from '@kbn/i18n'; -import { EuiButtonEmpty, EuiLoadingSpinner, EuiSpacer, EuiButton, EuiCallOut } from '@elastic/eui'; -import { useMount } from 'react-use'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { - ForLastExpression, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../../../triggers_actions_ui/public/common'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { IErrorObject } from '../../../../../../triggers_actions_ui/public/types'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { AlertsContextValue } from '../../../../../../triggers_actions_ui/public/application/context/alerts_context'; -import { LogDocumentCountAlertParams, Comparator } from '../../../../../common/alerting/logs/types'; -import { DocumentCount } from './document_count'; -import { Criteria } from './criteria'; -import { useSourceId } from '../../../../containers/source_id'; -import { LogSourceProvider, useLogSourceContext } from '../../../../containers/logs/log_source'; -import { GroupByExpression } from '../../shared/group_by_expression/group_by_expression'; - -export interface ExpressionCriteria { - field?: string; - comparator?: Comparator; - value?: string | number; -} - -interface LogsContextMeta { - isInternal?: boolean; -} - -export type AlertsContext = AlertsContextValue; -interface Props { - errors: IErrorObject; - alertParams: Partial; - setAlertParams(key: string, value: any): void; - setAlertProperty(key: string, value: any): void; - alertsContext: AlertsContext; - sourceId: string; -} - -const DEFAULT_CRITERIA = { field: 'log.level', comparator: Comparator.EQ, value: 'error' }; - -const DEFAULT_EXPRESSION = { - count: { - value: 75, - comparator: Comparator.GT, - }, - criteria: [DEFAULT_CRITERIA], - timeSize: 5, - timeUnit: 'm', -}; - -export const ExpressionEditor: React.FC = (props) => { - const isInternal = props.alertsContext.metadata?.isInternal; - const [sourceId] = useSourceId(); - - return ( - <> - {isInternal ? ( - - - - ) : ( - - - - - - )} - - ); -}; - -export const SourceStatusWrapper: React.FC = (props) => { - const { - initialize, - isLoadingSourceStatus, - isUninitialized, - hasFailedLoadingSourceStatus, - loadSourceStatus, - } = useLogSourceContext(); - const { children } = props; - - useMount(() => { - initialize(); - }); - - return ( - <> - {isLoadingSourceStatus || isUninitialized ? ( -
- - - -
- ) : hasFailedLoadingSourceStatus ? ( - - - {i18n.translate('xpack.infra.logs.alertFlyout.sourceStatusErrorTryAgain', { - defaultMessage: 'Try again', - })} - - - ) : ( - children - )} - - ); -}; - -export const Editor: React.FC = (props) => { - const { setAlertParams, alertParams, errors, alertsContext, sourceId } = props; - const [hasSetDefaults, setHasSetDefaults] = useState(false); - const { sourceStatus } = useLogSourceContext(); - useMount(() => { - for (const [key, value] of Object.entries({ ...DEFAULT_EXPRESSION, ...alertParams })) { - setAlertParams(key, value); - setHasSetDefaults(true); - } - }); - - const supportedFields = useMemo(() => { - if (sourceStatus?.logIndexFields) { - return sourceStatus.logIndexFields.filter((field) => { - return (field.type === 'string' || field.type === 'number') && field.searchable; - }); - } else { - return []; - } - /* eslint-disable-next-line react-hooks/exhaustive-deps */ - }, [sourceStatus]); - - const groupByFields = useMemo(() => { - if (sourceStatus?.logIndexFields) { - return sourceStatus.logIndexFields.filter((field) => { - return field.type === 'string' && field.aggregatable; - }); - } else { - return []; - } - /* eslint-disable-next-line react-hooks/exhaustive-deps */ - }, [sourceStatus]); - - const updateCount = useCallback( - (countParams) => { - const nextCountParams = { ...alertParams.count, ...countParams }; - setAlertParams('count', nextCountParams); - }, - [alertParams.count, setAlertParams] - ); - - const updateCriterion = useCallback( - (idx, criterionParams) => { - const nextCriteria = alertParams.criteria?.map((criterion, index) => { - return idx === index ? { ...criterion, ...criterionParams } : criterion; - }); - setAlertParams('criteria', nextCriteria ? nextCriteria : []); - }, - [alertParams, setAlertParams] - ); - - const updateTimeSize = useCallback( - (ts: number | undefined) => { - setAlertParams('timeSize', ts); - }, - [setAlertParams] - ); - - const updateTimeUnit = useCallback( - (tu: string) => { - setAlertParams('timeUnit', tu); - }, - [setAlertParams] - ); - - const updateGroupBy = useCallback( - (groups: string[]) => { - setAlertParams('groupBy', groups); - }, - [setAlertParams] - ); - - const addCriterion = useCallback(() => { - const nextCriteria = alertParams?.criteria - ? [...alertParams.criteria, DEFAULT_CRITERIA] - : [DEFAULT_CRITERIA]; - setAlertParams('criteria', nextCriteria); - /* eslint-disable-next-line react-hooks/exhaustive-deps */ - }, [alertParams, setAlertParams]); - - const removeCriterion = useCallback( - (idx) => { - const nextCriteria = alertParams?.criteria?.filter((criterion, index) => { - return index !== idx; - }); - setAlertParams('criteria', nextCriteria); - }, - /* eslint-disable-next-line react-hooks/exhaustive-deps */ - [alertParams, setAlertParams] - ); - - // Wait until the alert param defaults have been set - if (!hasSetDefaults) return null; - - return ( - <> - - - - - - - - -
- - - -
- - ); -}; - -// required for dynamic import -// eslint-disable-next-line import/no-default-export -export default ExpressionEditor; diff --git a/x-pack/plugins/infra/public/components/alerting/logs/log_threshold_alert_type.ts b/x-pack/plugins/infra/public/components/alerting/logs/log_threshold_alert_type.ts deleted file mode 100644 index a26a7328c9103..0000000000000 --- a/x-pack/plugins/infra/public/components/alerting/logs/log_threshold_alert_type.ts +++ /dev/null @@ -1,30 +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 { i18n } from '@kbn/i18n'; -import React from 'react'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { AlertTypeModel } from '../../../../../triggers_actions_ui/public/types'; -import { LOG_DOCUMENT_COUNT_ALERT_TYPE_ID } from '../../../../common/alerting/logs/types'; -import { validateExpression } from './validation'; - -export function getAlertType(): AlertTypeModel { - return { - id: LOG_DOCUMENT_COUNT_ALERT_TYPE_ID, - name: i18n.translate('xpack.infra.logs.alertFlyout.alertName', { - defaultMessage: 'Log threshold', - }), - iconClass: 'bell', - alertParamsExpression: React.lazy(() => import('./expression_editor/editor')), - validate: validateExpression, - defaultActionMessage: i18n.translate( - 'xpack.infra.logs.alerting.threshold.defaultActionMessage', - { - defaultMessage: `\\{\\{#context.group\\}\\}\\{\\{context.group\\}\\} - \\{\\{/context.group\\}\\}\\{\\{context.matchingDocuments\\}\\} log entries have matched the following conditions: \\{\\{context.conditions\\}\\}`, - } - ), - requiresAppContext: false, - }; -} diff --git a/x-pack/plugins/infra/public/components/alerting/logs/validation.ts b/x-pack/plugins/infra/public/components/alerting/logs/validation.ts deleted file mode 100644 index c8c513f57a9d7..0000000000000 --- a/x-pack/plugins/infra/public/components/alerting/logs/validation.ts +++ /dev/null @@ -1,102 +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 { i18n } from '@kbn/i18n'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ValidationResult } from '../../../../../triggers_actions_ui/public/types'; -import { LogDocumentCountAlertParams } from '../../../../common/alerting/logs/types'; - -export function validateExpression({ - count, - criteria, - timeSize, - timeUnit, -}: Partial): ValidationResult { - const validationResult = { errors: {} }; - - // NOTE: In the case of components provided by the Alerting framework the error property names - // must match what they expect. - const errors: { - count: { - value: string[]; - }; - criteria: { - [id: string]: { - field: string[]; - comparator: string[]; - value: string[]; - }; - }; - timeWindowSize: string[]; - timeSizeUnit: string[]; - } = { - count: { - value: [], - }, - criteria: {}, - timeSizeUnit: [], - timeWindowSize: [], - }; - - validationResult.errors = errors; - - // Document count validation - if (typeof count?.value !== 'number') { - errors.count.value.push( - i18n.translate('xpack.infra.logs.alertFlyout.error.documentCountRequired', { - defaultMessage: 'Document count is Required.', - }) - ); - } - - // Time validation - if (!timeSize) { - errors.timeWindowSize.push( - i18n.translate('xpack.infra.logs.alertFlyout.error.timeSizeRequired', { - defaultMessage: 'Time size is Required.', - }) - ); - } - - if (criteria && criteria.length > 0) { - // Criteria validation - criteria.forEach((criterion, idx: number) => { - const id = idx.toString(); - - errors.criteria[id] = { - field: [], - comparator: [], - value: [], - }; - - if (!criterion.field) { - errors.criteria[id].field.push( - i18n.translate('xpack.infra.logs.alertFlyout.error.criterionFieldRequired', { - defaultMessage: 'Field is required.', - }) - ); - } - - if (!criterion.comparator) { - errors.criteria[id].comparator.push( - i18n.translate('xpack.infra.logs.alertFlyout.error.criterionComparatorRequired', { - defaultMessage: 'Comparator is required.', - }) - ); - } - - if (!criterion.value) { - errors.criteria[id].value.push( - i18n.translate('xpack.infra.logs.alertFlyout.error.criterionValueRequired', { - defaultMessage: 'Value is required.', - }) - ); - } - }); - } - - return validationResult; -} diff --git a/x-pack/plugins/infra/public/components/alerting/shared/criterion_preview_chart/criterion_preview_chart.tsx b/x-pack/plugins/infra/public/components/alerting/shared/criterion_preview_chart/criterion_preview_chart.tsx deleted file mode 100644 index 239afd93a7a1f..0000000000000 --- a/x-pack/plugins/infra/public/components/alerting/shared/criterion_preview_chart/criterion_preview_chart.tsx +++ /dev/null @@ -1,136 +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, { useMemo } from 'react'; -import { niceTimeFormatter, TooltipValue } from '@elastic/charts'; -import { Theme, LIGHT_THEME, DARK_THEME } from '@elastic/charts'; -import { sum, min as getMin, max as getMax } from 'lodash'; -import moment from 'moment'; -import { i18n } from '@kbn/i18n'; -import { EuiText } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { formatNumber } from '../../../../../common/formatters/number'; -import { GetLogAlertsChartPreviewDataSuccessResponsePayload } from '../../../../../common/http_api'; - -type Series = GetLogAlertsChartPreviewDataSuccessResponsePayload['data']['series']; - -export const tooltipProps = { - headerFormatter: (tooltipValue: TooltipValue) => - moment(tooltipValue.value).format('Y-MM-DD HH:mm:ss'), -}; - -export const NUM_BUCKETS = 20; - -export const TIME_LABELS = { - s: i18n.translate('xpack.infra.alerts.timeLabels.seconds', { defaultMessage: 'seconds' }), - m: i18n.translate('xpack.infra.alerts.timeLabels.minutes', { defaultMessage: 'minutes' }), - h: i18n.translate('xpack.infra.alerts.timeLabels.hours', { defaultMessage: 'hours' }), - d: i18n.translate('xpack.infra.alerts.timeLabels.days', { defaultMessage: 'days' }), -}; - -export const useDateFormatter = (xMin?: number, xMax?: number) => { - const dateFormatter = useMemo(() => { - if (typeof xMin === 'number' && typeof xMax === 'number') { - return niceTimeFormatter([xMin, xMax]); - } else { - return (value: number) => `${value}`; - } - }, [xMin, xMax]); - return dateFormatter; -}; - -export const yAxisFormatter = formatNumber; - -export const getDomain = (series: Series, stacked: boolean = false) => { - let min: number | null = null; - let max: number | null = null; - const valuesByTimestamp = series.reduce<{ [timestamp: number]: number[] }>((acc, serie) => { - serie.points.forEach((point) => { - const valuesForTimestamp = acc[point.timestamp] || []; - acc[point.timestamp] = [...valuesForTimestamp, point.value]; - }); - return acc; - }, {}); - const pointValues = Object.values(valuesByTimestamp); - pointValues.forEach((results) => { - const maxResult = stacked ? sum(results) : getMax(results); - const minResult = getMin(results); - if (maxResult && (!max || maxResult > max)) { - max = maxResult; - } - if (minResult && (!min || minResult < min)) { - min = minResult; - } - }); - const timestampValues = Object.keys(valuesByTimestamp).map(Number); - const minTimestamp = getMin(timestampValues) || 0; - const maxTimestamp = getMax(timestampValues) || 0; - return { yMin: min || 0, yMax: max || 0, xMin: minTimestamp, xMax: maxTimestamp }; -}; - -export const getChartTheme = (isDarkMode: boolean): Theme => { - return isDarkMode ? DARK_THEME : LIGHT_THEME; -}; - -export const EmptyContainer: React.FC = ({ children }) => ( -
- {children} -
-); - -export const ChartContainer: React.FC = ({ children }) => ( -
- {children} -
-); - -export const NoDataState = () => { - return ( - - - - - - ); -}; - -export const LoadingState = () => { - return ( - - - - - - ); -}; - -export const ErrorState = () => { - return ( - - - - - - ); -}; diff --git a/x-pack/plugins/infra/public/components/logging/log_analysis_results/analyze_in_ml_button.tsx b/x-pack/plugins/infra/public/components/logging/log_analysis_results/analyze_in_ml_button.tsx index 3e54920160c53..c265876522767 100644 --- a/x-pack/plugins/infra/public/components/logging/log_analysis_results/analyze_in_ml_button.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_analysis_results/analyze_in_ml_button.tsx @@ -58,7 +58,7 @@ export const getOverallAnomalyExplorerLinkDescriptor = ( return { app: 'ml', - hash: '/explorer', + pathname: '/explorer', search: { _g }, }; }; @@ -89,7 +89,7 @@ export const getEntitySpecificSingleMetricViewerLink = ( return { app: 'ml', - hash: '/timeseriesexplorer', + pathname: '/timeseriesexplorer', search: { _g, _a }, }; }; diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_cleanup.ts b/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_cleanup.ts index 6fa2ac175ace6..4fdd6bdd282ba 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_cleanup.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_cleanup.ts @@ -5,21 +5,25 @@ */ import * as rt from 'io-ts'; -import { pipe } from 'fp-ts/lib/pipeable'; -import { fold } from 'fp-ts/lib/Either'; -import { identity } from 'fp-ts/lib/function'; -import { npStart } from '../../../../legacy_singletons'; +import type { HttpHandler } from 'src/core/public'; import { getDatafeedId, getJobId } from '../../../../../common/log_analysis'; -import { throwErrors, createPlainError } from '../../../../../common/runtime_types'; +import { decodeOrThrow } from '../../../../../common/runtime_types'; + +interface DeleteJobsRequestArgs { + spaceId: string; + sourceId: string; + jobTypes: JobType[]; +} export const callDeleteJobs = async ( - spaceId: string, - sourceId: string, - jobTypes: JobType[] + requestArgs: DeleteJobsRequestArgs, + fetch: HttpHandler ) => { + const { spaceId, sourceId, jobTypes } = requestArgs; + // NOTE: Deleting the jobs via this API will delete the datafeeds at the same time - const deleteJobsResponse = await npStart.http.fetch('/api/ml/jobs/delete_jobs', { + const deleteJobsResponse = await fetch('/api/ml/jobs/delete_jobs', { method: 'POST', body: JSON.stringify( deleteJobsRequestPayloadRT.encode({ @@ -28,28 +32,29 @@ export const callDeleteJobs = async ( ), }); - return pipe( - deleteJobsResponsePayloadRT.decode(deleteJobsResponse), - fold(throwErrors(createPlainError), identity) - ); + return decodeOrThrow(deleteJobsResponsePayloadRT)(deleteJobsResponse); }; -export const callGetJobDeletionTasks = async () => { - const jobDeletionTasksResponse = await npStart.http.fetch('/api/ml/jobs/deleting_jobs_tasks'); +export const callGetJobDeletionTasks = async (fetch: HttpHandler) => { + const jobDeletionTasksResponse = await fetch('/api/ml/jobs/deleting_jobs_tasks'); - return pipe( - getJobDeletionTasksResponsePayloadRT.decode(jobDeletionTasksResponse), - fold(throwErrors(createPlainError), identity) - ); + return decodeOrThrow(getJobDeletionTasksResponsePayloadRT)(jobDeletionTasksResponse); }; +interface StopDatafeedsRequestArgs { + spaceId: string; + sourceId: string; + jobTypes: JobType[]; +} + export const callStopDatafeeds = async ( - spaceId: string, - sourceId: string, - jobTypes: JobType[] + requestArgs: StopDatafeedsRequestArgs, + fetch: HttpHandler ) => { + const { spaceId, sourceId, jobTypes } = requestArgs; + // Stop datafeed due to https://github.com/elastic/kibana/issues/44652 - const stopDatafeedResponse = await npStart.http.fetch('/api/ml/jobs/stop_datafeeds', { + const stopDatafeedResponse = await fetch('/api/ml/jobs/stop_datafeeds', { method: 'POST', body: JSON.stringify( stopDatafeedsRequestPayloadRT.encode({ @@ -58,10 +63,7 @@ export const callStopDatafeeds = async ( ), }); - return pipe( - stopDatafeedsResponsePayloadRT.decode(stopDatafeedResponse), - fold(throwErrors(createPlainError), identity) - ); + return decodeOrThrow(stopDatafeedsResponsePayloadRT)(stopDatafeedResponse); }; export const deleteJobsRequestPayloadRT = rt.type({ diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_get_jobs_summary_api.ts b/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_get_jobs_summary_api.ts index 7441c0ab7d34c..7cb477dbe5b37 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_get_jobs_summary_api.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_get_jobs_summary_api.ts @@ -4,21 +4,24 @@ * you may not use this file except in compliance with the Elastic License. */ -import { fold } from 'fp-ts/lib/Either'; -import { identity } from 'fp-ts/lib/function'; -import { pipe } from 'fp-ts/lib/pipeable'; import * as rt from 'io-ts'; -import { npStart } from '../../../../legacy_singletons'; +import type { HttpHandler } from 'src/core/public'; import { getJobId, jobCustomSettingsRT } from '../../../../../common/log_analysis'; -import { createPlainError, throwErrors } from '../../../../../common/runtime_types'; +import { decodeOrThrow } from '../../../../../common/runtime_types'; + +interface RequestArgs { + spaceId: string; + sourceId: string; + jobTypes: JobType[]; +} export const callJobsSummaryAPI = async ( - spaceId: string, - sourceId: string, - jobTypes: JobType[] + requestArgs: RequestArgs, + fetch: HttpHandler ) => { - const response = await npStart.http.fetch('/api/ml/jobs/jobs_summary', { + const { spaceId, sourceId, jobTypes } = requestArgs; + const response = await fetch('/api/ml/jobs/jobs_summary', { method: 'POST', body: JSON.stringify( fetchJobStatusRequestPayloadRT.encode({ @@ -26,10 +29,7 @@ export const callJobsSummaryAPI = async ( }) ), }); - return pipe( - fetchJobStatusResponsePayloadRT.decode(response), - fold(throwErrors(createPlainError), identity) - ); + return decodeOrThrow(fetchJobStatusResponsePayloadRT)(response); }; export const fetchJobStatusRequestPayloadRT = rt.type({ diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_get_module.ts b/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_get_module.ts index b6b40d6dc651f..2bf18d4e52c79 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_get_module.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_get_module.ts @@ -4,24 +4,18 @@ * you may not use this file except in compliance with the Elastic License. */ -import { fold } from 'fp-ts/lib/Either'; -import { identity } from 'fp-ts/lib/function'; -import { pipe } from 'fp-ts/lib/pipeable'; import * as rt from 'io-ts'; -import { npStart } from '../../../../legacy_singletons'; +import type { HttpHandler } from 'src/core/public'; import { jobCustomSettingsRT } from '../../../../../common/log_analysis'; -import { createPlainError, throwErrors } from '../../../../../common/runtime_types'; +import { decodeOrThrow } from '../../../../../common/runtime_types'; -export const callGetMlModuleAPI = async (moduleId: string) => { - const response = await npStart.http.fetch(`/api/ml/modules/get_module/${moduleId}`, { +export const callGetMlModuleAPI = async (moduleId: string, fetch: HttpHandler) => { + const response = await fetch(`/api/ml/modules/get_module/${moduleId}`, { method: 'GET', }); - return pipe( - getMlModuleResponsePayloadRT.decode(response), - fold(throwErrors(createPlainError), identity) - ); + return decodeOrThrow(getMlModuleResponsePayloadRT)(response); }; const jobDefinitionRT = rt.type({ diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_setup_module_api.ts b/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_setup_module_api.ts index 7c8d63374924c..1f203ef9618b8 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_setup_module_api.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/api/ml_setup_module_api.ts @@ -4,27 +4,38 @@ * you may not use this file except in compliance with the Elastic License. */ -import { fold } from 'fp-ts/lib/Either'; -import { identity } from 'fp-ts/lib/function'; -import { pipe } from 'fp-ts/lib/pipeable'; import * as rt from 'io-ts'; -import { npStart } from '../../../../legacy_singletons'; +import type { HttpHandler } from 'src/core/public'; import { getJobIdPrefix, jobCustomSettingsRT } from '../../../../../common/log_analysis'; -import { createPlainError, throwErrors } from '../../../../../common/runtime_types'; - -export const callSetupMlModuleAPI = async ( - moduleId: string, - start: number | undefined, - end: number | undefined, - spaceId: string, - sourceId: string, - indexPattern: string, - jobOverrides: SetupMlModuleJobOverrides[] = [], - datafeedOverrides: SetupMlModuleDatafeedOverrides[] = [], - query?: object -) => { - const response = await npStart.http.fetch(`/api/ml/modules/setup/${moduleId}`, { +import { decodeOrThrow } from '../../../../../common/runtime_types'; + +interface RequestArgs { + moduleId: string; + start?: number; + end?: number; + spaceId: string; + sourceId: string; + indexPattern: string; + jobOverrides?: SetupMlModuleJobOverrides[]; + datafeedOverrides?: SetupMlModuleDatafeedOverrides[]; + query?: object; +} + +export const callSetupMlModuleAPI = async (requestArgs: RequestArgs, fetch: HttpHandler) => { + const { + moduleId, + start, + end, + spaceId, + sourceId, + indexPattern, + jobOverrides = [], + datafeedOverrides = [], + query, + } = requestArgs; + + const response = await fetch(`/api/ml/modules/setup/${moduleId}`, { method: 'POST', body: JSON.stringify( setupMlModuleRequestPayloadRT.encode({ @@ -40,10 +51,7 @@ export const callSetupMlModuleAPI = async ( ), }); - return pipe( - setupMlModuleResponsePayloadRT.decode(response), - fold(throwErrors(createPlainError), identity) - ); + return decodeOrThrow(setupMlModuleResponsePayloadRT)(response); }; const setupMlModuleTimeParamsRT = rt.partial({ diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/api/validate_datasets.ts b/x-pack/plugins/infra/public/containers/logs/log_analysis/api/validate_datasets.ts index 6c9d5e439d359..ec08d3ac107e5 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/api/validate_datasets.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/api/validate_datasets.ts @@ -4,21 +4,24 @@ * you may not use this file except in compliance with the Elastic License. */ +import type { HttpHandler } from 'src/core/public'; import { LOG_ANALYSIS_VALIDATE_DATASETS_PATH, validateLogEntryDatasetsRequestPayloadRT, validateLogEntryDatasetsResponsePayloadRT, } from '../../../../../common/http_api'; import { decodeOrThrow } from '../../../../../common/runtime_types'; -import { npStart } from '../../../../legacy_singletons'; -export const callValidateDatasetsAPI = async ( - indices: string[], - timestampField: string, - startTime: number, - endTime: number -) => { - const response = await npStart.http.fetch(LOG_ANALYSIS_VALIDATE_DATASETS_PATH, { +interface RequestArgs { + indices: string[]; + timestampField: string; + startTime: number; + endTime: number; +} + +export const callValidateDatasetsAPI = async (requestArgs: RequestArgs, fetch: HttpHandler) => { + const { indices, timestampField, startTime, endTime } = requestArgs; + const response = await fetch(LOG_ANALYSIS_VALIDATE_DATASETS_PATH, { method: 'POST', body: JSON.stringify( validateLogEntryDatasetsRequestPayloadRT.encode({ diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/api/validate_indices.ts b/x-pack/plugins/infra/public/containers/logs/log_analysis/api/validate_indices.ts index bbef7d201045f..465d09a744b19 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/api/validate_indices.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/api/validate_indices.ts @@ -4,10 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { fold } from 'fp-ts/lib/Either'; -import { pipe } from 'fp-ts/lib/pipeable'; -import { identity } from 'fp-ts/lib/function'; -import { npStart } from '../../../../legacy_singletons'; +import type { HttpHandler } from 'src/core/public'; + import { LOG_ANALYSIS_VALIDATE_INDICES_PATH, ValidationIndicesFieldSpecification, @@ -15,19 +13,19 @@ import { validationIndicesResponsePayloadRT, } from '../../../../../common/http_api'; -import { throwErrors, createPlainError } from '../../../../../common/runtime_types'; +import { decodeOrThrow } from '../../../../../common/runtime_types'; + +interface RequestArgs { + indices: string[]; + fields: ValidationIndicesFieldSpecification[]; +} -export const callValidateIndicesAPI = async ( - indices: string[], - fields: ValidationIndicesFieldSpecification[] -) => { - const response = await npStart.http.fetch(LOG_ANALYSIS_VALIDATE_INDICES_PATH, { +export const callValidateIndicesAPI = async (requestArgs: RequestArgs, fetch: HttpHandler) => { + const { indices, fields } = requestArgs; + const response = await fetch(LOG_ANALYSIS_VALIDATE_INDICES_PATH, { method: 'POST', body: JSON.stringify(validationIndicesRequestPayloadRT.encode({ data: { indices, fields } })), }); - return pipe( - validationIndicesResponsePayloadRT.decode(response), - fold(throwErrors(createPlainError), identity) - ); + return decodeOrThrow(validationIndicesResponsePayloadRT)(response); }; diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_capabilities.tsx b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_capabilities.tsx index 9116900ec2196..74b316f78259f 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_capabilities.tsx +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_capabilities.tsx @@ -6,18 +6,16 @@ import createContainer from 'constate'; import { useMemo, useState, useEffect } from 'react'; -import { fold } from 'fp-ts/lib/Either'; -import { pipe } from 'fp-ts/lib/pipeable'; -import { identity } from 'fp-ts/lib/function'; import { useTrackedPromise } from '../../../utils/use_tracked_promise'; -import { npStart } from '../../../legacy_singletons'; import { getMlCapabilitiesResponsePayloadRT, GetMlCapabilitiesResponsePayload, } from './api/ml_api_types'; -import { throwErrors, createPlainError } from '../../../../common/runtime_types'; +import { decodeOrThrow } from '../../../../common/runtime_types'; +import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; export const useLogAnalysisCapabilities = () => { + const { services } = useKibanaContextForPlugin(); const [mlCapabilities, setMlCapabilities] = useState( initialMlCapabilities ); @@ -26,12 +24,9 @@ export const useLogAnalysisCapabilities = () => { { cancelPreviousOn: 'resolution', createPromise: async () => { - const rawResponse = await npStart.http.fetch('/api/ml/ml_capabilities'); + const rawResponse = await services.http.fetch('/api/ml/ml_capabilities'); - return pipe( - getMlCapabilitiesResponsePayloadRT.decode(rawResponse), - fold(throwErrors(createPlainError), identity) - ); + return decodeOrThrow(getMlCapabilitiesResponsePayloadRT)(rawResponse); }, onResolve: (response) => { setMlCapabilities(response); diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_cleanup.tsx b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_cleanup.tsx index 522616f83d0cb..ec5e879131aa1 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_cleanup.tsx +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_cleanup.tsx @@ -3,17 +3,18 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - +import type { HttpHandler } from 'src/core/public'; import { getJobId } from '../../../../common/log_analysis'; import { callDeleteJobs, callGetJobDeletionTasks, callStopDatafeeds } from './api/ml_cleanup'; export const cleanUpJobsAndDatafeeds = async ( spaceId: string, sourceId: string, - jobTypes: JobType[] + jobTypes: JobType[], + fetch: HttpHandler ) => { try { - await callStopDatafeeds(spaceId, sourceId, jobTypes); + await callStopDatafeeds({ spaceId, sourceId, jobTypes }, fetch); } catch (err) { // Proceed only if datafeed has been deleted or didn't exist in the first place if (err?.res?.status !== 404) { @@ -21,27 +22,29 @@ export const cleanUpJobsAndDatafeeds = async ( } } - return await deleteJobs(spaceId, sourceId, jobTypes); + return await deleteJobs(spaceId, sourceId, jobTypes, fetch); }; const deleteJobs = async ( spaceId: string, sourceId: string, - jobTypes: JobType[] + jobTypes: JobType[], + fetch: HttpHandler ) => { - const deleteJobsResponse = await callDeleteJobs(spaceId, sourceId, jobTypes); - await waitUntilJobsAreDeleted(spaceId, sourceId, jobTypes); + const deleteJobsResponse = await callDeleteJobs({ spaceId, sourceId, jobTypes }, fetch); + await waitUntilJobsAreDeleted(spaceId, sourceId, jobTypes, fetch); return deleteJobsResponse; }; const waitUntilJobsAreDeleted = async ( spaceId: string, sourceId: string, - jobTypes: JobType[] + jobTypes: JobType[], + fetch: HttpHandler ) => { const moduleJobIds = jobTypes.map((jobType) => getJobId(spaceId, sourceId, jobType)); while (true) { - const { jobIds: jobIdsBeingDeleted } = await callGetJobDeletionTasks(); + const { jobIds: jobIdsBeingDeleted } = await callGetJobDeletionTasks(fetch); const needToWait = jobIdsBeingDeleted.some((jobId) => moduleJobIds.includes(jobId)); if (needToWait) { diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module.tsx b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module.tsx index 79768302a7310..27ef0039ae49f 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module.tsx +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module.tsx @@ -6,6 +6,7 @@ import { useCallback, useMemo } from 'react'; import { DatasetFilter } from '../../../../common/log_analysis'; +import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; import { useTrackedPromise } from '../../../utils/use_tracked_promise'; import { useModuleStatus } from './log_analysis_module_status'; import { ModuleDescriptor, ModuleSourceConfiguration } from './log_analysis_module_types'; @@ -17,6 +18,7 @@ export const useLogAnalysisModule = ({ sourceConfiguration: ModuleSourceConfiguration; moduleDescriptor: ModuleDescriptor; }) => { + const { services } = useKibanaContextForPlugin(); const { spaceId, sourceId, timestampField } = sourceConfiguration; const [moduleStatus, dispatchModuleStatus] = useModuleStatus(moduleDescriptor.jobTypes); @@ -25,7 +27,7 @@ export const useLogAnalysisModule = ({ cancelPreviousOn: 'resolution', createPromise: async () => { dispatchModuleStatus({ type: 'fetchingJobStatuses' }); - return await moduleDescriptor.getJobSummary(spaceId, sourceId); + return await moduleDescriptor.getJobSummary(spaceId, sourceId, services.http.fetch); }, onResolve: (jobResponse) => { dispatchModuleStatus({ @@ -52,13 +54,23 @@ export const useLogAnalysisModule = ({ datasetFilter: DatasetFilter ) => { dispatchModuleStatus({ type: 'startedSetup' }); - const setupResult = await moduleDescriptor.setUpModule(start, end, datasetFilter, { - indices: selectedIndices, - sourceId, + const setupResult = await moduleDescriptor.setUpModule( + start, + end, + datasetFilter, + { + indices: selectedIndices, + sourceId, + spaceId, + timestampField, + }, + services.http.fetch + ); + const jobSummaries = await moduleDescriptor.getJobSummary( spaceId, - timestampField, - }); - const jobSummaries = await moduleDescriptor.getJobSummary(spaceId, sourceId); + sourceId, + services.http.fetch + ); return { setupResult, jobSummaries }; }, onResolve: ({ setupResult: { datafeeds, jobs }, jobSummaries }) => { @@ -82,7 +94,7 @@ export const useLogAnalysisModule = ({ { cancelPreviousOn: 'resolution', createPromise: async () => { - return await moduleDescriptor.cleanUpModule(spaceId, sourceId); + return await moduleDescriptor.cleanUpModule(spaceId, sourceId, services.http.fetch); }, }, [spaceId, sourceId] diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module_definition.tsx b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module_definition.tsx index 1f643d0e5eb34..7a5c1d354dc34 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module_definition.tsx +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module_definition.tsx @@ -6,6 +6,7 @@ import { useCallback, useMemo, useState } from 'react'; import { getJobId } from '../../../../common/log_analysis'; +import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; import { useTrackedPromise } from '../../../utils/use_tracked_promise'; import { JobSummary } from './api/ml_get_jobs_summary_api'; import { GetMlModuleResponsePayload, JobDefinition } from './api/ml_get_module'; @@ -18,6 +19,7 @@ export const useLogAnalysisModuleDefinition = ({ sourceConfiguration: ModuleSourceConfiguration; moduleDescriptor: ModuleDescriptor; }) => { + const { services } = useKibanaContextForPlugin(); const [moduleDefinition, setModuleDefinition] = useState< GetMlModuleResponsePayload | undefined >(); @@ -40,7 +42,7 @@ export const useLogAnalysisModuleDefinition = ({ { cancelPreviousOn: 'resolution', createPromise: async () => { - return await moduleDescriptor.getModuleDefinition(); + return await moduleDescriptor.getModuleDefinition(services.http.fetch); }, onResolve: (response) => { setModuleDefinition(response); diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module_types.ts b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module_types.ts index ba355ad195b11..c42704860b032 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module_types.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_module_types.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import type { HttpHandler } from 'src/core/public'; import { ValidateLogEntryDatasetsResponsePayload, ValidationIndicesResponsePayload, @@ -23,24 +24,35 @@ export interface ModuleDescriptor { jobTypes: JobType[]; bucketSpan: number; getJobIds: (spaceId: string, sourceId: string) => Record; - getJobSummary: (spaceId: string, sourceId: string) => Promise; - getModuleDefinition: () => Promise; + getJobSummary: ( + spaceId: string, + sourceId: string, + fetch: HttpHandler + ) => Promise; + getModuleDefinition: (fetch: HttpHandler) => Promise; setUpModule: ( start: number | undefined, end: number | undefined, datasetFilter: DatasetFilter, - sourceConfiguration: ModuleSourceConfiguration + sourceConfiguration: ModuleSourceConfiguration, + fetch: HttpHandler ) => Promise; - cleanUpModule: (spaceId: string, sourceId: string) => Promise; + cleanUpModule: ( + spaceId: string, + sourceId: string, + fetch: HttpHandler + ) => Promise; validateSetupIndices: ( indices: string[], - timestampField: string + timestampField: string, + fetch: HttpHandler ) => Promise; validateSetupDatasets: ( indices: string[], timestampField: string, startTime: number, - endTime: number + endTime: number, + fetch: HttpHandler ) => Promise; } diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_setup_state.ts b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_setup_state.ts index e6fe8f4e92cc4..750a7104a3a98 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_setup_state.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/log_analysis_setup_state.ts @@ -18,6 +18,7 @@ import { ValidationIndicesError, ValidationUIError, } from '../../../components/logging/log_analysis_setup/initial_configuration_step'; +import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; import { useTrackedPromise } from '../../../utils/use_tracked_promise'; import { ModuleDescriptor, ModuleSourceConfiguration } from './log_analysis_module_types'; @@ -43,6 +44,7 @@ export const useAnalysisSetupState = ({ setUpModule, sourceConfiguration, }: AnalysisSetupStateArguments) => { + const { services } = useKibanaContextForPlugin(); const [startTime, setStartTime] = useState(Date.now() - fourWeeksInMs); const [endTime, setEndTime] = useState(undefined); @@ -158,7 +160,8 @@ export const useAnalysisSetupState = ({ createPromise: async () => { return await validateSetupIndices( sourceConfiguration.indices, - sourceConfiguration.timestampField + sourceConfiguration.timestampField, + services.http.fetch ); }, onResolve: ({ data: { errors } }) => { @@ -183,7 +186,8 @@ export const useAnalysisSetupState = ({ validIndexNames, sourceConfiguration.timestampField, startTime ?? 0, - endTime ?? Date.now() + endTime ?? Date.now(), + services.http.fetch ); }, onResolve: ({ data: { datasets } }) => { diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/modules/log_entry_categories/module_descriptor.ts b/x-pack/plugins/infra/public/containers/logs/log_analysis/modules/log_entry_categories/module_descriptor.ts index 9682b3e74db3b..46b28e091cc5c 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/modules/log_entry_categories/module_descriptor.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/modules/log_entry_categories/module_descriptor.ts @@ -5,6 +5,7 @@ */ import { i18n } from '@kbn/i18n'; +import type { HttpHandler } from 'src/core/public'; import { bucketSpan, categoriesMessageField, @@ -42,22 +43,26 @@ const getJobIds = (spaceId: string, sourceId: string) => {} as Record ); -const getJobSummary = async (spaceId: string, sourceId: string) => { - const response = await callJobsSummaryAPI(spaceId, sourceId, logEntryCategoriesJobTypes); +const getJobSummary = async (spaceId: string, sourceId: string, fetch: HttpHandler) => { + const response = await callJobsSummaryAPI( + { spaceId, sourceId, jobTypes: logEntryCategoriesJobTypes }, + fetch + ); const jobIds = Object.values(getJobIds(spaceId, sourceId)); return response.filter((jobSummary) => jobIds.includes(jobSummary.id)); }; -const getModuleDefinition = async () => { - return await callGetMlModuleAPI(moduleId); +const getModuleDefinition = async (fetch: HttpHandler) => { + return await callGetMlModuleAPI(moduleId, fetch); }; const setUpModule = async ( start: number | undefined, end: number | undefined, datasetFilter: DatasetFilter, - { spaceId, sourceId, indices, timestampField }: ModuleSourceConfiguration + { spaceId, sourceId, indices, timestampField }: ModuleSourceConfiguration, + fetch: HttpHandler ) => { const indexNamePattern = indices.join(','); const jobOverrides = [ @@ -101,46 +106,59 @@ const setUpModule = async ( }; return callSetupMlModuleAPI( - moduleId, - start, - end, - spaceId, - sourceId, - indexNamePattern, - jobOverrides, - [], - query + { + moduleId, + start, + end, + spaceId, + sourceId, + indexPattern: indexNamePattern, + jobOverrides, + query, + }, + fetch ); }; -const cleanUpModule = async (spaceId: string, sourceId: string) => { - return await cleanUpJobsAndDatafeeds(spaceId, sourceId, logEntryCategoriesJobTypes); +const cleanUpModule = async (spaceId: string, sourceId: string, fetch: HttpHandler) => { + return await cleanUpJobsAndDatafeeds(spaceId, sourceId, logEntryCategoriesJobTypes, fetch); }; -const validateSetupIndices = async (indices: string[], timestampField: string) => { - return await callValidateIndicesAPI(indices, [ - { - name: timestampField, - validTypes: ['date'], - }, - { - name: partitionField, - validTypes: ['keyword'], - }, +const validateSetupIndices = async ( + indices: string[], + timestampField: string, + fetch: HttpHandler +) => { + return await callValidateIndicesAPI( { - name: categoriesMessageField, - validTypes: ['text'], + indices, + fields: [ + { + name: timestampField, + validTypes: ['date'], + }, + { + name: partitionField, + validTypes: ['keyword'], + }, + { + name: categoriesMessageField, + validTypes: ['text'], + }, + ], }, - ]); + fetch + ); }; const validateSetupDatasets = async ( indices: string[], timestampField: string, startTime: number, - endTime: number + endTime: number, + fetch: HttpHandler ) => { - return await callValidateDatasetsAPI(indices, timestampField, startTime, endTime); + return await callValidateDatasetsAPI({ indices, timestampField, startTime, endTime }, fetch); }; export const logEntryCategoriesModule: ModuleDescriptor = { diff --git a/x-pack/plugins/infra/public/containers/logs/log_analysis/modules/log_entry_rate/module_descriptor.ts b/x-pack/plugins/infra/public/containers/logs/log_analysis/modules/log_entry_rate/module_descriptor.ts index 001174a2b7558..b97ec55105f5d 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_analysis/modules/log_entry_rate/module_descriptor.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_analysis/modules/log_entry_rate/module_descriptor.ts @@ -5,6 +5,7 @@ */ import { i18n } from '@kbn/i18n'; +import type { HttpHandler } from 'src/core/public'; import { bucketSpan, DatasetFilter, @@ -41,22 +42,26 @@ const getJobIds = (spaceId: string, sourceId: string) => {} as Record ); -const getJobSummary = async (spaceId: string, sourceId: string) => { - const response = await callJobsSummaryAPI(spaceId, sourceId, logEntryRateJobTypes); +const getJobSummary = async (spaceId: string, sourceId: string, fetch: HttpHandler) => { + const response = await callJobsSummaryAPI( + { spaceId, sourceId, jobTypes: logEntryRateJobTypes }, + fetch + ); const jobIds = Object.values(getJobIds(spaceId, sourceId)); return response.filter((jobSummary) => jobIds.includes(jobSummary.id)); }; -const getModuleDefinition = async () => { - return await callGetMlModuleAPI(moduleId); +const getModuleDefinition = async (fetch: HttpHandler) => { + return await callGetMlModuleAPI(moduleId, fetch); }; const setUpModule = async ( start: number | undefined, end: number | undefined, datasetFilter: DatasetFilter, - { spaceId, sourceId, indices, timestampField }: ModuleSourceConfiguration + { spaceId, sourceId, indices, timestampField }: ModuleSourceConfiguration, + fetch: HttpHandler ) => { const indexNamePattern = indices.join(','); const jobOverrides = [ @@ -93,42 +98,55 @@ const setUpModule = async ( : undefined; return callSetupMlModuleAPI( - moduleId, - start, - end, - spaceId, - sourceId, - indexNamePattern, - jobOverrides, - [], - query + { + moduleId, + start, + end, + spaceId, + sourceId, + indexPattern: indexNamePattern, + jobOverrides, + query, + }, + fetch ); }; -const cleanUpModule = async (spaceId: string, sourceId: string) => { - return await cleanUpJobsAndDatafeeds(spaceId, sourceId, logEntryRateJobTypes); +const cleanUpModule = async (spaceId: string, sourceId: string, fetch: HttpHandler) => { + return await cleanUpJobsAndDatafeeds(spaceId, sourceId, logEntryRateJobTypes, fetch); }; -const validateSetupIndices = async (indices: string[], timestampField: string) => { - return await callValidateIndicesAPI(indices, [ - { - name: timestampField, - validTypes: ['date'], - }, +const validateSetupIndices = async ( + indices: string[], + timestampField: string, + fetch: HttpHandler +) => { + return await callValidateIndicesAPI( { - name: partitionField, - validTypes: ['keyword'], + indices, + fields: [ + { + name: timestampField, + validTypes: ['date'], + }, + { + name: partitionField, + validTypes: ['keyword'], + }, + ], }, - ]); + fetch + ); }; const validateSetupDatasets = async ( indices: string[], timestampField: string, startTime: number, - endTime: number + endTime: number, + fetch: HttpHandler ) => { - return await callValidateDatasetsAPI(indices, timestampField, startTime, endTime); + return await callValidateDatasetsAPI({ indices, timestampField, startTime, endTime }, fetch); }; export const logEntryRateModule: ModuleDescriptor = { diff --git a/x-pack/plugins/infra/public/containers/logs/log_entries/api/fetch_log_entries.ts b/x-pack/plugins/infra/public/containers/logs/log_entries/api/fetch_log_entries.ts index 2a19a82892427..3bbd86cb0ef75 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_entries/api/fetch_log_entries.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_entries/api/fetch_log_entries.ts @@ -4,12 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { fold } from 'fp-ts/lib/Either'; -import { pipe } from 'fp-ts/lib/pipeable'; -import { identity } from 'fp-ts/lib/function'; -import { npStart } from '../../../../legacy_singletons'; +import type { HttpHandler } from 'src/core/public'; -import { throwErrors, createPlainError } from '../../../../../common/runtime_types'; +import { decodeOrThrow } from '../../../../../common/runtime_types'; import { LOG_ENTRIES_PATH, @@ -18,11 +15,11 @@ import { logEntriesResponseRT, } from '../../../../../common/http_api'; -export const fetchLogEntries = async (requestArgs: LogEntriesRequest) => { - const response = await npStart.http.fetch(LOG_ENTRIES_PATH, { +export const fetchLogEntries = async (requestArgs: LogEntriesRequest, fetch: HttpHandler) => { + const response = await fetch(LOG_ENTRIES_PATH, { method: 'POST', body: JSON.stringify(logEntriesRequestRT.encode(requestArgs)), }); - return pipe(logEntriesResponseRT.decode(response), fold(throwErrors(createPlainError), identity)); + return decodeOrThrow(logEntriesResponseRT)(response); }; diff --git a/x-pack/plugins/infra/public/containers/logs/log_entries/api/fetch_log_entries_item.ts b/x-pack/plugins/infra/public/containers/logs/log_entries/api/fetch_log_entries_item.ts index 5fde01e458e36..d459fba6cf957 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_entries/api/fetch_log_entries_item.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_entries/api/fetch_log_entries_item.ts @@ -4,12 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { fold } from 'fp-ts/lib/Either'; -import { pipe } from 'fp-ts/lib/pipeable'; -import { identity } from 'fp-ts/lib/function'; -import { npStart } from '../../../../legacy_singletons'; +import type { HttpHandler } from 'src/core/public'; -import { throwErrors, createPlainError } from '../../../../../common/runtime_types'; +import { decodeOrThrow } from '../../../../../common/runtime_types'; import { LOG_ENTRIES_ITEM_PATH, @@ -18,14 +15,14 @@ import { logEntriesItemResponseRT, } from '../../../../../common/http_api'; -export const fetchLogEntriesItem = async (requestArgs: LogEntriesItemRequest) => { - const response = await npStart.http.fetch(LOG_ENTRIES_ITEM_PATH, { +export const fetchLogEntriesItem = async ( + requestArgs: LogEntriesItemRequest, + fetch: HttpHandler +) => { + const response = await fetch(LOG_ENTRIES_ITEM_PATH, { method: 'POST', body: JSON.stringify(logEntriesItemRequestRT.encode(requestArgs)), }); - return pipe( - logEntriesItemResponseRT.decode(response), - fold(throwErrors(createPlainError), identity) - ); + return decodeOrThrow(logEntriesItemResponseRT)(response); }; diff --git a/x-pack/plugins/infra/public/containers/logs/log_entries/index.ts b/x-pack/plugins/infra/public/containers/logs/log_entries/index.ts index d5b2a0aaa61c0..4c8c610794b2e 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_entries/index.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_entries/index.ts @@ -14,6 +14,7 @@ import { LogEntriesBaseRequest, } from '../../../../common/http_api'; import { fetchLogEntries } from './api/fetch_log_entries'; +import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; const DESIRED_BUFFER_PAGES = 2; const LIVE_STREAM_INTERVAL = 5000; @@ -144,6 +145,7 @@ const useFetchEntriesEffect = ( dispatch: Dispatch, props: LogEntriesProps ) => { + const { services } = useKibanaContextForPlugin(); const [prevParams, cachePrevParams] = useState(); const [startedStreaming, setStartedStreaming] = useState(false); @@ -172,7 +174,7 @@ const useFetchEntriesEffect = ( before: 'last', }; - const { data: payload } = await fetchLogEntries(fetchArgs); + const { data: payload } = await fetchLogEntries(fetchArgs, services.http.fetch); dispatch({ type: Action.ReceiveNewEntries, payload }); // Move position to the bottom if it's the first load. @@ -228,7 +230,7 @@ const useFetchEntriesEffect = ( after: state.bottomCursor, }; - const { data: payload } = await fetchLogEntries(fetchArgs); + const { data: payload } = await fetchLogEntries(fetchArgs, services.http.fetch); dispatch({ type: getEntriesBefore ? Action.ReceiveEntriesBefore : Action.ReceiveEntriesAfter, diff --git a/x-pack/plugins/infra/public/containers/logs/log_flyout.tsx b/x-pack/plugins/infra/public/containers/logs/log_flyout.tsx index 0489892e58f2a..9ed2f5ad175c7 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_flyout.tsx +++ b/x-pack/plugins/infra/public/containers/logs/log_flyout.tsx @@ -9,6 +9,7 @@ import { isString } from 'lodash'; import React, { useContext, useEffect, useMemo, useState } from 'react'; import { LogEntriesItem } from '../../../common/http_api'; +import { useKibanaContextForPlugin } from '../../hooks/use_kibana'; import { UrlStateContainer } from '../../utils/url_state'; import { useTrackedPromise } from '../../utils/use_tracked_promise'; import { fetchLogEntriesItem } from './log_entries/api/fetch_log_entries_item'; @@ -26,6 +27,7 @@ export interface FlyoutOptionsUrlState { } export const useLogFlyout = () => { + const { services } = useKibanaContextForPlugin(); const { sourceId } = useLogSourceContext(); const [flyoutVisible, setFlyoutVisibility] = useState(false); const [flyoutId, setFlyoutId] = useState(null); @@ -39,7 +41,7 @@ export const useLogFlyout = () => { if (!flyoutId) { return; } - return await fetchLogEntriesItem({ sourceId, id: flyoutId }); + return await fetchLogEntriesItem({ sourceId, id: flyoutId }, services.http.fetch); }, onResolve: (response) => { if (response) { diff --git a/x-pack/plugins/infra/public/containers/logs/log_highlights/api/fetch_log_entries_highlights.ts b/x-pack/plugins/infra/public/containers/logs/log_highlights/api/fetch_log_entries_highlights.ts index 030a9d180c7b5..25865a30467f5 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_highlights/api/fetch_log_entries_highlights.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_highlights/api/fetch_log_entries_highlights.ts @@ -4,12 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { fold } from 'fp-ts/lib/Either'; -import { pipe } from 'fp-ts/lib/pipeable'; -import { identity } from 'fp-ts/lib/function'; -import { npStart } from '../../../../legacy_singletons'; +import type { HttpHandler } from 'src/core/public'; -import { throwErrors, createPlainError } from '../../../../../common/runtime_types'; +import { decodeOrThrow } from '../../../../../common/runtime_types'; import { LOG_ENTRIES_HIGHLIGHTS_PATH, @@ -18,14 +15,14 @@ import { logEntriesHighlightsResponseRT, } from '../../../../../common/http_api'; -export const fetchLogEntriesHighlights = async (requestArgs: LogEntriesHighlightsRequest) => { - const response = await npStart.http.fetch(LOG_ENTRIES_HIGHLIGHTS_PATH, { +export const fetchLogEntriesHighlights = async ( + requestArgs: LogEntriesHighlightsRequest, + fetch: HttpHandler +) => { + const response = await fetch(LOG_ENTRIES_HIGHLIGHTS_PATH, { method: 'POST', body: JSON.stringify(logEntriesHighlightsRequestRT.encode(requestArgs)), }); - return pipe( - logEntriesHighlightsResponseRT.decode(response), - fold(throwErrors(createPlainError), identity) - ); + return decodeOrThrow(logEntriesHighlightsResponseRT)(response); }; diff --git a/x-pack/plugins/infra/public/containers/logs/log_highlights/api/fetch_log_summary_highlights.ts b/x-pack/plugins/infra/public/containers/logs/log_highlights/api/fetch_log_summary_highlights.ts index bda8f535549c7..1cf95bc08a521 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_highlights/api/fetch_log_summary_highlights.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_highlights/api/fetch_log_summary_highlights.ts @@ -3,11 +3,9 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { fold } from 'fp-ts/lib/Either'; -import { pipe } from 'fp-ts/lib/pipeable'; -import { identity } from 'fp-ts/lib/function'; -import { npStart } from '../../../../legacy_singletons'; -import { throwErrors, createPlainError } from '../../../../../common/runtime_types'; + +import type { HttpHandler } from 'src/core/public'; +import { decodeOrThrow } from '../../../../../common/runtime_types'; import { LOG_ENTRIES_SUMMARY_HIGHLIGHTS_PATH, @@ -17,15 +15,13 @@ import { } from '../../../../../common/http_api'; export const fetchLogSummaryHighlights = async ( - requestArgs: LogEntriesSummaryHighlightsRequest + requestArgs: LogEntriesSummaryHighlightsRequest, + fetch: HttpHandler ) => { - const response = await npStart.http.fetch(LOG_ENTRIES_SUMMARY_HIGHLIGHTS_PATH, { + const response = await fetch(LOG_ENTRIES_SUMMARY_HIGHLIGHTS_PATH, { method: 'POST', body: JSON.stringify(logEntriesSummaryHighlightsRequestRT.encode(requestArgs)), }); - return pipe( - logEntriesSummaryHighlightsResponseRT.decode(response), - fold(throwErrors(createPlainError), identity) - ); + return decodeOrThrow(logEntriesSummaryHighlightsResponseRT)(response); }; diff --git a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_entry_highlights.tsx b/x-pack/plugins/infra/public/containers/logs/log_highlights/log_entry_highlights.tsx index dbeb8c71c11eb..b4edebe8f8207 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_entry_highlights.tsx +++ b/x-pack/plugins/infra/public/containers/logs/log_highlights/log_entry_highlights.tsx @@ -10,6 +10,7 @@ import { TimeKey } from '../../../../common/time'; import { useTrackedPromise } from '../../../utils/use_tracked_promise'; import { fetchLogEntriesHighlights } from './api/fetch_log_entries_highlights'; import { LogEntry, LogEntriesHighlightsResponse } from '../../../../common/http_api'; +import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; export const useLogEntryHighlights = ( sourceId: string, @@ -21,6 +22,7 @@ export const useLogEntryHighlights = ( filterQuery: string | null, highlightTerms: string[] ) => { + const { services } = useKibanaContextForPlugin(); const [logEntryHighlights, setLogEntryHighlights] = useState< LogEntriesHighlightsResponse['data'] >([]); @@ -32,15 +34,18 @@ export const useLogEntryHighlights = ( throw new Error('Skipping request: Insufficient parameters'); } - return await fetchLogEntriesHighlights({ - sourceId, - startTimestamp, - endTimestamp, - center: centerPoint, - size, - query: filterQuery || undefined, - highlightTerms, - }); + return await fetchLogEntriesHighlights( + { + sourceId, + startTimestamp, + endTimestamp, + center: centerPoint, + size, + query: filterQuery || undefined, + highlightTerms, + }, + services.http.fetch + ); }, onResolve: (response) => { setLogEntryHighlights(response.data); diff --git a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_summary_highlights.ts b/x-pack/plugins/infra/public/containers/logs/log_highlights/log_summary_highlights.ts index 6d982ee004ccc..14366891dbf59 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_highlights/log_summary_highlights.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_highlights/log_summary_highlights.ts @@ -11,6 +11,7 @@ import { useTrackedPromise } from '../../../utils/use_tracked_promise'; import { fetchLogSummaryHighlights } from './api/fetch_log_summary_highlights'; import { LogEntriesSummaryHighlightsResponse } from '../../../../common/http_api'; import { useBucketSize } from '../log_summary/bucket_size'; +import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; export const useLogSummaryHighlights = ( sourceId: string, @@ -20,6 +21,7 @@ export const useLogSummaryHighlights = ( filterQuery: string | null, highlightTerms: string[] ) => { + const { services } = useKibanaContextForPlugin(); const [logSummaryHighlights, setLogSummaryHighlights] = useState< LogEntriesSummaryHighlightsResponse['data'] >([]); @@ -34,14 +36,17 @@ export const useLogSummaryHighlights = ( throw new Error('Skipping request: Insufficient parameters'); } - return await fetchLogSummaryHighlights({ - sourceId, - startTimestamp, - endTimestamp, - bucketSize, - query: filterQuery, - highlightTerms, - }); + return await fetchLogSummaryHighlights( + { + sourceId, + startTimestamp, + endTimestamp, + bucketSize, + query: filterQuery, + highlightTerms, + }, + services.http.fetch + ); }, onResolve: (response) => { setLogSummaryHighlights(response.data); diff --git a/x-pack/plugins/infra/public/containers/logs/log_source/api/fetch_log_source_configuration.ts b/x-pack/plugins/infra/public/containers/logs/log_source/api/fetch_log_source_configuration.ts index e847302a6d367..c9ced069473a3 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_source/api/fetch_log_source_configuration.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_source/api/fetch_log_source_configuration.ts @@ -4,17 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import { HttpSetup } from 'src/core/public'; +import type { HttpHandler } from 'src/core/public'; import { getLogSourceConfigurationPath, getLogSourceConfigurationSuccessResponsePayloadRT, } from '../../../../../common/http_api/log_sources'; import { decodeOrThrow } from '../../../../../common/runtime_types'; -export const callFetchLogSourceConfigurationAPI = async ( - sourceId: string, - fetch: HttpSetup['fetch'] -) => { +export const callFetchLogSourceConfigurationAPI = async (sourceId: string, fetch: HttpHandler) => { const response = await fetch(getLogSourceConfigurationPath(sourceId), { method: 'GET', }); diff --git a/x-pack/plugins/infra/public/containers/logs/log_source/api/fetch_log_source_status.ts b/x-pack/plugins/infra/public/containers/logs/log_source/api/fetch_log_source_status.ts index 20e67a0a59c9f..5bc409115e595 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_source/api/fetch_log_source_status.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_source/api/fetch_log_source_status.ts @@ -4,14 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import { HttpSetup } from 'src/core/public'; +import type { HttpHandler } from 'src/core/public'; import { getLogSourceStatusPath, getLogSourceStatusSuccessResponsePayloadRT, } from '../../../../../common/http_api/log_sources'; import { decodeOrThrow } from '../../../../../common/runtime_types'; -export const callFetchLogSourceStatusAPI = async (sourceId: string, fetch: HttpSetup['fetch']) => { +export const callFetchLogSourceStatusAPI = async (sourceId: string, fetch: HttpHandler) => { const response = await fetch(getLogSourceStatusPath(sourceId), { method: 'GET', }); diff --git a/x-pack/plugins/infra/public/containers/logs/log_source/api/patch_log_source_configuration.ts b/x-pack/plugins/infra/public/containers/logs/log_source/api/patch_log_source_configuration.ts index 4361e4bef827f..33212c5d3b0f2 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_source/api/patch_log_source_configuration.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_source/api/patch_log_source_configuration.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { HttpSetup } from 'src/core/public'; +import type { HttpHandler } from 'src/core/public'; import { getLogSourceConfigurationPath, patchLogSourceConfigurationSuccessResponsePayloadRT, @@ -16,7 +16,7 @@ import { decodeOrThrow } from '../../../../../common/runtime_types'; export const callPatchLogSourceConfigurationAPI = async ( sourceId: string, patchedProperties: LogSourceConfigurationPropertiesPatch, - fetch: HttpSetup['fetch'] + fetch: HttpHandler ) => { const response = await fetch(getLogSourceConfigurationPath(sourceId), { method: 'PATCH', diff --git a/x-pack/plugins/infra/public/containers/logs/log_source/log_source.ts b/x-pack/plugins/infra/public/containers/logs/log_source/log_source.ts index 51b32a4c4eacf..e2dd4c523c03f 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_source/log_source.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_source/log_source.ts @@ -7,7 +7,7 @@ import createContainer from 'constate'; import { useCallback, useMemo, useState } from 'react'; import { useMountedState } from 'react-use'; -import { HttpSetup } from 'src/core/public'; +import type { HttpHandler } from 'src/core/public'; import { LogSourceConfiguration, LogSourceConfigurationProperties, @@ -26,13 +26,7 @@ export { LogSourceStatus, }; -export const useLogSource = ({ - sourceId, - fetch, -}: { - sourceId: string; - fetch: HttpSetup['fetch']; -}) => { +export const useLogSource = ({ sourceId, fetch }: { sourceId: string; fetch: HttpHandler }) => { const getIsMounted = useMountedState(); const [sourceConfiguration, setSourceConfiguration] = useState< LogSourceConfiguration | undefined diff --git a/x-pack/plugins/infra/public/containers/logs/log_stream/index.ts b/x-pack/plugins/infra/public/containers/logs/log_stream/index.ts index b414408512db2..4a6da6063e960 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_stream/index.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_stream/index.ts @@ -9,6 +9,7 @@ import { esKuery } from '../../../../../../../src/plugins/data/public'; import { fetchLogEntries } from '../log_entries/api/fetch_log_entries'; import { useTrackedPromise } from '../../../utils/use_tracked_promise'; import { LogEntry, LogEntriesCursor } from '../../../../common/http_api'; +import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; interface LogStreamProps { sourceId: string; @@ -31,6 +32,7 @@ export function useLogStream({ query, center, }: LogStreamProps): LogStreamState { + const { services } = useKibanaContextForPlugin(); const [entries, setEntries] = useState([]); const parsedQuery = useMemo(() => { @@ -47,13 +49,16 @@ export function useLogStream({ setEntries([]); const fetchPosition = center ? { center } : { before: 'last' }; - return fetchLogEntries({ - sourceId, - startTimestamp, - endTimestamp, - query: parsedQuery, - ...fetchPosition, - }); + return fetchLogEntries( + { + sourceId, + startTimestamp, + endTimestamp, + query: parsedQuery, + ...fetchPosition, + }, + services.http.fetch + ); }, onResolve: ({ data }) => { setEntries(data.entries); diff --git a/x-pack/plugins/infra/public/containers/logs/log_summary/api/fetch_log_summary.ts b/x-pack/plugins/infra/public/containers/logs/log_summary/api/fetch_log_summary.ts index f74f0dc0e3117..2be6538e21ebe 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_summary/api/fetch_log_summary.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_summary/api/fetch_log_summary.ts @@ -4,11 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { fold } from 'fp-ts/lib/Either'; -import { pipe } from 'fp-ts/lib/pipeable'; -import { identity } from 'fp-ts/lib/function'; -import { npStart } from '../../../../legacy_singletons'; -import { throwErrors, createPlainError } from '../../../../../common/runtime_types'; +import type { HttpHandler } from 'src/core/public'; +import { decodeOrThrow } from '../../../../../common/runtime_types'; import { LOG_ENTRIES_SUMMARY_PATH, @@ -17,14 +14,14 @@ import { logEntriesSummaryResponseRT, } from '../../../../../common/http_api'; -export const fetchLogSummary = async (requestArgs: LogEntriesSummaryRequest) => { - const response = await npStart.http.fetch(LOG_ENTRIES_SUMMARY_PATH, { +export const fetchLogSummary = async ( + requestArgs: LogEntriesSummaryRequest, + fetch: HttpHandler +) => { + const response = await fetch(LOG_ENTRIES_SUMMARY_PATH, { method: 'POST', body: JSON.stringify(logEntriesSummaryRequestRT.encode(requestArgs)), }); - return pipe( - logEntriesSummaryResponseRT.decode(response), - fold(throwErrors(createPlainError), identity) - ); + return decodeOrThrow(logEntriesSummaryResponseRT)(response); }; diff --git a/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.test.tsx b/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.test.tsx index 73d0e5efdf06b..652ea8c71dc44 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.test.tsx +++ b/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.test.tsx @@ -5,6 +5,8 @@ */ import { renderHook } from '@testing-library/react-hooks'; +// We are using this inside a `jest.mock` call. Jest requires dynamic dependencies to be prefixed with `mock` +import { coreMock as mockCoreMock } from 'src/core/public/mocks'; import { useLogSummary } from './log_summary'; @@ -16,6 +18,10 @@ import { datemathToEpochMillis } from '../../../utils/datemath'; jest.mock('./api/fetch_log_summary', () => ({ fetchLogSummary: jest.fn() })); const fetchLogSummaryMock = fetchLogSummary as jest.MockedFunction; +jest.mock('../../../hooks/use_kibana', () => ({ + useKibanaContextForPlugin: () => ({ services: mockCoreMock.createStart() }), +})); + describe('useLogSummary hook', () => { beforeEach(() => { fetchLogSummaryMock.mockClear(); @@ -53,7 +59,8 @@ describe('useLogSummary hook', () => { expect(fetchLogSummaryMock).toHaveBeenLastCalledWith( expect.objectContaining({ sourceId: 'INITIAL_SOURCE_ID', - }) + }), + expect.anything() ); expect(result.current.buckets).toEqual(firstMockResponse.data.buckets); @@ -64,7 +71,8 @@ describe('useLogSummary hook', () => { expect(fetchLogSummaryMock).toHaveBeenLastCalledWith( expect.objectContaining({ sourceId: 'CHANGED_SOURCE_ID', - }) + }), + expect.anything() ); expect(result.current.buckets).toEqual(secondMockResponse.data.buckets); }); @@ -96,7 +104,8 @@ describe('useLogSummary hook', () => { expect(fetchLogSummaryMock).toHaveBeenLastCalledWith( expect.objectContaining({ query: 'INITIAL_FILTER_QUERY', - }) + }), + expect.anything() ); expect(result.current.buckets).toEqual(firstMockResponse.data.buckets); @@ -107,7 +116,8 @@ describe('useLogSummary hook', () => { expect(fetchLogSummaryMock).toHaveBeenLastCalledWith( expect.objectContaining({ query: 'CHANGED_FILTER_QUERY', - }) + }), + expect.anything() ); expect(result.current.buckets).toEqual(secondMockResponse.data.buckets); }); @@ -132,7 +142,8 @@ describe('useLogSummary hook', () => { expect.objectContaining({ startTimestamp: firstRange.startTimestamp, endTimestamp: firstRange.endTimestamp, - }) + }), + expect.anything() ); const secondRange = createMockDateRange('now-20s', 'now'); @@ -145,7 +156,8 @@ describe('useLogSummary hook', () => { expect.objectContaining({ startTimestamp: secondRange.startTimestamp, endTimestamp: secondRange.endTimestamp, - }) + }), + expect.anything() ); }); }); diff --git a/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.tsx b/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.tsx index b83be77656863..be0d87f5d267d 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.tsx +++ b/x-pack/plugins/infra/public/containers/logs/log_summary/log_summary.tsx @@ -10,6 +10,7 @@ import { useCancellableEffect } from '../../../utils/cancellable_effect'; import { fetchLogSummary } from './api/fetch_log_summary'; import { LogEntriesSummaryResponse } from '../../../../common/http_api'; import { useBucketSize } from './bucket_size'; +import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; export type LogSummaryBuckets = LogEntriesSummaryResponse['data']['buckets']; @@ -19,6 +20,7 @@ export const useLogSummary = ( endTimestamp: number | null, filterQuery: string | null ) => { + const { services } = useKibanaContextForPlugin(); const [logSummaryBuckets, setLogSummaryBuckets] = useState([]); const bucketSize = useBucketSize(startTimestamp, endTimestamp); @@ -28,13 +30,16 @@ export const useLogSummary = ( return; } - fetchLogSummary({ - sourceId, - startTimestamp, - endTimestamp, - bucketSize, - query: filterQuery, - }).then((response) => { + fetchLogSummary( + { + sourceId, + startTimestamp, + endTimestamp, + bucketSize, + query: filterQuery, + }, + services.http.fetch + ).then((response) => { if (!getIsCancelled()) { setLogSummaryBuckets(response.data.buckets); } diff --git a/x-pack/plugins/infra/public/containers/ml/api/ml_cleanup.ts b/x-pack/plugins/infra/public/containers/ml/api/ml_cleanup.ts index 23fa338e74f14..fa7d8f14c6a9a 100644 --- a/x-pack/plugins/infra/public/containers/ml/api/ml_cleanup.ts +++ b/x-pack/plugins/infra/public/containers/ml/api/ml_cleanup.ts @@ -5,21 +5,24 @@ */ import * as rt from 'io-ts'; -import { pipe } from 'fp-ts/lib/pipeable'; -import { fold } from 'fp-ts/lib/Either'; -import { identity } from 'fp-ts/lib/function'; -import { npStart } from '../../../legacy_singletons'; - +import type { HttpHandler } from 'src/core/public'; import { getDatafeedId, getJobId } from '../../../../common/infra_ml'; -import { throwErrors, createPlainError } from '../../../../common/runtime_types'; +import { decodeOrThrow } from '../../../../common/runtime_types'; + +interface DeleteJobsRequestArgs { + spaceId: string; + sourceId: string; + jobTypes: JobType[]; +} export const callDeleteJobs = async ( - spaceId: string, - sourceId: string, - jobTypes: JobType[] + requestArgs: DeleteJobsRequestArgs, + fetch: HttpHandler ) => { + const { spaceId, sourceId, jobTypes } = requestArgs; + // NOTE: Deleting the jobs via this API will delete the datafeeds at the same time - const deleteJobsResponse = await npStart.http.fetch('/api/ml/jobs/delete_jobs', { + const deleteJobsResponse = await fetch('/api/ml/jobs/delete_jobs', { method: 'POST', body: JSON.stringify( deleteJobsRequestPayloadRT.encode({ @@ -28,28 +31,29 @@ export const callDeleteJobs = async ( ), }); - return pipe( - deleteJobsResponsePayloadRT.decode(deleteJobsResponse), - fold(throwErrors(createPlainError), identity) - ); + return decodeOrThrow(deleteJobsResponsePayloadRT)(deleteJobsResponse); }; -export const callGetJobDeletionTasks = async () => { - const jobDeletionTasksResponse = await npStart.http.fetch('/api/ml/jobs/deleting_jobs_tasks'); +export const callGetJobDeletionTasks = async (fetch: HttpHandler) => { + const jobDeletionTasksResponse = await fetch('/api/ml/jobs/deleting_jobs_tasks'); - return pipe( - getJobDeletionTasksResponsePayloadRT.decode(jobDeletionTasksResponse), - fold(throwErrors(createPlainError), identity) - ); + return decodeOrThrow(getJobDeletionTasksResponsePayloadRT)(jobDeletionTasksResponse); }; +interface StopDatafeedsRequestArgs { + spaceId: string; + sourceId: string; + jobTypes: JobType[]; +} + export const callStopDatafeeds = async ( - spaceId: string, - sourceId: string, - jobTypes: JobType[] + requestArgs: StopDatafeedsRequestArgs, + fetch: HttpHandler ) => { + const { spaceId, sourceId, jobTypes } = requestArgs; + // Stop datafeed due to https://github.com/elastic/kibana/issues/44652 - const stopDatafeedResponse = await npStart.http.fetch('/api/ml/jobs/stop_datafeeds', { + const stopDatafeedResponse = await fetch('/api/ml/jobs/stop_datafeeds', { method: 'POST', body: JSON.stringify( stopDatafeedsRequestPayloadRT.encode({ @@ -58,10 +62,7 @@ export const callStopDatafeeds = async ( ), }); - return pipe( - stopDatafeedsResponsePayloadRT.decode(stopDatafeedResponse), - fold(throwErrors(createPlainError), identity) - ); + return decodeOrThrow(stopDatafeedsResponsePayloadRT)(stopDatafeedResponse); }; export const deleteJobsRequestPayloadRT = rt.type({ diff --git a/x-pack/plugins/infra/public/containers/ml/api/ml_get_jobs_summary_api.ts b/x-pack/plugins/infra/public/containers/ml/api/ml_get_jobs_summary_api.ts index 3fddb63f69791..84b5df3d172c7 100644 --- a/x-pack/plugins/infra/public/containers/ml/api/ml_get_jobs_summary_api.ts +++ b/x-pack/plugins/infra/public/containers/ml/api/ml_get_jobs_summary_api.ts @@ -4,21 +4,24 @@ * you may not use this file except in compliance with the Elastic License. */ -import { fold } from 'fp-ts/lib/Either'; -import { identity } from 'fp-ts/lib/function'; -import { pipe } from 'fp-ts/lib/pipeable'; import * as rt from 'io-ts'; -import { npStart } from '../../../legacy_singletons'; +import type { HttpHandler } from 'src/core/public'; import { getJobId, jobCustomSettingsRT } from '../../../../common/infra_ml'; -import { createPlainError, throwErrors } from '../../../../common/runtime_types'; +import { decodeOrThrow } from '../../../../common/runtime_types'; + +interface RequestArgs { + spaceId: string; + sourceId: string; + jobTypes: JobType[]; +} export const callJobsSummaryAPI = async ( - spaceId: string, - sourceId: string, - jobTypes: JobType[] + requestArgs: RequestArgs, + fetch: HttpHandler ) => { - const response = await npStart.http.fetch('/api/ml/jobs/jobs_summary', { + const { spaceId, sourceId, jobTypes } = requestArgs; + const response = await fetch('/api/ml/jobs/jobs_summary', { method: 'POST', body: JSON.stringify( fetchJobStatusRequestPayloadRT.encode({ @@ -26,10 +29,7 @@ export const callJobsSummaryAPI = async ( }) ), }); - return pipe( - fetchJobStatusResponsePayloadRT.decode(response), - fold(throwErrors(createPlainError), identity) - ); + return decodeOrThrow(fetchJobStatusResponsePayloadRT)(response); }; export const fetchJobStatusRequestPayloadRT = rt.type({ diff --git a/x-pack/plugins/infra/public/containers/ml/api/ml_get_module.ts b/x-pack/plugins/infra/public/containers/ml/api/ml_get_module.ts index d492522c120a1..75ce335fbe49c 100644 --- a/x-pack/plugins/infra/public/containers/ml/api/ml_get_module.ts +++ b/x-pack/plugins/infra/public/containers/ml/api/ml_get_module.ts @@ -4,24 +4,18 @@ * you may not use this file except in compliance with the Elastic License. */ -import { fold } from 'fp-ts/lib/Either'; -import { identity } from 'fp-ts/lib/function'; -import { pipe } from 'fp-ts/lib/pipeable'; import * as rt from 'io-ts'; -import { npStart } from '../../../legacy_singletons'; +import type { HttpHandler } from 'src/core/public'; import { jobCustomSettingsRT } from '../../../../common/log_analysis'; -import { createPlainError, throwErrors } from '../../../../common/runtime_types'; +import { decodeOrThrow } from '../../../../common/runtime_types'; -export const callGetMlModuleAPI = async (moduleId: string) => { - const response = await npStart.http.fetch(`/api/ml/modules/get_module/${moduleId}`, { +export const callGetMlModuleAPI = async (moduleId: string, fetch: HttpHandler) => { + const response = await fetch(`/api/ml/modules/get_module/${moduleId}`, { method: 'GET', }); - return pipe( - getMlModuleResponsePayloadRT.decode(response), - fold(throwErrors(createPlainError), identity) - ); + return decodeOrThrow(getMlModuleResponsePayloadRT)(response); }; const jobDefinitionRT = rt.type({ diff --git a/x-pack/plugins/infra/public/containers/ml/api/ml_setup_module_api.ts b/x-pack/plugins/infra/public/containers/ml/api/ml_setup_module_api.ts index 06b0e075387b0..36dced1bd2680 100644 --- a/x-pack/plugins/infra/public/containers/ml/api/ml_setup_module_api.ts +++ b/x-pack/plugins/infra/public/containers/ml/api/ml_setup_module_api.ts @@ -4,27 +4,38 @@ * you may not use this file except in compliance with the Elastic License. */ -import { fold } from 'fp-ts/lib/Either'; -import { identity } from 'fp-ts/lib/function'; -import { pipe } from 'fp-ts/lib/pipeable'; import * as rt from 'io-ts'; -import { npStart } from '../../../legacy_singletons'; +import type { HttpHandler } from 'src/core/public'; import { getJobIdPrefix, jobCustomSettingsRT } from '../../../../common/infra_ml'; -import { createPlainError, throwErrors } from '../../../../common/runtime_types'; - -export const callSetupMlModuleAPI = async ( - moduleId: string, - start: number | undefined, - end: number | undefined, - spaceId: string, - sourceId: string, - indexPattern: string, - jobOverrides: SetupMlModuleJobOverrides[] = [], - datafeedOverrides: SetupMlModuleDatafeedOverrides[] = [], - query?: object -) => { - const response = await npStart.http.fetch(`/api/ml/modules/setup/${moduleId}`, { +import { decodeOrThrow } from '../../../../common/runtime_types'; + +interface RequestArgs { + moduleId: string; + start?: number; + end?: number; + spaceId: string; + sourceId: string; + indexPattern: string; + jobOverrides?: SetupMlModuleJobOverrides[]; + datafeedOverrides?: SetupMlModuleDatafeedOverrides[]; + query?: object; +} + +export const callSetupMlModuleAPI = async (requestArgs: RequestArgs, fetch: HttpHandler) => { + const { + moduleId, + start, + end, + spaceId, + sourceId, + indexPattern, + jobOverrides = [], + datafeedOverrides = [], + query, + } = requestArgs; + + const response = await fetch(`/api/ml/modules/setup/${moduleId}`, { method: 'POST', body: JSON.stringify( setupMlModuleRequestPayloadRT.encode({ @@ -40,10 +51,7 @@ export const callSetupMlModuleAPI = async ( ), }); - return pipe( - setupMlModuleResponsePayloadRT.decode(response), - fold(throwErrors(createPlainError), identity) - ); + return decodeOrThrow(setupMlModuleResponsePayloadRT)(response); }; const setupMlModuleTimeParamsRT = rt.partial({ diff --git a/x-pack/plugins/infra/public/containers/ml/infra_ml_capabilities.tsx b/x-pack/plugins/infra/public/containers/ml/infra_ml_capabilities.tsx index f4c90a459af6a..bc488a51e2aff 100644 --- a/x-pack/plugins/infra/public/containers/ml/infra_ml_capabilities.tsx +++ b/x-pack/plugins/infra/public/containers/ml/infra_ml_capabilities.tsx @@ -10,14 +10,15 @@ import { fold } from 'fp-ts/lib/Either'; import { pipe } from 'fp-ts/lib/pipeable'; import { identity } from 'fp-ts/lib/function'; import { useTrackedPromise } from '../../utils/use_tracked_promise'; -import { npStart } from '../../legacy_singletons'; import { getMlCapabilitiesResponsePayloadRT, GetMlCapabilitiesResponsePayload, } from './api/ml_api_types'; import { throwErrors, createPlainError } from '../../../common/runtime_types'; +import { useKibanaContextForPlugin } from '../../hooks/use_kibana'; export const useInfraMLCapabilities = () => { + const { services } = useKibanaContextForPlugin(); const [mlCapabilities, setMlCapabilities] = useState( initialMlCapabilities ); @@ -26,7 +27,7 @@ export const useInfraMLCapabilities = () => { { cancelPreviousOn: 'resolution', createPromise: async () => { - const rawResponse = await npStart.http.fetch('/api/ml/ml_capabilities'); + const rawResponse = await services.http.fetch('/api/ml/ml_capabilities'); return pipe( getMlCapabilitiesResponsePayloadRT.decode(rawResponse), diff --git a/x-pack/plugins/infra/public/containers/ml/infra_ml_cleanup.tsx b/x-pack/plugins/infra/public/containers/ml/infra_ml_cleanup.tsx index 736982c8043b1..871e61ecfe507 100644 --- a/x-pack/plugins/infra/public/containers/ml/infra_ml_cleanup.tsx +++ b/x-pack/plugins/infra/public/containers/ml/infra_ml_cleanup.tsx @@ -4,16 +4,18 @@ * you may not use this file except in compliance with the Elastic License. */ +import { HttpHandler } from 'src/core/public'; import { getJobId } from '../../../common/infra_ml'; import { callDeleteJobs, callGetJobDeletionTasks, callStopDatafeeds } from './api/ml_cleanup'; export const cleanUpJobsAndDatafeeds = async ( spaceId: string, sourceId: string, - jobTypes: JobType[] + jobTypes: JobType[], + fetch: HttpHandler ) => { try { - await callStopDatafeeds(spaceId, sourceId, jobTypes); + await callStopDatafeeds({ spaceId, sourceId, jobTypes }, fetch); } catch (err) { // Proceed only if datafeed has been deleted or didn't exist in the first place if (err?.res?.status !== 404) { @@ -21,27 +23,29 @@ export const cleanUpJobsAndDatafeeds = async ( } } - return await deleteJobs(spaceId, sourceId, jobTypes); + return await deleteJobs(spaceId, sourceId, jobTypes, fetch); }; const deleteJobs = async ( spaceId: string, sourceId: string, - jobTypes: JobType[] + jobTypes: JobType[], + fetch: HttpHandler ) => { - const deleteJobsResponse = await callDeleteJobs(spaceId, sourceId, jobTypes); - await waitUntilJobsAreDeleted(spaceId, sourceId, jobTypes); + const deleteJobsResponse = await callDeleteJobs({ spaceId, sourceId, jobTypes }, fetch); + await waitUntilJobsAreDeleted(spaceId, sourceId, jobTypes, fetch); return deleteJobsResponse; }; const waitUntilJobsAreDeleted = async ( spaceId: string, sourceId: string, - jobTypes: JobType[] + jobTypes: JobType[], + fetch: HttpHandler ) => { const moduleJobIds = jobTypes.map((jobType) => getJobId(spaceId, sourceId, jobType)); while (true) { - const { jobIds: jobIdsBeingDeleted } = await callGetJobDeletionTasks(); + const { jobIds: jobIdsBeingDeleted } = await callGetJobDeletionTasks(fetch); const needToWait = jobIdsBeingDeleted.some((jobId) => moduleJobIds.includes(jobId)); if (needToWait) { diff --git a/x-pack/plugins/infra/public/containers/ml/infra_ml_module.tsx b/x-pack/plugins/infra/public/containers/ml/infra_ml_module.tsx index 349541d108f5e..5408084a5246e 100644 --- a/x-pack/plugins/infra/public/containers/ml/infra_ml_module.tsx +++ b/x-pack/plugins/infra/public/containers/ml/infra_ml_module.tsx @@ -6,6 +6,7 @@ import { useCallback, useMemo } from 'react'; import { DatasetFilter } from '../../../common/infra_ml'; +import { useKibanaContextForPlugin } from '../../hooks/use_kibana'; import { useTrackedPromise } from '../../utils/use_tracked_promise'; import { useModuleStatus } from './infra_ml_module_status'; import { ModuleDescriptor, ModuleSourceConfiguration } from './infra_ml_module_types'; @@ -17,6 +18,7 @@ export const useInfraMLModule = ({ sourceConfiguration: ModuleSourceConfiguration; moduleDescriptor: ModuleDescriptor; }) => { + const { services } = useKibanaContextForPlugin(); const { spaceId, sourceId, timestampField } = sourceConfiguration; const [moduleStatus, dispatchModuleStatus] = useModuleStatus(moduleDescriptor.jobTypes); @@ -25,7 +27,7 @@ export const useInfraMLModule = ({ cancelPreviousOn: 'resolution', createPromise: async () => { dispatchModuleStatus({ type: 'fetchingJobStatuses' }); - return await moduleDescriptor.getJobSummary(spaceId, sourceId); + return await moduleDescriptor.getJobSummary(spaceId, sourceId, services.http.fetch); }, onResolve: (jobResponse) => { dispatchModuleStatus({ @@ -54,18 +56,25 @@ export const useInfraMLModule = ({ ) => { dispatchModuleStatus({ type: 'startedSetup' }); const setupResult = await moduleDescriptor.setUpModule( - start, - end, - datasetFilter, { - indices: selectedIndices, - sourceId, - spaceId, - timestampField, + start, + end, + datasetFilter, + moduleSourceConfiguration: { + indices: selectedIndices, + sourceId, + spaceId, + timestampField, + }, + partitionField, }, - partitionField + services.http.fetch + ); + const jobSummaries = await moduleDescriptor.getJobSummary( + spaceId, + sourceId, + services.http.fetch ); - const jobSummaries = await moduleDescriptor.getJobSummary(spaceId, sourceId); return { setupResult, jobSummaries }; }, onResolve: ({ setupResult: { datafeeds, jobs }, jobSummaries }) => { @@ -89,7 +98,7 @@ export const useInfraMLModule = ({ { cancelPreviousOn: 'resolution', createPromise: async () => { - return await moduleDescriptor.cleanUpModule(spaceId, sourceId); + return await moduleDescriptor.cleanUpModule(spaceId, sourceId, services.http.fetch); }, }, [spaceId, sourceId] diff --git a/x-pack/plugins/infra/public/containers/ml/infra_ml_module_definition.tsx b/x-pack/plugins/infra/public/containers/ml/infra_ml_module_definition.tsx index 3c7ffcfd4a4e2..a747a2853d1f7 100644 --- a/x-pack/plugins/infra/public/containers/ml/infra_ml_module_definition.tsx +++ b/x-pack/plugins/infra/public/containers/ml/infra_ml_module_definition.tsx @@ -6,6 +6,7 @@ import { useCallback, useMemo, useState } from 'react'; import { getJobId } from '../../../common/log_analysis'; +import { useKibanaContextForPlugin } from '../../hooks/use_kibana'; import { useTrackedPromise } from '../../utils/use_tracked_promise'; import { JobSummary } from './api/ml_get_jobs_summary_api'; import { GetMlModuleResponsePayload, JobDefinition } from './api/ml_get_module'; @@ -18,6 +19,7 @@ export const useInfraMLModuleDefinition = ({ sourceConfiguration: ModuleSourceConfiguration; moduleDescriptor: ModuleDescriptor; }) => { + const { services } = useKibanaContextForPlugin(); const [moduleDefinition, setModuleDefinition] = useState< GetMlModuleResponsePayload | undefined >(); @@ -40,7 +42,7 @@ export const useInfraMLModuleDefinition = ({ { cancelPreviousOn: 'resolution', createPromise: async () => { - return await moduleDescriptor.getModuleDefinition(); + return await moduleDescriptor.getModuleDefinition(services.http.fetch); }, onResolve: (response) => { setModuleDefinition(response); diff --git a/x-pack/plugins/infra/public/containers/ml/infra_ml_module_types.ts b/x-pack/plugins/infra/public/containers/ml/infra_ml_module_types.ts index a9f2671de8259..976a64e8034bc 100644 --- a/x-pack/plugins/infra/public/containers/ml/infra_ml_module_types.ts +++ b/x-pack/plugins/infra/public/containers/ml/infra_ml_module_types.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 { HttpHandler } from 'src/core/public'; import { ValidateLogEntryDatasetsResponsePayload, ValidationIndicesResponsePayload, @@ -16,6 +16,14 @@ import { SetupMlModuleResponsePayload } from './api/ml_setup_module_api'; export { JobModelSizeStats, JobSummary } from './api/ml_get_jobs_summary_api'; +export interface SetUpModuleArgs { + start?: number | undefined; + end?: number | undefined; + datasetFilter?: DatasetFilter; + moduleSourceConfiguration: ModuleSourceConfiguration; + partitionField?: string; +} + export interface ModuleDescriptor { moduleId: string; moduleName: string; @@ -23,25 +31,32 @@ export interface ModuleDescriptor { jobTypes: JobType[]; bucketSpan: number; getJobIds: (spaceId: string, sourceId: string) => Record; - getJobSummary: (spaceId: string, sourceId: string) => Promise; - getModuleDefinition: () => Promise; + getJobSummary: ( + spaceId: string, + sourceId: string, + fetch: HttpHandler + ) => Promise; + getModuleDefinition: (fetch: HttpHandler) => Promise; setUpModule: ( - start: number | undefined, - end: number | undefined, - datasetFilter: DatasetFilter, - sourceConfiguration: ModuleSourceConfiguration, - partitionField?: string + setUpModuleArgs: SetUpModuleArgs, + fetch: HttpHandler ) => Promise; - cleanUpModule: (spaceId: string, sourceId: string) => Promise; - validateSetupIndices: ( + cleanUpModule: ( + spaceId: string, + sourceId: string, + fetch: HttpHandler + ) => Promise; + validateSetupIndices?: ( indices: string[], - timestampField: string + timestampField: string, + fetch: HttpHandler ) => Promise; - validateSetupDatasets: ( + validateSetupDatasets?: ( indices: string[], timestampField: string, startTime: number, - endTime: number + endTime: number, + fetch: HttpHandler ) => Promise; } diff --git a/x-pack/plugins/infra/public/containers/ml/infra_ml_setup_state.ts b/x-pack/plugins/infra/public/containers/ml/infra_ml_setup_state.ts deleted file mode 100644 index 0dfe3b301f240..0000000000000 --- a/x-pack/plugins/infra/public/containers/ml/infra_ml_setup_state.ts +++ /dev/null @@ -1,289 +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 { isEqual } from 'lodash'; -import { useCallback, useEffect, useMemo, useState } from 'react'; -import { usePrevious } from 'react-use'; -import { - combineDatasetFilters, - DatasetFilter, - filterDatasetFilter, - isExampleDataIndex, -} from '../../../common/infra_ml'; -import { - AvailableIndex, - ValidationIndicesError, - ValidationUIError, -} from '../../components/logging/log_analysis_setup/initial_configuration_step'; -import { useTrackedPromise } from '../../utils/use_tracked_promise'; -import { ModuleDescriptor, ModuleSourceConfiguration } from './infra_ml_module_types'; - -type SetupHandler = ( - indices: string[], - startTime: number | undefined, - endTime: number | undefined, - datasetFilter: DatasetFilter -) => void; - -interface AnalysisSetupStateArguments { - cleanUpAndSetUpModule: SetupHandler; - moduleDescriptor: ModuleDescriptor; - setUpModule: SetupHandler; - sourceConfiguration: ModuleSourceConfiguration; -} - -const fourWeeksInMs = 86400000 * 7 * 4; - -export const useAnalysisSetupState = ({ - cleanUpAndSetUpModule, - moduleDescriptor: { validateSetupDatasets, validateSetupIndices }, - setUpModule, - sourceConfiguration, -}: AnalysisSetupStateArguments) => { - const [startTime, setStartTime] = useState(Date.now() - fourWeeksInMs); - const [endTime, setEndTime] = useState(undefined); - - const isTimeRangeValid = useMemo( - () => (startTime != null && endTime != null ? startTime < endTime : true), - [endTime, startTime] - ); - - const [validatedIndices, setValidatedIndices] = useState( - sourceConfiguration.indices.map((indexName) => ({ - name: indexName, - validity: 'unknown' as const, - })) - ); - - const updateIndicesWithValidationErrors = useCallback( - (validationErrors: ValidationIndicesError[]) => - setValidatedIndices((availableIndices) => - availableIndices.map((previousAvailableIndex) => { - const indexValiationErrors = validationErrors.filter( - ({ index }) => index === previousAvailableIndex.name - ); - - if (indexValiationErrors.length > 0) { - return { - validity: 'invalid', - name: previousAvailableIndex.name, - errors: indexValiationErrors, - }; - } else if (previousAvailableIndex.validity === 'valid') { - return { - ...previousAvailableIndex, - validity: 'valid', - errors: [], - }; - } else { - return { - validity: 'valid', - name: previousAvailableIndex.name, - isSelected: !isExampleDataIndex(previousAvailableIndex.name), - availableDatasets: [], - datasetFilter: { - type: 'includeAll' as const, - }, - }; - } - }) - ), - [] - ); - - const updateIndicesWithAvailableDatasets = useCallback( - (availableDatasets: Array<{ indexName: string; datasets: string[] }>) => - setValidatedIndices((availableIndices) => - availableIndices.map((previousAvailableIndex) => { - if (previousAvailableIndex.validity !== 'valid') { - return previousAvailableIndex; - } - - const availableDatasetsForIndex = availableDatasets.filter( - ({ indexName }) => indexName === previousAvailableIndex.name - ); - const newAvailableDatasets = availableDatasetsForIndex.flatMap( - ({ datasets }) => datasets - ); - - // filter out datasets that have disappeared if this index' datasets were updated - const newDatasetFilter: DatasetFilter = - availableDatasetsForIndex.length > 0 - ? filterDatasetFilter(previousAvailableIndex.datasetFilter, (dataset) => - newAvailableDatasets.includes(dataset) - ) - : previousAvailableIndex.datasetFilter; - - return { - ...previousAvailableIndex, - availableDatasets: newAvailableDatasets, - datasetFilter: newDatasetFilter, - }; - }) - ), - [] - ); - - const validIndexNames = useMemo( - () => validatedIndices.filter((index) => index.validity === 'valid').map((index) => index.name), - [validatedIndices] - ); - - const selectedIndexNames = useMemo( - () => - validatedIndices - .filter((index) => index.validity === 'valid' && index.isSelected) - .map((i) => i.name), - [validatedIndices] - ); - - const datasetFilter = useMemo( - () => - validatedIndices - .flatMap((validatedIndex) => - validatedIndex.validity === 'valid' - ? validatedIndex.datasetFilter - : { type: 'includeAll' as const } - ) - .reduce(combineDatasetFilters, { type: 'includeAll' as const }), - [validatedIndices] - ); - - const [validateIndicesRequest, validateIndices] = useTrackedPromise( - { - cancelPreviousOn: 'resolution', - createPromise: async () => { - return await validateSetupIndices( - sourceConfiguration.indices, - sourceConfiguration.timestampField - ); - }, - onResolve: ({ data: { errors } }) => { - updateIndicesWithValidationErrors(errors); - }, - onReject: () => { - setValidatedIndices([]); - }, - }, - [sourceConfiguration.indices, sourceConfiguration.timestampField] - ); - - const [validateDatasetsRequest, validateDatasets] = useTrackedPromise( - { - cancelPreviousOn: 'resolution', - createPromise: async () => { - if (validIndexNames.length === 0) { - return { data: { datasets: [] } }; - } - - return await validateSetupDatasets( - validIndexNames, - sourceConfiguration.timestampField, - startTime ?? 0, - endTime ?? Date.now() - ); - }, - onResolve: ({ data: { datasets } }) => { - updateIndicesWithAvailableDatasets(datasets); - }, - }, - [validIndexNames, sourceConfiguration.timestampField, startTime, endTime] - ); - - const setUp = useCallback(() => { - return setUpModule(selectedIndexNames, startTime, endTime, datasetFilter); - }, [setUpModule, selectedIndexNames, startTime, endTime, datasetFilter]); - - const cleanUpAndSetUp = useCallback(() => { - return cleanUpAndSetUpModule(selectedIndexNames, startTime, endTime, datasetFilter); - }, [cleanUpAndSetUpModule, selectedIndexNames, startTime, endTime, datasetFilter]); - - const isValidating = useMemo( - () => validateIndicesRequest.state === 'pending' || validateDatasetsRequest.state === 'pending', - [validateDatasetsRequest.state, validateIndicesRequest.state] - ); - - const validationErrors = useMemo(() => { - if (isValidating) { - return []; - } - - return [ - // validate request status - ...(validateIndicesRequest.state === 'rejected' || - validateDatasetsRequest.state === 'rejected' - ? [{ error: 'NETWORK_ERROR' as const }] - : []), - // validation request results - ...validatedIndices.reduce((errors, index) => { - return index.validity === 'invalid' && selectedIndexNames.includes(index.name) - ? [...errors, ...index.errors] - : errors; - }, []), - // index count - ...(selectedIndexNames.length === 0 ? [{ error: 'TOO_FEW_SELECTED_INDICES' as const }] : []), - // time range - ...(!isTimeRangeValid ? [{ error: 'INVALID_TIME_RANGE' as const }] : []), - ]; - }, [ - isValidating, - validateIndicesRequest.state, - validateDatasetsRequest.state, - validatedIndices, - selectedIndexNames, - isTimeRangeValid, - ]); - - const prevStartTime = usePrevious(startTime); - const prevEndTime = usePrevious(endTime); - const prevValidIndexNames = usePrevious(validIndexNames); - - useEffect(() => { - if (!isTimeRangeValid) { - return; - } - - validateIndices(); - }, [isTimeRangeValid, validateIndices]); - - useEffect(() => { - if (!isTimeRangeValid) { - return; - } - - if ( - startTime !== prevStartTime || - endTime !== prevEndTime || - !isEqual(validIndexNames, prevValidIndexNames) - ) { - validateDatasets(); - } - }, [ - endTime, - isTimeRangeValid, - prevEndTime, - prevStartTime, - prevValidIndexNames, - startTime, - validIndexNames, - validateDatasets, - ]); - - return { - cleanUpAndSetUp, - datasetFilter, - endTime, - isValidating, - selectedIndexNames, - setEndTime, - setStartTime, - setUp, - startTime, - validatedIndices, - setValidatedIndices, - validationErrors, - }; -}; diff --git a/x-pack/plugins/infra/public/containers/ml/modules/metrics_hosts/module_descriptor.ts b/x-pack/plugins/infra/public/containers/ml/modules/metrics_hosts/module_descriptor.ts index cec87fb1144e3..47230cbed977f 100644 --- a/x-pack/plugins/infra/public/containers/ml/modules/metrics_hosts/module_descriptor.ts +++ b/x-pack/plugins/infra/public/containers/ml/modules/metrics_hosts/module_descriptor.ts @@ -5,22 +5,32 @@ */ import { i18n } from '@kbn/i18n'; -import { ModuleDescriptor, ModuleSourceConfiguration } from '../../infra_ml_module_types'; +import { HttpHandler } from 'src/core/public'; +import { ModuleDescriptor, SetUpModuleArgs } from '../../infra_ml_module_types'; import { cleanUpJobsAndDatafeeds } from '../../infra_ml_cleanup'; import { callJobsSummaryAPI } from '../../api/ml_get_jobs_summary_api'; import { callGetMlModuleAPI } from '../../api/ml_get_module'; import { callSetupMlModuleAPI } from '../../api/ml_setup_module_api'; -import { callValidateIndicesAPI } from '../../../logs/log_analysis/api/validate_indices'; -import { callValidateDatasetsAPI } from '../../../logs/log_analysis/api/validate_datasets'; import { metricsHostsJobTypes, getJobId, MetricsHostsJobType, - DatasetFilter, bucketSpan, - partitionField, } from '../../../../../common/infra_ml'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import MemoryJob from '../../../../../../ml/server/models/data_recognizer/modules/metrics_ui_hosts/ml/hosts_memory_usage.json'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import MemoryDatafeed from '../../../../../../ml/server/models/data_recognizer/modules/metrics_ui_hosts/ml/datafeed_hosts_memory_usage.json'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import NetworkInJob from '../../../../../../ml/server/models/data_recognizer/modules/metrics_ui_hosts/ml/hosts_network_in.json'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import NetworkInDatafeed from '../../../../../../ml/server/models/data_recognizer/modules/metrics_ui_hosts/ml/datafeed_hosts_network_in.json'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import NetworkOutJob from '../../../../../../ml/server/models/data_recognizer/modules/metrics_ui_hosts/ml/hosts_network_out.json'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import NetworkOutDatafeed from '../../../../../../ml/server/models/data_recognizer/modules/metrics_ui_hosts/ml/datafeed_hosts_network_out.json'; +type JobType = 'hosts_memory_usage' | 'hosts_network_in' | 'hosts_network_out'; const moduleId = 'metrics_ui_hosts'; const moduleName = i18n.translate('xpack.infra.ml.metricsModuleName', { defaultMessage: 'Metrics anomanly detection', @@ -38,76 +48,126 @@ const getJobIds = (spaceId: string, sourceId: string) => {} as Record ); -const getJobSummary = async (spaceId: string, sourceId: string) => { - const response = await callJobsSummaryAPI(spaceId, sourceId, metricsHostsJobTypes); +const getJobSummary = async (spaceId: string, sourceId: string, fetch: HttpHandler) => { + const response = await callJobsSummaryAPI( + { spaceId, sourceId, jobTypes: metricsHostsJobTypes }, + fetch + ); const jobIds = Object.values(getJobIds(spaceId, sourceId)); return response.filter((jobSummary) => jobIds.includes(jobSummary.id)); }; -const getModuleDefinition = async () => { - return await callGetMlModuleAPI(moduleId); +const getModuleDefinition = async (fetch: HttpHandler) => { + return await callGetMlModuleAPI(moduleId, fetch); }; -const setUpModule = async ( - start: number | undefined, - end: number | undefined, - datasetFilter: DatasetFilter, - { spaceId, sourceId, indices, timestampField }: ModuleSourceConfiguration, - pField?: string -) => { +const setUpModule = async (setUpModuleArgs: SetUpModuleArgs, fetch: HttpHandler) => { + const { + start, + end, + moduleSourceConfiguration: { spaceId, sourceId, indices, timestampField }, + partitionField, + } = setUpModuleArgs; + const indexNamePattern = indices.join(','); - const jobIds = ['hosts_memory_usage', 'hosts_network_in', 'hosts_network_out']; - const jobOverrides = jobIds.map((id) => ({ - job_id: id, - data_description: { - time_field: timestampField, - }, - custom_settings: { - metrics_source_config: { - indexPattern: indexNamePattern, - timestampField, - bucketSpan, + const jobIds: JobType[] = ['hosts_memory_usage', 'hosts_network_in', 'hosts_network_out']; + + const jobOverrides = jobIds.map((id) => { + const { job: defaultJobConfig } = getDefaultJobConfigs(id); + + // eslint-disable-next-line @typescript-eslint/naming-convention + const analysis_config: any = { + ...defaultJobConfig.analysis_config, + }; + + if (partitionField) { + analysis_config.detectors[0].partition_field_name = partitionField; + if (analysis_config.influencers.indexOf(partitionField) === -1) { + analysis_config.influencers.push(partitionField); + } + } + + return { + job_id: id, + data_description: { + time_field: timestampField, }, - }, - })); + analysis_config, + custom_settings: { + metrics_source_config: { + indexPattern: indexNamePattern, + timestampField, + bucketSpan, + }, + }, + }; + }); - return callSetupMlModuleAPI( - moduleId, - start, - end, - spaceId, - sourceId, - indexNamePattern, - jobOverrides, - [] - ); -}; + const datafeedOverrides = jobIds.map((id) => { + const { datafeed: defaultDatafeedConfig } = getDefaultJobConfigs(id); -const cleanUpModule = async (spaceId: string, sourceId: string) => { - return await cleanUpJobsAndDatafeeds(spaceId, sourceId, metricsHostsJobTypes); -}; + if (!partitionField || id === 'hosts_memory_usage') { + // Since the host memory usage doesn't have custom aggs, we don't need to do anything to add a partition field + return defaultDatafeedConfig; + } -const validateSetupIndices = async (indices: string[], timestampField: string) => { - return await callValidateIndicesAPI(indices, [ - { - name: timestampField, - validTypes: ['date'], - }, + // If we have a partition field, we need to change the aggregation to do a terms agg at the top level + const aggregations = { + [partitionField]: { + terms: { + field: partitionField, + }, + aggregations: { + ...defaultDatafeedConfig.aggregations, + }, + }, + }; + + return { + ...defaultDatafeedConfig, + job_id: id, + aggregations, + }; + }); + + return callSetupMlModuleAPI( { - name: partitionField, - validTypes: ['keyword'], + moduleId, + start, + end, + spaceId, + sourceId, + indexPattern: indexNamePattern, + jobOverrides, + datafeedOverrides, }, - ]); + fetch + ); +}; + +const getDefaultJobConfigs = (jobId: JobType): { datafeed: any; job: any } => { + switch (jobId) { + case 'hosts_memory_usage': + return { + datafeed: MemoryDatafeed, + job: MemoryJob, + }; + case 'hosts_network_in': + return { + datafeed: NetworkInDatafeed, + job: NetworkInJob, + }; + case 'hosts_network_out': + return { + datafeed: NetworkOutDatafeed, + job: NetworkOutJob, + }; + } }; -const validateSetupDatasets = async ( - indices: string[], - timestampField: string, - startTime: number, - endTime: number -) => { - return await callValidateDatasetsAPI(indices, timestampField, startTime, endTime); +const cleanUpModule = async (spaceId: string, sourceId: string, fetch: HttpHandler) => { + return await cleanUpJobsAndDatafeeds(spaceId, sourceId, metricsHostsJobTypes, fetch); }; export const metricHostsModule: ModuleDescriptor = { @@ -121,6 +181,4 @@ export const metricHostsModule: ModuleDescriptor = { getModuleDefinition, setUpModule, cleanUpModule, - validateSetupDatasets, - validateSetupIndices, }; diff --git a/x-pack/plugins/infra/public/containers/ml/modules/metrics_k8s/module_descriptor.ts b/x-pack/plugins/infra/public/containers/ml/modules/metrics_k8s/module_descriptor.ts index cbcff1c307af6..488803dc113b0 100644 --- a/x-pack/plugins/infra/public/containers/ml/modules/metrics_k8s/module_descriptor.ts +++ b/x-pack/plugins/infra/public/containers/ml/modules/metrics_k8s/module_descriptor.ts @@ -5,22 +5,33 @@ */ import { i18n } from '@kbn/i18n'; -import { ModuleDescriptor, ModuleSourceConfiguration } from '../../infra_ml_module_types'; +import { HttpHandler } from 'src/core/public'; +import { ModuleDescriptor, SetUpModuleArgs } from '../../infra_ml_module_types'; import { cleanUpJobsAndDatafeeds } from '../../infra_ml_cleanup'; import { callJobsSummaryAPI } from '../../api/ml_get_jobs_summary_api'; import { callGetMlModuleAPI } from '../../api/ml_get_module'; import { callSetupMlModuleAPI } from '../../api/ml_setup_module_api'; -import { callValidateIndicesAPI } from '../../../logs/log_analysis/api/validate_indices'; -import { callValidateDatasetsAPI } from '../../../logs/log_analysis/api/validate_datasets'; import { metricsK8SJobTypes, getJobId, MetricK8sJobType, - DatasetFilter, bucketSpan, - partitionField, } from '../../../../../common/infra_ml'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import MemoryJob from '../../../../../../ml/server/models/data_recognizer/modules/metrics_ui_k8s/ml/k8s_memory_usage.json'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import MemoryDatafeed from '../../../../../../ml/server/models/data_recognizer/modules/metrics_ui_k8s/ml/datafeed_k8s_memory_usage.json'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import NetworkInJob from '../../../../../../ml/server/models/data_recognizer/modules/metrics_ui_k8s/ml/k8s_network_in.json'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import NetworkInDatafeed from '../../../../../../ml/server/models/data_recognizer/modules/metrics_ui_k8s/ml/datafeed_k8s_network_in.json'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import NetworkOutJob from '../../../../../../ml/server/models/data_recognizer/modules/metrics_ui_k8s/ml/k8s_network_out.json'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import NetworkOutDatafeed from '../../../../../../ml/server/models/data_recognizer/modules/metrics_ui_k8s/ml/datafeed_k8s_network_out.json'; +type JobType = 'k8s_memory_usage' | 'k8s_network_in' | 'k8s_network_out'; +export const DEFAULT_K8S_PARTITION_FIELD = 'kubernetes.namespace'; const moduleId = 'metrics_ui_k8s'; const moduleName = i18n.translate('xpack.infra.ml.metricsModuleName', { defaultMessage: 'Metrics anomanly detection', @@ -38,79 +49,130 @@ const getJobIds = (spaceId: string, sourceId: string) => {} as Record ); -const getJobSummary = async (spaceId: string, sourceId: string) => { - const response = await callJobsSummaryAPI(spaceId, sourceId, metricsK8SJobTypes); +const getJobSummary = async (spaceId: string, sourceId: string, fetch: HttpHandler) => { + const response = await callJobsSummaryAPI( + { spaceId, sourceId, jobTypes: metricsK8SJobTypes }, + fetch + ); const jobIds = Object.values(getJobIds(spaceId, sourceId)); return response.filter((jobSummary) => jobIds.includes(jobSummary.id)); }; -const getModuleDefinition = async () => { - return await callGetMlModuleAPI(moduleId); +const getModuleDefinition = async (fetch: HttpHandler) => { + return await callGetMlModuleAPI(moduleId, fetch); }; -const setUpModule = async ( - start: number | undefined, - end: number | undefined, - datasetFilter: DatasetFilter, - { spaceId, sourceId, indices, timestampField }: ModuleSourceConfiguration, - pField?: string -) => { +const setUpModule = async (setUpModuleArgs: SetUpModuleArgs, fetch: HttpHandler) => { + const { + start, + end, + moduleSourceConfiguration: { spaceId, sourceId, indices, timestampField }, + partitionField, + } = setUpModuleArgs; + const indexNamePattern = indices.join(','); - const jobIds = ['k8s_memory_usage', 'k8s_network_in', 'k8s_network_out']; - const jobOverrides = jobIds.map((id) => ({ - job_id: id, - analysis_config: { - bucket_span: `${bucketSpan}ms`, - }, - data_description: { - time_field: timestampField, - }, - custom_settings: { - metrics_source_config: { - indexPattern: indexNamePattern, - timestampField, - bucketSpan, + const jobIds: JobType[] = ['k8s_memory_usage', 'k8s_network_in', 'k8s_network_out']; + const jobOverrides = jobIds.map((id) => { + const { job: defaultJobConfig } = getDefaultJobConfigs(id); + + // eslint-disable-next-line @typescript-eslint/naming-convention + const analysis_config: any = { + ...defaultJobConfig.analysis_config, + }; + + if (partitionField) { + analysis_config.detectors[0].partition_field_name = partitionField; + if (analysis_config.influencers.indexOf(partitionField) === -1) { + analysis_config.influencers.push(partitionField); + } + } + + return { + job_id: id, + data_description: { + time_field: timestampField, }, - }, - })); + analysis_config, + custom_settings: { + metrics_source_config: { + indexPattern: indexNamePattern, + timestampField, + bucketSpan, + }, + }, + }; + }); - return callSetupMlModuleAPI( - moduleId, - start, - end, - spaceId, - sourceId, - indexNamePattern, - jobOverrides, - [] - ); -}; + const datafeedOverrides = jobIds.map((id) => { + const { datafeed: defaultDatafeedConfig } = getDefaultJobConfigs(id); -const cleanUpModule = async (spaceId: string, sourceId: string) => { - return await cleanUpJobsAndDatafeeds(spaceId, sourceId, metricsK8SJobTypes); -}; + if (!partitionField || id === 'k8s_memory_usage') { + // Since the host memory usage doesn't have custom aggs, we don't need to do anything to add a partition field + return defaultDatafeedConfig; + } -const validateSetupIndices = async (indices: string[], timestampField: string) => { - return await callValidateIndicesAPI(indices, [ - { - name: timestampField, - validTypes: ['date'], - }, + // Because the ML K8s jobs ship with a default partition field of {kubernetes.namespace}, ignore that agg and wrap it in our own agg. + const innerAggregation = + defaultDatafeedConfig.aggregations[DEFAULT_K8S_PARTITION_FIELD].aggregations; + + // If we have a partition field, we need to change the aggregation to do a terms agg to partition the data at the top level + const aggregations = { + [partitionField]: { + terms: { + field: partitionField, + size: 25, // 25 is arbitratry and only used to keep the number of buckets to a managable level in the event that the user choose a high cardinality partition field. + }, + aggregations: { + ...innerAggregation, + }, + }, + }; + + return { + ...defaultDatafeedConfig, + job_id: id, + aggregations, + }; + }); + + return callSetupMlModuleAPI( { - name: partitionField, - validTypes: ['keyword'], + moduleId, + start, + end, + spaceId, + sourceId, + indexPattern: indexNamePattern, + jobOverrides, + datafeedOverrides, }, - ]); + fetch + ); +}; + +const getDefaultJobConfigs = (jobId: JobType): { datafeed: any; job: any } => { + switch (jobId) { + case 'k8s_memory_usage': + return { + datafeed: MemoryDatafeed, + job: MemoryJob, + }; + case 'k8s_network_in': + return { + datafeed: NetworkInDatafeed, + job: NetworkInJob, + }; + case 'k8s_network_out': + return { + datafeed: NetworkOutDatafeed, + job: NetworkOutJob, + }; + } }; -const validateSetupDatasets = async ( - indices: string[], - timestampField: string, - startTime: number, - endTime: number -) => { - return await callValidateDatasetsAPI(indices, timestampField, startTime, endTime); +const cleanUpModule = async (spaceId: string, sourceId: string, fetch: HttpHandler) => { + return await cleanUpJobsAndDatafeeds(spaceId, sourceId, metricsK8SJobTypes, fetch); }; export const metricHostsModule: ModuleDescriptor = { @@ -124,6 +186,4 @@ export const metricHostsModule: ModuleDescriptor = { getModuleDefinition, setUpModule, cleanUpModule, - validateSetupDatasets, - validateSetupIndices, }; diff --git a/x-pack/plugins/infra/public/hooks/use_link_props.test.tsx b/x-pack/plugins/infra/public/hooks/use_link_props.test.tsx index d93cc44c45623..8c1647bd79798 100644 --- a/x-pack/plugins/infra/public/hooks/use_link_props.test.tsx +++ b/x-pack/plugins/infra/public/hooks/use_link_props.test.tsx @@ -129,7 +129,7 @@ describe('useLinkProps hook', () => { it('Provides the correct props with hash options', () => { const { result } = renderUseLinkPropsHook({ app: 'ml', - hash: '/explorer', + pathname: '/explorer', search: { type: 'host', id: 'some-id', @@ -137,7 +137,7 @@ describe('useLinkProps hook', () => { }, }); expect(result.current.href).toBe( - '/test-basepath/s/test-space/app/ml#/explorer?type=host&id=some-id&count=12345' + '/test-basepath/s/test-space/app/ml/explorer?type=host&id=some-id&count=12345' ); expect(result.current.onClick).toBeDefined(); }); @@ -145,7 +145,7 @@ describe('useLinkProps hook', () => { it('Provides the correct props with more complex encoding', () => { const { result } = renderUseLinkPropsHook({ app: 'ml', - hash: '/explorer', + pathname: '/explorer', search: { type: 'host + host', name: 'this name has spaces and ** and %', @@ -155,7 +155,7 @@ describe('useLinkProps hook', () => { }, }); expect(result.current.href).toBe( - '/test-basepath/s/test-space/app/ml#/explorer?type=host%20%2B%20host&name=this%20name%20has%20spaces%20and%20**%20and%20%25&id=some-id&count=12345&animals=dog,cat,bear' + '/test-basepath/s/test-space/app/ml/explorer?type=host%20%2B%20host&name=this%20name%20has%20spaces%20and%20**%20and%20%25&id=some-id&count=12345&animals=dog,cat,bear' ); expect(result.current.onClick).toBeDefined(); }); diff --git a/x-pack/plugins/infra/public/legacy_singletons.ts b/x-pack/plugins/infra/public/legacy_singletons.ts deleted file mode 100644 index f57047f21c281..0000000000000 --- a/x-pack/plugins/infra/public/legacy_singletons.ts +++ /dev/null @@ -1,14 +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 { CoreStart } from 'kibana/public'; - -let npStart: CoreStart; - -export function registerStartSingleton(start: CoreStart) { - npStart = start; -} - -export { npStart }; diff --git a/x-pack/plugins/infra/public/pages/link_to/link_to_logs.test.tsx b/x-pack/plugins/infra/public/pages/link_to/link_to_logs.test.tsx index 945b299674aaa..4f83e37d7e029 100644 --- a/x-pack/plugins/infra/public/pages/link_to/link_to_logs.test.tsx +++ b/x-pack/plugins/infra/public/pages/link_to/link_to_logs.test.tsx @@ -14,7 +14,6 @@ import { createMemoryHistory } from 'history'; import React from 'react'; import { Route, Router, Switch } from 'react-router-dom'; import { httpServiceMock } from 'src/core/public/mocks'; -// import { HttpSetup } from 'src/core/public'; import { KibanaContextProvider } from 'src/plugins/kibana_react/public'; import { useLogSource } from '../../containers/logs/log_source'; import { diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_datasets.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_datasets.ts index a8cd7854efb6b..5f34d45635b60 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_datasets.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_datasets.ts @@ -4,24 +4,28 @@ * you may not use this file except in compliance with the Elastic License. */ -import { fold } from 'fp-ts/lib/Either'; -import { pipe } from 'fp-ts/lib/pipeable'; -import { identity } from 'fp-ts/lib/function'; -import { npStart } from '../../../../legacy_singletons'; +import type { HttpHandler } from 'src/core/public'; import { getLogEntryCategoryDatasetsRequestPayloadRT, getLogEntryCategoryDatasetsSuccessReponsePayloadRT, LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORY_DATASETS_PATH, } from '../../../../../common/http_api/log_analysis'; -import { createPlainError, throwErrors } from '../../../../../common/runtime_types'; +import { decodeOrThrow } from '../../../../../common/runtime_types'; + +interface RequestArgs { + sourceId: string; + startTime: number; + endTime: number; +} export const callGetLogEntryCategoryDatasetsAPI = async ( - sourceId: string, - startTime: number, - endTime: number + requestArgs: RequestArgs, + fetch: HttpHandler ) => { - const response = await npStart.http.fetch(LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORY_DATASETS_PATH, { + const { sourceId, startTime, endTime } = requestArgs; + + const response = await fetch(LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORY_DATASETS_PATH, { method: 'POST', body: JSON.stringify( getLogEntryCategoryDatasetsRequestPayloadRT.encode({ @@ -36,8 +40,5 @@ export const callGetLogEntryCategoryDatasetsAPI = async ( ), }); - return pipe( - getLogEntryCategoryDatasetsSuccessReponsePayloadRT.decode(response), - fold(throwErrors(createPlainError), identity) - ); + return decodeOrThrow(getLogEntryCategoryDatasetsSuccessReponsePayloadRT)(response); }; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_examples.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_examples.ts index a10d077a2dd4f..c4b756ebf5d58 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_examples.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_log_entry_category_examples.ts @@ -4,26 +4,30 @@ * you may not use this file except in compliance with the Elastic License. */ -import { fold } from 'fp-ts/lib/Either'; -import { pipe } from 'fp-ts/lib/pipeable'; -import { identity } from 'fp-ts/lib/function'; -import { npStart } from '../../../../legacy_singletons'; +import type { HttpHandler } from 'src/core/public'; import { getLogEntryCategoryExamplesRequestPayloadRT, getLogEntryCategoryExamplesSuccessReponsePayloadRT, LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORY_EXAMPLES_PATH, } from '../../../../../common/http_api/log_analysis'; -import { createPlainError, throwErrors } from '../../../../../common/runtime_types'; +import { decodeOrThrow } from '../../../../../common/runtime_types'; + +interface RequestArgs { + sourceId: string; + startTime: number; + endTime: number; + categoryId: number; + exampleCount: number; +} export const callGetLogEntryCategoryExamplesAPI = async ( - sourceId: string, - startTime: number, - endTime: number, - categoryId: number, - exampleCount: number + requestArgs: RequestArgs, + fetch: HttpHandler ) => { - const response = await npStart.http.fetch(LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORY_EXAMPLES_PATH, { + const { sourceId, startTime, endTime, categoryId, exampleCount } = requestArgs; + + const response = await fetch(LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORY_EXAMPLES_PATH, { method: 'POST', body: JSON.stringify( getLogEntryCategoryExamplesRequestPayloadRT.encode({ @@ -40,8 +44,5 @@ export const callGetLogEntryCategoryExamplesAPI = async ( ), }); - return pipe( - getLogEntryCategoryExamplesSuccessReponsePayloadRT.decode(response), - fold(throwErrors(createPlainError), identity) - ); + return decodeOrThrow(getLogEntryCategoryExamplesSuccessReponsePayloadRT)(response); }; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_top_log_entry_categories.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_top_log_entry_categories.ts index 2ebcff4fd3ca5..fd53803796339 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_top_log_entry_categories.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/service_calls/get_top_log_entry_categories.ts @@ -4,28 +4,31 @@ * you may not use this file except in compliance with the Elastic License. */ -import { fold } from 'fp-ts/lib/Either'; -import { pipe } from 'fp-ts/lib/pipeable'; -import { identity } from 'fp-ts/lib/function'; -import { npStart } from '../../../../legacy_singletons'; +import type { HttpHandler } from 'src/core/public'; import { getLogEntryCategoriesRequestPayloadRT, getLogEntryCategoriesSuccessReponsePayloadRT, LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORIES_PATH, } from '../../../../../common/http_api/log_analysis'; -import { createPlainError, throwErrors } from '../../../../../common/runtime_types'; +import { decodeOrThrow } from '../../../../../common/runtime_types'; + +interface RequestArgs { + sourceId: string; + startTime: number; + endTime: number; + categoryCount: number; + datasets?: string[]; +} export const callGetTopLogEntryCategoriesAPI = async ( - sourceId: string, - startTime: number, - endTime: number, - categoryCount: number, - datasets?: string[] + requestArgs: RequestArgs, + fetch: HttpHandler ) => { + const { sourceId, startTime, endTime, categoryCount, datasets } = requestArgs; const intervalDuration = endTime - startTime; - const response = await npStart.http.fetch(LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORIES_PATH, { + const response = await fetch(LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORIES_PATH, { method: 'POST', body: JSON.stringify( getLogEntryCategoriesRequestPayloadRT.encode({ @@ -60,8 +63,5 @@ export const callGetTopLogEntryCategoriesAPI = async ( ), }); - return pipe( - getLogEntryCategoriesSuccessReponsePayloadRT.decode(response), - fold(throwErrors(createPlainError), identity) - ); + return decodeOrThrow(getLogEntryCategoriesSuccessReponsePayloadRT)(response); }; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_categories_results.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_categories_results.ts index 123b188046b85..0a12c433db60a 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_categories_results.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_categories_results.ts @@ -13,6 +13,7 @@ import { import { useTrackedPromise, CanceledPromiseError } from '../../../utils/use_tracked_promise'; import { callGetTopLogEntryCategoriesAPI } from './service_calls/get_top_log_entry_categories'; import { callGetLogEntryCategoryDatasetsAPI } from './service_calls/get_log_entry_category_datasets'; +import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; type TopLogEntryCategories = GetLogEntryCategoriesSuccessResponsePayload['data']['categories']; type LogEntryCategoryDatasets = GetLogEntryCategoryDatasetsSuccessResponsePayload['data']['datasets']; @@ -34,6 +35,7 @@ export const useLogEntryCategoriesResults = ({ sourceId: string; startTime: number; }) => { + const { services } = useKibanaContextForPlugin(); const [topLogEntryCategories, setTopLogEntryCategories] = useState([]); const [logEntryCategoryDatasets, setLogEntryCategoryDatasets] = useState< LogEntryCategoryDatasets @@ -44,11 +46,14 @@ export const useLogEntryCategoriesResults = ({ cancelPreviousOn: 'creation', createPromise: async () => { return await callGetTopLogEntryCategoriesAPI( - sourceId, - startTime, - endTime, - categoriesCount, - filteredDatasets + { + sourceId, + startTime, + endTime, + categoryCount: categoriesCount, + datasets: filteredDatasets, + }, + services.http.fetch ); }, onResolve: ({ data: { categories } }) => { @@ -71,7 +76,10 @@ export const useLogEntryCategoriesResults = ({ { cancelPreviousOn: 'creation', createPromise: async () => { - return await callGetLogEntryCategoryDatasetsAPI(sourceId, startTime, endTime); + return await callGetLogEntryCategoryDatasetsAPI( + { sourceId, startTime, endTime }, + services.http.fetch + ); }, onResolve: ({ data: { datasets } }) => { setLogEntryCategoryDatasets(datasets); diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_category_examples.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_category_examples.tsx index cdf3b642a8012..84b9f045288cc 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_category_examples.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_categories/use_log_entry_category_examples.tsx @@ -7,6 +7,7 @@ import { useMemo, useState } from 'react'; import { LogEntryCategoryExample } from '../../../../common/http_api'; +import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; import { useTrackedPromise } from '../../../utils/use_tracked_promise'; import { callGetLogEntryCategoryExamplesAPI } from './service_calls/get_log_entry_category_examples'; @@ -23,6 +24,8 @@ export const useLogEntryCategoryExamples = ({ sourceId: string; startTime: number; }) => { + const { services } = useKibanaContextForPlugin(); + const [logEntryCategoryExamples, setLogEntryCategoryExamples] = useState< LogEntryCategoryExample[] >([]); @@ -32,11 +35,14 @@ export const useLogEntryCategoryExamples = ({ cancelPreviousOn: 'creation', createPromise: async () => { return await callGetLogEntryCategoryExamplesAPI( - sourceId, - startTime, - endTime, - categoryId, - exampleCount + { + sourceId, + startTime, + endTime, + categoryId, + exampleCount, + }, + services.http.fetch ); }, onResolve: ({ data: { examples } }) => { diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies.ts index 21696df566ed9..7f90604bfefdd 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { npStart } from '../../../../legacy_singletons'; +import type { HttpHandler } from 'src/core/public'; import { getLogEntryAnomaliesRequestPayloadRT, getLogEntryAnomaliesSuccessReponsePayloadRT, @@ -13,15 +13,18 @@ import { import { decodeOrThrow } from '../../../../../common/runtime_types'; import { Sort, Pagination } from '../../../../../common/http_api/log_analysis'; -export const callGetLogEntryAnomaliesAPI = async ( - sourceId: string, - startTime: number, - endTime: number, - sort: Sort, - pagination: Pagination, - datasets?: string[] -) => { - const response = await npStart.http.fetch(LOG_ANALYSIS_GET_LOG_ENTRY_ANOMALIES_PATH, { +interface RequestArgs { + sourceId: string; + startTime: number; + endTime: number; + sort: Sort; + pagination: Pagination; + datasets?: string[]; +} + +export const callGetLogEntryAnomaliesAPI = async (requestArgs: RequestArgs, fetch: HttpHandler) => { + const { sourceId, startTime, endTime, sort, pagination, datasets } = requestArgs; + const response = await fetch(LOG_ANALYSIS_GET_LOG_ENTRY_ANOMALIES_PATH, { method: 'POST', body: JSON.stringify( getLogEntryAnomaliesRequestPayloadRT.encode({ diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies_datasets.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies_datasets.ts index 24be5a646d103..c62bec691590c 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies_datasets.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_anomalies_datasets.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { npStart } from '../../../../legacy_singletons'; +import type { HttpHandler } from 'src/core/public'; import { decodeOrThrow } from '../../../../../common/runtime_types'; import { getLogEntryAnomaliesDatasetsRequestPayloadRT, @@ -12,12 +12,18 @@ import { LOG_ANALYSIS_GET_LOG_ENTRY_ANOMALIES_DATASETS_PATH, } from '../../../../../common/http_api/log_analysis'; +interface RequestArgs { + sourceId: string; + startTime: number; + endTime: number; +} + export const callGetLogEntryAnomaliesDatasetsAPI = async ( - sourceId: string, - startTime: number, - endTime: number + requestArgs: RequestArgs, + fetch: HttpHandler ) => { - const response = await npStart.http.fetch(LOG_ANALYSIS_GET_LOG_ENTRY_ANOMALIES_DATASETS_PATH, { + const { sourceId, startTime, endTime } = requestArgs; + const response = await fetch(LOG_ANALYSIS_GET_LOG_ENTRY_ANOMALIES_DATASETS_PATH, { method: 'POST', body: JSON.stringify( getLogEntryAnomaliesDatasetsRequestPayloadRT.encode({ diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_examples.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_examples.ts index a125b53f9e635..ab724a2f435b2 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_examples.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_examples.ts @@ -4,27 +4,27 @@ * you may not use this file except in compliance with the Elastic License. */ -import { fold } from 'fp-ts/lib/Either'; -import { pipe } from 'fp-ts/lib/pipeable'; -import { identity } from 'fp-ts/lib/function'; -import { npStart } from '../../../../legacy_singletons'; +import type { HttpHandler } from 'src/core/public'; import { getLogEntryExamplesRequestPayloadRT, getLogEntryExamplesSuccessReponsePayloadRT, LOG_ANALYSIS_GET_LOG_ENTRY_RATE_EXAMPLES_PATH, } from '../../../../../common/http_api/log_analysis'; -import { createPlainError, throwErrors } from '../../../../../common/runtime_types'; +import { decodeOrThrow } from '../../../../../common/runtime_types'; -export const callGetLogEntryExamplesAPI = async ( - sourceId: string, - startTime: number, - endTime: number, - dataset: string, - exampleCount: number, - categoryId?: string -) => { - const response = await npStart.http.fetch(LOG_ANALYSIS_GET_LOG_ENTRY_RATE_EXAMPLES_PATH, { +interface RequestArgs { + sourceId: string; + startTime: number; + endTime: number; + dataset: string; + exampleCount: number; + categoryId?: string; +} + +export const callGetLogEntryExamplesAPI = async (requestArgs: RequestArgs, fetch: HttpHandler) => { + const { sourceId, startTime, endTime, dataset, exampleCount, categoryId } = requestArgs; + const response = await fetch(LOG_ANALYSIS_GET_LOG_ENTRY_RATE_EXAMPLES_PATH, { method: 'POST', body: JSON.stringify( getLogEntryExamplesRequestPayloadRT.encode({ @@ -42,8 +42,5 @@ export const callGetLogEntryExamplesAPI = async ( ), }); - return pipe( - getLogEntryExamplesSuccessReponsePayloadRT.decode(response), - fold(throwErrors(createPlainError), identity) - ); + return decodeOrThrow(getLogEntryExamplesSuccessReponsePayloadRT)(response); }; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_rate.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_rate.ts index 77111d279309d..c9189bd803955 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_rate.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/service_calls/get_log_entry_rate.ts @@ -4,25 +4,25 @@ * you may not use this file except in compliance with the Elastic License. */ -import { fold } from 'fp-ts/lib/Either'; -import { pipe } from 'fp-ts/lib/pipeable'; -import { identity } from 'fp-ts/lib/function'; -import { npStart } from '../../../../legacy_singletons'; +import type { HttpHandler } from 'src/core/public'; import { getLogEntryRateRequestPayloadRT, getLogEntryRateSuccessReponsePayloadRT, LOG_ANALYSIS_GET_LOG_ENTRY_RATE_PATH, } from '../../../../../common/http_api/log_analysis'; -import { createPlainError, throwErrors } from '../../../../../common/runtime_types'; +import { decodeOrThrow } from '../../../../../common/runtime_types'; -export const callGetLogEntryRateAPI = async ( - sourceId: string, - startTime: number, - endTime: number, - bucketDuration: number, - datasets?: string[] -) => { - const response = await npStart.http.fetch(LOG_ANALYSIS_GET_LOG_ENTRY_RATE_PATH, { +interface RequestArgs { + sourceId: string; + startTime: number; + endTime: number; + bucketDuration: number; + datasets?: string[]; +} + +export const callGetLogEntryRateAPI = async (requestArgs: RequestArgs, fetch: HttpHandler) => { + const { sourceId, startTime, endTime, bucketDuration, datasets } = requestArgs; + const response = await fetch(LOG_ANALYSIS_GET_LOG_ENTRY_RATE_PATH, { method: 'POST', body: JSON.stringify( getLogEntryRateRequestPayloadRT.encode({ @@ -38,8 +38,5 @@ export const callGetLogEntryRateAPI = async ( }) ), }); - return pipe( - getLogEntryRateSuccessReponsePayloadRT.decode(response), - fold(throwErrors(createPlainError), identity) - ); + return decodeOrThrow(getLogEntryRateSuccessReponsePayloadRT)(response); }; diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_anomalies_results.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_anomalies_results.ts index 52632e54390a9..37c99272f0872 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_anomalies_results.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_anomalies_results.ts @@ -16,6 +16,7 @@ import { GetLogEntryAnomaliesDatasetsSuccessResponsePayload, LogEntryAnomaly, } from '../../../../common/http_api/log_analysis'; +import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; export type SortOptions = Sort; export type PaginationOptions = Pick; @@ -161,6 +162,8 @@ export const useLogEntryAnomaliesResults = ({ }; }; + const { services } = useKibanaContextForPlugin(); + const [reducerState, dispatch] = useReducer(stateReducer, STATE_DEFAULTS, initStateReducer); const [logEntryAnomalies, setLogEntryAnomalies] = useState([]); @@ -177,15 +180,18 @@ export const useLogEntryAnomaliesResults = ({ filteredDatasets: queryFilteredDatasets, } = reducerState; return await callGetLogEntryAnomaliesAPI( - sourceId, - queryStartTime, - queryEndTime, - sortOptions, { - ...paginationOptions, - cursor: paginationCursor, + sourceId, + startTime: queryStartTime, + endTime: queryEndTime, + sort: sortOptions, + pagination: { + ...paginationOptions, + cursor: paginationCursor, + }, + datasets: queryFilteredDatasets, }, - queryFilteredDatasets + services.http.fetch ); }, onResolve: ({ data: { anomalies, paginationCursors: requestCursors, hasMoreEntries } }) => { @@ -286,7 +292,10 @@ export const useLogEntryAnomaliesResults = ({ { cancelPreviousOn: 'creation', createPromise: async () => { - return await callGetLogEntryAnomaliesDatasetsAPI(sourceId, startTime, endTime); + return await callGetLogEntryAnomaliesDatasetsAPI( + { sourceId, startTime, endTime }, + services.http.fetch + ); }, onResolve: ({ data: { datasets } }) => { setLogEntryAnomaliesDatasets(datasets); diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_examples.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_examples.ts index fae5bd200a415..e809ab9cd5a6f 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_examples.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_examples.ts @@ -7,6 +7,7 @@ import { useMemo, useState } from 'react'; import { LogEntryExample } from '../../../../common/http_api'; +import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; import { useTrackedPromise } from '../../../utils/use_tracked_promise'; import { callGetLogEntryExamplesAPI } from './service_calls/get_log_entry_examples'; @@ -25,6 +26,7 @@ export const useLogEntryExamples = ({ startTime: number; categoryId?: string; }) => { + const { services } = useKibanaContextForPlugin(); const [logEntryExamples, setLogEntryExamples] = useState([]); const [getLogEntryExamplesRequest, getLogEntryExamples] = useTrackedPromise( @@ -32,12 +34,15 @@ export const useLogEntryExamples = ({ cancelPreviousOn: 'creation', createPromise: async () => { return await callGetLogEntryExamplesAPI( - sourceId, - startTime, - endTime, - dataset, - exampleCount, - categoryId + { + sourceId, + startTime, + endTime, + dataset, + exampleCount, + categoryId, + }, + services.http.fetch ); }, onResolve: ({ data: { examples } }) => { diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_rate_results.ts b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_rate_results.ts index a52dab58cb018..aef94afa505f1 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_rate_results.ts +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/use_log_entry_rate_results.ts @@ -12,6 +12,7 @@ import { LogEntryRatePartition, LogEntryRateAnomaly, } from '../../../../common/http_api/log_analysis'; +import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; import { useTrackedPromise } from '../../../utils/use_tracked_promise'; import { callGetLogEntryRateAPI } from './service_calls/get_log_entry_rate'; @@ -49,6 +50,7 @@ export const useLogEntryRateResults = ({ bucketDuration: number; filteredDatasets?: string[]; }) => { + const { services } = useKibanaContextForPlugin(); const [logEntryRate, setLogEntryRate] = useState(null); const [getLogEntryRateRequest, getLogEntryRate] = useTrackedPromise( @@ -56,11 +58,14 @@ export const useLogEntryRateResults = ({ cancelPreviousOn: 'resolution', createPromise: async () => { return await callGetLogEntryRateAPI( - sourceId, - startTime, - endTime, - bucketDuration, - filteredDatasets + { + sourceId, + startTime, + endTime, + bucketDuration, + datasets: filteredDatasets, + }, + services.http.fetch ); }, onResolve: ({ data }) => { diff --git a/x-pack/plugins/infra/public/pages/logs/page_content.tsx b/x-pack/plugins/infra/public/pages/logs/page_content.tsx index 426ae8e9d05a8..e85f0d9bf446b 100644 --- a/x-pack/plugins/infra/public/pages/logs/page_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/page_content.tsx @@ -10,6 +10,7 @@ import React from 'react'; import { Route, Switch } from 'react-router-dom'; import { useMount } from 'react-use'; +import { AlertDropdown } from '../../alerting/log_threshold'; import { useKibana } from '../../../../../../src/plugins/kibana_react/public'; import { DocumentTitle } from '../../components/document_title'; import { Header } from '../../components/header'; @@ -23,7 +24,6 @@ import { LogEntryCategoriesPage } from './log_entry_categories'; import { LogEntryRatePage } from './log_entry_rate'; import { LogsSettingsPage } from './settings'; import { StreamPage } from './stream'; -import { AlertDropdown } from '../../components/alerting/logs/alert_dropdown'; export const LogsPageContent: React.FunctionComponent = () => { const uiCapabilities = useKibana().services.application?.capabilities; diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/anomoly_detection_flyout.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/anomoly_detection_flyout.tsx index b063713fa2c97..b5d224910e819 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/anomoly_detection_flyout.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/anomoly_detection_flyout.tsx @@ -50,10 +50,10 @@ export const AnomalyDetectionFlyout = () => { return ( <> - + {showFlyout && ( diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/flyout_home.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/flyout_home.tsx index 9cf898b684336..5b520084ebb74 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/flyout_home.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/flyout_home.tsx @@ -5,7 +5,7 @@ */ import React, { useState, useCallback, useEffect } from 'react'; -import { EuiFlyoutHeader, EuiTitle, EuiFlyoutBody, EuiTabs, EuiTab, EuiSpacer } from '@elastic/eui'; +import { EuiFlyoutHeader, EuiTitle, EuiFlyoutBody, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiText, EuiFlexGroup, EuiFlexItem, EuiCard, EuiIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -30,7 +30,7 @@ interface Props { } export const FlyoutHome = (props: Props) => { - const [tab, setTab] = useState<'jobs' | 'anomalies'>('jobs'); + const [tab] = useState<'jobs' | 'anomalies'>('jobs'); const { goToSetup } = props; const { fetchJobStatus: fetchHostJobStatus, @@ -56,18 +56,10 @@ export const FlyoutHome = (props: Props) => { goToSetup('kubernetes'); }, [goToSetup]); - const goToJobs = useCallback(() => { - setTab('jobs'); - }, []); - const jobIds = [ ...(k8sJobSummaries || []).map((k) => k.id), ...(hostJobSummaries || []).map((h) => h.id), ]; - const anomaliesUrl = useLinkProps({ - app: 'ml', - pathname: `/explorer?_g=${createResultsUrl(jobIds)}`, - }); useEffect(() => { if (hasInfraMLReadCapabilities) { @@ -84,7 +76,7 @@ export const FlyoutHome = (props: Props) => { return ( ); @@ -105,30 +97,24 @@ export const FlyoutHome = (props: Props) => { - - - - - - - - +
+ +

+ +

+
+
+ {hostJobSummaries.length > 0 && ( <> 0} hasK8sJobs={k8sJobSummaries.length > 0} + jobIds={jobIds} /> @@ -151,6 +137,7 @@ export const FlyoutHome = (props: Props) => { interface CalloutProps { hasHostJobs: boolean; hasK8sJobs: boolean; + jobIds: string[]; } const JobsEnabledCallout = (props: CalloutProps) => { let target = ''; @@ -175,8 +162,34 @@ const JobsEnabledCallout = (props: CalloutProps) => { pathname: '/jobs', }); + const anomaliesUrl = useLinkProps({ + app: 'ml', + pathname: `/explorer?_g=${createResultsUrl(props.jobIds)}`, + }); + return ( <> + + + + + + + + + + + + + + + { } iconType="check" /> - - - - ); }; @@ -211,30 +217,11 @@ interface CreateJobTab { const CreateJobTab = (props: CreateJobTab) => { return ( <> -
- -

- -

-
- -

- -

-
-
- - + {/* */} } // title="Hosts" title={ @@ -245,7 +232,7 @@ const CreateJobTab = (props: CreateJobTab) => { } description={ } @@ -254,7 +241,7 @@ const CreateJobTab = (props: CreateJobTab) => { {props.hasHostJobs && ( @@ -262,7 +249,7 @@ const CreateJobTab = (props: CreateJobTab) => { {!props.hasHostJobs && ( @@ -273,7 +260,7 @@ const CreateJobTab = (props: CreateJobTab) => { } title={ { } description={ } @@ -292,7 +279,7 @@ const CreateJobTab = (props: CreateJobTab) => { {props.hasK8sJobs && ( @@ -300,7 +287,7 @@ const CreateJobTab = (props: CreateJobTab) => { {!props.hasK8sJobs && ( diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/job_setup_screen.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/job_setup_screen.tsx index 730cd7b6e9ef5..c327d187f6bc2 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/job_setup_screen.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/ml/anomaly_detection/job_setup_screen.tsx @@ -20,6 +20,7 @@ import { useSourceViaHttp } from '../../../../../../containers/source/use_source import { useMetricK8sModuleContext } from '../../../../../../containers/ml/modules/metrics_k8s/module'; import { useMetricHostsModuleContext } from '../../../../../../containers/ml/modules/metrics_hosts/module'; import { FixedDatePicker } from '../../../../../../components/fixed_datepicker'; +import { DEFAULT_K8S_PARTITION_FIELD } from '../../../../../../containers/ml/modules/metrics_k8s/module_descriptor'; interface Props { jobType: 'hosts' | 'kubernetes'; @@ -107,7 +108,7 @@ export const JobSetupScreen = (props: Props) => { useEffect(() => { if (props.jobType === 'kubernetes') { - setPartitionField(['kubernetes.namespace']); + setPartitionField([DEFAULT_K8S_PARTITION_FIELD]); } }, [props.jobType]); @@ -223,7 +224,7 @@ export const JobSetupScreen = (props: Props) => { label={ } compressed diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/timeline/timeline.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/timeline/timeline.tsx index 2792b6eb18b00..a3b02b858385e 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/timeline/timeline.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/timeline/timeline.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useMemo, useCallback } from 'react'; +import React, { useMemo, useCallback, useEffect } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import moment from 'moment'; @@ -18,7 +18,12 @@ import { TooltipValue, niceTimeFormatter, ElementClickListener, + RectAnnotation, + RectAnnotationDatum, } from '@elastic/charts'; +import { EuiFlexItem } from '@elastic/eui'; +import { EuiFlexGroup } from '@elastic/eui'; +import { EuiIcon } from '@elastic/eui'; import { useUiSetting } from '../../../../../../../../../src/plugins/kibana_react/public'; import { toMetricOpt } from '../../../../../../common/snapshot_metric_i18n'; import { MetricsExplorerAggregation } from '../../../../../../common/http_api'; @@ -35,6 +40,8 @@ import { calculateDomain } from '../../../metrics_explorer/components/helpers/ca import { euiStyled } from '../../../../../../../observability/public'; import { InfraFormatter } from '../../../../../lib/lib'; +import { useMetricsHostsAnomaliesResults } from '../../hooks/use_metrics_hosts_anomalies'; +import { useMetricsK8sAnomaliesResults } from '../../hooks/use_metrics_k8s_anomalies'; interface Props { interval: string; @@ -47,7 +54,8 @@ export const Timeline: React.FC = ({ interval, yAxisFormatter, isVisible const { metric, nodeType, accountId, region } = useWaffleOptionsContext(); const { currentTime, jumpToTime, stopAutoReload } = useWaffleTimeContext(); const { filterQueryAsJson } = useWaffleFiltersContext(); - const { loading, error, timeseries, reload } = useTimeline( + + const { loading, error, startTime, endTime, timeseries, reload } = useTimeline( filterQueryAsJson, [metric], nodeType, @@ -59,6 +67,40 @@ export const Timeline: React.FC = ({ interval, yAxisFormatter, isVisible isVisible ); + const anomalyParams = { + sourceId: 'default', + startTime, + endTime, + defaultSortOptions: { + direction: 'desc' as const, + field: 'anomalyScore' as const, + }, + defaultPaginationOptions: { pageSize: 100 }, + }; + + const { metricsHostsAnomalies, getMetricsHostsAnomalies } = useMetricsHostsAnomaliesResults( + anomalyParams + ); + const { metricsK8sAnomalies, getMetricsK8sAnomalies } = useMetricsK8sAnomaliesResults( + anomalyParams + ); + + const getAnomalies = useMemo(() => { + if (nodeType === 'host') { + return getMetricsHostsAnomalies; + } else if (nodeType === 'pod') { + return getMetricsK8sAnomalies; + } + }, [nodeType, getMetricsK8sAnomalies, getMetricsHostsAnomalies]); + + const anomalies = useMemo(() => { + if (nodeType === 'host') { + return metricsHostsAnomalies; + } else if (nodeType === 'pod') { + return metricsK8sAnomalies; + } + }, [nodeType, metricsHostsAnomalies, metricsK8sAnomalies]); + const metricLabel = toMetricOpt(metric.type)?.textLC; const chartMetric = { @@ -104,6 +146,25 @@ export const Timeline: React.FC = ({ interval, yAxisFormatter, isVisible [jumpToTime, stopAutoReload] ); + const anomalyMetricName = useMemo(() => { + const metricType = metric.type; + if (metricType === 'memory') { + return 'memory_usage'; + } + if (metricType === 'rx') { + return 'network_in'; + } + if (metricType === 'tx') { + return 'network_out'; + } + }, [metric]); + + useEffect(() => { + if (getAnomalies && anomalyMetricName) { + getAnomalies(anomalyMetricName); + } + }, [getAnomalies, anomalyMetricName]); + if (loading) { return ( @@ -130,21 +191,86 @@ export const Timeline: React.FC = ({ interval, yAxisFormatter, isVisible ); } + function generateAnnotationData(results: Array<[number, string[]]>): RectAnnotationDatum[] { + return results.map((anomaly) => { + const [val, influencers] = anomaly; + return { + coordinates: { + x0: val, + x1: moment(val).add(15, 'minutes').valueOf(), + y0: dataDomain?.min, + y1: dataDomain?.max, + }, + details: influencers.join(','), + }; + }); + } + return ( - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {anomalies && ( + [a.startTime, a.influencers]) + )} + style={{ fill: '#D36086' }} + /> + )} props.theme.eui.paddingSizes.xs}; + padding-left: ${(props) => props.theme.eui.paddingSizes.xs}; width: 100%; height: 100%; `; diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_metrics_hosts_anomalies.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_metrics_hosts_anomalies.ts index f755057d0b76d..02170f41a32ca 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_metrics_hosts_anomalies.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_metrics_hosts_anomalies.ts @@ -5,8 +5,10 @@ */ import { useMemo, useState, useCallback, useEffect, useReducer } from 'react'; +import { HttpHandler } from 'src/core/public'; import { INFA_ML_GET_METRICS_HOSTS_ANOMALIES_PATH, + Metric, Sort, Pagination, PaginationCursor, @@ -15,8 +17,8 @@ import { getMetricsHostsAnomaliesSuccessReponsePayloadRT, } from '../../../../../common/http_api/infra_ml'; import { useTrackedPromise } from '../../../../utils/use_tracked_promise'; -import { npStart } from '../../../../legacy_singletons'; import { decodeOrThrow } from '../../../../../common/runtime_types'; +import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana'; export type SortOptions = Sort; export type PaginationOptions = Pick; @@ -148,6 +150,7 @@ export const useMetricsHostsAnomaliesResults = ({ onGetMetricsHostsAnomaliesDatasetsError?: (error: Error) => void; filteredDatasets?: string[]; }) => { + const { services } = useKibanaContextForPlugin(); const initStateReducer = (stateDefaults: ReducerStateDefaults): ReducerState => { return { ...stateDefaults, @@ -168,7 +171,7 @@ export const useMetricsHostsAnomaliesResults = ({ const [getMetricsHostsAnomaliesRequest, getMetricsHostsAnomalies] = useTrackedPromise( { cancelPreviousOn: 'creation', - createPromise: async () => { + createPromise: async (metric: Metric) => { const { timeRange: { start: queryStartTime, end: queryEndTime }, sortOptions, @@ -176,14 +179,18 @@ export const useMetricsHostsAnomaliesResults = ({ paginationCursor, } = reducerState; return await callGetMetricHostsAnomaliesAPI( - sourceId, - queryStartTime, - queryEndTime, - sortOptions, { - ...paginationOptions, - cursor: paginationCursor, - } + sourceId, + startTime: queryStartTime, + endTime: queryEndTime, + metric, + sort: sortOptions, + pagination: { + ...paginationOptions, + cursor: paginationCursor, + }, + }, + services.http.fetch ); }, onResolve: ({ data: { anomalies, paginationCursors: requestCursors, hasMoreEntries } }) => { @@ -249,10 +256,6 @@ export const useMetricsHostsAnomaliesResults = ({ }); }, [filteredDatasets]); - useEffect(() => { - getMetricsHostsAnomalies(); - }, [getMetricsHostsAnomalies]); // TODO: FIgure out the deps here. - const handleFetchNextPage = useCallback(() => { if (reducerState.lastReceivedCursors) { dispatch({ type: 'fetchNextPage' }); @@ -290,14 +293,21 @@ export const useMetricsHostsAnomaliesResults = ({ }; }; +interface RequestArgs { + sourceId: string; + startTime: number; + endTime: number; + metric: Metric; + sort: Sort; + pagination: Pagination; +} + export const callGetMetricHostsAnomaliesAPI = async ( - sourceId: string, - startTime: number, - endTime: number, - sort: Sort, - pagination: Pagination + requestArgs: RequestArgs, + fetch: HttpHandler ) => { - const response = await npStart.http.fetch(INFA_ML_GET_METRICS_HOSTS_ANOMALIES_PATH, { + const { sourceId, startTime, endTime, metric, sort, pagination } = requestArgs; + const response = await fetch(INFA_ML_GET_METRICS_HOSTS_ANOMALIES_PATH, { method: 'POST', body: JSON.stringify( getMetricsHostsAnomaliesRequestPayloadRT.encode({ @@ -307,6 +317,7 @@ export const callGetMetricHostsAnomaliesAPI = async ( startTime, endTime, }, + metric, sort, pagination, }, diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_metrics_k8s_anomalies.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_metrics_k8s_anomalies.ts index 4a7b78e1fdf92..951951b9b6106 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_metrics_k8s_anomalies.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_metrics_k8s_anomalies.ts @@ -5,6 +5,7 @@ */ import { useMemo, useState, useCallback, useEffect, useReducer } from 'react'; +import { HttpHandler } from 'src/core/public'; import { Sort, Pagination, @@ -13,10 +14,11 @@ import { getMetricsK8sAnomaliesSuccessReponsePayloadRT, getMetricsK8sAnomaliesRequestPayloadRT, MetricsK8sAnomaly, + Metric, } from '../../../../../common/http_api/infra_ml'; import { useTrackedPromise } from '../../../../utils/use_tracked_promise'; -import { npStart } from '../../../../legacy_singletons'; import { decodeOrThrow } from '../../../../../common/runtime_types'; +import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana'; export type SortOptions = Sort; export type PaginationOptions = Pick; @@ -148,6 +150,7 @@ export const useMetricsK8sAnomaliesResults = ({ onGetMetricsHostsAnomaliesDatasetsError?: (error: Error) => void; filteredDatasets?: string[]; }) => { + const { services } = useKibanaContextForPlugin(); const initStateReducer = (stateDefaults: ReducerStateDefaults): ReducerState => { return { ...stateDefaults, @@ -168,7 +171,7 @@ export const useMetricsK8sAnomaliesResults = ({ const [getMetricsK8sAnomaliesRequest, getMetricsK8sAnomalies] = useTrackedPromise( { cancelPreviousOn: 'creation', - createPromise: async () => { + createPromise: async (metric: Metric) => { const { timeRange: { start: queryStartTime, end: queryEndTime }, sortOptions, @@ -177,15 +180,19 @@ export const useMetricsK8sAnomaliesResults = ({ filteredDatasets: queryFilteredDatasets, } = reducerState; return await callGetMetricsK8sAnomaliesAPI( - sourceId, - queryStartTime, - queryEndTime, - sortOptions, { - ...paginationOptions, - cursor: paginationCursor, + sourceId, + startTime: queryStartTime, + endTime: queryEndTime, + metric, + sort: sortOptions, + pagination: { + ...paginationOptions, + cursor: paginationCursor, + }, + datasets: queryFilteredDatasets, }, - queryFilteredDatasets + services.http.fetch ); }, onResolve: ({ data: { anomalies, paginationCursors: requestCursors, hasMoreEntries } }) => { @@ -251,10 +258,6 @@ export const useMetricsK8sAnomaliesResults = ({ }); }, [filteredDatasets]); - useEffect(() => { - getMetricsK8sAnomalies(); - }, [getMetricsK8sAnomalies]); - const handleFetchNextPage = useCallback(() => { if (reducerState.lastReceivedCursors) { dispatch({ type: 'fetchNextPage' }); @@ -292,15 +295,22 @@ export const useMetricsK8sAnomaliesResults = ({ }; }; +interface RequestArgs { + sourceId: string; + startTime: number; + endTime: number; + metric: Metric; + sort: Sort; + pagination: Pagination; + datasets?: string[]; +} + export const callGetMetricsK8sAnomaliesAPI = async ( - sourceId: string, - startTime: number, - endTime: number, - sort: Sort, - pagination: Pagination, - datasets?: string[] + requestArgs: RequestArgs, + fetch: HttpHandler ) => { - const response = await npStart.http.fetch(INFA_ML_GET_METRICS_K8S_ANOMALIES_PATH, { + const { sourceId, startTime, endTime, metric, sort, pagination, datasets } = requestArgs; + const response = await fetch(INFA_ML_GET_METRICS_K8S_ANOMALIES_PATH, { method: 'POST', body: JSON.stringify( getMetricsK8sAnomaliesRequestPayloadRT.encode({ @@ -310,6 +320,7 @@ export const callGetMetricsK8sAnomaliesAPI = async ( startTime, endTime, }, + metric, sort, pagination, datasets, diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_timeline.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_timeline.ts index acf9011ac7ddd..597c268180819 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_timeline.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/hooks/use_timeline.ts @@ -81,10 +81,12 @@ export function useTimeline( ]); const { timeLength, intervalInSeconds } = timeLengthResult; + const endTime = currentTime + intervalInSeconds * 1000; + const startTime = currentTime - timeLength * 1000; const timerange: InfraTimerangeInput = { interval: displayInterval ?? '', - to: currentTime + intervalInSeconds * 1000, - from: currentTime - timeLength * 1000, + to: endTime, + from: startTime, ignoreLookback: true, forceInterval: true, }; @@ -127,6 +129,8 @@ export function useTimeline( error: (error && error.message) || null, loading: !interval ? true : loading, timeseries, + startTime, + endTime, reload: makeRequest, }; } diff --git a/x-pack/plugins/infra/public/plugin.ts b/x-pack/plugins/infra/public/plugin.ts index 66715b3fee28b..0e49ca93010fd 100644 --- a/x-pack/plugins/infra/public/plugin.ts +++ b/x-pack/plugins/infra/public/plugin.ts @@ -8,8 +8,7 @@ import { AppMountParameters, PluginInitializerContext } from 'kibana/public'; import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/public'; import { createMetricThresholdAlertType } from './alerting/metric_threshold'; import { createInventoryMetricAlertType } from './alerting/inventory'; -import { getAlertType as getLogsAlertType } from './components/alerting/logs/log_threshold_alert_type'; -import { registerStartSingleton } from './legacy_singletons'; +import { getAlertType as getLogsAlertType } from './alerting/log_threshold'; import { registerFeatures } from './register_feature'; import { InfraClientSetupDeps, @@ -98,9 +97,7 @@ export class Plugin implements InfraClientPluginClass { }); } - start(core: InfraClientCoreStart, _plugins: InfraClientStartDeps) { - registerStartSingleton(core); - } + start(_core: InfraClientCoreStart, _plugins: InfraClientStartDeps) {} stop() {} } diff --git a/x-pack/plugins/infra/public/utils/apollo_client.ts b/x-pack/plugins/infra/public/utils/apollo_client.ts index 3c69ef4c98fac..41831a03cabbb 100644 --- a/x-pack/plugins/infra/public/utils/apollo_client.ts +++ b/x-pack/plugins/infra/public/utils/apollo_client.ts @@ -16,6 +16,7 @@ export const createApolloClient = (fetch: HttpHandler) => { const cache = new InMemoryCache({ addTypename: false, fragmentMatcher: new IntrospectionFragmentMatcher({ + // @ts-expect-error apollo-cache-inmemory types don't match actual introspection data introspectionQueryResultData, }), }); diff --git a/x-pack/plugins/infra/scripts/storybook.js b/x-pack/plugins/infra/scripts/storybook.js deleted file mode 100644 index 05d5daedf58f2..0000000000000 --- a/x-pack/plugins/infra/scripts/storybook.js +++ /dev/null @@ -1,13 +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 { join } from 'path'; - -// eslint-disable-next-line -require('@kbn/storybook').runStorybookCli({ - name: 'infra', - storyGlobs: [join(__dirname, '..', 'public', 'components', '**', '*.stories.tsx')], -}); diff --git a/x-pack/plugins/infra/server/features.ts b/x-pack/plugins/infra/server/features.ts index 12ac57eb90186..444530c4d79f0 100644 --- a/x-pack/plugins/infra/server/features.ts +++ b/x-pack/plugins/infra/server/features.ts @@ -5,7 +5,7 @@ */ import { i18n } from '@kbn/i18n'; -import { LOG_DOCUMENT_COUNT_ALERT_TYPE_ID } from '../common/alerting/logs/types'; +import { LOG_DOCUMENT_COUNT_ALERT_TYPE_ID } from '../common/alerting/logs/log_threshold/types'; import { METRIC_INVENTORY_THRESHOLD_ALERT_TYPE_ID } from './lib/alerting/inventory_metric_threshold/types'; import { METRIC_THRESHOLD_ALERT_TYPE_ID } from './lib/alerting/metric_threshold/types'; import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/server'; diff --git a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts index 99904f15b4606..b56ede1974393 100644 --- a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts @@ -148,8 +148,10 @@ export const FIRED_ACTIONS = { const formatMetric = (metric: SnapshotMetricType, value: number) => { const metricFormatter = get(METRIC_FORMATTERS, metric, METRIC_FORMATTERS.count); - if (value == null) { - return ''; + if (isNaN(value)) { + return i18n.translate('xpack.infra.metrics.alerting.inventory.noDataFormattedValue', { + defaultMessage: '[NO DATA]', + }); } const formatter = createFormatter(metricFormatter.formatter, metricFormatter.template); return formatter(value); diff --git a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_chart_preview.ts b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_chart_preview.ts index 71115ad3a5745..e1657968b3f92 100644 --- a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_chart_preview.ts +++ b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_chart_preview.ts @@ -23,7 +23,7 @@ import { UngroupedSearchQueryResponse, GroupedSearchQueryResponse, GroupedSearchQueryResponseRT, -} from '../../../../common/alerting/logs/types'; +} from '../../../../common/alerting/logs/log_threshold/types'; import { decodeOrThrow } from '../../../../common/runtime_types'; const COMPOSITE_GROUP_SIZE = 40; diff --git a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.test.ts b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.test.ts index f730513991a78..e04fe338f3436 100644 --- a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.test.ts +++ b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.test.ts @@ -17,11 +17,11 @@ import { import { Comparator, AlertStates, - LogDocumentCountAlertParams, + AlertParams, Criterion, UngroupedSearchQueryResponse, GroupedSearchQueryResponse, -} from '../../../../common/alerting/logs/types'; +} from '../../../../common/alerting/logs/log_threshold/types'; import { alertsMock } from '../../../../../alerts/server/mocks'; // Mocks // @@ -56,7 +56,7 @@ const negativeCriteria: Criterion[] = [ { ...textField, comparator: Comparator.NOT_MATCH_PHRASE }, ]; -const baseAlertParams: Pick = { +const baseAlertParams: Pick = { count: { comparator: Comparator.GT, value: 5, @@ -85,7 +85,7 @@ describe('Log threshold executor', () => { }); describe('Criteria filter building', () => { test('Handles positive criteria', () => { - const alertParams: LogDocumentCountAlertParams = { + const alertParams: AlertParams = { ...baseAlertParams, criteria: positiveCriteria, }; @@ -140,7 +140,7 @@ describe('Log threshold executor', () => { }); test('Handles negative criteria', () => { - const alertParams: LogDocumentCountAlertParams = { + const alertParams: AlertParams = { ...baseAlertParams, criteria: negativeCriteria, }; @@ -168,7 +168,7 @@ describe('Log threshold executor', () => { }); test('Handles time range', () => { - const alertParams: LogDocumentCountAlertParams = { ...baseAlertParams, criteria: [] }; + const alertParams: AlertParams = { ...baseAlertParams, criteria: [] }; const filters = buildFiltersFromCriteria(alertParams, TIMESTAMP_FIELD); expect(typeof filters.rangeFilter.range[TIMESTAMP_FIELD].gte).toBe('number'); expect(typeof filters.rangeFilter.range[TIMESTAMP_FIELD].lte).toBe('number'); @@ -183,7 +183,7 @@ describe('Log threshold executor', () => { describe('ES queries', () => { describe('Query generation', () => { test('Correctly generates ungrouped queries', () => { - const alertParams: LogDocumentCountAlertParams = { + const alertParams: AlertParams = { ...baseAlertParams, criteria: [...positiveCriteria, ...negativeCriteria], }; @@ -279,7 +279,7 @@ describe('Log threshold executor', () => { }); test('Correctly generates grouped queries', () => { - const alertParams: LogDocumentCountAlertParams = { + const alertParams: AlertParams = { ...baseAlertParams, groupBy: ['host.name'], criteria: [...positiveCriteria, ...negativeCriteria], @@ -303,25 +303,6 @@ describe('Log threshold executor', () => { }, }, ], - must_not: [ - { - term: { - keywordField: { - value: 'error', - }, - }, - }, - { - match: { - textField: 'Something went wrong', - }, - }, - { - match_phrase: { - textField: 'Something went wrong', - }, - }, - ], }, }, aggregations: { @@ -398,6 +379,25 @@ describe('Log threshold executor', () => { }, }, ], + must_not: [ + { + term: { + keywordField: { + value: 'error', + }, + }, + }, + { + match: { + textField: 'Something went wrong', + }, + }, + { + match_phrase: { + textField: 'Something went wrong', + }, + }, + ], }, }, }, @@ -467,6 +467,7 @@ describe('Log threshold executor', () => { conditions: ' numericField more than 10', group: null, matchingDocuments: 10, + isRatio: false, }, }, ]); @@ -593,6 +594,7 @@ describe('Log threshold executor', () => { conditions: ' numericField more than 10', group: 'i-am-a-host-name-1, i-am-a-dataset-1', matchingDocuments: 10, + isRatio: false, }, }, ]); @@ -612,6 +614,7 @@ describe('Log threshold executor', () => { conditions: ' numericField more than 10', group: 'i-am-a-host-name-3, i-am-a-dataset-3', matchingDocuments: 20, + isRatio: false, }, }, ]); diff --git a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts index 224b898141c36..0ea65f94c9400 100644 --- a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts @@ -14,14 +14,21 @@ import { import { AlertStates, Comparator, - LogDocumentCountAlertParams, + AlertParams, Criterion, GroupedSearchQueryResponseRT, UngroupedSearchQueryResponseRT, UngroupedSearchQueryResponse, GroupedSearchQueryResponse, - LogDocumentCountAlertParamsRT, -} from '../../../../common/alerting/logs/types'; + AlertParamsRT, + isRatioAlertParams, + hasGroupBy, + getNumerator, + getDenominator, + Criteria, + CountAlertParams, + RatioAlertParams, +} from '../../../../common/alerting/logs/log_threshold/types'; import { InfraBackendLibs } from '../../infra_types'; import { getIntervalInSeconds } from '../../../utils/get_interval_in_seconds'; import { decodeOrThrow } from '../../../../common/runtime_types'; @@ -42,7 +49,6 @@ export const createLogThresholdExecutor = (libs: InfraBackendLibs) => async function ({ services, params }: AlertExecutorOptions) { const { alertInstanceFactory, savedObjectsClient, callCluster } = services; const { sources } = libs; - const { groupBy } = params; const sourceConfiguration = await sources.getSourceConfiguration(savedObjectsClient, 'default'); const indexPattern = sourceConfiguration.configuration.logAlias; @@ -50,30 +56,23 @@ export const createLogThresholdExecutor = (libs: InfraBackendLibs) => const alertInstance = alertInstanceFactory(UNGROUPED_FACTORY_KEY); try { - const validatedParams = decodeOrThrow(LogDocumentCountAlertParamsRT)(params); + const validatedParams = decodeOrThrow(AlertParamsRT)(params); - const query = - groupBy && groupBy.length > 0 - ? getGroupedESQuery(validatedParams, timestampField, indexPattern) - : getUngroupedESQuery(validatedParams, timestampField, indexPattern); - - if (!query) { - throw new Error('ES query could not be built from the provided alert params'); - } - - if (groupBy && groupBy.length > 0) { - processGroupByResults( - await getGroupedResults(query, callCluster), + if (!isRatioAlertParams(validatedParams)) { + await executeAlert( validatedParams, - alertInstanceFactory, - updateAlertInstance + timestampField, + indexPattern, + callCluster, + alertInstanceFactory ); } else { - processUngroupedResults( - await getUngroupedResults(query, callCluster), + await executeRatioAlert( validatedParams, - alertInstanceFactory, - updateAlertInstance + timestampField, + indexPattern, + callCluster, + alertInstanceFactory ); } } catch (e) { @@ -85,9 +84,97 @@ export const createLogThresholdExecutor = (libs: InfraBackendLibs) => } }; +async function executeAlert( + alertParams: CountAlertParams, + timestampField: string, + indexPattern: string, + callCluster: AlertServices['callCluster'], + alertInstanceFactory: AlertServices['alertInstanceFactory'] +) { + const query = getESQuery(alertParams, timestampField, indexPattern); + + if (!query) { + throw new Error('ES query could not be built from the provided alert params'); + } + + if (hasGroupBy(alertParams)) { + processGroupByResults( + await getGroupedResults(query, callCluster), + alertParams, + alertInstanceFactory, + updateAlertInstance + ); + } else { + processUngroupedResults( + await getUngroupedResults(query, callCluster), + alertParams, + alertInstanceFactory, + updateAlertInstance + ); + } +} + +async function executeRatioAlert( + alertParams: RatioAlertParams, + timestampField: string, + indexPattern: string, + callCluster: AlertServices['callCluster'], + alertInstanceFactory: AlertServices['alertInstanceFactory'] +) { + // Ratio alert params are separated out into two standard sets of alert params + const numeratorParams: AlertParams = { + ...alertParams, + criteria: getNumerator(alertParams.criteria), + }; + + const denominatorParams: AlertParams = { + ...alertParams, + criteria: getDenominator(alertParams.criteria), + }; + + const numeratorQuery = getESQuery(numeratorParams, timestampField, indexPattern); + const denominatorQuery = getESQuery(denominatorParams, timestampField, indexPattern); + + if (!numeratorQuery || !denominatorQuery) { + throw new Error('ES query could not be built from the provided ratio alert params'); + } + + if (hasGroupBy(alertParams)) { + const numeratorGroupedResults = await getGroupedResults(numeratorQuery, callCluster); + const denominatorGroupedResults = await getGroupedResults(denominatorQuery, callCluster); + processGroupByRatioResults( + numeratorGroupedResults, + denominatorGroupedResults, + alertParams, + alertInstanceFactory, + updateAlertInstance + ); + } else { + const numeratorUngroupedResults = await getUngroupedResults(numeratorQuery, callCluster); + const denominatorUngroupedResults = await getUngroupedResults(denominatorQuery, callCluster); + processUngroupedRatioResults( + numeratorUngroupedResults, + denominatorUngroupedResults, + alertParams, + alertInstanceFactory, + updateAlertInstance + ); + } +} + +const getESQuery = ( + alertParams: Omit & { criteria: Criteria }, + timestampField: string, + indexPattern: string +) => { + return hasGroupBy(alertParams) + ? getGroupedESQuery(alertParams, timestampField, indexPattern) + : getUngroupedESQuery(alertParams, timestampField, indexPattern); +}; + export const processUngroupedResults = ( results: UngroupedSearchQueryResponse, - params: LogDocumentCountAlertParams, + params: CountAlertParams, alertInstanceFactory: AlertExecutorOptions['services']['alertInstanceFactory'], alertInstaceUpdater: AlertInstanceUpdater ) => { @@ -102,8 +189,41 @@ export const processUngroupedResults = ( actionGroup: FIRED_ACTIONS.id, context: { matchingDocuments: documentCount, - conditions: createConditionsMessage(criteria), + conditions: createConditionsMessageForCriteria(criteria), + group: null, + isRatio: false, + }, + }, + ]); + } else { + alertInstaceUpdater(alertInstance, AlertStates.OK); + } +}; + +export const processUngroupedRatioResults = ( + numeratorResults: UngroupedSearchQueryResponse, + denominatorResults: UngroupedSearchQueryResponse, + params: RatioAlertParams, + alertInstanceFactory: AlertExecutorOptions['services']['alertInstanceFactory'], + alertInstaceUpdater: AlertInstanceUpdater +) => { + const { count, criteria } = params; + + const alertInstance = alertInstanceFactory(UNGROUPED_FACTORY_KEY); + const numeratorCount = numeratorResults.hits.total.value; + const denominatorCount = denominatorResults.hits.total.value; + const ratio = getRatio(numeratorCount, denominatorCount); + + if (ratio !== undefined && checkValueAgainstComparatorMap[count.comparator](ratio, count.value)) { + alertInstaceUpdater(alertInstance, AlertStates.ALERT, [ + { + actionGroup: FIRED_ACTIONS.id, + context: { + ratio, + numeratorConditions: createConditionsMessageForCriteria(getNumerator(criteria)), + denominatorConditions: createConditionsMessageForCriteria(getDenominator(criteria)), group: null, + isRatio: true, }, }, ]); @@ -112,24 +232,39 @@ export const processUngroupedResults = ( } }; -interface ReducedGroupByResults { +const getRatio = (numerator: number, denominator: number) => { + // We follow the mathematics principle that dividing by 0 isn't possible, + // and a ratio is therefore undefined (or indeterminate). + if (numerator === 0 || denominator === 0) return undefined; + return numerator / denominator; +}; + +interface ReducedGroupByResult { name: string; documentCount: number; } +type ReducedGroupByResults = ReducedGroupByResult[]; + +const getReducedGroupByResults = ( + results: GroupedSearchQueryResponse['aggregations']['groups']['buckets'] +): ReducedGroupByResults => { + return results.reduce((acc, groupBucket) => { + const groupName = Object.values(groupBucket.key).join(', '); + const groupResult = { name: groupName, documentCount: groupBucket.filtered_results.doc_count }; + return [...acc, groupResult]; + }, []); +}; + export const processGroupByResults = ( results: GroupedSearchQueryResponse['aggregations']['groups']['buckets'], - params: LogDocumentCountAlertParams, + params: CountAlertParams, alertInstanceFactory: AlertExecutorOptions['services']['alertInstanceFactory'], alertInstaceUpdater: AlertInstanceUpdater ) => { const { count, criteria } = params; - const groupResults = results.reduce((acc, groupBucket) => { - const groupName = Object.values(groupBucket.key).join(', '); - const groupResult = { name: groupName, documentCount: groupBucket.filtered_results.doc_count }; - return [...acc, groupResult]; - }, []); + const groupResults = getReducedGroupByResults(results); groupResults.forEach((group) => { const alertInstance = alertInstanceFactory(group.name); @@ -141,8 +276,53 @@ export const processGroupByResults = ( actionGroup: FIRED_ACTIONS.id, context: { matchingDocuments: documentCount, - conditions: createConditionsMessage(criteria), + conditions: createConditionsMessageForCriteria(criteria), group: group.name, + isRatio: false, + }, + }, + ]); + } else { + alertInstaceUpdater(alertInstance, AlertStates.OK); + } + }); +}; + +export const processGroupByRatioResults = ( + numeratorResults: GroupedSearchQueryResponse['aggregations']['groups']['buckets'], + denominatorResults: GroupedSearchQueryResponse['aggregations']['groups']['buckets'], + params: RatioAlertParams, + alertInstanceFactory: AlertExecutorOptions['services']['alertInstanceFactory'], + alertInstaceUpdater: AlertInstanceUpdater +) => { + const { count, criteria } = params; + + const numeratorGroupResults = getReducedGroupByResults(numeratorResults); + const denominatorGroupResults = getReducedGroupByResults(denominatorResults); + + numeratorGroupResults.forEach((numeratorGroup) => { + const alertInstance = alertInstanceFactory(numeratorGroup.name); + const numeratorDocumentCount = numeratorGroup.documentCount; + const denominatorGroup = denominatorGroupResults.find( + (_group) => _group.name === numeratorGroup.name + ); + // If there is no matching group, a ratio cannot be determined, and is therefore undefined. + const ratio = denominatorGroup + ? getRatio(numeratorDocumentCount, denominatorGroup.documentCount) + : undefined; + if ( + ratio !== undefined && + checkValueAgainstComparatorMap[count.comparator](ratio, count.value) + ) { + alertInstaceUpdater(alertInstance, AlertStates.ALERT, [ + { + actionGroup: FIRED_ACTIONS.id, + context: { + ratio, + numeratorConditions: createConditionsMessageForCriteria(getNumerator(criteria)), + denominatorConditions: createConditionsMessageForCriteria(getDenominator(criteria)), + group: numeratorGroup.name, + isRatio: true, }, }, ]); @@ -172,7 +352,7 @@ export const updateAlertInstance: AlertInstanceUpdater = (alertInstance, state, }; export const buildFiltersFromCriteria = ( - params: Omit, + params: Pick & { criteria: Criteria }, timestampField: string ) => { const { timeSize, timeUnit, criteria } = params; @@ -223,7 +403,7 @@ export const buildFiltersFromCriteria = ( }; export const getGroupedESQuery = ( - params: Omit, + params: Pick & { criteria: Criteria }, timestampField: string, index: string ): object | undefined => { @@ -254,6 +434,7 @@ export const getGroupedESQuery = ( bool: { // Scope the inner filtering back to the unpadded range filter: [rangeFilter, ...mustFilters], + ...(mustNotFilters.length > 0 && { must_not: mustNotFilters }), }, }, }, @@ -265,7 +446,6 @@ export const getGroupedESQuery = ( query: { bool: { filter: [groupedRangeFilter], - ...(mustNotFilters.length > 0 && { must_not: mustNotFilters }), }, }, aggregations, @@ -281,7 +461,7 @@ export const getGroupedESQuery = ( }; export const getUngroupedESQuery = ( - params: Omit, + params: Pick & { criteria: Criteria }, timestampField: string, index: string ): object => { @@ -315,7 +495,7 @@ type Filter = { [key in SupportedESQueryTypes]?: object; }; -const buildFiltersForCriteria = (criteria: LogDocumentCountAlertParams['criteria']) => { +const buildFiltersForCriteria = (criteria: Criteria) => { let filters: Filter[] = []; criteria.forEach((criterion) => { @@ -443,7 +623,7 @@ const getGroupedResults = async (query: object, callCluster: AlertServices['call return compositeGroupBuckets; }; -const createConditionsMessage = (criteria: LogDocumentCountAlertParams['criteria']) => { +const createConditionsMessageForCriteria = (criteria: Criteria) => { const parts = criteria.map((criterion, index) => { const { field, comparator, value } = criterion; return `${index === 0 ? '' : 'and'} ${field} ${comparator} ${value}`; diff --git a/x-pack/plugins/infra/server/lib/alerting/log_threshold/register_log_threshold_alert_type.ts b/x-pack/plugins/infra/server/lib/alerting/log_threshold/register_log_threshold_alert_type.ts index ab55601f4c475..2c1d7e0976607 100644 --- a/x-pack/plugins/infra/server/lib/alerting/log_threshold/register_log_threshold_alert_type.ts +++ b/x-pack/plugins/infra/server/lib/alerting/log_threshold/register_log_threshold_alert_type.ts @@ -4,14 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ import { i18n } from '@kbn/i18n'; -import { schema } from '@kbn/config-schema'; import { PluginSetupContract } from '../../../../../alerts/server'; import { createLogThresholdExecutor, FIRED_ACTIONS } from './log_threshold_executor'; import { LOG_DOCUMENT_COUNT_ALERT_TYPE_ID, - Comparator, -} from '../../../../common/alerting/logs/types'; + AlertParamsRT, +} from '../../../../common/alerting/logs/log_threshold/types'; import { InfraBackendLibs } from '../../infra_types'; +import { decodeOrThrow } from '../../../../common/runtime_types'; const documentCountActionVariableDescription = i18n.translate( 'xpack.infra.logs.alerting.threshold.documentCountActionVariableDescription', @@ -34,33 +34,33 @@ const groupByActionVariableDescription = i18n.translate( } ); -const countSchema = schema.object({ - value: schema.number(), - comparator: schema.oneOf([ - schema.literal(Comparator.GT), - schema.literal(Comparator.LT), - schema.literal(Comparator.GT_OR_EQ), - schema.literal(Comparator.LT_OR_EQ), - schema.literal(Comparator.EQ), - ]), -}); +const isRatioActionVariableDescription = i18n.translate( + 'xpack.infra.logs.alerting.threshold.isRatioActionVariableDescription', + { + defaultMessage: 'Denotes whether this alert was configured with a ratio', + } +); + +const ratioActionVariableDescription = i18n.translate( + 'xpack.infra.logs.alerting.threshold.ratioActionVariableDescription', + { + defaultMessage: 'The ratio value of the two sets of criteria', + } +); -const criteriaSchema = schema.object({ - field: schema.string(), - comparator: schema.oneOf([ - schema.literal(Comparator.GT), - schema.literal(Comparator.LT), - schema.literal(Comparator.GT_OR_EQ), - schema.literal(Comparator.LT_OR_EQ), - schema.literal(Comparator.EQ), - schema.literal(Comparator.NOT_EQ), - schema.literal(Comparator.MATCH), - schema.literal(Comparator.NOT_MATCH), - schema.literal(Comparator.MATCH_PHRASE), - schema.literal(Comparator.NOT_MATCH_PHRASE), - ]), - value: schema.oneOf([schema.number(), schema.string()]), -}); +const numeratorConditionsActionVariableDescription = i18n.translate( + 'xpack.infra.logs.alerting.threshold.numeratorConditionsActionVariableDescription', + { + defaultMessage: 'The conditions that the numerator of the ratio needed to fulfill', + } +); + +const denominatorConditionsActionVariableDescription = i18n.translate( + 'xpack.infra.logs.alerting.threshold.denominatorConditionsActionVariableDescription', + { + defaultMessage: 'The conditions that the denominator of the ratio needed to fulfill', + } +); export async function registerLogThresholdAlertType( alertingPlugin: PluginSetupContract, @@ -76,13 +76,9 @@ export async function registerLogThresholdAlertType( id: LOG_DOCUMENT_COUNT_ALERT_TYPE_ID, name: 'Log threshold', validate: { - params: schema.object({ - count: countSchema, - criteria: schema.arrayOf(criteriaSchema), - timeUnit: schema.string(), - timeSize: schema.number(), - groupBy: schema.maybe(schema.arrayOf(schema.string())), - }), + params: { + validate: (params) => decodeOrThrow(AlertParamsRT)(params), + }, }, defaultActionGroupId: FIRED_ACTIONS.id, actionGroups: [FIRED_ACTIONS], @@ -92,6 +88,14 @@ export async function registerLogThresholdAlertType( { name: 'matchingDocuments', description: documentCountActionVariableDescription }, { name: 'conditions', description: conditionsActionVariableDescription }, { name: 'group', description: groupByActionVariableDescription }, + // Ratio alerts + { name: 'isRatio', description: isRatioActionVariableDescription }, + { name: 'ratio', description: ratioActionVariableDescription }, + { name: 'numeratorConditions', description: numeratorConditionsActionVariableDescription }, + { + name: 'denominatorConditions', + description: denominatorConditionsActionVariableDescription, + }, ], }, producer: 'logs', diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts index c85685b4cdca8..4dec552c5bd6c 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts @@ -131,11 +131,24 @@ const formatAlertResult = ( } & AlertResult ) => { const { metric, currentValue, threshold } = alertResult; - if (!metric.endsWith('.pct')) return alertResult; + const noDataValue = i18n.translate( + 'xpack.infra.metrics.alerting.threshold.noDataFormattedValue', + { + defaultMessage: '[NO DATA]', + } + ); + if (!metric.endsWith('.pct')) + return { + ...alertResult, + currentValue: currentValue ?? noDataValue, + }; const formatter = createFormatter('percent'); return { ...alertResult, - currentValue: formatter(currentValue), + currentValue: + currentValue !== null && typeof currentValue !== 'undefined' + ? formatter(currentValue) + : noDataValue, threshold: Array.isArray(threshold) ? threshold.map((v: number) => formatter(v)) : threshold, }; }; diff --git a/x-pack/plugins/infra/server/lib/infra_ml/metrics_hosts_anomalies.ts b/x-pack/plugins/infra/server/lib/infra_ml/metrics_hosts_anomalies.ts index e0afa458aac88..a3a0f91afaab8 100644 --- a/x-pack/plugins/infra/server/lib/infra_ml/metrics_hosts_anomalies.ts +++ b/x-pack/plugins/infra/server/lib/infra_ml/metrics_hosts_anomalies.ts @@ -7,7 +7,7 @@ import { RequestHandlerContext } from 'src/core/server'; import { InfraRequestHandlerContext } from '../../types'; import { TracingSpan, startTracingSpan } from '../../../common/performance_tracing'; -import { fetchMlJob, getLogEntryDatasets } from './common'; +import { fetchMlJob } from './common'; import { getJobId, metricsHostsJobTypes } from '../../../common/infra_ml'; import { Sort, Pagination } from '../../../common/http_api/infra_ml'; import type { MlSystem, MlAnomalyDetectors } from '../../types'; @@ -21,37 +21,43 @@ import { interface MappedAnomalyHit { id: string; anomalyScore: number; - dataset: string; typical: number; actual: number; jobId: string; startTime: number; duration: number; - hostName: string[]; + influencers: string[]; categoryId?: string; } async function getCompatibleAnomaliesJobIds( spaceId: string, sourceId: string, + metric: 'memory_usage' | 'network_in' | 'network_out' | undefined, mlAnomalyDetectors: MlAnomalyDetectors ) { - const metricsHostsJobIds = metricsHostsJobTypes.map((jt) => getJobId(spaceId, sourceId, jt)); + let metricsHostsJobIds = metricsHostsJobTypes; + + if (metric) { + metricsHostsJobIds = metricsHostsJobIds.filter((jt) => jt === `hosts_${metric}`); + } const jobIds: string[] = []; let jobSpans: TracingSpan[] = []; try { await Promise.all( - metricsHostsJobIds.map((id) => { - return (async () => { - const { - timing: { spans }, - } = await fetchMlJob(mlAnomalyDetectors, id); - jobIds.push(id); - jobSpans = [...jobSpans, ...spans]; - })(); - }) + metricsHostsJobIds + .map((jt) => getJobId(spaceId, sourceId, jt)) + .map((id) => { + return (async () => { + const { + timing: { spans }, + } = await fetchMlJob(mlAnomalyDetectors, id); + jobIds.push(id); + jobSpans = [...jobSpans, ...spans]; + })(); + }) ); } catch (e) { if (isMlPrivilegesError(e)) { @@ -71,6 +77,7 @@ export async function getMetricsHostsAnomalies( sourceId: string, startTime: number, endTime: number, + metric: 'memory_usage' | 'network_in' | 'network_out' | undefined, sort: Sort, pagination: Pagination ) { @@ -82,6 +89,7 @@ export async function getMetricsHostsAnomalies( } = await getCompatibleAnomaliesJobIds( context.infra.spaceId, sourceId, + metric, context.infra.mlAnomalyDetectors ); @@ -131,22 +139,20 @@ const parseAnomalyResult = (anomaly: MappedAnomalyHit, jobId: string) => { const { id, anomalyScore, - dataset, typical, actual, duration, - hostName, + influencers, startTime: anomalyStartTime, } = anomaly; return { id, anomalyScore, - dataset, typical, actual, duration, - hostName, + influencers, startTime: anomalyStartTime, type: 'metrics_hosts' as const, jobId, @@ -169,16 +175,6 @@ async function fetchMetricsHostsAnomalies( const finalizeFetchLogEntryAnomaliesSpan = startTracingSpan('fetch metrics hosts anomalies'); - // console.log( - // 'data', - // JSON.stringify( - // await mlSystem.mlAnomalySearch( - // createMetricsHostsAnomaliesQuery(jobIds, startTime, endTime, sort, expandedPagination) - // ), - // null, - // 2 - // ) - // ); const results = decodeOrThrow(metricsHostsAnomaliesResponseRT)( await mlSystem.mlAnomalySearch( createMetricsHostsAnomaliesQuery(jobIds, startTime, endTime, sort, expandedPagination) @@ -216,11 +212,13 @@ async function fetchMetricsHostsAnomalies( record_score: anomalyScore, typical, actual, + influencers, bucket_span: duration, timestamp: anomalyStartTime, by_field_value: categoryId, } = result._source; + const hostInfluencers = influencers.filter((i) => i.influencer_field_name === 'host.name'); return { id: result._id, anomalyScore, @@ -228,7 +226,10 @@ async function fetchMetricsHostsAnomalies( typical: typical[0], actual: actual[0], jobId: job_id, - hostName: result._source['host.name'], + influencers: hostInfluencers.reduce( + (acc: string[], i) => [...acc, ...i.influencer_field_values], + [] + ), startTime: anomalyStartTime, duration: duration * 1000, categoryId, @@ -246,44 +247,3 @@ async function fetchMetricsHostsAnomalies( }, }; } - -// TODO: FIgure out why we need datasets -export async function getMetricsHostsAnomaliesDatasets( - context: { - infra: { - mlSystem: MlSystem; - mlAnomalyDetectors: MlAnomalyDetectors; - spaceId: string; - }; - }, - sourceId: string, - startTime: number, - endTime: number -) { - const { - jobIds, - timing: { spans: jobSpans }, - } = await getCompatibleAnomaliesJobIds( - context.infra.spaceId, - sourceId, - context.infra.mlAnomalyDetectors - ); - - if (jobIds.length === 0) { - throw new InsufficientAnomalyMlJobsConfigured( - 'Log rate or categorisation ML jobs need to be configured to search for anomaly datasets' - ); - } - - const { - data: datasets, - timing: { spans: datasetsSpans }, - } = await getLogEntryDatasets(context.infra.mlSystem, startTime, endTime, jobIds); - - return { - datasets, - timing: { - spans: [...jobSpans, ...datasetsSpans], - }, - }; -} diff --git a/x-pack/plugins/infra/server/lib/infra_ml/metrics_k8s_anomalies.ts b/x-pack/plugins/infra/server/lib/infra_ml/metrics_k8s_anomalies.ts index 29507900e1847..1a9b48ade83ed 100644 --- a/x-pack/plugins/infra/server/lib/infra_ml/metrics_k8s_anomalies.ts +++ b/x-pack/plugins/infra/server/lib/infra_ml/metrics_k8s_anomalies.ts @@ -7,7 +7,7 @@ import { RequestHandlerContext } from 'src/core/server'; import { InfraRequestHandlerContext } from '../../types'; import { TracingSpan, startTracingSpan } from '../../../common/performance_tracing'; -import { fetchMlJob, getLogEntryDatasets } from './common'; +import { fetchMlJob } from './common'; import { getJobId, metricsK8SJobTypes } from '../../../common/infra_ml'; import { Sort, Pagination } from '../../../common/http_api/infra_ml'; import type { MlSystem, MlAnomalyDetectors } from '../../types'; @@ -21,11 +21,11 @@ import { interface MappedAnomalyHit { id: string; anomalyScore: number; - // dataset: string; typical: number; actual: number; jobId: string; startTime: number; + influencers: string[]; duration: number; categoryId?: string; } @@ -33,24 +33,31 @@ interface MappedAnomalyHit { async function getCompatibleAnomaliesJobIds( spaceId: string, sourceId: string, + metric: 'memory_usage' | 'network_in' | 'network_out' | undefined, mlAnomalyDetectors: MlAnomalyDetectors ) { - const metricsK8sJobIds = metricsK8SJobTypes.map((jt) => getJobId(spaceId, sourceId, jt)); + let metricsK8sJobIds = metricsK8SJobTypes; + + if (metric) { + metricsK8sJobIds = metricsK8sJobIds.filter((jt) => jt === `k8s_${metric}`); + } const jobIds: string[] = []; let jobSpans: TracingSpan[] = []; try { await Promise.all( - metricsK8sJobIds.map((id) => { - return (async () => { - const { - timing: { spans }, - } = await fetchMlJob(mlAnomalyDetectors, id); - jobIds.push(id); - jobSpans = [...jobSpans, ...spans]; - })(); - }) + metricsK8sJobIds + .map((jt) => getJobId(spaceId, sourceId, jt)) + .map((id) => { + return (async () => { + const { + timing: { spans }, + } = await fetchMlJob(mlAnomalyDetectors, id); + jobIds.push(id); + jobSpans = [...jobSpans, ...spans]; + })(); + }) ); } catch (e) { if (isMlPrivilegesError(e)) { @@ -70,6 +77,7 @@ export async function getMetricK8sAnomalies( sourceId: string, startTime: number, endTime: number, + metric: 'memory_usage' | 'network_in' | 'network_out' | undefined, sort: Sort, pagination: Pagination ) { @@ -81,6 +89,7 @@ export async function getMetricK8sAnomalies( } = await getCompatibleAnomaliesJobIds( context.infra.spaceId, sourceId, + metric, context.infra.mlAnomalyDetectors ); @@ -126,21 +135,21 @@ const parseAnomalyResult = (anomaly: MappedAnomalyHit, jobId: string) => { const { id, anomalyScore, - // dataset, typical, actual, duration, + influencers, startTime: anomalyStartTime, } = anomaly; return { id, anomalyScore, - // dataset, typical, actual, duration, startTime: anomalyStartTime, + influencers, type: 'metrics_k8s' as const, jobId, }; @@ -199,19 +208,25 @@ async function fetchMetricK8sAnomalies( record_score: anomalyScore, typical, actual, - // partition_field_value: dataset, bucket_span: duration, timestamp: anomalyStartTime, by_field_value: categoryId, + influencers, } = result._source; + const podInfluencers = influencers.filter( + (i) => i.influencer_field_name === 'kubernetes.pod.uid' + ); return { id: result._id, anomalyScore, - // dataset, typical: typical[0], actual: actual[0], jobId: job_id, + influencers: podInfluencers.reduce( + (acc: string[], i) => [...acc, ...i.influencer_field_values], + [] + ), startTime: anomalyStartTime, duration: duration * 1000, categoryId, @@ -229,44 +244,3 @@ async function fetchMetricK8sAnomalies( }, }; } - -// TODO: FIgure out why we need datasets -export async function getMetricK8sAnomaliesDatasets( - context: { - infra: { - mlSystem: MlSystem; - mlAnomalyDetectors: MlAnomalyDetectors; - spaceId: string; - }; - }, - sourceId: string, - startTime: number, - endTime: number -) { - const { - jobIds, - timing: { spans: jobSpans }, - } = await getCompatibleAnomaliesJobIds( - context.infra.spaceId, - sourceId, - context.infra.mlAnomalyDetectors - ); - - if (jobIds.length === 0) { - throw new InsufficientAnomalyMlJobsConfigured( - 'Log rate or categorisation ML jobs need to be configured to search for anomaly datasets' - ); - } - - const { - data: datasets, - timing: { spans: datasetsSpans }, - } = await getLogEntryDatasets(context.infra.mlSystem, startTime, endTime, jobIds); - - return { - datasets, - timing: { - spans: [...jobSpans, ...datasetsSpans], - }, - }; -} diff --git a/x-pack/plugins/infra/server/lib/infra_ml/queries/common.ts b/x-pack/plugins/infra/server/lib/infra_ml/queries/common.ts index 63e39ef022392..eb08b6d692336 100644 --- a/x-pack/plugins/infra/server/lib/infra_ml/queries/common.ts +++ b/x-pack/plugins/infra/server/lib/infra_ml/queries/common.ts @@ -40,6 +40,16 @@ export const createTimeRangeFilters = (startTime: number, endTime: number) => [ }, ]; +export const createAnomalyScoreFilter = (minScore: number) => [ + { + range: { + record_score: { + gte: minScore, + }, + }, + }, +]; + export const createResultTypeFilters = (resultTypes: Array<'model_plot' | 'record'>) => [ { terms: { diff --git a/x-pack/plugins/infra/server/lib/infra_ml/queries/metrics_hosts_anomalies.ts b/x-pack/plugins/infra/server/lib/infra_ml/queries/metrics_hosts_anomalies.ts index b61119b60bc18..bbdc77af1fbe6 100644 --- a/x-pack/plugins/infra/server/lib/infra_ml/queries/metrics_hosts_anomalies.ts +++ b/x-pack/plugins/infra/server/lib/infra_ml/queries/metrics_hosts_anomalies.ts @@ -11,6 +11,7 @@ import { createTimeRangeFilters, createResultTypeFilters, defaultRequestParameters, + createAnomalyScoreFilter, } from './common'; import { Sort, Pagination } from '../../../../common/http_api/infra_ml'; @@ -35,6 +36,7 @@ export const createMetricsHostsAnomaliesQuery = ( const filters = [ ...createJobIdsFilters(jobIds), + ...createAnomalyScoreFilter(50), ...createTimeRangeFilters(startTime, endTime), ...createResultTypeFilters(['record']), ]; @@ -86,6 +88,12 @@ export const metricsHostsAnomalyHitRT = rt.type({ record_score: rt.number, typical: rt.array(rt.number), actual: rt.array(rt.number), + influencers: rt.array( + rt.type({ + influencer_field_name: rt.string, + influencer_field_values: rt.array(rt.string), + }) + ), 'host.name': rt.array(rt.string), bucket_span: rt.number, timestamp: rt.number, diff --git a/x-pack/plugins/infra/server/lib/infra_ml/queries/metrics_k8s_anomalies.ts b/x-pack/plugins/infra/server/lib/infra_ml/queries/metrics_k8s_anomalies.ts index 84ed8b064c5ca..79bfdc91dc5a4 100644 --- a/x-pack/plugins/infra/server/lib/infra_ml/queries/metrics_k8s_anomalies.ts +++ b/x-pack/plugins/infra/server/lib/infra_ml/queries/metrics_k8s_anomalies.ts @@ -11,6 +11,7 @@ import { createTimeRangeFilters, createResultTypeFilters, defaultRequestParameters, + createAnomalyScoreFilter, } from './common'; import { Sort, Pagination } from '../../../../common/http_api/infra_ml'; @@ -35,6 +36,7 @@ export const createMetricsK8sAnomaliesQuery = ( const filters = [ ...createJobIdsFilters(jobIds), + ...createAnomalyScoreFilter(50), ...createTimeRangeFilters(startTime, endTime), ...createResultTypeFilters(['record']), ]; @@ -48,6 +50,8 @@ export const createMetricsK8sAnomaliesQuery = ( 'timestamp', 'bucket_span', 'by_field_value', + 'influencers.influencer_field_name', + 'influencers.influencer_field_values', ]; const { querySortDirection, queryCursor } = parsePaginationCursor(sort, pagination); @@ -83,7 +87,12 @@ export const metricsK8sAnomalyHitRT = rt.type({ record_score: rt.number, typical: rt.array(rt.number), actual: rt.array(rt.number), - // partition_field_value: rt.string, + influencers: rt.array( + rt.type({ + influencer_field_name: rt.string, + influencer_field_values: rt.array(rt.string), + }) + ), bucket_span: rt.number, timestamp: rt.number, }), diff --git a/x-pack/plugins/infra/server/lib/metrics/constants.ts b/x-pack/plugins/infra/server/lib/metrics/constants.ts index 590eaf5605c72..dcff96ed155dc 100644 --- a/x-pack/plugins/infra/server/lib/metrics/constants.ts +++ b/x-pack/plugins/infra/server/lib/metrics/constants.ts @@ -4,13 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ export const EMPTY_RESPONSE = { - series: [ - { - id: '*', - keys: ['*'], - columns: [], - rows: [], - }, - ], + series: [], info: { total: 0, afterKey: null, interval: 0 }, }; diff --git a/x-pack/plugins/infra/server/routes/infra_ml/results/metrics_hosts_anomalies.ts b/x-pack/plugins/infra/server/routes/infra_ml/results/metrics_hosts_anomalies.ts index 29122ae159cdc..9dc309c605206 100644 --- a/x-pack/plugins/infra/server/routes/infra_ml/results/metrics_hosts_anomalies.ts +++ b/x-pack/plugins/infra/server/routes/infra_ml/results/metrics_hosts_anomalies.ts @@ -36,6 +36,7 @@ export const initGetHostsAnomaliesRoute = ({ framework }: InfraBackendLibs) => { timeRange: { startTime, endTime }, sort: sortParam, pagination: paginationParam, + metric, }, } = request.body; @@ -54,12 +55,11 @@ export const initGetHostsAnomaliesRoute = ({ framework }: InfraBackendLibs) => { sourceId, startTime, endTime, + metric, sort, pagination ); - // console.log('---- anomalies', anomalies); - return response.ok({ body: getMetricsHostsAnomaliesSuccessReponsePayloadRT.encode({ data: { diff --git a/x-pack/plugins/infra/server/routes/infra_ml/results/metrics_k8s_anomalies.ts b/x-pack/plugins/infra/server/routes/infra_ml/results/metrics_k8s_anomalies.ts index 5260c55836c59..1618018b85fcf 100644 --- a/x-pack/plugins/infra/server/routes/infra_ml/results/metrics_k8s_anomalies.ts +++ b/x-pack/plugins/infra/server/routes/infra_ml/results/metrics_k8s_anomalies.ts @@ -35,6 +35,7 @@ export const initGetK8sAnomaliesRoute = ({ framework }: InfraBackendLibs) => { timeRange: { startTime, endTime }, sort: sortParam, pagination: paginationParam, + metric, }, } = request.body; @@ -53,6 +54,7 @@ export const initGetK8sAnomaliesRoute = ({ framework }: InfraBackendLibs) => { sourceId, startTime, endTime, + metric, sort, pagination ); diff --git a/x-pack/plugins/infra/server/usage/usage_collector.ts b/x-pack/plugins/infra/server/usage/usage_collector.ts index 598ee21e6f273..54f6d2f6121db 100644 --- a/x-pack/plugins/infra/server/usage/usage_collector.ts +++ b/x-pack/plugins/infra/server/usage/usage_collector.ts @@ -14,6 +14,17 @@ interface InfraopsSum { logs: number; } +interface Usage { + last_24_hours: { + hits: { + infraops_hosts: number; + infraops_docker: number; + infraops_kubernetes: number; + logs: number; + }; + }; +} + export class UsageCollector { public static registerUsageCollector(usageCollection: UsageCollectionSetup): void { const collector = UsageCollector.getUsageCollector(usageCollection); @@ -21,12 +32,22 @@ export class UsageCollector { } public static getUsageCollector(usageCollection: UsageCollectionSetup) { - return usageCollection.makeUsageCollector({ + return usageCollection.makeUsageCollector({ type: 'infraops', isReady: () => true, fetch: async () => { return this.getReport(); }, + schema: { + last_24_hours: { + hits: { + infraops_hosts: { type: 'long' }, + infraops_docker: { type: 'long' }, + infraops_kubernetes: { type: 'long' }, + logs: { type: 'long' }, + }, + }, + }, }); } diff --git a/x-pack/plugins/ingest_manager/common/constants/agent.ts b/x-pack/plugins/ingest_manager/common/constants/agent.ts index 82d2ad712ef02..30b8a6b740609 100644 --- a/x-pack/plugins/ingest_manager/common/constants/agent.ts +++ b/x-pack/plugins/ingest_manager/common/constants/agent.ts @@ -13,10 +13,12 @@ export const AGENT_TYPE_EPHEMERAL = 'EPHEMERAL'; export const AGENT_TYPE_TEMPORARY = 'TEMPORARY'; export const AGENT_POLLING_REQUEST_TIMEOUT_MS = 300000; // 5 minutes +export const AGENT_POLLING_REQUEST_TIMEOUT_MARGIN_MS = 20000; // 20s + export const AGENT_POLLING_THRESHOLD_MS = 30000; export const AGENT_POLLING_INTERVAL = 1000; export const AGENT_UPDATE_LAST_CHECKIN_INTERVAL_MS = 30000; export const AGENT_UPDATE_ACTIONS_INTERVAL_MS = 5000; -export const AGENT_POLICY_ROLLOUT_RATE_LIMIT_INTERVAL_MS = 5000; -export const AGENT_POLICY_ROLLOUT_RATE_LIMIT_REQUEST_PER_INTERVAL = 25; +export const AGENT_POLICY_ROLLOUT_RATE_LIMIT_INTERVAL_MS = 1000; +export const AGENT_POLICY_ROLLOUT_RATE_LIMIT_REQUEST_PER_INTERVAL = 5; diff --git a/x-pack/plugins/ingest_manager/common/constants/index.ts b/x-pack/plugins/ingest_manager/common/constants/index.ts index 519e2861cdc1d..bdc5714f7e2fe 100644 --- a/x-pack/plugins/ingest_manager/common/constants/index.ts +++ b/x-pack/plugins/ingest_manager/common/constants/index.ts @@ -13,3 +13,9 @@ export * from './epm'; export * from './output'; export * from './enrollment_api_key'; export * from './settings'; + +// TODO: This is the default `index.max_result_window` ES setting, which dictates +// the maximum amount of results allowed to be returned from a search. It's possible +// for the actual setting to differ from the default. Can we retrieve the real +// setting in the future? +export const SO_SEARCH_LIMIT = 10000; diff --git a/x-pack/plugins/ingest_manager/common/openapi/spec_oas3.json b/x-pack/plugins/ingest_manager/common/openapi/spec_oas3.json index b7856e6d57402..a780ae5599793 100644 --- a/x-pack/plugins/ingest_manager/common/openapi/spec_oas3.json +++ b/x-pack/plugins/ingest_manager/common/openapi/spec_oas3.json @@ -1543,7 +1543,7 @@ } }, "format_version": "1.0.0", - "datasets": [ + "data_streams": [ { "title": "CoreDNS logs", "name": "log", @@ -1764,7 +1764,7 @@ ] } }, - "datasets": [ + "data_streams": [ { "id": "endpoint", "title": "Endpoint Events", @@ -2757,7 +2757,7 @@ "data": "{\"config\":{\"id\":\"ae556400-5e39-11ea-8b49-f9747e466f7b\",\"outputs\":{\"default\":{\"type\":\"elasticsearch\",\"hosts\":[\"http://localhost:9200\"],\"api_key\":\"\",\"api_token\":\"6ckkp3ABz7e_XRqr3LM8:gQuDfUNSRgmY0iziYqP9Hw\"}},\"packagePolicies\":[]}}", "created_at": "2020-03-04T20:02:56.149Z", "id": "6a95c00a-d76d-4931-97c3-0bf935272d7d", - "type": "CONFIG_CHANGE" + "type": "POLICY_CHANGE" } ], "access_api_key_id": "6Mkkp3ABz7e_XRqrzLNJ", @@ -2920,7 +2920,7 @@ "actions": [ { "agent_id": "a6f14bd2-1a2a-481c-9212-9494d064ffdf", - "type": "CONFIG_CHANGE", + "type": "POLICY_CHANGE", "data": { "config": { "id": "2fe89350-a5e0-11ea-a587-5f886c8a849f", @@ -3961,7 +3961,7 @@ "format_version": { "type": "string" }, - "datasets": { + "data_streams": { "type": "array", "items": { "type": "object", diff --git a/x-pack/plugins/ingest_manager/common/services/is_valid_namespace.test.ts b/x-pack/plugins/ingest_manager/common/services/is_valid_namespace.test.ts index 40f37cc456f94..3ed9e3a087a92 100644 --- a/x-pack/plugins/ingest_manager/common/services/is_valid_namespace.test.ts +++ b/x-pack/plugins/ingest_manager/common/services/is_valid_namespace.test.ts @@ -7,22 +7,32 @@ import { isValidNamespace } from './is_valid_namespace'; describe('Ingest Manager - isValidNamespace', () => { it('returns true for valid namespaces', () => { - expect(isValidNamespace('default')).toBe(true); - expect(isValidNamespace('namespace-with-dash')).toBe(true); - expect(isValidNamespace('123')).toBe(true); + expect(isValidNamespace('default').valid).toBe(true); + expect(isValidNamespace('namespace-with-dash').valid).toBe(true); + expect(isValidNamespace('123').valid).toBe(true); + expect(isValidNamespace('testlength😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀😀').valid).toBe( + true + ); }); it('returns false for invalid namespaces', () => { - expect(isValidNamespace('Default')).toBe(false); - expect(isValidNamespace('namespace with spaces')).toBe(false); - expect(isValidNamespace('foo/bar')).toBe(false); - expect(isValidNamespace('foo\\bar')).toBe(false); - expect(isValidNamespace('foo*bar')).toBe(false); - expect(isValidNamespace('foo?bar')).toBe(false); - expect(isValidNamespace('foo"bar')).toBe(false); - expect(isValidNamespace('foo, |, space character, comma, #, : - /^[^\*\\/\?"<>|\s,#:]+$/.test(namespace) - ); +// and implements a limit based on https://github.com/elastic/kibana/issues/75846 +export function isValidNamespace(namespace: string): { valid: boolean; error?: string } { + if (!namespace.trim()) { + return { + valid: false, + error: i18n.translate('xpack.ingestManager.namespaceValidation.requiredErrorMessage', { + defaultMessage: 'Namespace is required', + }), + }; + } else if (namespace !== namespace.toLowerCase()) { + return { + valid: false, + error: i18n.translate('xpack.ingestManager.namespaceValidation.lowercaseErrorMessage', { + defaultMessage: 'Namespace must be lowercase', + }), + }; + } else if (/[\*\\/\?"<>|\s,#:]+/.test(namespace)) { + return { + valid: false, + error: i18n.translate( + 'xpack.ingestManager.namespaceValidation.invalidCharactersErrorMessage', + { + defaultMessage: 'Namespace contains invalid characters', + } + ), + }; + } + // Node.js doesn't have Blob, and browser doesn't have Buffer :) + else if ( + (typeof Blob === 'function' && new Blob([namespace]).size > 100) || + (typeof Buffer === 'function' && Buffer.from(namespace).length > 100) + ) { + return { + valid: false, + error: i18n.translate('xpack.ingestManager.namespaceValidation.tooLongErrorMessage', { + defaultMessage: 'Namespace cannot be more than 100 bytes', + }), + }; + } + + return { valid: true }; } diff --git a/x-pack/plugins/ingest_manager/common/services/limited_package.ts b/x-pack/plugins/ingest_manager/common/services/limited_package.ts index 21d1dbd1556b7..8d2a251ae015e 100644 --- a/x-pack/plugins/ingest_manager/common/services/limited_package.ts +++ b/x-pack/plugins/ingest_manager/common/services/limited_package.ts @@ -7,7 +7,7 @@ import { PackageInfo, AgentPolicy, PackagePolicy } from '../types'; // Assume packages only ever include 1 config template for now export const isPackageLimited = (packageInfo: PackageInfo): boolean => { - return packageInfo.config_templates?.[0]?.multiple === false; + return packageInfo.policy_templates?.[0]?.multiple === false; }; export const doesAgentPolicyAlreadyIncludePackage = ( diff --git a/x-pack/plugins/ingest_manager/common/services/package_to_package_policy.test.ts b/x-pack/plugins/ingest_manager/common/services/package_to_package_policy.test.ts index 6c3559d7cc5a0..a62fcddd16e0f 100644 --- a/x-pack/plugins/ingest_manager/common/services/package_to_package_policy.test.ts +++ b/x-pack/plugins/ingest_manager/common/services/package_to_package_policy.test.ts @@ -34,14 +34,14 @@ describe('Ingest Manager - packageToPackagePolicy', () => { describe('packageToPackagePolicyInputs', () => { it('returns empty array for packages with no config templates', () => { expect(packageToPackagePolicyInputs(mockPackage)).toEqual([]); - expect(packageToPackagePolicyInputs({ ...mockPackage, config_templates: [] })).toEqual([]); + expect(packageToPackagePolicyInputs({ ...mockPackage, policy_templates: [] })).toEqual([]); }); it('returns empty array for packages with a config template but no inputs', () => { expect( packageToPackagePolicyInputs(({ ...mockPackage, - config_templates: [{ inputs: [] }], + policy_templates: [{ inputs: [] }], } as unknown) as PackageInfo) ).toEqual([]); }); @@ -50,13 +50,13 @@ describe('Ingest Manager - packageToPackagePolicy', () => { expect( packageToPackagePolicyInputs(({ ...mockPackage, - config_templates: [{ inputs: [{ type: 'foo' }] }], + policy_templates: [{ inputs: [{ type: 'foo' }] }], } as unknown) as PackageInfo) ).toEqual([{ type: 'foo', enabled: true, streams: [] }]); expect( packageToPackagePolicyInputs(({ ...mockPackage, - config_templates: [{ inputs: [{ type: 'foo' }, { type: 'bar' }] }], + policy_templates: [{ inputs: [{ type: 'foo' }, { type: 'bar' }] }], } as unknown) as PackageInfo) ).toEqual([ { type: 'foo', enabled: true, streams: [] }, @@ -68,12 +68,12 @@ describe('Ingest Manager - packageToPackagePolicy', () => { expect( packageToPackagePolicyInputs(({ ...mockPackage, - datasets: [ - { type: 'logs', name: 'foo', streams: [{ input: 'foo' }] }, - { type: 'logs', name: 'bar', streams: [{ input: 'bar' }] }, - { type: 'logs', name: 'bar2', streams: [{ input: 'bar' }] }, + data_streams: [ + { type: 'logs', dataset: 'foo', streams: [{ input: 'foo' }] }, + { type: 'logs', dataset: 'bar', streams: [{ input: 'bar' }] }, + { type: 'logs', dataset: 'bar2', streams: [{ input: 'bar' }] }, ], - config_templates: [ + policy_templates: [ { inputs: [{ type: 'foo' }, { type: 'bar' }], }, @@ -102,15 +102,15 @@ describe('Ingest Manager - packageToPackagePolicy', () => { expect( packageToPackagePolicyInputs(({ ...mockPackage, - datasets: [ + data_streams: [ { type: 'logs', - name: 'foo', + dataset: 'foo', streams: [{ input: 'foo', vars: [{ default: 'foo-var-value', name: 'var-name' }] }], }, { type: 'logs', - name: 'bar', + dataset: 'bar', streams: [ { input: 'bar', @@ -120,7 +120,7 @@ describe('Ingest Manager - packageToPackagePolicy', () => { }, { type: 'logs', - name: 'bar2', + dataset: 'bar2', streams: [ { input: 'bar', @@ -129,7 +129,7 @@ describe('Ingest Manager - packageToPackagePolicy', () => { ], }, ], - config_templates: [ + policy_templates: [ { inputs: [{ type: 'foo' }, { type: 'bar' }], }, @@ -173,15 +173,15 @@ describe('Ingest Manager - packageToPackagePolicy', () => { expect( packageToPackagePolicyInputs(({ ...mockPackage, - datasets: [ + data_streams: [ { type: 'logs', - name: 'foo', + dataset: 'foo', streams: [{ input: 'foo', vars: [{ default: 'foo-var-value', name: 'var-name' }] }], }, { type: 'logs', - name: 'bar', + dataset: 'bar', streams: [ { input: 'bar', @@ -191,7 +191,7 @@ describe('Ingest Manager - packageToPackagePolicy', () => { }, { type: 'logs', - name: 'bar2', + dataset: 'bar2', streams: [ { input: 'bar', @@ -201,7 +201,7 @@ describe('Ingest Manager - packageToPackagePolicy', () => { }, { type: 'logs', - name: 'disabled', + dataset: 'disabled', streams: [ { input: 'with-disabled-streams', @@ -212,7 +212,7 @@ describe('Ingest Manager - packageToPackagePolicy', () => { }, { type: 'logs', - name: 'disabled2', + dataset: 'disabled2', streams: [ { input: 'with-disabled-streams', @@ -221,7 +221,7 @@ describe('Ingest Manager - packageToPackagePolicy', () => { ], }, ], - config_templates: [ + policy_templates: [ { inputs: [ { @@ -372,13 +372,13 @@ describe('Ingest Manager - packageToPackagePolicy', () => { }); }); it('returns package policy with inputs', () => { - const mockPackageWithConfigTemplates = ({ + const mockPackageWithPolicyTemplates = ({ ...mockPackage, - config_templates: [{ inputs: [{ type: 'foo' }] }], + policy_templates: [{ inputs: [{ type: 'foo' }] }], } as unknown) as PackageInfo; expect( - packageToPackagePolicy(mockPackageWithConfigTemplates, '1', '2', 'default', 'pkgPolicy-1') + packageToPackagePolicy(mockPackageWithPolicyTemplates, '1', '2', 'default', 'pkgPolicy-1') ).toEqual({ policy_id: '1', namespace: 'default', diff --git a/x-pack/plugins/ingest_manager/common/services/package_to_package_policy.ts b/x-pack/plugins/ingest_manager/common/services/package_to_package_policy.ts index eab2e8ac2d745..822747916ebc5 100644 --- a/x-pack/plugins/ingest_manager/common/services/package_to_package_policy.ts +++ b/x-pack/plugins/ingest_manager/common/services/package_to_package_policy.ts @@ -5,7 +5,7 @@ */ import { PackageInfo, - RegistryConfigTemplate, + RegistryPolicyTemplate, RegistryVarsEntry, RegistryStream, PackagePolicy, @@ -22,14 +22,14 @@ const getStreamsForInputType = ( ): Array => { const streams: Array = []; - (packageInfo.datasets || []).forEach((dataset) => { - (dataset.streams || []).forEach((stream) => { + (packageInfo.data_streams || []).forEach((dataStream) => { + (dataStream.streams || []).forEach((stream) => { if (stream.input === inputType) { streams.push({ ...stream, data_stream: { - type: dataset.type, - dataset: dataset.name, + type: dataStream.type, + dataset: dataStream.dataset, }, }); } @@ -46,9 +46,9 @@ export const packageToPackagePolicyInputs = (packageInfo: PackageInfo): PackageP const inputs: PackagePolicy['inputs'] = []; // Assume package will only ever ship one package policy template for now - const packagePolicyTemplate: RegistryConfigTemplate | null = - packageInfo.config_templates && packageInfo.config_templates[0] - ? packageInfo.config_templates[0] + const packagePolicyTemplate: RegistryPolicyTemplate | null = + packageInfo.policy_templates && packageInfo.policy_templates[0] + ? packageInfo.policy_templates[0] : null; // Create package policy input property diff --git a/x-pack/plugins/ingest_manager/common/types/models/agent.ts b/x-pack/plugins/ingest_manager/common/types/models/agent.ts index 7110fd4ce52ea..6ac783820ce82 100644 --- a/x-pack/plugins/ingest_manager/common/types/models/agent.ts +++ b/x-pack/plugins/ingest_manager/common/types/models/agent.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 { FullAgentPolicy } from './agent_policy'; import { AGENT_TYPE_EPHEMERAL, AGENT_TYPE_PERMANENT, AGENT_TYPE_TEMPORARY } from '../../constants'; export type AgentType = @@ -22,7 +22,7 @@ export type AgentStatus = | 'upgrading' | 'degraded'; -export type AgentActionType = 'CONFIG_CHANGE' | 'UNENROLL' | 'UPGRADE'; +export type AgentActionType = 'POLICY_CHANGE' | 'UNENROLL' | 'UPGRADE'; export interface NewAgentAction { type: AgentActionType; data?: any; @@ -42,13 +42,24 @@ export interface AgentAction extends NewAgentAction { export interface AgentPolicyAction extends NewAgentAction { id: string; type: AgentActionType; - data?: any; + data: { + policy: FullAgentPolicy; + }; policy_id: string; policy_revision: number; created_at: string; ack_data?: any; } +// Make policy change action renaming BWC with agent version <= 7.9 +// eslint-disable-next-line @typescript-eslint/naming-convention +export type AgentPolicyActionV7_9 = Omit & { + type: 'CONFIG_CHANGE'; + data: { + config: FullAgentPolicy; + }; +}; + interface CommonAgentActionSOAttributes { type: AgentActionType; sent_at?: string; diff --git a/x-pack/plugins/ingest_manager/common/types/models/epm.ts b/x-pack/plugins/ingest_manager/common/types/models/epm.ts index 8bc5d9f7210b2..d2d1f22dda3a0 100644 --- a/x-pack/plugins/ingest_manager/common/types/models/epm.ts +++ b/x-pack/plugins/ingest_manager/common/types/models/epm.ts @@ -67,8 +67,8 @@ export interface RegistryPackage { assets?: string[]; internal?: boolean; format_version: string; - datasets?: Dataset[]; - config_templates?: RegistryConfigTemplate[]; + data_streams?: RegistryDataStream[]; + policy_templates?: RegistryPolicyTemplate[]; download: string; path: string; } @@ -80,7 +80,7 @@ interface RegistryImage { size?: string; type?: string; } -export interface RegistryConfigTemplate { +export interface RegistryPolicyTemplate { name: string; title: string; description: string; @@ -127,8 +127,8 @@ export type RegistrySearchResult = Pick< | 'internal' | 'download' | 'path' - | 'datasets' - | 'config_templates' + | 'data_streams' + | 'policy_templates' >; export type ScreenshotItem = RegistryImage; @@ -174,9 +174,9 @@ export type ElasticsearchAssetTypeToParts = Record< ElasticsearchAssetParts[] >; -export interface Dataset { +export interface RegistryDataStream { type: string; - name: string; + dataset: string; title: string; release: string; streams?: RegistryStream[]; diff --git a/x-pack/plugins/ingest_manager/common/types/rest_spec/epm.ts b/x-pack/plugins/ingest_manager/common/types/rest_spec/epm.ts index 7ed2fed91aa93..0709eddaa52ec 100644 --- a/x-pack/plugins/ingest_manager/common/types/rest_spec/epm.ts +++ b/x-pack/plugins/ingest_manager/common/types/rest_spec/epm.ts @@ -71,7 +71,7 @@ export interface InstallPackageResponse { response: AssetReference[]; } -export interface IBulkInstallPackageError { +export interface IBulkInstallPackageHTTPError { name: string; statusCode: number; error: string | Error; @@ -86,7 +86,7 @@ export interface BulkInstallPackageInfo { } export interface BulkInstallPackagesResponse { - response: Array; + response: Array; } export interface BulkInstallPackagesRequest { diff --git a/x-pack/plugins/ingest_manager/dev_docs/epm.md b/x-pack/plugins/ingest_manager/dev_docs/epm.md index 20209d09e6cc2..a066b6deb3bc8 100644 --- a/x-pack/plugins/ingest_manager/dev_docs/epm.md +++ b/x-pack/plugins/ingest_manager/dev_docs/epm.md @@ -26,5 +26,5 @@ When a package is installed or upgraded, certain Kibana and Elasticsearch assets ### Generation - Index templates are generated from `YAML` files contained in the package. -- There is one index template per dataset. -- For the generation of an index template, all `yml` files contained in the package subdirectory `dataset/DATASET_NAME/fields/` are used. +- There is one index template per data stream. +- For the generation of an index template, all `yml` files contained in the package subdirectory `data_stream/DATASET_NAME/fields/` are used. diff --git a/x-pack/plugins/ingest_manager/dev_docs/indexing_strategy.md b/x-pack/plugins/ingest_manager/dev_docs/indexing_strategy.md index fd7edcb7fcca0..42a0bbc218869 100644 --- a/x-pack/plugins/ingest_manager/dev_docs/indexing_strategy.md +++ b/x-pack/plugins/ingest_manager/dev_docs/indexing_strategy.md @@ -6,48 +6,48 @@ Overall documentation of Ingest Management is now maintained in the `elastic/sta Ingest Management enforces an indexing strategy to allow the system to automatically detect indices and run queries on it. In short the indexing strategy looks as following: ``` -{dataset.type}-{dataset.name}-{dataset.namespace} +{data_stream.type}-{data_stream.dataset}-{data_stream.namespace} ``` -The `{dataset.type}` can be `logs` or `metrics`. The `{dataset.namespace}` is the part where the user can use free form. The only two requirement are that it has only characters allowed in an Elasticsearch index name and does NOT contain a `-`. The `dataset` is defined by the data that is indexed. The same requirements as for the namespace apply. It is expected that the fields for type, namespace and dataset are part of each event and are constant keywords. If there is a dataset or a namespace with a `-` inside, it is recommended to replace it either by a `.` or a `_`. +The `{data_stream.type}` can be `logs` or `metrics`. The `{data_stream.namespace}` is the part where the user can use free form. The only two requirement are that it has only characters allowed in an Elasticsearch index name and does NOT contain a `-`. The `data_stream` is defined by the data that is indexed. The same requirements as for the namespace apply. It is expected that the fields for type, dataset, and namespace are part of each event and are constant keywords. If there is a dataset or a namespace with a `-` inside, it is recommended to replace it either by a `.` or a `_`. -Note: More `{dataset.type}`s might be added in the future like `traces`. +Note: More `{data_stream.type}`s might be added in the future like `traces`. This indexing strategy has a few advantages: -* Each index contains only the fields which are relevant for the dataset. This leads to more dense indices and better field completion. -* ILM policies can be applied per namespace per dataset. -* Rollups can be specified per namespace per dataset. -* Having the namespace user configurable makes setting security permissions possible. -* Having a global metrics and logs template, allows to create new indices on demand which still follow the convention. This is common in the case of k8s as an example. -* Constant keywords allow to narrow down the indices we need to access for querying very efficiently. This is especially relevant in environments which a large number of indices or with indices on slower nodes. +- Each index contains only the fields which are relevant for the datta stream. This leads to more dense indices and better field completion. +- ILM policies can be applied per namespace per data stream. +- Rollups can be specified per namespace per data stream. +- Having the namespace user configurable makes setting security permissions possible. +- Having a global metrics and logs template, allows to create new indices on demand which still follow the convention. This is common in the case of k8s as an example. +- Constant keywords allow to narrow down the indices we need to access for querying very efficiently. This is especially relevant in environments which a large number of indices or with indices on slower nodes. Overall it creates smaller indices in size, makes querying more efficient and allows users to define their own naming parts in namespace and still benefiting from all features that can be built on top of the indexing startegy. ## Ingest Pipeline -The ingest pipelines for a specific dataset will have the following naming scheme: +The ingest pipelines for a specific data stream will have the following naming scheme: ``` -{dataset.type}-{dataset.name}-{package.version} +{data_stream.type}-{data_stream.dataset}-{package.version} ``` -As an example, the ingest pipeline for the Nginx access logs is called `logs-nginx.access-3.4.1`. The same ingest pipeline is used for all namespaces. It is possible that a dataset has multiple ingest pipelines in which case a suffix is added to the name. +As an example, the ingest pipeline for the Nginx access logs is called `logs-nginx.access-3.4.1`. The same ingest pipeline is used for all namespaces. It is possible that a data stream has multiple ingest pipelines in which case a suffix is added to the name. The version is included in each pipeline to allow upgrades. The pipeline itself is listed in the index template and is automatically applied at ingest time. ## Templates & ILM Policies -To make the above strategy possible, alias templates are required. For each type there is a basic alias template with a default ILM policy. These default templates apply to all indices which follow the indexing strategy and do not have a more specific dataset alias template. +To make the above strategy possible, alias templates are required. For each type there is a basic alias template with a default ILM policy. These default templates apply to all indices which follow the indexing strategy and do not have a more specific data stream alias template. The `metrics` and `logs` alias template contain all the basic fields from ECS. Each type template contains an ILM policy. Modifying this default ILM policy will affect all data covered by the default templates. -The templates for a dataset are called as following: +The templates for a data stream are called as following: ``` -{dataset.type}-{dataset.name} +{data_stream.type}-{data_stream.dataset} ``` The pattern used inside the index template is `{type}-{dataset}-*` to match all namespaces. diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/constants/index.ts b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/constants/index.ts index 185e1fa5eb0ce..b97d39bac920b 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/constants/index.ts +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/constants/index.ts @@ -7,6 +7,7 @@ export { PLUGIN_ID, EPM_API_ROUTES, AGENT_API_ROUTES, + SO_SEARCH_LIMIT, AGENT_POLICY_SAVED_OBJECT_TYPE, AGENT_EVENT_SAVED_OBJECT_TYPE, AGENT_SAVED_OBJECT_TYPE, diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/hooks/use_breadcrumbs.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/hooks/use_breadcrumbs.tsx index 1d80495d2b347..b263f46b90a25 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/hooks/use_breadcrumbs.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/hooks/use_breadcrumbs.tsx @@ -11,7 +11,7 @@ import { useCore } from './use_core'; const BASE_BREADCRUMB: ChromeBreadcrumb = { href: pagePathGetters.overview(), text: i18n.translate('xpack.ingestManager.breadcrumbs.appTitle', { - defaultMessage: 'Ingest Manager', + defaultMessage: 'Fleet', }), }; @@ -155,21 +155,15 @@ const breadcrumbGetters: { fleet: () => [ BASE_BREADCRUMB, { - text: i18n.translate('xpack.ingestManager.breadcrumbs.fleetPageTitle', { - defaultMessage: 'Fleet', + text: i18n.translate('xpack.ingestManager.breadcrumbs.agentsPageTitle', { + defaultMessage: 'Agents', }), }, ], fleet_agent_list: () => [ BASE_BREADCRUMB, { - href: pagePathGetters.fleet(), - text: i18n.translate('xpack.ingestManager.breadcrumbs.fleetPageTitle', { - defaultMessage: 'Fleet', - }), - }, - { - text: i18n.translate('xpack.ingestManager.breadcrumbs.fleetAgentsPageTitle', { + text: i18n.translate('xpack.ingestManager.breadcrumbs.agentsPageTitle', { defaultMessage: 'Agents', }), }, @@ -178,12 +172,7 @@ const breadcrumbGetters: { BASE_BREADCRUMB, { href: pagePathGetters.fleet(), - text: i18n.translate('xpack.ingestManager.breadcrumbs.fleetPageTitle', { - defaultMessage: 'Fleet', - }), - }, - { - text: i18n.translate('xpack.ingestManager.breadcrumbs.fleetAgentsPageTitle', { + text: i18n.translate('xpack.ingestManager.breadcrumbs.agentsPageTitle', { defaultMessage: 'Agents', }), }, @@ -193,12 +182,12 @@ const breadcrumbGetters: { BASE_BREADCRUMB, { href: pagePathGetters.fleet(), - text: i18n.translate('xpack.ingestManager.breadcrumbs.fleetPageTitle', { - defaultMessage: 'Fleet', + text: i18n.translate('xpack.ingestManager.breadcrumbs.agentsPageTitle', { + defaultMessage: 'Agents', }), }, { - text: i18n.translate('xpack.ingestManager.breadcrumbs.fleetEnrollmentTokensPageTitle', { + text: i18n.translate('xpack.ingestManager.breadcrumbs.enrollmentTokensPageTitle', { defaultMessage: 'Enrollment tokens', }), }, diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/default.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/default.tsx index 7da8330740532..5de47ee4f410b 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/default.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/layouts/default.tsx @@ -83,8 +83,8 @@ export const DefaultLayout: React.FunctionComponent = ({ disabled={!fleet?.enabled} > diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/components/agent_policy_form.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/components/agent_policy_form.tsx index b216270aa08f0..c716f7b12e78c 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/components/agent_policy_form.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/components/agent_policy_form.tsx @@ -28,7 +28,7 @@ import { isValidNamespace } from '../../../services'; import { AgentPolicyDeleteProvider } from './agent_policy_delete_provider'; interface ValidationResults { - [key: string]: JSX.Element[]; + [key: string]: Array; } const StyledEuiAccordion = styled(EuiAccordion)` @@ -41,6 +41,7 @@ export const agentPolicyFormValidation = ( agentPolicy: Partial ): ValidationResults => { const errors: ValidationResults = {}; + const namespaceValidation = isValidNamespace(agentPolicy.namespace || ''); if (!agentPolicy.name?.trim()) { errors.name = [ @@ -51,20 +52,8 @@ export const agentPolicyFormValidation = ( ]; } - if (!agentPolicy.namespace?.trim()) { - errors.namespace = [ - , - ]; - } else if (!isValidNamespace(agentPolicy.namespace)) { - errors.namespace = [ - , - ]; + if (!namespaceValidation.valid && namespaceValidation.error) { + errors.namespace = [namespaceValidation.error]; } return errors; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/create_package_policy_page/services/validate_package_policy.test..ts b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/create_package_policy_page/services/validate_package_policy.test..ts index aae750cb67499..d621db615f2bd 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/create_package_policy_page/services/validate_package_policy.test..ts +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/create_package_policy_page/services/validate_package_policy.test..ts @@ -7,7 +7,7 @@ import { PackageInfo, InstallationStatus, NewPackagePolicy, - RegistryConfigTemplate, + RegistryPolicyTemplate, } from '../../../../types'; import { validatePackagePolicy, validationHasErrors } from './validate_package_policy'; @@ -32,9 +32,9 @@ describe('Ingest Manager - validatePackagePolicy()', () => { }, }, status: InstallationStatus.notInstalled, - datasets: [ + data_streams: [ { - name: 'foo', + dataset: 'foo', streams: [ { input: 'foo', @@ -44,7 +44,7 @@ describe('Ingest Manager - validatePackagePolicy()', () => { ], }, { - name: 'bar', + dataset: 'bar', streams: [ { input: 'bar', @@ -59,7 +59,7 @@ describe('Ingest Manager - validatePackagePolicy()', () => { ], }, { - name: 'bar2', + dataset: 'bar2', streams: [ { input: 'bar', @@ -69,7 +69,7 @@ describe('Ingest Manager - validatePackagePolicy()', () => { ], }, { - name: 'disabled', + dataset: 'disabled', streams: [ { input: 'with-disabled-streams', @@ -80,7 +80,7 @@ describe('Ingest Manager - validatePackagePolicy()', () => { ], }, { - name: 'disabled2', + dataset: 'disabled2', streams: [ { input: 'with-disabled-streams', @@ -90,7 +90,7 @@ describe('Ingest Manager - validatePackagePolicy()', () => { ], }, ], - config_templates: [ + policy_templates: [ { name: 'pkgPolicy1', title: 'Package policy 1', @@ -465,7 +465,7 @@ describe('Ingest Manager - validatePackagePolicy()', () => { expect( validatePackagePolicy(validPackagePolicy, { ...mockPackage, - config_templates: undefined, + policy_templates: undefined, }) ).toEqual({ name: null, @@ -476,7 +476,7 @@ describe('Ingest Manager - validatePackagePolicy()', () => { expect( validatePackagePolicy(validPackagePolicy, { ...mockPackage, - config_templates: [], + policy_templates: [], }) ).toEqual({ name: null, @@ -490,7 +490,7 @@ describe('Ingest Manager - validatePackagePolicy()', () => { expect( validatePackagePolicy(validPackagePolicy, { ...mockPackage, - config_templates: [{} as RegistryConfigTemplate], + policy_templates: [{} as RegistryPolicyTemplate], }) ).toEqual({ name: null, @@ -501,7 +501,7 @@ describe('Ingest Manager - validatePackagePolicy()', () => { expect( validatePackagePolicy(validPackagePolicy, { ...mockPackage, - config_templates: [({ inputs: [] } as unknown) as RegistryConfigTemplate], + policy_templates: [({ inputs: [] } as unknown) as RegistryPolicyTemplate], }) ).toEqual({ name: null, diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/create_package_policy_page/services/validate_package_policy.ts b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/create_package_policy_page/services/validate_package_policy.ts index 2714f1fe2e6e5..04cd21884e8f2 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/create_package_policy_page/services/validate_package_policy.ts +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/create_package_policy_page/services/validate_package_policy.ts @@ -50,6 +50,7 @@ export const validatePackagePolicy = ( namespace: null, inputs: {}, }; + const namespaceValidation = isValidNamespace(packagePolicy.namespace); if (!packagePolicy.name.trim()) { validationResults.name = [ @@ -59,26 +60,16 @@ export const validatePackagePolicy = ( ]; } - if (!packagePolicy.namespace.trim()) { - validationResults.namespace = [ - i18n.translate('xpack.ingestManager.packagePolicyValidation.namespaceRequiredErrorMessage', { - defaultMessage: 'Namespace is required', - }), - ]; - } else if (!isValidNamespace(packagePolicy.namespace)) { - validationResults.namespace = [ - i18n.translate('xpack.ingestManager.packagePolicyValidation.namespaceInvalidErrorMessage', { - defaultMessage: 'Namespace contains invalid characters', - }), - ]; + if (!namespaceValidation.valid && namespaceValidation.error) { + validationResults.namespace = [namespaceValidation.error]; } if ( - !packageInfo.config_templates || - packageInfo.config_templates.length === 0 || - !packageInfo.config_templates[0] || - !packageInfo.config_templates[0].inputs || - packageInfo.config_templates[0].inputs.length === 0 + !packageInfo.policy_templates || + packageInfo.policy_templates.length === 0 || + !packageInfo.policy_templates[0] || + !packageInfo.policy_templates[0].inputs || + packageInfo.policy_templates[0].inputs.length === 0 ) { validationResults.inputs = null; return validationResults; @@ -87,16 +78,16 @@ export const validatePackagePolicy = ( const registryInputsByType: Record< string, RegistryInput - > = packageInfo.config_templates[0].inputs.reduce((inputs, registryInput) => { + > = packageInfo.policy_templates[0].inputs.reduce((inputs, registryInput) => { inputs[registryInput.type] = registryInput; return inputs; }, {} as Record); const registryStreamsByDataset: Record = ( - packageInfo.datasets || [] - ).reduce((datasets, registryDataset) => { - datasets[registryDataset.name] = registryDataset.streams || []; - return datasets; + packageInfo.data_streams || [] + ).reduce((dataStreams, registryDataStream) => { + dataStreams[registryDataStream.dataset] = registryDataStream.streams || []; + return dataStreams; }, {} as Record); // Validate each package policy input with either its own config fields or streams diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/create_package_policy_page/step_configure_package.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/create_package_policy_page/step_configure_package.tsx index b77153daee2fc..d3d5e60c34e58 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/create_package_policy_page/step_configure_package.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_policy/create_package_policy_page/step_configure_package.tsx @@ -17,13 +17,13 @@ const findStreamsForInputType = ( ): Array => { const streams: Array = []; - (packageInfo.datasets || []).forEach((dataset) => { - (dataset.streams || []).forEach((stream) => { + (packageInfo.data_streams || []).forEach((dataStream) => { + (dataStream.streams || []).forEach((stream) => { if (stream.input === inputType) { streams.push({ ...stream, data_stream: { - dataset: dataset.name, + dataset: dataStream.dataset, }, }); } @@ -53,14 +53,14 @@ export const StepConfigurePackagePolicy: React.FunctionComponent<{ // Configure inputs (and their streams) // Assume packages only export one config template for now const renderConfigureInputs = () => - packageInfo.config_templates && - packageInfo.config_templates[0] && - packageInfo.config_templates[0].inputs && - packageInfo.config_templates[0].inputs.length ? ( + packageInfo.policy_templates && + packageInfo.policy_templates[0] && + packageInfo.policy_templates[0].inputs && + packageInfo.policy_templates[0].inputs.length ? ( <> - {packageInfo.config_templates[0].inputs.map((packageInput) => { + {packageInfo.policy_templates[0].inputs.map((packageInput) => { const packagePolicyInput = packagePolicy.inputs.find( (input) => input.type === packageInput.type ); diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_list_page/components/bulk_actions.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_list_page/components/bulk_actions.tsx index 25684c9faf594..ee453b9e786f1 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_list_page/components/bulk_actions.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/agent_list_page/components/bulk_actions.tsx @@ -15,7 +15,8 @@ import { EuiIcon, EuiPortal, } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n/react'; +import { FormattedMessage, FormattedNumber } from '@kbn/i18n/react'; +import { SO_SEARCH_LIMIT } from '../../../../constants'; import { Agent } from '../../../../types'; import { AgentReassignAgentPolicyFlyout, AgentUnenrollAgentModal } from '../../components'; @@ -153,11 +154,22 @@ export const AgentBulkActions: React.FunctionComponent<{ - + {totalAgents > SO_SEARCH_LIMIT ? ( + , + total: , + }} + /> + ) : ( + + )} {(selectionMode === 'manual' && selectedAgents.length) || @@ -184,7 +196,7 @@ export const AgentBulkActions: React.FunctionComponent<{ count: selectionMode === 'manual' ? selectedAgents.length - : totalAgents - totalInactiveAgents, + : Math.min(totalAgents - totalInactiveAgents, SO_SEARCH_LIMIT), }} /> diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/agent_policy_selection.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/agent_policy_selection.tsx index 7f23c645f9a2e..874d42a8db095 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/agent_policy_selection.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/agent_policy_selection.tsx @@ -8,6 +8,7 @@ import React, { useState, useEffect } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiSelect, EuiSpacer, EuiText, EuiButtonEmpty } from '@elastic/eui'; +import { SO_SEARCH_LIMIT } from '../../../../constants'; import { AgentPolicy, GetEnrollmentAPIKeysResponse } from '../../../../types'; import { sendGetEnrollmentAPIKeys, useCore } from '../../../../hooks'; import { AgentPolicyPackageBadges } from '../agent_policy_package_badges'; @@ -98,7 +99,7 @@ export const EnrollmentStepAgentPolicy: React.FC = (props) => { try { const res = await sendGetEnrollmentAPIKeys({ page: 1, - perPage: 10000, + perPage: SO_SEARCH_LIMIT, }); if (res.error) { throw res.error; diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/managed_instructions.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/managed_instructions.tsx index 04fef7f4b3f21..e620424f88f4e 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/managed_instructions.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/agent_enrollment_flyout/managed_instructions.tsx @@ -74,14 +74,14 @@ export const ManagedInstructions = React.memo(({ agentPolicies }) => { ) : ( <> ), diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/list_layout.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/list_layout.tsx index b01dbbd57c16f..278beb5dfe35f 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/list_layout.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/components/list_layout.tsx @@ -126,7 +126,7 @@ export const ListLayout: React.FunctionComponent<{}> = ({ children }) => {

- +

@@ -134,7 +134,7 @@ export const ListLayout: React.FunctionComponent<{}> = ({ children }) => {

diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/setup_page/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/setup_page/index.tsx index fbd74f8b03e72..7f0a23caa5fa2 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/setup_page/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/setup_page/index.tsx @@ -73,7 +73,7 @@ export const SetupPage: React.FunctionComponent<{ ) { return ( - + @@ -95,15 +95,15 @@ export const SetupPage: React.FunctionComponent<{ @@ -127,7 +127,7 @@ export const SetupPage: React.FunctionComponent<{ >
diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/overview/components/agent_policy_section.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/overview/components/agent_policy_section.tsx index 617be92b3b1fe..e54eff1cbd4a5 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/overview/components/agent_policy_section.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/overview/components/agent_policy_section.tsx @@ -15,6 +15,7 @@ import { } from '@elastic/eui'; import { OverviewPanel } from './overview_panel'; import { OverviewStats } from './overview_stats'; +import { SO_SEARCH_LIMIT } from '../../../constants'; import { useLink, useGetPackagePolicies } from '../../../hooks'; import { AgentPolicy } from '../../../types'; import { Loading } from '../../fleet/components'; @@ -25,7 +26,7 @@ export const OverviewPolicySection: React.FC<{ agentPolicies: AgentPolicy[] }> = const { getHref } = useLink(); const packagePoliciesRequest = useGetPackagePolicies({ page: 1, - perPage: 10000, + perPage: SO_SEARCH_LIMIT, }); return ( diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/overview/components/agent_section.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/overview/components/agent_section.tsx index d7b08bf5ffa3a..482105cdea300 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/overview/components/agent_section.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/overview/components/agent_section.tsx @@ -25,8 +25,8 @@ export const OverviewAgentSection = () => { return ( {

diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/types/index.ts b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/types/index.ts index 71a44089b8bf7..e825448f359d6 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/types/index.ts +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/types/index.ts @@ -89,7 +89,7 @@ export { RegistryVarsEntry, RegistryInput, RegistryStream, - RegistryConfigTemplate, + RegistryPolicyTemplate, PackageList, PackageListItem, PackagesGroupedByStatus, diff --git a/x-pack/plugins/ingest_manager/public/plugin.ts b/x-pack/plugins/ingest_manager/public/plugin.ts index 5f7bfe865e892..59741ce79dd8b 100644 --- a/x-pack/plugins/ingest_manager/public/plugin.ts +++ b/x-pack/plugins/ingest_manager/public/plugin.ts @@ -78,7 +78,7 @@ export class IngestManagerPlugin core.application.register({ id: PLUGIN_ID, category: DEFAULT_APP_CATEGORIES.management, - title: i18n.translate('xpack.ingestManager.appTitle', { defaultMessage: 'Ingest Manager' }), + title: i18n.translate('xpack.ingestManager.appTitle', { defaultMessage: 'Fleet' }), order: 9020, euiIconType: 'logoElastic', async mount(params: AppMountParameters) { diff --git a/x-pack/plugins/ingest_manager/server/constants/index.ts b/x-pack/plugins/ingest_manager/server/constants/index.ts index d677b79bb46f8..c69ee7e4b6092 100644 --- a/x-pack/plugins/ingest_manager/server/constants/index.ts +++ b/x-pack/plugins/ingest_manager/server/constants/index.ts @@ -8,6 +8,7 @@ export { AGENT_TYPE_EPHEMERAL, AGENT_TYPE_TEMPORARY, AGENT_POLLING_THRESHOLD_MS, + AGENT_POLLING_REQUEST_TIMEOUT_MARGIN_MS, AGENT_POLLING_INTERVAL, AGENT_UPDATE_LAST_CHECKIN_INTERVAL_MS, AGENT_POLICY_ROLLOUT_RATE_LIMIT_REQUEST_PER_INTERVAL, @@ -31,6 +32,7 @@ export { SETTINGS_API_ROUTES, APP_API_ROUTES, // Saved object types + SO_SEARCH_LIMIT, AGENT_SAVED_OBJECT_TYPE, AGENT_EVENT_SAVED_OBJECT_TYPE, AGENT_ACTION_SAVED_OBJECT_TYPE, diff --git a/x-pack/plugins/ingest_manager/server/plugin.ts b/x-pack/plugins/ingest_manager/server/plugin.ts index f0f7bca29c99e..6237b6d9ba357 100644 --- a/x-pack/plugins/ingest_manager/server/plugin.ts +++ b/x-pack/plugins/ingest_manager/server/plugin.ts @@ -172,7 +172,7 @@ export class IngestManagerPlugin this.encryptedSavedObjectsSetup = deps.encryptedSavedObjects; this.cloud = deps.cloud; - registerSavedObjects(core.savedObjects); + registerSavedObjects(core.savedObjects, deps.encryptedSavedObjects); registerEncryptedSavedObjects(deps.encryptedSavedObjects); // Register feature diff --git a/x-pack/plugins/ingest_manager/server/routes/agent/acks_handlers.test.ts b/x-pack/plugins/ingest_manager/server/routes/agent/acks_handlers.test.ts index 33b9dc617075b..3d7f5c4a17adb 100644 --- a/x-pack/plugins/ingest_manager/server/routes/agent/acks_handlers.test.ts +++ b/x-pack/plugins/ingest_manager/server/routes/agent/acks_handlers.test.ts @@ -73,7 +73,7 @@ describe('test acks handlers', () => { const ackService: AcksService = { acknowledgeAgentActions: jest.fn().mockReturnValueOnce([ { - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', id: 'action1', }, ]), diff --git a/x-pack/plugins/ingest_manager/server/routes/agent/actions_handlers.test.ts b/x-pack/plugins/ingest_manager/server/routes/agent/actions_handlers.test.ts index 5445a46fbe2b4..4574bcc64d4ce 100644 --- a/x-pack/plugins/ingest_manager/server/routes/agent/actions_handlers.test.ts +++ b/x-pack/plugins/ingest_manager/server/routes/agent/actions_handlers.test.ts @@ -23,7 +23,7 @@ describe('test actions handlers schema', () => { it('validate that new agent actions schema is valid', async () => { expect( NewAgentActionSchema.validate({ - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', data: 'data', sent_at: '2020-03-14T19:45:02.620Z', }) @@ -53,7 +53,7 @@ describe('test actions handlers', () => { const postNewAgentActionRequest: PostNewAgentActionRequest = { body: { action: { - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', data: 'data', sent_at: '2020-03-14T19:45:02.620Z', }, @@ -66,7 +66,7 @@ describe('test actions handlers', () => { const mockRequest = httpServerMock.createKibanaRequest(postNewAgentActionRequest); const agentAction = ({ - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', id: 'action1', sent_at: '2020-03-14T19:45:02.620Z', timestamp: '2019-01-04T14:32:03.36764-05:00', diff --git a/x-pack/plugins/ingest_manager/server/routes/epm/handlers.ts b/x-pack/plugins/ingest_manager/server/routes/epm/handlers.ts index 7ae896c1f30a6..c55979d187f9d 100644 --- a/x-pack/plugins/ingest_manager/server/routes/epm/handlers.ts +++ b/x-pack/plugins/ingest_manager/server/routes/epm/handlers.ts @@ -13,7 +13,9 @@ import { GetCategoriesResponse, GetPackagesResponse, GetLimitedPackagesResponse, + BulkInstallPackageInfo, BulkInstallPackagesResponse, + IBulkInstallPackageHTTPError, } from '../../../common'; import { GetCategoriesRequestSchema, @@ -26,21 +28,21 @@ import { BulkUpgradePackagesFromRegistryRequestSchema, } from '../../types'; import { + BulkInstallResponse, + bulkInstallPackages, getCategories, getPackages, getFile, getPackageInfo, + handleInstallPackageFailure, installPackage, + isBulkInstallError, removeInstallation, getLimitedPackages, getInstallationObject, } from '../../services/epm/packages'; -import { defaultIngestErrorHandler } from '../../errors'; +import { defaultIngestErrorHandler, ingestErrorToResponseOptions } from '../../errors'; import { splitPkgKey } from '../../services/epm/registry'; -import { - handleInstallPackageFailure, - bulkInstallPackages, -} from '../../services/epm/packages/install'; export const getCategoriesHandler: RequestHandler< undefined, @@ -171,6 +173,21 @@ export const installPackageFromRegistryHandler: RequestHandler< } }; +const bulkInstallServiceResponseToHttpEntry = ( + result: BulkInstallResponse +): BulkInstallPackageInfo | IBulkInstallPackageHTTPError => { + if (isBulkInstallError(result)) { + const { statusCode, body } = ingestErrorToResponseOptions(result.error); + return { + name: result.name, + statusCode, + error: body.message, + }; + } else { + return result; + } +}; + export const bulkInstallPackagesFromRegistryHandler: RequestHandler< undefined, undefined, @@ -178,13 +195,14 @@ export const bulkInstallPackagesFromRegistryHandler: RequestHandler< > = async (context, request, response) => { const savedObjectsClient = context.core.savedObjects.client; const callCluster = context.core.elasticsearch.legacy.client.callAsCurrentUser; - const res = await bulkInstallPackages({ + const bulkInstalledResponses = await bulkInstallPackages({ savedObjectsClient, callCluster, packagesToUpgrade: request.body.packages, }); + const payload = bulkInstalledResponses.map(bulkInstallServiceResponseToHttpEntry); const body: BulkInstallPackagesResponse = { - response: res, + response: payload, }; return response.ok({ body }); }; diff --git a/x-pack/plugins/ingest_manager/server/saved_objects/index.ts b/x-pack/plugins/ingest_manager/server/saved_objects/index.ts index fd08b76a3916b..95433f896b9a3 100644 --- a/x-pack/plugins/ingest_manager/server/saved_objects/index.ts +++ b/x-pack/plugins/ingest_manager/server/saved_objects/index.ts @@ -24,6 +24,7 @@ import { migrateEnrollmentApiKeysToV7100, migratePackagePolicyToV7100, migrateSettingsToV7100, + migrateAgentActionToV7100, } from './migrations/to_v7_10_0'; /* @@ -32,7 +33,9 @@ import { * Please update typings in `/common/types` as well as * schemas in `/server/types` if mappings are updated. */ -const savedObjectTypes: { [key: string]: SavedObjectsType } = { +const getSavedObjectTypes = ( + encryptedSavedObjects: EncryptedSavedObjectsPluginSetup +): { [key: string]: SavedObjectsType } => ({ [GLOBAL_SETTINGS_SAVED_OBJECT_TYPE]: { name: GLOBAL_SETTINGS_SAVED_OBJECT_TYPE, hidden: false, @@ -109,6 +112,9 @@ const savedObjectTypes: { [key: string]: SavedObjectsType } = { created_at: { type: 'date' }, }, }, + migrations: { + '7.10.0': migrateAgentActionToV7100(encryptedSavedObjects), + }, }, [AGENT_EVENT_SAVED_OBJECT_TYPE]: { name: AGENT_EVENT_SAVED_OBJECT_TYPE, @@ -300,9 +306,13 @@ const savedObjectTypes: { [key: string]: SavedObjectsType } = { }, }, }, -}; +}); -export function registerSavedObjects(savedObjects: SavedObjectsServiceSetup) { +export function registerSavedObjects( + savedObjects: SavedObjectsServiceSetup, + encryptedSavedObjects: EncryptedSavedObjectsPluginSetup +) { + const savedObjectTypes = getSavedObjectTypes(encryptedSavedObjects); Object.values(savedObjectTypes).forEach((type) => { savedObjects.registerType(type); }); diff --git a/x-pack/plugins/ingest_manager/server/saved_objects/migrations/to_v7_10_0.ts b/x-pack/plugins/ingest_manager/server/saved_objects/migrations/to_v7_10_0.ts index 5e36ce46c099b..2a49c135074e5 100644 --- a/x-pack/plugins/ingest_manager/server/saved_objects/migrations/to_v7_10_0.ts +++ b/x-pack/plugins/ingest_manager/server/saved_objects/migrations/to_v7_10_0.ts @@ -4,7 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { SavedObjectMigrationFn } from 'kibana/server'; +import { SavedObjectMigrationFn, SavedObjectUnsanitizedDoc } from 'kibana/server'; +import { EncryptedSavedObjectsPluginSetup } from '../../../../encrypted_saved_objects/server'; import { Agent, AgentEvent, @@ -12,6 +13,7 @@ import { PackagePolicy, EnrollmentAPIKey, Settings, + AgentAction, } from '../../types'; export const migrateAgentToV7100: SavedObjectMigrationFn< @@ -92,3 +94,43 @@ export const migrateSettingsToV7100: SavedObjectMigrationFn< return settingsDoc; }; + +export const migrateAgentActionToV7100 = ( + encryptedSavedObjects: EncryptedSavedObjectsPluginSetup +): SavedObjectMigrationFn => { + return encryptedSavedObjects.createMigration( + (agentActionDoc): agentActionDoc is SavedObjectUnsanitizedDoc => { + // @ts-expect-error + return agentActionDoc.attributes.type === 'CONFIG_CHANGE'; + }, + (agentActionDoc) => { + let agentActionData; + try { + agentActionData = agentActionDoc.attributes.data + ? JSON.parse(agentActionDoc.attributes.data) + : undefined; + } catch (e) { + // Silently swallow JSON parsing error + } + if (agentActionData && agentActionData.config) { + const { + attributes: { data, ...restOfAttributes }, + } = agentActionDoc; + const { config, ...restOfData } = agentActionData; + return { + ...agentActionDoc, + attributes: { + ...restOfAttributes, + type: 'POLICY_CHANGE', + data: JSON.stringify({ + ...restOfData, + policy: config, + }), + }, + }; + } else { + return agentActionDoc; + } + } + ); +}; diff --git a/x-pack/plugins/ingest_manager/server/services/agent_policy.ts b/x-pack/plugins/ingest_manager/server/services/agent_policy.ts index 64b11512fae10..12ea8ab92f6c4 100644 --- a/x-pack/plugins/ingest_manager/server/services/agent_policy.ts +++ b/x-pack/plugins/ingest_manager/server/services/agent_policy.ts @@ -33,7 +33,7 @@ const SAVED_OBJECT_TYPE = AGENT_POLICY_SAVED_OBJECT_TYPE; class AgentPolicyService { private triggerAgentPolicyUpdatedEvent = async ( soClient: SavedObjectsClientContract, - action: string, + action: 'created' | 'updated' | 'deleted', agentPolicyId: string ) => { return agentPolicyUpdateEventHandler(soClient, action, agentPolicyId); @@ -258,7 +258,11 @@ class AgentPolicyService { id: string, options?: { user?: AuthenticatedUser } ): Promise { - return this._update(soClient, id, {}, options?.user); + const res = await this._update(soClient, id, {}, options?.user); + + await this.triggerAgentPolicyUpdatedEvent(soClient, 'updated', id); + + return res; } public async bumpAllAgentPolicies( soClient: SavedObjectsClientContract, @@ -277,7 +281,15 @@ class AgentPolicyService { }; return policy; }); - return soClient.bulkUpdate(bumpedPolicies); + const res = await soClient.bulkUpdate(bumpedPolicies); + + await Promise.all( + currentPolicies.saved_objects.map((policy) => + this.triggerAgentPolicyUpdatedEvent(soClient, 'updated', policy.id) + ) + ); + + return res; } public async assignPackagePolicies( @@ -399,8 +411,8 @@ class AgentPolicyService { }, []); await createAgentPolicyAction(soClient, { - type: 'CONFIG_CHANGE', - data: { config: policy } as any, + type: 'POLICY_CHANGE', + data: { policy }, ack_data: { packages }, created_at: new Date().toISOString(), policy_id: policy.id, diff --git a/x-pack/plugins/ingest_manager/server/services/agent_policy_update.ts b/x-pack/plugins/ingest_manager/server/services/agent_policy_update.ts index ff20e25e5bf0d..4ddb3cfb6a6a5 100644 --- a/x-pack/plugins/ingest_manager/server/services/agent_policy_update.ts +++ b/x-pack/plugins/ingest_manager/server/services/agent_policy_update.ts @@ -4,11 +4,27 @@ * you may not use this file except in compliance with the Elastic License. */ -import { SavedObjectsClientContract } from 'src/core/server'; +import { KibanaRequest, SavedObjectsClientContract } from 'src/core/server'; import { generateEnrollmentAPIKey, deleteEnrollmentApiKeyForAgentPolicyId } from './api_keys'; import { unenrollForAgentPolicyId } from './agents'; import { outputService } from './output'; import { agentPolicyService } from './agent_policy'; +import { appContextService } from './app_context'; + +const fakeRequest = ({ + headers: {}, + getBasePath: () => '', + path: '/', + route: { settings: {} }, + url: { + href: '/', + }, + raw: { + req: { + url: '/', + }, + }, +} as unknown) as KibanaRequest; export async function agentPolicyUpdateEventHandler( soClient: SavedObjectsClientContract, @@ -17,20 +33,25 @@ export async function agentPolicyUpdateEventHandler( ) { const adminUser = await outputService.getAdminUser(soClient); const outputId = await outputService.getDefaultOutputId(soClient); + // If no admin user and no default output fleet is not enabled just skip this hook if (!adminUser || !outputId) { return; } + // `soClient` from ingest `appContextService` is used to create policy change actions + // to ensure encrypted SOs are handled correctly + const internalSoClient = appContextService.getInternalUserSOClient(fakeRequest); + if (action === 'created') { await generateEnrollmentAPIKey(soClient, { agentPolicyId, }); - await agentPolicyService.createFleetPolicyChangeAction(soClient, agentPolicyId); + await agentPolicyService.createFleetPolicyChangeAction(internalSoClient, agentPolicyId); } if (action === 'updated') { - await agentPolicyService.createFleetPolicyChangeAction(soClient, agentPolicyId); + await agentPolicyService.createFleetPolicyChangeAction(internalSoClient, agentPolicyId); } if (action === 'deleted') { diff --git a/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts b/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts index c7b4098803827..8bcf275fce6ac 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts @@ -28,7 +28,7 @@ describe('test agent acks services', () => { references: [], type: AGENT_ACTION_SAVED_OBJECT_TYPE, attributes: { - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', agent_id: 'id', sent_at: '2020-03-14T19:45:02.620Z', timestamp: '2019-01-04T14:32:03.36764-05:00', @@ -61,7 +61,7 @@ describe('test agent acks services', () => { const mockSavedObjectsClient = savedObjectsClientMock.create(); const actionAttributes = { - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', policy_id: 'policy1', policy_revision: 4, sent_at: '2020-03-14T19:45:02.620Z', @@ -120,7 +120,7 @@ describe('test agent acks services', () => { const mockSavedObjectsClient = savedObjectsClientMock.create(); const actionAttributes = { - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', policy_id: 'policy1', policy_revision: 4, sent_at: '2020-03-14T19:45:02.620Z', @@ -180,7 +180,7 @@ describe('test agent acks services', () => { const mockSavedObjectsClient = savedObjectsClientMock.create(); const actionAttributes = { - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', policy_id: 'policy1', policy_revision: 4, sent_at: '2020-03-14T19:45:02.620Z', @@ -235,7 +235,7 @@ describe('test agent acks services', () => { references: [], type: AGENT_ACTION_SAVED_OBJECT_TYPE, attributes: { - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', sent_at: '2020-03-14T19:45:02.620Z', timestamp: '2019-01-04T14:32:03.36764-05:00', created_at: '2020-03-14T19:45:02.620Z', @@ -319,7 +319,7 @@ describe('test agent acks services', () => { references: [], type: AGENT_ACTION_SAVED_OBJECT_TYPE, attributes: { - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', agent_id: 'id', sent_at: '2020-03-14T19:45:02.620Z', timestamp: '2019-01-04T14:32:03.36764-05:00', diff --git a/x-pack/plugins/ingest_manager/server/services/agents/acks.ts b/x-pack/plugins/ingest_manager/server/services/agents/acks.ts index e22ee4256b0e2..a552caa12b95e 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/acks.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/acks.ts @@ -16,6 +16,7 @@ import { Agent, AgentAction, AgentPolicyAction, + AgentPolicyActionV7_9, AgentEvent, AgentEventSOAttributes, AgentSOAttributes, @@ -132,18 +133,20 @@ async function fetchActionsUsingCache( return [...freshActions, ...actions]; } -function isAgentPolicyAction(action: AgentAction | AgentPolicyAction): action is AgentPolicyAction { +function isAgentPolicyAction( + action: AgentAction | AgentPolicyAction | AgentPolicyActionV7_9 +): action is AgentPolicyAction | AgentPolicyActionV7_9 { return (action as AgentPolicyAction).policy_id !== undefined; } function getLatestConfigChangePolicyActionIfUpdated( agent: Agent, - actions: Array -): AgentPolicyAction | null { - return actions.reduce((acc, action) => { + actions: Array +): AgentPolicyAction | AgentPolicyActionV7_9 | null { + return actions.reduce((acc, action) => { if ( !isAgentPolicyAction(action) || - action.type !== 'CONFIG_CHANGE' || + (action.type !== 'POLICY_CHANGE' && action.type !== 'CONFIG_CHANGE') || action.policy_id !== agent.policy_id || (action?.policy_revision ?? 0) < (agent.policy_revision || 0) ) { diff --git a/x-pack/plugins/ingest_manager/server/services/agents/actions.test.ts b/x-pack/plugins/ingest_manager/server/services/agents/actions.test.ts index bcb3fc7fdc7bd..8fde684aa38bf 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/actions.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/actions.test.ts @@ -15,7 +15,7 @@ describe('test agent actions services', () => { const newAgentAction: Omit = { agent_id: 'agentid', - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', data: { content: 'data' }, sent_at: '2020-03-14T19:45:02.620Z', created_at: '2020-03-14T19:45:02.620Z', @@ -24,7 +24,7 @@ describe('test agent actions services', () => { Promise.resolve({ attributes: { agent_id: 'agentid', - type: 'CONFIG_CHANGE', + type: 'POLICY_CHANGE', data: JSON.stringify({ content: 'data' }), sent_at: '2020-03-14T19:45:02.620Z', created_at: '2020-03-14T19:45:02.620Z', diff --git a/x-pack/plugins/ingest_manager/server/services/agents/checkin/rxjs_utils.test.ts b/x-pack/plugins/ingest_manager/server/services/agents/checkin/rxjs_utils.test.ts index 5e84e3a50bb44..2909899418ec2 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/checkin/rxjs_utils.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/checkin/rxjs_utils.test.ts @@ -15,9 +15,13 @@ describe('createRateLimiter', () => { scheduler.run(({ expectObservable, cold }) => { const source = cold('a-b-c-d-e-f|'); - const rateLimiter = createRateLimiter(10, 1, 2, scheduler); + const intervalMs = 10; + const perInterval = 1; + const maxDelayMs = 50; + const rateLimiter = createRateLimiter(intervalMs, perInterval, maxDelayMs, scheduler); const obs = source.pipe(rateLimiter()); - const results = 'a 9ms b 9ms c 9ms d 9ms e 9ms (f|)'; + // f should be dropped because of maxDelay + const results = 'a 9ms b 9ms c 9ms d 9ms (e|)'; expectObservable(obs).toBe(results); }); }); diff --git a/x-pack/plugins/ingest_manager/server/services/agents/checkin/rxjs_utils.ts b/x-pack/plugins/ingest_manager/server/services/agents/checkin/rxjs_utils.ts index 3bbfbbd4ec1bf..bbdaa9975eeac 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/checkin/rxjs_utils.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/checkin/rxjs_utils.ts @@ -54,6 +54,8 @@ export function createRateLimiter( let countInCurrentInterval = 0; function createRateLimitOperator(): Rx.OperatorFunction { + const maxIntervalEnd = scheduler.now() + maxDelay; + return Rx.pipe( concatMap(function rateLimit(value: T) { const now = scheduler.now(); @@ -61,9 +63,9 @@ export function createRateLimiter( countInCurrentInterval = 1; intervalEnd = now + ratelimitIntervalMs; return Rx.of(value); - } else if (intervalEnd >= now + maxDelay) { - // re-rate limit in the future to avoid to schedule too far in the future as some observer can unsubscribe - return Rx.of(value).pipe(delay(maxDelay, scheduler), createRateLimitOperator()); + } else if (intervalEnd >= maxIntervalEnd) { + // drop the value as it's never going to success as long polling timeout is going to happen before we can send the policy + return Rx.EMPTY; } else { if (++countInCurrentInterval > ratelimitRequestPerInterval) { countInCurrentInterval = 1; diff --git a/x-pack/plugins/ingest_manager/server/services/agents/checkin/state_new_actions.test.ts b/x-pack/plugins/ingest_manager/server/services/agents/checkin/state_new_actions.test.ts new file mode 100644 index 0000000000000..f4a2147131570 --- /dev/null +++ b/x-pack/plugins/ingest_manager/server/services/agents/checkin/state_new_actions.test.ts @@ -0,0 +1,164 @@ +/* + * 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 { savedObjectsClientMock } from 'src/core/server/mocks'; +import { createAgentActionFromPolicyAction } from './state_new_actions'; +import { OutputType, Agent, AgentPolicyAction } from '../../../types'; + +jest.mock('../../app_context', () => ({ + appContextService: { + getEncryptedSavedObjects: () => ({ + getDecryptedAsInternalUser: () => ({ + attributes: { + default_api_key: 'MOCK_API_KEY', + }, + }), + }), + }, +})); + +describe('test agent checkin new action services', () => { + describe('createAgentActionFromPolicyAction()', () => { + const mockSavedObjectsClient = savedObjectsClientMock.create(); + const mockAgent: Agent = { + id: 'agent1', + active: true, + type: 'PERMANENT', + local_metadata: { elastic: { agent: { version: '7.10.0' } } }, + user_provided_metadata: {}, + current_error_events: [], + packages: [], + enrolled_at: '2020-03-14T19:45:02.620Z', + }; + const mockPolicyAction: AgentPolicyAction = { + id: 'action1', + type: 'POLICY_CHANGE', + policy_id: 'policy1', + policy_revision: 1, + sent_at: '2020-03-14T19:45:02.620Z', + created_at: '2020-03-14T19:45:02.620Z', + data: { + policy: { + id: 'policy1', + outputs: { + default: { + type: OutputType.Elasticsearch, + hosts: [], + ca_sha256: undefined, + api_key: undefined, + }, + }, + inputs: [], + }, + }, + }; + + it('should return POLICY_CHANGE and data.policy for agent version >= 7.10', async () => { + const expectedResult = [ + { + agent_id: 'agent1', + created_at: '2020-03-14T19:45:02.620Z', + data: { + policy: { + id: 'policy1', + inputs: [], + outputs: { default: { api_key: 'MOCK_API_KEY', hosts: [], type: 'elasticsearch' } }, + }, + }, + id: 'action1', + sent_at: '2020-03-14T19:45:02.620Z', + type: 'POLICY_CHANGE', + }, + ]; + + expect( + await createAgentActionFromPolicyAction(mockSavedObjectsClient, mockAgent, mockPolicyAction) + ).toEqual(expectedResult); + + expect( + await createAgentActionFromPolicyAction( + mockSavedObjectsClient, + { ...mockAgent, local_metadata: { elastic: { agent: { version: '7.10.0-SNAPSHOT' } } } }, + mockPolicyAction + ) + ).toEqual(expectedResult); + + expect( + await createAgentActionFromPolicyAction( + mockSavedObjectsClient, + { ...mockAgent, local_metadata: { elastic: { agent: { version: '7.10.2' } } } }, + mockPolicyAction + ) + ).toEqual(expectedResult); + + expect( + await createAgentActionFromPolicyAction( + mockSavedObjectsClient, + { ...mockAgent, local_metadata: { elastic: { agent: { version: '8.0.0' } } } }, + mockPolicyAction + ) + ).toEqual(expectedResult); + + expect( + await createAgentActionFromPolicyAction( + mockSavedObjectsClient, + { ...mockAgent, local_metadata: { elastic: { agent: { version: '8.0.0-SNAPSHOT' } } } }, + mockPolicyAction + ) + ).toEqual(expectedResult); + }); + + it('should return CONNFIG_CHANGE and data.config for agent version <= 7.9', async () => { + const expectedResult = [ + { + agent_id: 'agent1', + created_at: '2020-03-14T19:45:02.620Z', + data: { + config: { + id: 'policy1', + inputs: [], + outputs: { default: { api_key: 'MOCK_API_KEY', hosts: [], type: 'elasticsearch' } }, + }, + }, + id: 'action1', + sent_at: '2020-03-14T19:45:02.620Z', + type: 'CONFIG_CHANGE', + }, + ]; + + expect( + await createAgentActionFromPolicyAction( + mockSavedObjectsClient, + { ...mockAgent, local_metadata: { elastic: { agent: { version: '7.9.0' } } } }, + mockPolicyAction + ) + ).toEqual(expectedResult); + + expect( + await createAgentActionFromPolicyAction( + mockSavedObjectsClient, + { ...mockAgent, local_metadata: { elastic: { agent: { version: '7.9.3' } } } }, + mockPolicyAction + ) + ).toEqual(expectedResult); + + expect( + await createAgentActionFromPolicyAction( + mockSavedObjectsClient, + { ...mockAgent, local_metadata: { elastic: { agent: { version: '7.9.1-SNAPSHOT' } } } }, + mockPolicyAction + ) + ).toEqual(expectedResult); + + expect( + await createAgentActionFromPolicyAction( + mockSavedObjectsClient, + { ...mockAgent, local_metadata: { elastic: { agent: { version: '7.8.2' } } } }, + mockPolicyAction + ) + ).toEqual(expectedResult); + }); + }); +}); diff --git a/x-pack/plugins/ingest_manager/server/services/agents/checkin/state_new_actions.ts b/x-pack/plugins/ingest_manager/server/services/agents/checkin/state_new_actions.ts index fbbed87b031e2..8ae151577fefa 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/checkin/state_new_actions.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/checkin/state_new_actions.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 semver from 'semver'; import { timer, from, Observable, TimeoutError } from 'rxjs'; import { omit } from 'lodash'; import { @@ -16,11 +16,18 @@ import { take, } from 'rxjs/operators'; import { SavedObjectsClientContract, KibanaRequest } from 'src/core/server'; -import { Agent, AgentAction, AgentPolicyAction, AgentSOAttributes } from '../../../types'; +import { + Agent, + AgentAction, + AgentPolicyAction, + AgentPolicyActionV7_9, + AgentSOAttributes, +} from '../../../types'; import * as APIKeysService from '../../api_keys'; import { AGENT_SAVED_OBJECT_TYPE, AGENT_UPDATE_ACTIONS_INTERVAL_MS, + AGENT_POLLING_REQUEST_TIMEOUT_MARGIN_MS, AGENT_POLICY_ROLLOUT_RATE_LIMIT_INTERVAL_MS, AGENT_POLICY_ROLLOUT_RATE_LIMIT_REQUEST_PER_INTERVAL, } from '../../../constants'; @@ -32,8 +39,6 @@ import { import { appContextService } from '../../app_context'; import { toPromiseAbortable, AbortError, createRateLimiter } from './rxjs_utils'; -const RATE_LIMIT_MAX_DELAY_MS = 5 * 60 * 1000; // 5 minutes - function getInternalUserSOClient() { const fakeRequest = ({ headers: {}, @@ -105,15 +110,40 @@ async function getOrCreateAgentDefaultOutputAPIKey( return outputAPIKey.key; } -async function createAgentActionFromPolicyAction( +export async function createAgentActionFromPolicyAction( soClient: SavedObjectsClientContract, agent: Agent, policyAction: AgentPolicyAction ) { + // Transform the policy action for agent version <= 7.9.x for BWC + const agentVersion = semver.parse((agent.local_metadata?.elastic as any)?.agent?.version); + const agentPolicyAction: AgentPolicyAction | AgentPolicyActionV7_9 = + agentVersion && + semver.lt( + agentVersion, + // A prerelease tag is added here so that agent versions with prerelease tags can be compared + // correctly using `semvar` + '7.10.0-SNAPSHOT', + // `@types/semvar` is out of date with the version of `semvar` we use and doesn't have a + // corresponding release version we can update the typing to :( so, the typing error is + // suppressed here even though it is supported by `semvar` + // @ts-expect-error + { includePrerelease: true } + ) + ? { + ...policyAction, + type: 'CONFIG_CHANGE', + data: { + config: policyAction.data.policy, + }, + } + : policyAction; + + // Create agent action const newAgentAction: AgentAction = Object.assign( omit( // Faster than clone - JSON.parse(JSON.stringify(policyAction)) as AgentPolicyAction, + JSON.parse(JSON.stringify(agentPolicyAction)) as AgentPolicyAction, 'policy_id', 'policy_revision' ), @@ -123,27 +153,41 @@ async function createAgentActionFromPolicyAction( ); // Mutate the policy to set the api token for this agent - newAgentAction.data.config.outputs.default.api_key = await getOrCreateAgentDefaultOutputAPIKey( - soClient, - agent - ); + const apiKey = await getOrCreateAgentDefaultOutputAPIKey(soClient, agent); + if (newAgentAction.data.policy) { + newAgentAction.data.policy.outputs.default.api_key = apiKey; + } + // BWC for agent <= 7.9 + else if (newAgentAction.data.config) { + newAgentAction.data.config.outputs.default.api_key = apiKey; + } return [newAgentAction]; } +function getPollingTimeoutMs() { + const pollingTimeoutMs = appContextService.getConfig()?.fleet.pollingRequestTimeout ?? 0; + // Set a timeout 20s before the real timeout to have a chance to respond an empty response before socket timeout + return Math.max( + pollingTimeoutMs - AGENT_POLLING_REQUEST_TIMEOUT_MARGIN_MS, + AGENT_POLLING_REQUEST_TIMEOUT_MARGIN_MS + ); +} + export function agentCheckinStateNewActionsFactory() { // Shared Observables const agentPolicies$ = new Map>(); const newActions$ = createNewActionsSharedObservable(); // Rx operators - const pollingTimeoutMs = appContextService.getConfig()?.fleet.pollingRequestTimeout ?? 0; + const pollingTimeoutMs = getPollingTimeoutMs(); + const rateLimiterIntervalMs = appContextService.getConfig()?.fleet.agentPolicyRolloutRateLimitIntervalMs ?? AGENT_POLICY_ROLLOUT_RATE_LIMIT_INTERVAL_MS; const rateLimiterRequestPerInterval = appContextService.getConfig()?.fleet.agentPolicyRolloutRateLimitRequestPerInterval ?? AGENT_POLICY_ROLLOUT_RATE_LIMIT_REQUEST_PER_INTERVAL; - const rateLimiterMaxDelay = Math.min(RATE_LIMIT_MAX_DELAY_MS, pollingTimeoutMs); + const rateLimiterMaxDelay = pollingTimeoutMs; const rateLimiter = createRateLimiter( rateLimiterIntervalMs, @@ -169,10 +213,7 @@ export function agentCheckinStateNewActionsFactory() { } const stream$ = agentPolicy$.pipe( - timeout( - // Set a timeout 3s before the real timeout to have a chance to respond an empty response before socket timeout - Math.max(pollingTimeoutMs - 3000, 3000) - ), + timeout(pollingTimeoutMs), filter( (action) => agent.policy_id !== undefined && diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/index.test.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/index.test.ts index bdd8883ea29c2..78aa17da5030c 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/index.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/index.test.ts @@ -4,12 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Dataset } from '../../../types'; -import { getDatasetAssetBaseName } from './index'; +import { RegistryDataStream } from '../../../types'; +import { getRegistryDataStreamAssetBaseName } from './index'; test('getBaseName', () => { - const dataset: Dataset = { - name: 'nginx.access', + const dataStream: RegistryDataStream = { + dataset: 'nginx.access', title: 'Nginx Acess Logs', release: 'beta', type: 'logs', @@ -17,6 +17,6 @@ test('getBaseName', () => { package: 'nginx', path: 'access', }; - const name = getDatasetAssetBaseName(dataset); + const name = getRegistryDataStreamAssetBaseName(dataStream); expect(name).toStrictEqual('logs-nginx.access'); }); diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/index.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/index.ts index 0cb09ba054bf1..17cd28cc8a081 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/index.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/index.ts @@ -4,12 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Dataset } from '../../../types'; +import { RegistryDataStream } from '../../../types'; /** * Creates the base name for Elasticsearch assets in the form of - * {type}-{id} + * {type}-{dataset} */ -export function getDatasetAssetBaseName(dataset: Dataset): string { - return `${dataset.type}-${dataset.name}`; +export function getRegistryDataStreamAssetBaseName(dataStream: RegistryDataStream): string { + return `${dataStream.type}-${dataStream.dataset}`; } diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/ingest_pipeline/ingest_pipelines.test.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/ingest_pipeline/ingest_pipelines.test.ts index 36a19c512a8b4..378dd271779b4 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/ingest_pipeline/ingest_pipelines.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/ingest_pipeline/ingest_pipelines.test.ts @@ -7,7 +7,7 @@ import { readFileSync } from 'fs'; import path from 'path'; import { rewriteIngestPipeline, getPipelineNameForInstallation } from './install'; -import { Dataset } from '../../../../types'; +import { RegistryDataStream } from '../../../../types'; test('a json-format pipeline with pipeline references is correctly rewritten', () => { const inputStandard = readFileSync( @@ -106,8 +106,8 @@ test('a yml-format pipeline with no pipeline references stays unchanged', () => }); test('getPipelineNameForInstallation gets correct name', () => { - const dataset: Dataset = { - name: 'coredns.log', + const dataStream: RegistryDataStream = { + dataset: 'coredns.log', title: 'CoreDNS logs', release: 'ga', type: 'logs', @@ -118,19 +118,19 @@ test('getPipelineNameForInstallation gets correct name', () => { const packageVersion = '1.0.1'; const pipelineRefName = 'pipeline-json'; const pipelineEntryNameForInstallation = getPipelineNameForInstallation({ - pipelineName: dataset.ingest_pipeline, - dataset, + pipelineName: dataStream.ingest_pipeline, + dataStream, packageVersion, }); const pipelineRefNameForInstallation = getPipelineNameForInstallation({ pipelineName: pipelineRefName, - dataset, + dataStream, packageVersion, }); expect(pipelineEntryNameForInstallation).toBe( - `${dataset.type}-${dataset.name}-${packageVersion}` + `${dataStream.type}-${dataStream.dataset}-${packageVersion}` ); expect(pipelineRefNameForInstallation).toBe( - `${dataset.type}-${dataset.name}-${packageVersion}-${pipelineRefName}` + `${dataStream.type}-${dataStream.dataset}-${packageVersion}-${pipelineRefName}` ); }); diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/ingest_pipeline/install.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/ingest_pipeline/install.ts index 878c6ea8f2804..6088bcb71f878 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/ingest_pipeline/install.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/ingest_pipeline/install.ts @@ -7,7 +7,7 @@ import { SavedObjectsClientContract } from 'src/core/server'; import { EsAssetReference, - Dataset, + RegistryDataStream, ElasticsearchAssetType, RegistryPackage, } from '../../../../types'; @@ -30,17 +30,19 @@ export const installPipelines = async ( // unlike other ES assets, pipeline names are versioned so after a template is updated // it can be created pointing to the new template, without removing the old one and effecting data // so do not remove the currently installed pipelines here - const datasets = registryPackage.datasets; - if (!datasets?.length) return []; + const dataStreams = registryPackage.data_streams; + if (!dataStreams?.length) return []; const pipelinePaths = paths.filter((path) => isPipeline(path)); // get and save pipeline refs before installing pipelines - const pipelineRefs = datasets.reduce((acc, dataset) => { - const filteredPaths = pipelinePaths.filter((path) => isDatasetPipeline(path, dataset.path)); + const pipelineRefs = dataStreams.reduce((acc, dataStream) => { + const filteredPaths = pipelinePaths.filter((path) => + isDataStreamPipeline(path, dataStream.path) + ); const pipelineObjectRefs = filteredPaths.map((path) => { const { name } = getNameAndExtension(path); const nameForInstallation = getPipelineNameForInstallation({ pipelineName: name, - dataset, + dataStream, packageVersion: registryPackage.version, }); return { id: nameForInstallation, type: ElasticsearchAssetType.ingestPipeline }; @@ -49,11 +51,11 @@ export const installPipelines = async ( return acc; }, []); await saveInstalledEsRefs(savedObjectsClient, registryPackage.name, pipelineRefs); - const pipelines = datasets.reduce>>((acc, dataset) => { - if (dataset.ingest_pipeline) { + const pipelines = dataStreams.reduce>>((acc, dataStream) => { + if (dataStream.ingest_pipeline) { acc.push( - installPipelinesForDataset({ - dataset, + installPipelinesForDataStream({ + dataStream, callCluster, paths: pipelinePaths, pkgVersion: registryPackage.version, @@ -86,18 +88,18 @@ export function rewriteIngestPipeline( return pipeline; } -export async function installPipelinesForDataset({ +export async function installPipelinesForDataStream({ callCluster, pkgVersion, paths, - dataset, + dataStream, }: { callCluster: CallESAsCurrentUser; pkgVersion: string; paths: string[]; - dataset: Dataset; + dataStream: RegistryDataStream; }): Promise { - const pipelinePaths = paths.filter((path) => isDatasetPipeline(path, dataset.path)); + const pipelinePaths = paths.filter((path) => isDataStreamPipeline(path, dataStream.path)); let pipelines: any[] = []; const substitutions: RewriteSubstitution[] = []; @@ -105,7 +107,7 @@ export async function installPipelinesForDataset({ const { name, extension } = getNameAndExtension(path); const nameForInstallation = getPipelineNameForInstallation({ pipelineName: name, - dataset, + dataStream, packageVersion: pkgVersion, }); const content = Registry.getAsset(path).toString('utf-8'); @@ -175,13 +177,13 @@ async function installPipeline({ const isDirectory = ({ path }: Registry.ArchiveEntry) => path.endsWith('/'); -const isDatasetPipeline = (path: string, datasetName: string) => { +const isDataStreamPipeline = (path: string, dataStreamDataset: string) => { const pathParts = Registry.pathParts(path); return ( !isDirectory({ path }) && pathParts.type === ElasticsearchAssetType.ingestPipeline && pathParts.dataset !== undefined && - datasetName === pathParts.dataset + dataStreamDataset === pathParts.dataset ); }; const isPipeline = (path: string) => { @@ -206,15 +208,15 @@ const getNameAndExtension = ( export const getPipelineNameForInstallation = ({ pipelineName, - dataset, + dataStream, packageVersion, }: { pipelineName: string; - dataset: Dataset; + dataStream: RegistryDataStream; packageVersion: string; }): string => { - const isPipelineEntry = pipelineName === dataset.ingest_pipeline; + const isPipelineEntry = pipelineName === dataStream.ingest_pipeline; const suffix = isPipelineEntry ? '' : `-${pipelineName}`; // if this is the pipeline entry, don't add a suffix - return `${dataset.type}-${dataset.name}-${packageVersion}${suffix}`; + return `${dataStream.type}-${dataStream.dataset}-${packageVersion}${suffix}`; }; diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/install.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/install.ts index f4e8c3bfd99d3..8f80feb268910 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/install.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/install.ts @@ -7,7 +7,7 @@ import Boom from 'boom'; import { SavedObjectsClientContract } from 'src/core/server'; import { - Dataset, + RegistryDataStream, RegistryPackage, ElasticsearchAssetType, TemplateRef, @@ -38,29 +38,32 @@ export const installTemplates = async ( registryPackage.name, ElasticsearchAssetType.indexTemplate ); - // build templates per dataset from yml files - const datasets = registryPackage.datasets; - if (!datasets) return []; + // build templates per data stream from yml files + const dataStreams = registryPackage.data_streams; + if (!dataStreams) return []; // get template refs to save - const installedTemplateRefs = datasets.map((dataset) => ({ - id: generateTemplateName(dataset), + const installedTemplateRefs = dataStreams.map((dataStream) => ({ + id: generateTemplateName(dataStream), type: ElasticsearchAssetType.indexTemplate, })); // add package installation's references to index templates await saveInstalledEsRefs(savedObjectsClient, registryPackage.name, installedTemplateRefs); - if (datasets) { - const installTemplatePromises = datasets.reduce>>((acc, dataset) => { - acc.push( - installTemplateForDataset({ - pkg: registryPackage, - callCluster, - dataset, - }) - ); - return acc; - }, []); + if (dataStreams) { + const installTemplatePromises = dataStreams.reduce>>( + (acc, dataStream) => { + acc.push( + installTemplateForDataStream({ + pkg: registryPackage, + callCluster, + dataStream, + }) + ); + return acc; + }, + [] + ); const res = await Promise.all(installTemplatePromises); const installedTemplates = res.flat(); @@ -158,25 +161,25 @@ const isComponentTemplate = (path: string) => { }; /** - * installTemplatesForDataset installs one template for each dataset + * installTemplateForDataStream installs one template for each data stream * - * The template is currently loaded with the pkgey-package-dataset + * The template is currently loaded with the pkgkey-package-data_stream */ -export async function installTemplateForDataset({ +export async function installTemplateForDataStream({ pkg, callCluster, - dataset, + dataStream, }: { pkg: RegistryPackage; callCluster: CallESAsCurrentUser; - dataset: Dataset; + dataStream: RegistryDataStream; }): Promise { - const fields = await loadFieldsFromYaml(pkg, dataset.path); + const fields = await loadFieldsFromYaml(pkg, dataStream.path); return installTemplate({ callCluster, fields, - dataset, + dataStream, packageVersion: pkg.version, packageName: pkg.name, }); @@ -237,7 +240,7 @@ function buildComponentTemplates(registryElasticsearch: RegistryElasticsearch | return { settingsTemplate, mappingsTemplate }; } -async function installDatasetComponentTemplates( +async function installDataStreamComponentTemplates( templateName: string, registryElasticsearch: RegistryElasticsearch | undefined, callCluster: CallESAsCurrentUser @@ -277,35 +280,35 @@ async function installDatasetComponentTemplates( export async function installTemplate({ callCluster, fields, - dataset, + dataStream, packageVersion, packageName, }: { callCluster: CallESAsCurrentUser; fields: Field[]; - dataset: Dataset; + dataStream: RegistryDataStream; packageVersion: string; packageName: string; }): Promise { const mappings = generateMappings(processFields(fields)); - const templateName = generateTemplateName(dataset); + const templateName = generateTemplateName(dataStream); let pipelineName; - if (dataset.ingest_pipeline) { + if (dataStream.ingest_pipeline) { pipelineName = getPipelineNameForInstallation({ - pipelineName: dataset.ingest_pipeline, - dataset, + pipelineName: dataStream.ingest_pipeline, + dataStream, packageVersion, }); } - const composedOfTemplates = await installDatasetComponentTemplates( + const composedOfTemplates = await installDataStreamComponentTemplates( templateName, - dataset.elasticsearch, + dataStream.elasticsearch, callCluster ); const template = getTemplate({ - type: dataset.type, + type: dataStream.type, templateName, mappings, pipelineName, diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/template.test.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/template.test.ts index 99e568bf771f8..cc1aa79c7491c 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/template.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/template.test.ts @@ -212,6 +212,37 @@ test('tests processing keyword field with multi fields with analyzed text field' expect(mappings).toEqual(keywordWithAnalyzedMultiFieldsMapping); }); +test('tests processing keyword field with multi fields with normalized keyword field', () => { + const keywordWithNormalizedMultiFieldsLiteralYml = ` + - name: keywordWithNormalizedMultiField + type: keyword + multi_fields: + - name: normalized + type: keyword + normalizer: lowercase + `; + + const keywordWithNormalizedMultiFieldsMapping = { + properties: { + keywordWithNormalizedMultiField: { + ignore_above: 1024, + type: 'keyword', + fields: { + normalized: { + type: 'keyword', + ignore_above: 1024, + normalizer: 'lowercase', + }, + }, + }, + }, + }; + const fields: Field[] = safeLoad(keywordWithNormalizedMultiFieldsLiteralYml); + const processedFields = processFields(fields); + const mappings = generateMappings(processedFields); + expect(mappings).toEqual(keywordWithNormalizedMultiFieldsMapping); +}); + test('tests processing object field with no other attributes', () => { const objectFieldLiteralYml = ` - name: objectField diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/template.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/template.ts index 71e49acf1766f..e0fea59107c26 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/template.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/template/template.ts @@ -6,13 +6,13 @@ import { Field, Fields } from '../../fields/field'; import { - Dataset, + RegistryDataStream, CallESAsCurrentUser, TemplateRef, IndexTemplate, IndexTemplateMappings, } from '../../../../types'; -import { getDatasetAssetBaseName } from '../index'; +import { getRegistryDataStreamAssetBaseName } from '../index'; interface Properties { [key: string]: any; @@ -189,6 +189,9 @@ function generateKeywordMapping(field: Field): IndexTemplateMapping { if (field.ignore_above) { mapping.ignore_above = field.ignore_above; } + if (field.normalizer) { + mapping.normalizer = field.normalizer; + } return mapping; } @@ -222,22 +225,24 @@ function getDefaultProperties(field: Field): Properties { /** * Generates the template name out of the given information */ -export function generateTemplateName(dataset: Dataset): string { - return getDatasetAssetBaseName(dataset); +export function generateTemplateName(dataStream: RegistryDataStream): string { + return getRegistryDataStreamAssetBaseName(dataStream); } /** - * Returns a map of the dataset path fields to elasticsearch index pattern. - * @param datasets an array of Dataset objects + * Returns a map of the data stream path fields to elasticsearch index pattern. + * @param dataStreams an array of RegistryDataStream objects */ -export function generateESIndexPatterns(datasets: Dataset[] | undefined): Record { - if (!datasets) { +export function generateESIndexPatterns( + dataStreams: RegistryDataStream[] | undefined +): Record { + if (!dataStreams) { return {}; } const patterns: Record = {}; - for (const dataset of datasets) { - patterns[dataset.path] = generateTemplateName(dataset) + '-*'; + for (const dataStream of dataStreams) { + patterns[dataStream.path] = generateTemplateName(dataStream) + '-*'; } return patterns; } @@ -389,7 +394,7 @@ const updateExistingIndex = async ({ }) => { const { settings, mappings } = indexTemplate.template; - // for now, remove from object so as not to update stream or dataset properties of the index until type and name + // for now, remove from object so as not to update stream or data stream properties of the index until type and name // are added in https://github.com/elastic/kibana/issues/66551. namespace value we will continue // to skip updating and assume the value in the index mapping is correct delete mappings.properties.stream; diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/install.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/install.ts index dfa03ec9d527d..d8aff10492595 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/install.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/install.ts @@ -9,7 +9,6 @@ import { SavedObjectsClientContract } from 'kibana/server'; import { saveInstalledEsRefs } from '../../packages/install'; import * as Registry from '../../registry'; import { - Dataset, ElasticsearchAssetType, EsAssetReference, RegistryPackage, @@ -24,12 +23,7 @@ interface TransformInstallation { content: string; } -interface TransformPathDataset { - path: string; - dataset: Dataset; -} - -export const installTransformForDataset = async ( +export const installTransform = async ( registryPackage: RegistryPackage, paths: string[], callCluster: CallESAsCurrentUser, @@ -51,53 +45,32 @@ export const installTransformForDataset = async ( callCluster, previousInstalledTransformEsAssets.map((asset) => asset.id) ); - // install the latest dataset - const datasets = registryPackage.datasets; - if (!datasets?.length) return []; - const installNameSuffix = `${registryPackage.version}`; + const installNameSuffix = `${registryPackage.version}`; const transformPaths = paths.filter((path) => isTransform(path)); let installedTransforms: EsAssetReference[] = []; if (transformPaths.length > 0) { - const transformPathDatasets = datasets.reduce((acc, dataset) => { - transformPaths.forEach((path) => { - if (isDatasetTransform(path, dataset.path)) { - acc.push({ path, dataset }); - } + const transformRefs = transformPaths.reduce((acc, path) => { + acc.push({ + id: getTransformNameForInstallation(registryPackage, path, installNameSuffix), + type: ElasticsearchAssetType.transform, }); + return acc; }, []); - const transformRefs = transformPathDatasets.reduce( - (acc, transformPathDataset) => { - if (transformPathDataset) { - acc.push({ - id: getTransformNameForInstallation(transformPathDataset, installNameSuffix), - type: ElasticsearchAssetType.transform, - }); - } - return acc; - }, - [] - ); - // get and save transform refs before installing transforms await saveInstalledEsRefs(savedObjectsClient, registryPackage.name, transformRefs); - const transforms: TransformInstallation[] = transformPathDatasets.map( - (transformPathDataset: TransformPathDataset) => { - return { - installationName: getTransformNameForInstallation( - transformPathDataset, - installNameSuffix - ), - content: getAsset(transformPathDataset.path).toString('utf-8'), - }; - } - ); + const transforms: TransformInstallation[] = transformPaths.map((path: string) => { + return { + installationName: getTransformNameForInstallation(registryPackage, path, installNameSuffix), + content: getAsset(path).toString('utf-8'), + }; + }); const installationPromises = transforms.map(async (transform) => { - return installTransform({ callCluster, transform }); + return handleTransformInstall({ callCluster, transform }); }); installedTransforms = await Promise.all(installationPromises).then((results) => results.flat()); @@ -123,20 +96,10 @@ export const installTransformForDataset = async ( const isTransform = (path: string) => { const pathParts = Registry.pathParts(path); - return pathParts.type === ElasticsearchAssetType.transform; + return !path.endsWith('/') && pathParts.type === ElasticsearchAssetType.transform; }; -const isDatasetTransform = (path: string, datasetName: string) => { - const pathParts = Registry.pathParts(path); - return ( - !path.endsWith('/') && - pathParts.type === ElasticsearchAssetType.transform && - pathParts.dataset !== undefined && - datasetName === pathParts.dataset - ); -}; - -async function installTransform({ +async function handleTransformInstall({ callCluster, transform, }: { @@ -160,9 +123,12 @@ async function installTransform({ } const getTransformNameForInstallation = ( - transformDataset: TransformPathDataset, + registryPackage: RegistryPackage, + path: string, suffix: string ) => { - const filename = transformDataset?.path.split('/')?.pop()?.split('.')[0]; - return `${transformDataset.dataset.type}-${transformDataset.dataset.name}-${filename}-${suffix}`; + const pathPaths = path.split('/'); + const filename = pathPaths?.pop()?.split('.')[0]; + const folderName = pathPaths?.pop(); + return `${registryPackage.name}.${folderName}-${filename}-${suffix}`; }; diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/remove.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/remove.ts index a527d05f1c49b..02d5dfc64d07d 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/remove.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/remove.ts @@ -25,6 +25,19 @@ export const deleteTransforms = async ( ) => { await Promise.all( transformIds.map(async (transformId) => { + // get the index the transform + const transformResponse: { + count: number; + transforms: Array<{ + dest: { + index: string; + }; + }>; + } = await callCluster('transport.request', { + method: 'GET', + path: `/_transform/${transformId}`, + }); + await stopTransforms([transformId], callCluster); await callCluster('transport.request', { method: 'DELETE', @@ -32,6 +45,15 @@ export const deleteTransforms = async ( path: `/_transform/${transformId}`, ignore: [404], }); + + // expect this to be 1 + for (const transform of transformResponse.transforms) { + await callCluster('transport.request', { + method: 'DELETE', + path: `/${transform?.dest?.index}`, + ignore: [404], + }); + } }) ); }; diff --git a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/transform.test.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/transform.test.ts index c43a33df2db61..768c6af1d8915 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/transform.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/transform.test.ts @@ -14,7 +14,7 @@ jest.mock('./common', () => { }; }); -import { installTransformForDataset } from './install'; +import { installTransform } from './install'; import { ILegacyScopedClusterClient, SavedObject, SavedObjectsClientContract } from 'kibana/server'; import { ElasticsearchAssetType, Installation, RegistryPackage } from '../../../../types'; import { getInstallation, getInstallationObject } from '../../packages'; @@ -47,7 +47,7 @@ describe('test transform install', () => { type: ElasticsearchAssetType.ingestPipeline, }, { - id: 'metrics-endpoint.metadata_current-default-0.15.0-dev.0', + id: 'endpoint.metadata_current-default-0.15.0-dev.0', type: ElasticsearchAssetType.transform, }, ], @@ -60,15 +60,15 @@ describe('test transform install', () => { type: ElasticsearchAssetType.ingestPipeline, }, { - id: 'metrics-endpoint.metadata_current-default-0.15.0-dev.0', + id: 'endpoint.metadata_current-default-0.15.0-dev.0', type: ElasticsearchAssetType.transform, }, { - id: 'metrics-endpoint.metadata_current-default-0.16.0-dev.0', + id: 'endpoint.metadata_current-default-0.16.0-dev.0', type: ElasticsearchAssetType.transform, }, { - id: 'metrics-endpoint.metadata-default-0.16.0-dev.0', + id: 'endpoint.metadata-default-0.16.0-dev.0', type: ElasticsearchAssetType.transform, }, ], @@ -91,14 +91,33 @@ describe('test transform install', () => { } as unknown) as SavedObject) ); - await installTransformForDataset( + legacyScopedClusterClient.callAsCurrentUser.mockReturnValueOnce( + Promise.resolve({ + count: 1, + transforms: [ + { + dest: { + index: 'index', + }, + }, + ], + } as { + count: number; + transforms: Array<{ + dest: { + index: string; + }; + }>; + }) + ); + await installTransform( ({ name: 'endpoint', version: '0.16.0-dev.0', - datasets: [ + data_streams: [ { type: 'metrics', - name: 'endpoint.metadata', + dataset: 'endpoint.metadata', title: 'Endpoint Metadata', release: 'experimental', package: 'endpoint', @@ -112,7 +131,7 @@ describe('test transform install', () => { }, { type: 'metrics', - name: 'endpoint.metadata_current', + dataset: 'endpoint.metadata_current', title: 'Endpoint Metadata Current', release: 'experimental', package: 'endpoint', @@ -127,19 +146,27 @@ describe('test transform install', () => { ], } as unknown) as RegistryPackage, [ - 'endpoint-0.16.0-dev.0/dataset/policy/elasticsearch/ingest_pipeline/default.json', - 'endpoint-0.16.0-dev.0/dataset/metadata/elasticsearch/transform/default.json', - 'endpoint-0.16.0-dev.0/dataset/metadata_current/elasticsearch/transform/default.json', + 'endpoint-0.16.0-dev.0/data_stream/policy/elasticsearch/ingest_pipeline/default.json', + 'endpoint-0.16.0-dev.0/elasticsearch/transform/metadata/default.json', + 'endpoint-0.16.0-dev.0/elasticsearch/transform/metadata_current/default.json', ], legacyScopedClusterClient.callAsCurrentUser, savedObjectsClient ); + expect(legacyScopedClusterClient.callAsCurrentUser.mock.calls).toEqual([ + [ + 'transport.request', + { + method: 'GET', + path: '/_transform/endpoint.metadata_current-default-0.15.0-dev.0', + }, + ], [ 'transport.request', { method: 'POST', - path: '/_transform/metrics-endpoint.metadata_current-default-0.15.0-dev.0/_stop', + path: '/_transform/endpoint.metadata_current-default-0.15.0-dev.0/_stop', query: 'force=true', ignore: [404], }, @@ -149,7 +176,15 @@ describe('test transform install', () => { { method: 'DELETE', query: 'force=true', - path: '/_transform/metrics-endpoint.metadata_current-default-0.15.0-dev.0', + path: '/_transform/endpoint.metadata_current-default-0.15.0-dev.0', + ignore: [404], + }, + ], + [ + 'transport.request', + { + method: 'DELETE', + path: '/index', ignore: [404], }, ], @@ -157,7 +192,7 @@ describe('test transform install', () => { 'transport.request', { method: 'PUT', - path: '/_transform/metrics-endpoint.metadata-default-0.16.0-dev.0', + path: '/_transform/endpoint.metadata-default-0.16.0-dev.0', query: 'defer_validation=true', body: '{"content": "data"}', }, @@ -166,7 +201,7 @@ describe('test transform install', () => { 'transport.request', { method: 'PUT', - path: '/_transform/metrics-endpoint.metadata_current-default-0.16.0-dev.0', + path: '/_transform/endpoint.metadata_current-default-0.16.0-dev.0', query: 'defer_validation=true', body: '{"content": "data"}', }, @@ -175,14 +210,14 @@ describe('test transform install', () => { 'transport.request', { method: 'POST', - path: '/_transform/metrics-endpoint.metadata-default-0.16.0-dev.0/_start', + path: '/_transform/endpoint.metadata-default-0.16.0-dev.0/_start', }, ], [ 'transport.request', { method: 'POST', - path: '/_transform/metrics-endpoint.metadata_current-default-0.16.0-dev.0/_start', + path: '/_transform/endpoint.metadata_current-default-0.16.0-dev.0/_start', }, ], ]); @@ -198,15 +233,15 @@ describe('test transform install', () => { type: 'ingest_pipeline', }, { - id: 'metrics-endpoint.metadata_current-default-0.15.0-dev.0', + id: 'endpoint.metadata_current-default-0.15.0-dev.0', type: 'transform', }, { - id: 'metrics-endpoint.metadata-default-0.16.0-dev.0', + id: 'endpoint.metadata-default-0.16.0-dev.0', type: 'transform', }, { - id: 'metrics-endpoint.metadata_current-default-0.16.0-dev.0', + id: 'endpoint.metadata_current-default-0.16.0-dev.0', type: 'transform', }, ], @@ -222,11 +257,11 @@ describe('test transform install', () => { type: 'ingest_pipeline', }, { - id: 'metrics-endpoint.metadata_current-default-0.16.0-dev.0', + id: 'endpoint.metadata_current-default-0.16.0-dev.0', type: 'transform', }, { - id: 'metrics-endpoint.metadata-default-0.16.0-dev.0', + id: 'endpoint.metadata-default-0.16.0-dev.0', type: 'transform', }, ], @@ -263,14 +298,14 @@ describe('test transform install', () => { >) ); legacyScopedClusterClient.callAsCurrentUser = jest.fn(); - await installTransformForDataset( + await installTransform( ({ name: 'endpoint', version: '0.16.0-dev.0', - datasets: [ + data_streams: [ { type: 'metrics', - name: 'endpoint.metadata_current', + dataset: 'endpoint.metadata_current', title: 'Endpoint Metadata', release: 'experimental', package: 'endpoint', @@ -284,7 +319,7 @@ describe('test transform install', () => { }, ], } as unknown) as RegistryPackage, - ['endpoint-0.16.0-dev.0/dataset/metadata_current/elasticsearch/transform/default.json'], + ['endpoint-0.16.0-dev.0/elasticsearch/transform/metadata_current/default.json'], legacyScopedClusterClient.callAsCurrentUser, savedObjectsClient ); @@ -294,7 +329,7 @@ describe('test transform install', () => { 'transport.request', { method: 'PUT', - path: '/_transform/metrics-endpoint.metadata_current-default-0.16.0-dev.0', + path: '/_transform/endpoint.metadata_current-default-0.16.0-dev.0', query: 'defer_validation=true', body: '{"content": "data"}', }, @@ -303,7 +338,7 @@ describe('test transform install', () => { 'transport.request', { method: 'POST', - path: '/_transform/metrics-endpoint.metadata_current-default-0.16.0-dev.0/_start', + path: '/_transform/endpoint.metadata_current-default-0.16.0-dev.0/_start', }, ], ]); @@ -313,7 +348,7 @@ describe('test transform install', () => { 'endpoint', { installed_es: [ - { id: 'metrics-endpoint.metadata_current-default-0.16.0-dev.0', type: 'transform' }, + { id: 'endpoint.metadata_current-default-0.16.0-dev.0', type: 'transform' }, ], }, ], @@ -324,7 +359,7 @@ describe('test transform install', () => { const previousInstallation: Installation = ({ installed_es: [ { - id: 'metrics-endpoint.metadata-current-default-0.15.0-dev.0', + id: 'endpoint.metadata-current-default-0.15.0-dev.0', type: ElasticsearchAssetType.transform, }, ], @@ -346,14 +381,33 @@ describe('test transform install', () => { } as unknown) as SavedObject) ); - await installTransformForDataset( + legacyScopedClusterClient.callAsCurrentUser.mockReturnValueOnce( + Promise.resolve({ + count: 1, + transforms: [ + { + dest: { + index: 'index', + }, + }, + ], + } as { + count: number; + transforms: Array<{ + dest: { + index: string; + }; + }>; + }) + ); + await installTransform( ({ name: 'endpoint', version: '0.16.0-dev.0', - datasets: [ + data_streams: [ { type: 'metrics', - name: 'endpoint.metadata', + dataset: 'endpoint.metadata', title: 'Endpoint Metadata', release: 'experimental', package: 'endpoint', @@ -367,7 +421,7 @@ describe('test transform install', () => { }, { type: 'metrics', - name: 'endpoint.metadata_current', + dataset: 'endpoint.metadata_current', title: 'Endpoint Metadata Current', release: 'experimental', package: 'endpoint', @@ -387,11 +441,18 @@ describe('test transform install', () => { ); expect(legacyScopedClusterClient.callAsCurrentUser.mock.calls).toEqual([ + [ + 'transport.request', + { + method: 'GET', + path: '/_transform/endpoint.metadata-current-default-0.15.0-dev.0', + }, + ], [ 'transport.request', { method: 'POST', - path: '/_transform/metrics-endpoint.metadata-current-default-0.15.0-dev.0/_stop', + path: '/_transform/endpoint.metadata-current-default-0.15.0-dev.0/_stop', query: 'force=true', ignore: [404], }, @@ -401,7 +462,15 @@ describe('test transform install', () => { { method: 'DELETE', query: 'force=true', - path: '/_transform/metrics-endpoint.metadata-current-default-0.15.0-dev.0', + path: '/_transform/endpoint.metadata-current-default-0.15.0-dev.0', + ignore: [404], + }, + ], + [ + 'transport.request', + { + method: 'DELETE', + path: '/index', ignore: [404], }, ], diff --git a/x-pack/plugins/ingest_manager/server/services/epm/fields/field.ts b/x-pack/plugins/ingest_manager/server/services/epm/fields/field.ts index a44e5e4221f9f..5913302e77ba6 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/fields/field.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/fields/field.ts @@ -20,6 +20,7 @@ export interface Field { index?: boolean; required?: boolean; multi_fields?: Fields; + normalizer?: string; doc_values?: boolean; copy_to?: string; analyzer?: string; diff --git a/x-pack/plugins/ingest_manager/server/services/epm/kibana/index_pattern/install.ts b/x-pack/plugins/ingest_manager/server/services/epm/kibana/index_pattern/install.ts index 7fe3713e186ee..bde542412f123 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/kibana/index_pattern/install.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/kibana/index_pattern/install.ts @@ -122,8 +122,8 @@ export async function installIndexPatterns( return; } - // get all dataset fields from all installed packages - const fields = await getAllDatasetFieldsByType(installedPackagesInfo, indexPatternType); + // get all data stream fields from all installed packages + const fields = await getAllDataStreamFieldsByType(installedPackagesInfo, indexPatternType); const kibanaIndexPattern = createIndexPattern(indexPatternType, fields); // create or overwrite the index pattern @@ -135,23 +135,27 @@ export async function installIndexPatterns( } // loops through all given packages and returns an array -// of all fields from all datasets matching datasetType -export const getAllDatasetFieldsByType = async ( +// of all fields from all data streams matching data stream type +export const getAllDataStreamFieldsByType = async ( packages: RegistryPackage[], - datasetType: IndexPatternType + dataStreamType: IndexPatternType ): Promise => { - const datasetsPromises = packages.reduce>>((acc, pkg) => { - if (pkg.datasets) { - // filter out datasets by datasetType - const matchingDatasets = pkg.datasets.filter((dataset) => dataset.type === datasetType); - matchingDatasets.forEach((dataset) => acc.push(loadFieldsFromYaml(pkg, dataset.path))); + const dataStreamsPromises = packages.reduce>>((acc, pkg) => { + if (pkg.data_streams) { + // filter out data streams by data stream type + const matchingDataStreams = pkg.data_streams.filter( + (dataStream) => dataStream.type === dataStreamType + ); + matchingDataStreams.forEach((dataStream) => + acc.push(loadFieldsFromYaml(pkg, dataStream.path)) + ); } return acc; }, []); - // get all the datasets for each installed package into one array - const allDatasetFields: Fields[] = await Promise.all(datasetsPromises); - return allDatasetFields.flat(); + // get all the data stream fields for each installed package into one array + const allDataStreamFields: Fields[] = await Promise.all(dataStreamsPromises); + return allDataStreamFields.flat(); }; // creates or updates index pattern diff --git a/x-pack/plugins/ingest_manager/server/services/epm/packages/assets.test.ts b/x-pack/plugins/ingest_manager/server/services/epm/packages/assets.test.ts index 6d5ca036aeb13..78b42b03be831 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/packages/assets.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/packages/assets.test.ts @@ -11,8 +11,8 @@ const tests = [ { package: { assets: [ - '/package/coredns/1.0.1/dataset/log/elasticsearch/ingest-pipeline/pipeline-plaintext.json', - '/package/coredns/1.0.1/dataset/log/elasticsearch/ingest-pipeline/pipeline-json.json', + '/package/coredns/1.0.1/data_stream/log/elasticsearch/ingest-pipeline/pipeline-plaintext.json', + '/package/coredns/1.0.1/data_stream/log/elasticsearch/ingest-pipeline/pipeline-json.json', ], path: '/package/coredns/1.0.1', }, @@ -21,15 +21,15 @@ const tests = [ return true; }, expected: [ - '/package/coredns/1.0.1/dataset/log/elasticsearch/ingest-pipeline/pipeline-plaintext.json', - '/package/coredns/1.0.1/dataset/log/elasticsearch/ingest-pipeline/pipeline-json.json', + '/package/coredns/1.0.1/data_stream/log/elasticsearch/ingest-pipeline/pipeline-plaintext.json', + '/package/coredns/1.0.1/data_stream/log/elasticsearch/ingest-pipeline/pipeline-json.json', ], }, { package: { assets: [ - '/package/coredns-1.0.1/dataset/log/elasticsearch/ingest-pipeline/pipeline-plaintext.json', - '/package/coredns-1.0.1/dataset/log/elasticsearch/ingest-pipeline/pipeline-json.json', + '/package/coredns-1.0.1/data_stream/log/elasticsearch/ingest-pipeline/pipeline-plaintext.json', + '/package/coredns-1.0.1/data_stream/log/elasticsearch/ingest-pipeline/pipeline-json.json', ], path: '/package/coredns/1.0.1', }, @@ -43,8 +43,8 @@ const tests = [ { package: { assets: [ - '/package/coredns-1.0.1/dataset/log/elasticsearch/ingest-pipeline/pipeline-plaintext.json', - '/package/coredns-1.0.1/dataset/log/elasticsearch/ingest-pipeline/pipeline-json.json', + '/package/coredns-1.0.1/data_stream/log/elasticsearch/ingest-pipeline/pipeline-plaintext.json', + '/package/coredns-1.0.1/data_stream/log/elasticsearch/ingest-pipeline/pipeline-json.json', ], }, // Filter which does not exist diff --git a/x-pack/plugins/ingest_manager/server/services/epm/packages/assets.ts b/x-pack/plugins/ingest_manager/server/services/epm/packages/assets.ts index 19a023eb2ad4c..a8abc12917781 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/packages/assets.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/packages/assets.ts @@ -9,9 +9,9 @@ import * as Registry from '../registry'; import { ensureCachedArchiveInfo } from '../registry'; // paths from RegistryPackage are routes to the assets on EPR -// e.g. `/package/nginx/1.2.0/dataset/access/fields/fields.yml` +// e.g. `/package/nginx/1.2.0/data_stream/access/fields/fields.yml` // paths for ArchiveEntry are routes to the assets in the archive -// e.g. `nginx-1.2.0/dataset/access/fields/fields.yml` +// e.g. `nginx-1.2.0/data_stream/access/fields/fields.yml` // RegistryPackage paths have a `/package/` prefix compared to ArchiveEntry paths // and different package and version structure const EPR_PATH_PREFIX = '/package'; @@ -37,7 +37,7 @@ export function getAssets( // if dataset, filter for them if (datasetName) { - const comparePath = `${packageInfo.path}/dataset/${datasetName}/`; + const comparePath = `${packageInfo.path}/data_stream/${datasetName}/`; if (!path.includes(comparePath)) { continue; } diff --git a/x-pack/plugins/ingest_manager/server/services/epm/packages/bulk_install_packages.ts b/x-pack/plugins/ingest_manager/server/services/epm/packages/bulk_install_packages.ts new file mode 100644 index 0000000000000..af937c5593082 --- /dev/null +++ b/x-pack/plugins/ingest_manager/server/services/epm/packages/bulk_install_packages.ts @@ -0,0 +1,61 @@ +/* + * 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 { SavedObjectsClientContract } from 'src/core/server'; +import { CallESAsCurrentUser } from '../../../types'; +import * as Registry from '../registry'; +import { getInstallationObject } from './index'; +import { BulkInstallResponse, IBulkInstallPackageError, upgradePackage } from './install'; + +interface BulkInstallPackagesParams { + savedObjectsClient: SavedObjectsClientContract; + packagesToUpgrade: string[]; + callCluster: CallESAsCurrentUser; +} + +export async function bulkInstallPackages({ + savedObjectsClient, + packagesToUpgrade, + callCluster, +}: BulkInstallPackagesParams): Promise { + const installedAndLatestPromises = packagesToUpgrade.map((pkgToUpgrade) => + Promise.all([ + getInstallationObject({ savedObjectsClient, pkgName: pkgToUpgrade }), + Registry.fetchFindLatestPackage(pkgToUpgrade), + ]) + ); + const installedAndLatestResults = await Promise.allSettled(installedAndLatestPromises); + const installResponsePromises = installedAndLatestResults.map(async (result, index) => { + const pkgToUpgrade = packagesToUpgrade[index]; + if (result.status === 'fulfilled') { + const [installedPkg, latestPkg] = result.value; + return upgradePackage({ + savedObjectsClient, + callCluster, + installedPkg, + latestPkg, + pkgToUpgrade, + }); + } else { + return { name: pkgToUpgrade, error: result.reason }; + } + }); + const installResults = await Promise.allSettled(installResponsePromises); + const installResponses = installResults.map((result, index) => { + const pkgToUpgrade = packagesToUpgrade[index]; + if (result.status === 'fulfilled') { + return result.value; + } else { + return { name: pkgToUpgrade, error: result.reason }; + } + }); + + return installResponses; +} + +export function isBulkInstallError(test: any): test is IBulkInstallPackageError { + return 'error' in test && test.error instanceof Error; +} diff --git a/x-pack/plugins/ingest_manager/server/services/epm/packages/ensure_installed_default_packages.test.ts b/x-pack/plugins/ingest_manager/server/services/epm/packages/ensure_installed_default_packages.test.ts new file mode 100644 index 0000000000000..f0b487ad59774 --- /dev/null +++ b/x-pack/plugins/ingest_manager/server/services/epm/packages/ensure_installed_default_packages.test.ts @@ -0,0 +1,144 @@ +/* + * 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 { ElasticsearchAssetType, Installation, KibanaAssetType } from '../../../types'; +import { SavedObject, SavedObjectsClientContract } from 'src/core/server'; + +jest.mock('./install'); +jest.mock('./bulk_install_packages'); +jest.mock('./get'); + +import { bulkInstallPackages, isBulkInstallError } from './bulk_install_packages'; +const { ensureInstalledDefaultPackages } = jest.requireActual('./install'); +const { isBulkInstallError: actualIsBulkInstallError } = jest.requireActual( + './bulk_install_packages' +); +import { getInstallation } from './get'; +import { savedObjectsClientMock } from 'src/core/server/mocks'; +import { appContextService } from '../../app_context'; +import { createAppContextStartContractMock } from '../../../mocks'; + +// if we add this assertion, TS will type check the return value +// and the editor will also know about .mockImplementation, .mock.calls, etc +const mockedBulkInstallPackages = bulkInstallPackages as jest.MockedFunction< + typeof bulkInstallPackages +>; +const mockedIsBulkInstallError = isBulkInstallError as jest.MockedFunction< + typeof isBulkInstallError +>; +const mockedGetInstallation = getInstallation as jest.MockedFunction; + +// I was unable to get the actual implementation set in the `jest.mock()` call at the top to work +// so this will set the `isBulkInstallError` function back to the actual implementation +mockedIsBulkInstallError.mockImplementation(actualIsBulkInstallError); + +const mockInstallation: SavedObject = { + id: 'test-pkg', + references: [], + type: 'epm-packages', + attributes: { + id: 'test-pkg', + installed_kibana: [{ type: KibanaAssetType.dashboard, id: 'dashboard-1' }], + installed_es: [{ type: ElasticsearchAssetType.ingestPipeline, id: 'pipeline' }], + es_index_patterns: { pattern: 'pattern-name' }, + name: 'test package', + version: '1.0.0', + install_status: 'installed', + install_version: '1.0.0', + install_started_at: new Date().toISOString(), + }, +}; + +describe('ensureInstalledDefaultPackages', () => { + let soClient: jest.Mocked; + beforeEach(async () => { + soClient = savedObjectsClientMock.create(); + appContextService.start(createAppContextStartContractMock()); + }); + afterEach(async () => { + appContextService.stop(); + }); + it('should return an array of Installation objects when successful', async () => { + mockedGetInstallation.mockImplementation(async () => { + return mockInstallation.attributes; + }); + mockedBulkInstallPackages.mockImplementationOnce(async function () { + return [ + { + name: mockInstallation.attributes.name, + assets: [], + newVersion: '', + oldVersion: '', + statusCode: 200, + }, + ]; + }); + const resp = await ensureInstalledDefaultPackages(soClient, jest.fn()); + expect(resp).toEqual([mockInstallation.attributes]); + }); + it('should throw the first Error it finds', async () => { + class SomeCustomError extends Error {} + mockedGetInstallation.mockImplementation(async () => { + return mockInstallation.attributes; + }); + mockedBulkInstallPackages.mockImplementationOnce(async function () { + return [ + { + name: 'success one', + assets: [], + newVersion: '', + oldVersion: '', + statusCode: 200, + }, + { + name: 'success two', + assets: [], + newVersion: '', + oldVersion: '', + statusCode: 200, + }, + { + name: 'failure one', + error: new SomeCustomError('abc 123'), + }, + { + name: 'success three', + assets: [], + newVersion: '', + oldVersion: '', + statusCode: 200, + }, + { + name: 'failure two', + error: new Error('zzz'), + }, + ]; + }); + const installPromise = ensureInstalledDefaultPackages(soClient, jest.fn()); + expect.assertions(2); + expect(installPromise).rejects.toThrow(SomeCustomError); + expect(installPromise).rejects.toThrow('abc 123'); + }); + it('should throw an error when get installation returns undefined', async () => { + mockedGetInstallation.mockImplementation(async () => { + return undefined; + }); + mockedBulkInstallPackages.mockImplementationOnce(async function () { + return [ + { + name: 'undefined package', + assets: [], + newVersion: '', + oldVersion: '', + statusCode: 200, + }, + ]; + }); + const installPromise = ensureInstalledDefaultPackages(soClient, jest.fn()); + expect.assertions(1); + expect(installPromise).rejects.toThrow(); + }); +}); diff --git a/x-pack/plugins/ingest_manager/server/services/epm/packages/get.ts b/x-pack/plugins/ingest_manager/server/services/epm/packages/get.ts index c4232247cc4bd..2d11b6157804f 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/packages/get.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/packages/get.ts @@ -51,14 +51,14 @@ export async function getPackages( } // Get package names for packages which cannot have more than one package policy on an agent policy -// Assume packages only export one config template for now +// Assume packages only export one policy template for now export async function getLimitedPackages(options: { savedObjectsClient: SavedObjectsClientContract; }): Promise { const { savedObjectsClient } = options; const allPackages = await getPackages({ savedObjectsClient, experimental: true }); const installedPackages = allPackages.filter( - (pkg) => (pkg.status = InstallationStatus.installed) + (pkg) => pkg.status === InstallationStatus.installed ); const installedPackagesInfo = await Promise.all( installedPackages.map((pkgInstall) => { diff --git a/x-pack/plugins/ingest_manager/server/services/epm/packages/get_install_type.test.ts b/x-pack/plugins/ingest_manager/server/services/epm/packages/get_install_type.test.ts new file mode 100644 index 0000000000000..cce4b7fee8fd7 --- /dev/null +++ b/x-pack/plugins/ingest_manager/server/services/epm/packages/get_install_type.test.ts @@ -0,0 +1,101 @@ +/* + * 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 { SavedObject } from 'src/core/server'; +import { ElasticsearchAssetType, Installation, KibanaAssetType } from '../../../types'; +import { getInstallType } from './install'; + +const mockInstallation: SavedObject = { + id: 'test-pkg', + references: [], + type: 'epm-packages', + attributes: { + id: 'test-pkg', + installed_kibana: [{ type: KibanaAssetType.dashboard, id: 'dashboard-1' }], + installed_es: [{ type: ElasticsearchAssetType.ingestPipeline, id: 'pipeline' }], + es_index_patterns: { pattern: 'pattern-name' }, + name: 'test packagek', + version: '1.0.0', + install_status: 'installed', + install_version: '1.0.0', + install_started_at: new Date().toISOString(), + }, +}; +const mockInstallationUpdateFail: SavedObject = { + id: 'test-pkg', + references: [], + type: 'epm-packages', + attributes: { + id: 'test-pkg', + installed_kibana: [{ type: KibanaAssetType.dashboard, id: 'dashboard-1' }], + installed_es: [{ type: ElasticsearchAssetType.ingestPipeline, id: 'pipeline' }], + es_index_patterns: { pattern: 'pattern-name' }, + name: 'test packagek', + version: '1.0.0', + install_status: 'installing', + install_version: '1.0.1', + install_started_at: new Date().toISOString(), + }, +}; + +describe('getInstallType', () => { + it('should return correct type when installing and no other version is currently installed', () => { + const installTypeInstall = getInstallType({ pkgVersion: '1.0.0', installedPkg: undefined }); + expect(installTypeInstall).toBe('install'); + + // @ts-expect-error can only be 'install' if no installedPkg given + expect(installTypeInstall === 'update').toBe(false); + // @ts-expect-error can only be 'install' if no installedPkg given + expect(installTypeInstall === 'reinstall').toBe(false); + // @ts-expect-error can only be 'install' if no installedPkg given + expect(installTypeInstall === 'reupdate').toBe(false); + // @ts-expect-error can only be 'install' if no installedPkg given + expect(installTypeInstall === 'rollback').toBe(false); + }); + + it('should return correct type when installing the same version', () => { + const installTypeReinstall = getInstallType({ + pkgVersion: '1.0.0', + installedPkg: mockInstallation, + }); + expect(installTypeReinstall).toBe('reinstall'); + + // @ts-expect-error cannot be 'install' if given installedPkg + expect(installTypeReinstall === 'install').toBe(false); + }); + + it('should return correct type when moving from one version to another', () => { + const installTypeUpdate = getInstallType({ + pkgVersion: '1.0.1', + installedPkg: mockInstallation, + }); + expect(installTypeUpdate).toBe('update'); + + // @ts-expect-error cannot be 'install' if given installedPkg + expect(installTypeUpdate === 'install').toBe(false); + }); + + it('should return correct type when update fails and trys again', () => { + const installTypeReupdate = getInstallType({ + pkgVersion: '1.0.1', + installedPkg: mockInstallationUpdateFail, + }); + expect(installTypeReupdate).toBe('reupdate'); + + // @ts-expect-error cannot be 'install' if given installedPkg + expect(installTypeReupdate === 'install').toBe(false); + }); + + it('should return correct type when attempting to rollback from a failed update', () => { + const installTypeRollback = getInstallType({ + pkgVersion: '1.0.0', + installedPkg: mockInstallationUpdateFail, + }); + expect(installTypeRollback).toBe('rollback'); + + // @ts-expect-error cannot be 'install' if given installedPkg + expect(installTypeRollback === 'install').toBe(false); + }); +}); diff --git a/x-pack/plugins/ingest_manager/server/services/epm/packages/index.ts b/x-pack/plugins/ingest_manager/server/services/epm/packages/index.ts index 57c4f77432455..94aa969c2d2b8 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/packages/index.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/packages/index.ts @@ -12,6 +12,8 @@ import { InstallationStatus, KibanaAssetType, } from '../../../types'; + +export { bulkInstallPackages, isBulkInstallError } from './bulk_install_packages'; export { getCategories, getFile, @@ -23,7 +25,13 @@ export { SearchParams, } from './get'; -export { installPackage, ensureInstalledPackage } from './install'; +export { + BulkInstallResponse, + handleInstallPackageFailure, + installPackage, + IBulkInstallPackageError, + ensureInstalledPackage, +} from './install'; export { removeInstallation } from './remove'; type RequiredPackage = 'system' | 'endpoint'; diff --git a/x-pack/plugins/ingest_manager/server/services/epm/packages/install.test.ts b/x-pack/plugins/ingest_manager/server/services/epm/packages/install.test.ts deleted file mode 100644 index 2f60c74d3514f..0000000000000 --- a/x-pack/plugins/ingest_manager/server/services/epm/packages/install.test.ts +++ /dev/null @@ -1,103 +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 { ElasticsearchAssetType, Installation, KibanaAssetType } from '../../../types'; -import { SavedObject } from 'src/core/server'; -import { getInstallType } from './install'; - -const mockInstallation: SavedObject = { - id: 'test-pkg', - references: [], - type: 'epm-packages', - attributes: { - id: 'test-pkg', - installed_kibana: [{ type: KibanaAssetType.dashboard, id: 'dashboard-1' }], - installed_es: [{ type: ElasticsearchAssetType.ingestPipeline, id: 'pipeline' }], - es_index_patterns: { pattern: 'pattern-name' }, - name: 'test packagek', - version: '1.0.0', - install_status: 'installed', - install_version: '1.0.0', - install_started_at: new Date().toISOString(), - }, -}; -const mockInstallationUpdateFail: SavedObject = { - id: 'test-pkg', - references: [], - type: 'epm-packages', - attributes: { - id: 'test-pkg', - installed_kibana: [{ type: KibanaAssetType.dashboard, id: 'dashboard-1' }], - installed_es: [{ type: ElasticsearchAssetType.ingestPipeline, id: 'pipeline' }], - es_index_patterns: { pattern: 'pattern-name' }, - name: 'test packagek', - version: '1.0.0', - install_status: 'installing', - install_version: '1.0.1', - install_started_at: new Date().toISOString(), - }, -}; -describe('install', () => { - describe('getInstallType', () => { - it('should return correct type when installing and no other version is currently installed', () => { - const installTypeInstall = getInstallType({ pkgVersion: '1.0.0', installedPkg: undefined }); - expect(installTypeInstall).toBe('install'); - - // @ts-expect-error can only be 'install' if no installedPkg given - expect(installTypeInstall === 'update').toBe(false); - // @ts-expect-error can only be 'install' if no installedPkg given - expect(installTypeInstall === 'reinstall').toBe(false); - // @ts-expect-error can only be 'install' if no installedPkg given - expect(installTypeInstall === 'reupdate').toBe(false); - // @ts-expect-error can only be 'install' if no installedPkg given - expect(installTypeInstall === 'rollback').toBe(false); - }); - - it('should return correct type when installing the same version', () => { - const installTypeReinstall = getInstallType({ - pkgVersion: '1.0.0', - installedPkg: mockInstallation, - }); - expect(installTypeReinstall).toBe('reinstall'); - - // @ts-expect-error cannot be 'install' if given installedPkg - expect(installTypeReinstall === 'install').toBe(false); - }); - - it('should return correct type when moving from one version to another', () => { - const installTypeUpdate = getInstallType({ - pkgVersion: '1.0.1', - installedPkg: mockInstallation, - }); - expect(installTypeUpdate).toBe('update'); - - // @ts-expect-error cannot be 'install' if given installedPkg - expect(installTypeUpdate === 'install').toBe(false); - }); - - it('should return correct type when update fails and trys again', () => { - const installTypeReupdate = getInstallType({ - pkgVersion: '1.0.1', - installedPkg: mockInstallationUpdateFail, - }); - expect(installTypeReupdate).toBe('reupdate'); - - // @ts-expect-error cannot be 'install' if given installedPkg - expect(installTypeReupdate === 'install').toBe(false); - }); - - it('should return correct type when attempting to rollback from a failed update', () => { - const installTypeRollback = getInstallType({ - pkgVersion: '1.0.0', - installedPkg: mockInstallationUpdateFail, - }); - expect(installTypeRollback).toBe('rollback'); - - // @ts-expect-error cannot be 'install' if given installedPkg - expect(installTypeRollback === 'install').toBe(false); - }); - }); -}); diff --git a/x-pack/plugins/ingest_manager/server/services/epm/packages/install.ts b/x-pack/plugins/ingest_manager/server/services/epm/packages/install.ts index 800151a41a429..d7262ebb66b2e 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/packages/install.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/packages/install.ts @@ -8,7 +8,7 @@ import { SavedObject, SavedObjectsClientContract } from 'src/core/server'; import semver from 'semver'; import Boom from 'boom'; import { UnwrapPromise } from '@kbn/utility-types'; -import { BulkInstallPackageInfo, IBulkInstallPackageError } from '../../../../common'; +import { BulkInstallPackageInfo } from '../../../../common'; import { PACKAGES_SAVED_OBJECT_TYPE, MAX_TIME_COMPLETE_INSTALL } from '../../../constants'; import { AssetReference, @@ -23,7 +23,13 @@ import { } from '../../../types'; import { installIndexPatterns } from '../kibana/index_pattern/install'; import * as Registry from '../registry'; -import { getInstallation, getInstallationObject, isRequiredPackage } from './index'; +import { + getInstallation, + getInstallationObject, + isRequiredPackage, + bulkInstallPackages, + isBulkInstallError, +} from './index'; import { installTemplates } from '../elasticsearch/template/install'; import { generateESIndexPatterns } from '../elasticsearch/template/template'; import { installPipelines, deletePreviousPipelines } from '../elasticsearch/ingest_pipeline/'; @@ -36,13 +42,9 @@ import { } from '../kibana/assets/install'; import { updateCurrentWriteIndices } from '../elasticsearch/template/template'; import { deleteKibanaSavedObjectsAssets, removeInstallation } from './remove'; -import { - IngestManagerError, - PackageOutdatedError, - ingestErrorToResponseOptions, -} from '../../../errors'; +import { IngestManagerError, PackageOutdatedError } from '../../../errors'; import { getPackageSavedObjects } from './get'; -import { installTransformForDataset } from '../elasticsearch/transform/install'; +import { installTransform } from '../elasticsearch/transform/install'; import { appContextService } from '../../app_context'; export async function installLatestPackage(options: { @@ -68,17 +70,27 @@ export async function ensureInstalledDefaultPackages( callCluster: CallESAsCurrentUser ): Promise { const installations = []; - for (const pkgName in DefaultPackages) { - if (!DefaultPackages.hasOwnProperty(pkgName)) continue; - const installation = ensureInstalledPackage({ - savedObjectsClient, - pkgName, - callCluster, - }); - installations.push(installation); + const bulkResponse = await bulkInstallPackages({ + savedObjectsClient, + packagesToUpgrade: Object.values(DefaultPackages), + callCluster, + }); + + for (const resp of bulkResponse) { + if (isBulkInstallError(resp)) { + throw resp.error; + } else { + installations.push(getInstallation({ savedObjectsClient, pkgName: resp.name })); + } } - return Promise.all(installations); + const retrievedInstallations = await Promise.all(installations); + return retrievedInstallations.map((installation, index) => { + if (!installation) { + throw new Error(`could not get installation ${bulkResponse[index].name}`); + } + return installation; + }); } export async function ensureInstalledPackage(options: { @@ -154,21 +166,11 @@ export async function handleInstallPackageFailure({ } } -type BulkInstallResponse = BulkInstallPackageInfo | IBulkInstallPackageError; -function bulkInstallErrorToOptions({ - pkgToUpgrade, - error, -}: { - pkgToUpgrade: string; +export interface IBulkInstallPackageError { + name: string; error: Error; -}): IBulkInstallPackageError { - const { statusCode, body } = ingestErrorToResponseOptions(error); - return { - name: pkgToUpgrade, - statusCode, - error: body.message, - }; } +export type BulkInstallResponse = BulkInstallPackageInfo | IBulkInstallPackageError; interface UpgradePackageParams { savedObjectsClient: SavedObjectsClientContract; @@ -177,7 +179,7 @@ interface UpgradePackageParams { latestPkg: UnwrapPromise>; pkgToUpgrade: string; } -async function upgradePackage({ +export async function upgradePackage({ savedObjectsClient, callCluster, installedPkg, @@ -207,7 +209,7 @@ async function upgradePackage({ installedPkg, callCluster, }); - return bulkInstallErrorToOptions({ pkgToUpgrade, error: installFailed }); + return { name: pkgToUpgrade, error: installFailed }; } } else { // package was already at the latest version @@ -223,51 +225,6 @@ async function upgradePackage({ } } -interface BulkInstallPackagesParams { - savedObjectsClient: SavedObjectsClientContract; - packagesToUpgrade: string[]; - callCluster: CallESAsCurrentUser; -} -export async function bulkInstallPackages({ - savedObjectsClient, - packagesToUpgrade, - callCluster, -}: BulkInstallPackagesParams): Promise { - const installedAndLatestPromises = packagesToUpgrade.map((pkgToUpgrade) => - Promise.all([ - getInstallationObject({ savedObjectsClient, pkgName: pkgToUpgrade }), - Registry.fetchFindLatestPackage(pkgToUpgrade), - ]) - ); - const installedAndLatestResults = await Promise.allSettled(installedAndLatestPromises); - const installResponsePromises = installedAndLatestResults.map(async (result, index) => { - const pkgToUpgrade = packagesToUpgrade[index]; - if (result.status === 'fulfilled') { - const [installedPkg, latestPkg] = result.value; - return upgradePackage({ - savedObjectsClient, - callCluster, - installedPkg, - latestPkg, - pkgToUpgrade, - }); - } else { - return bulkInstallErrorToOptions({ pkgToUpgrade, error: result.reason }); - } - }); - const installResults = await Promise.allSettled(installResponsePromises); - const installResponses = installResults.map((result, index) => { - const pkgToUpgrade = packagesToUpgrade[index]; - if (result.status === 'fulfilled') { - return result.value; - } else { - return bulkInstallErrorToOptions({ pkgToUpgrade, error: result.reason }); - } - }); - - return installResponses; -} - interface InstallPackageParams { savedObjectsClient: SavedObjectsClientContract; pkgkey: string; @@ -302,7 +259,7 @@ export async function installPackage({ const removable = !isRequiredPackage(pkgName); const { internal = false } = registryPackageInfo; - const toSaveESIndexPatterns = generateESIndexPatterns(registryPackageInfo.datasets); + const toSaveESIndexPatterns = generateESIndexPatterns(registryPackageInfo.data_streams); // add the package installation to the saved object. // if some installation already exists, just update install info @@ -347,7 +304,7 @@ export async function installPackage({ // currently only the base package has an ILM policy // at some point ILM policies can be installed/modified - // per dataset and we should then save them + // per data stream and we should then save them await installILMPolicy(paths, callCluster); // installs versionized pipelines without removing currently installed ones @@ -368,7 +325,7 @@ export async function installPackage({ // update current backing indices of each data stream await updateCurrentWriteIndices(callCluster, installedTemplates); - const installedTransforms = await installTransformForDataset( + const installedTransforms = await installTransform( registryPackageInfo, paths, callCluster, diff --git a/x-pack/plugins/ingest_manager/server/services/epm/registry/index.test.ts b/x-pack/plugins/ingest_manager/server/services/epm/registry/index.test.ts index b40638eefbae2..2fd9175549026 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/registry/index.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/registry/index.test.ts @@ -41,11 +41,11 @@ const testPaths = [ }, }, { - path: 'coredns-1.0.1/dataset/stats/fields/coredns.stats.yml', + path: 'coredns-1.0.1/data_stream/stats/fields/coredns.stats.yml', assetParts: { dataset: 'stats', file: 'coredns.stats.yml', - path: 'coredns-1.0.1/dataset/stats/fields/coredns.stats.yml', + path: 'coredns-1.0.1/data_stream/stats/fields/coredns.stats.yml', pkgkey: 'coredns-1.0.1', service: '', type: 'fields', diff --git a/x-pack/plugins/ingest_manager/server/services/epm/registry/index.ts b/x-pack/plugins/ingest_manager/server/services/epm/registry/index.ts index 96f7530641390..22f1b670b2cc4 100644 --- a/x-pack/plugins/ingest_manager/server/services/epm/registry/index.ts +++ b/x-pack/plugins/ingest_manager/server/services/epm/registry/index.ts @@ -158,12 +158,12 @@ export function pathParts(path: string): AssetParts { let [pkgkey, service, type, file] = path.split('/'); - // if it's a dataset - if (service === 'dataset') { + // if it's a data stream + if (service === 'data_stream') { // save the dataset name dataset = type; - // drop the `dataset/dataset-name` portion & re-parse - [pkgkey, service, type, file] = path.replace(`dataset/${dataset}/`, '').split('/'); + // drop the `data_stream/dataset-name` portion & re-parse + [pkgkey, service, type, file] = path.replace(`data_stream/${dataset}/`, '').split('/'); } // This is to cover for the fields.yml files inside the "fields" directory diff --git a/x-pack/plugins/ingest_manager/server/services/package_policy.test.ts b/x-pack/plugins/ingest_manager/server/services/package_policy.test.ts index 0d89c52957632..6064e5bae0634 100644 --- a/x-pack/plugins/ingest_manager/server/services/package_policy.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/package_policy.test.ts @@ -45,14 +45,14 @@ describe('Package policy service', () => { it('should work with config variables from the stream', async () => { const inputs = await packagePolicyService.assignPackageStream( ({ - datasets: [ + data_streams: [ { type: 'logs', - name: 'package.dataset1', + dataset: 'package.dataset1', streams: [{ input: 'log', template_path: 'some_template_path.yml' }], }, ], - config_templates: [ + policy_templates: [ { inputs: [{ type: 'log' }], }, @@ -64,7 +64,7 @@ describe('Package policy service', () => { enabled: true, streams: [ { - id: 'dataset01', + id: 'datastream01', data_stream: { dataset: 'package.dataset1', type: 'logs' }, enabled: true, vars: { @@ -84,7 +84,7 @@ describe('Package policy service', () => { enabled: true, streams: [ { - id: 'dataset01', + id: 'datastream01', data_stream: { dataset: 'package.dataset1', type: 'logs' }, enabled: true, vars: { @@ -106,14 +106,14 @@ describe('Package policy service', () => { it('should work with config variables at the input level', async () => { const inputs = await packagePolicyService.assignPackageStream( ({ - datasets: [ + data_streams: [ { - name: 'package.dataset1', + dataset: 'package.dataset1', type: 'logs', streams: [{ input: 'log', template_path: 'some_template_path.yml' }], }, ], - config_templates: [ + policy_templates: [ { inputs: [{ type: 'log' }], }, @@ -130,7 +130,7 @@ describe('Package policy service', () => { }, streams: [ { - id: 'dataset01', + id: 'datastream01', data_stream: { dataset: 'package.dataset1', type: 'logs' }, enabled: true, }, @@ -150,7 +150,7 @@ describe('Package policy service', () => { }, streams: [ { - id: 'dataset01', + id: 'datastream01', data_stream: { dataset: 'package.dataset1', type: 'logs' }, enabled: true, compiled_stream: { diff --git a/x-pack/plugins/ingest_manager/server/services/package_policy.ts b/x-pack/plugins/ingest_manager/server/services/package_policy.ts index 3a02544250ff0..d91f6e8580fc3 100644 --- a/x-pack/plugins/ingest_manager/server/services/package_policy.ts +++ b/x-pack/plugins/ingest_manager/server/services/package_policy.ts @@ -375,19 +375,19 @@ async function _assignPackageStreamToStream( return { ...stream, compiled_stream: undefined }; } const datasetPath = getDataset(stream.data_stream.dataset); - const packageDatasets = pkgInfo.datasets; - if (!packageDatasets) { - throw new Error('Stream template not found, no datasets'); + const packageDataStreams = pkgInfo.data_streams; + if (!packageDataStreams) { + throw new Error('Stream template not found, no data streams'); } - const packageDataset = packageDatasets.find( - (pkgDataset) => pkgDataset.name === stream.data_stream.dataset + const packageDataStream = packageDataStreams.find( + (pkgDataStream) => pkgDataStream.dataset === stream.data_stream.dataset ); - if (!packageDataset) { + if (!packageDataStream) { throw new Error(`Stream template not found, unable to find dataset ${datasetPath}`); } - const streamFromPkg = (packageDataset.streams || []).find( + const streamFromPkg = (packageDataStream.streams || []).find( (pkgStream) => pkgStream.input === input.type ); if (!streamFromPkg) { diff --git a/x-pack/plugins/ingest_manager/server/services/saved_object.ts b/x-pack/plugins/ingest_manager/server/services/saved_object.ts index 06772206d5198..77c0e446d5c23 100644 --- a/x-pack/plugins/ingest_manager/server/services/saved_object.ts +++ b/x-pack/plugins/ingest_manager/server/services/saved_object.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { SavedObjectsClientContract, SavedObjectsFindResponse } from 'src/core/server'; +import { SO_SEARCH_LIMIT } from '../constants'; import { ListWithKuery } from '../types'; /** @@ -40,19 +41,13 @@ export const findAllSOs = async ( const { type, sortField, sortOrder, kuery } = options; let savedObjectResults: SavedObjectsFindResponse['saved_objects'] = []; - // TODO: This is the default `index.max_result_window` ES setting, which dictates - // the maximum amount of results allowed to be returned from a search. It's possible - // for the actual setting to differ from the default. Can we retrieve the real - // setting in the future? - const searchLimit = 10000; - const query = { type, sortField, sortOrder, filter: kuery, page: 1, - perPage: searchLimit, + perPage: SO_SEARCH_LIMIT, }; const { saved_objects: initialSOs, total } = await soClient.find(query); diff --git a/x-pack/plugins/ingest_manager/server/services/setup.ts b/x-pack/plugins/ingest_manager/server/services/setup.ts index f02057bae1598..c7ecf843d6a51 100644 --- a/x-pack/plugins/ingest_manager/server/services/setup.ts +++ b/x-pack/plugins/ingest_manager/server/services/setup.ts @@ -22,6 +22,7 @@ import { Output, DEFAULT_AGENT_POLICIES_PACKAGES, } from '../../common'; +import { SO_SEARCH_LIMIT } from '../constants'; import { getPackageInfo } from './epm/packages'; import { packagePolicyService } from './package_policy'; import { generateEnrollmentAPIKey } from './api_keys'; @@ -159,7 +160,7 @@ export async function setupFleet( }); const { items: agentPolicies } = await agentPolicyService.list(soClient, { - perPage: 10000, + perPage: SO_SEARCH_LIMIT, }); await Promise.all( diff --git a/x-pack/plugins/ingest_manager/server/types/index.tsx b/x-pack/plugins/ingest_manager/server/types/index.tsx index d00491afef72b..fc5ba1af196ad 100644 --- a/x-pack/plugins/ingest_manager/server/types/index.tsx +++ b/x-pack/plugins/ingest_manager/server/types/index.tsx @@ -17,6 +17,7 @@ export { AgentEventSOAttributes, AgentAction, AgentPolicyAction, + AgentPolicyActionV7_9, BaseAgentActionSOAttributes, AgentActionSOAttributes, AgentPolicyActionSOAttributes, @@ -44,7 +45,7 @@ export { InstallationStatus, PackageInfo, RegistryVarsEntry, - Dataset, + RegistryDataStream, RegistryElasticsearch, AssetReference, EsAssetReference, diff --git a/x-pack/plugins/ingest_manager/server/types/models/agent.ts b/x-pack/plugins/ingest_manager/server/types/models/agent.ts index 15004e60a6fa4..87e9257b7189c 100644 --- a/x-pack/plugins/ingest_manager/server/types/models/agent.ts +++ b/x-pack/plugins/ingest_manager/server/types/models/agent.ts @@ -63,7 +63,7 @@ export const AgentEventSchema = schema.object({ export const NewAgentActionSchema = schema.object({ type: schema.oneOf([ - schema.literal('CONFIG_CHANGE'), + schema.literal('POLICY_CHANGE'), schema.literal('UNENROLL'), schema.literal('UPGRADE'), ]), diff --git a/x-pack/plugins/ingest_manager/server/types/models/package_policy.ts b/x-pack/plugins/ingest_manager/server/types/models/package_policy.ts index c23918210114e..6673c12d51511 100644 --- a/x-pack/plugins/ingest_manager/server/types/models/package_policy.ts +++ b/x-pack/plugins/ingest_manager/server/types/models/package_policy.ts @@ -9,8 +9,9 @@ import { isValidNamespace } from '../../../common'; export const NamespaceSchema = schema.string({ minLength: 1, validate: (value) => { - if (!isValidNamespace(value)) { - return 'Namespace contains invalid characters'; + const namespaceValidation = isValidNamespace(value || ''); + if (!namespaceValidation.valid && namespaceValidation.error) { + return namespaceValidation.error; } }, }); diff --git a/x-pack/plugins/ingest_pipelines/README.md b/x-pack/plugins/ingest_pipelines/README.md index a469511bdbbd2..00d4f5a91863d 100644 --- a/x-pack/plugins/ingest_pipelines/README.md +++ b/x-pack/plugins/ingest_pipelines/README.md @@ -11,7 +11,7 @@ It requires a Basic license and the following cluster privileges: `manage_pipeli ## Development -A new app called Ingest Node Pipelines is registered in the Management section and follows a typical CRUD UI pattern. The client-side portion of this app lives in [public/application](public/application) and uses endpoints registered in [server/routes/api](server/routes/api). +A new app called Ingest Node Pipelines is registered in the Management section and follows a typical CRUD UI pattern. The client-side portion of this app lives in [public/application](public/application) and uses endpoints registered in [server/routes/api](server/routes/api). For more information on the pipeline processors editor component, check out the [component readme](public/application/components/pipeline_processors_editor/README.md). See the [kibana contributing guide](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md) for instructions on setting up your development environment. @@ -19,6 +19,83 @@ See the [kibana contributing guide](https://github.com/elastic/kibana/blob/maste The app has the following test coverage: -- Complete API integration tests +- API integration tests - Smoke-level functional test - Client-integration tests + +### Quick steps for manual testing + +You can run the following request in Console to create an ingest node pipeline: + +``` +PUT _ingest/pipeline/test_pipeline +{ + "description": "_description", + "processors": [ + { + "set": { + "field": "field1", + "value": "value1" + } + }, + { + "rename": { + "field": "dont_exist", + "target_field": "field1", + "ignore_failure": true + } + }, + { + "rename": { + "field": "foofield", + "target_field": "new_field", + "on_failure": [ + { + "set": { + "field": "field2", + "value": "value2" + } + } + ] + } + }, + { + "drop": { + "if": "false" + } + }, + { + "drop": { + "if": "true" + } + } + ] +} +``` + +Then, go to the Ingest Node Pipelines UI to edit, delete, clone, or view details of the pipeline. + +To simulate a pipeline, go to the "Edit" page of your pipeline. Click the "Add documents" link under the "Processors" section. You may add the following sample documents to test the pipeline: + +``` +// The first document in this example should trigger the on_failure processor in the pipeline, while the second one should succeed. +[ + { + "_index": "my_index", + "_id": "id1", + "_source": { + "foo": "bar" + } + }, + { + "_index": "my_index", + "_id": "id2", + "_source": { + "foo": "baz", + "foofield": "bar" + } + } +] +``` + +Alternatively, you can add a document from an existing index, or create some sample data of your own. Afterward, click the "Run the pipeline" button to view the output. diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/README.md b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/README.md index d29af67d3179c..4761bd9e6c70b 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/README.md +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/README.md @@ -7,18 +7,37 @@ pipeline. ## Editor components -The top-level API consists of 3 pieces that enable the maximum amount -of flexibility for consuming code to determine overall layout. +The top-level API consists of two pieces: -- PipelineProcessorsEditorContext -- ProcessorsEditor -- GlobalOnFailureProcessorsEditor +- ProcessorsEditorContextProvider +- PipelineProcessorsEditor -The editor components must be wrapped inside of the context component +The editor component must be wrapped inside of the context component as this is where the shared processors state is contained. -## Load JSON button +Example usage from the [PipelineFormFields](../pipeline_form/pipeline_form_fields.tsx) component: -This component is totally standalone. It gives users a button that +``` + + + +``` + +The editor has a dependency on `KibanaContextProvider`, which is defined in the main app's `index.tsx` file. Note that the editor also relies on imports from `public/shared_imports.ts` and `common/types.ts`. + +### ProcessorsEditorContextProvider +This component manages state for the processors, as well as state for the test pipeline functionality. + +### PipelineProcessorsEditor +This component is responsible for building the layout of the processors editor. + +It contains the processor and on-failure processor editors. It also includes the following capabilities that are rendered within the processors header: + +- **Load JSON button:** This component gives users a button that presents a modal for loading a pipeline. It does some basic validation on the JSON to ensure that it is correct. +- **Test pipeline actions:** This component presents users with a toolbar to test a pipeline. It includes a flyout where users can add sample documents. It issues a request to simulate the pipeline and displays the output. Once the request is successful, a user can use the documents dropdown to view the results for a particular document. diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/test_pipeline.helpers.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/test_pipeline.helpers.tsx index 215ef63d9782e..222e0a491e0d2 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/test_pipeline.helpers.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/test_pipeline.helpers.tsx @@ -25,13 +25,7 @@ import { apiService, } from '../../../services'; -import { - ProcessorsEditorContextProvider, - Props, - GlobalOnFailureProcessorsEditor, - ProcessorsEditor, -} from '../'; -import { TestPipelineActions } from '../'; +import { ProcessorsEditorContextProvider, Props, PipelineProcessorsEditor } from '../'; import { initHttpRequests } from './http_requests.helpers'; @@ -105,9 +99,7 @@ const testBedSetup = registerTestBed( (props: Props) => ( - - - + ), @@ -179,6 +171,41 @@ const createActions = (testBed: TestBed) => { }); }, + clickDocumentsDropdown() { + act(() => { + find('documentsDropdown.documentsButton').simulate('click'); + }); + component.update(); + }, + + clickEditDocumentsButton() { + act(() => { + find('editDocumentsButton').simulate('click'); + }); + component.update(); + }, + + clickClearAllButton() { + act(() => { + find('clearAllDocumentsButton').simulate('click'); + }); + component.update(); + }, + + async clickConfirmResetButton() { + const modal = document.body.querySelector( + '[data-test-subj="resetDocumentsConfirmationModal"]' + ); + const confirmButton: HTMLButtonElement | null = modal!.querySelector( + '[data-test-subj="confirmModalConfirmButton"]' + ); + + await act(async () => { + confirmButton!.click(); + }); + component.update(); + }, + async clickProcessor(processorSelector: string) { await act(async () => { find(`${processorSelector}.manageItemButton`).simulate('click'); @@ -230,6 +257,7 @@ type TestSubject = | 'addDocumentsButton' | 'testPipelineFlyout' | 'documentsDropdown' + | 'documentsDropdown.documentsButton' | 'outputTab' | 'documentsEditor' | 'runPipelineButton' @@ -248,6 +276,8 @@ type TestSubject = | 'configurationTab' | 'outputTab' | 'processorOutputTabContent' + | 'editDocumentsButton' + | 'clearAllDocumentsButton' | 'addDocumentsAccordion' | 'addDocumentButton' | 'addDocumentError' diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/test_pipeline.test.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/test_pipeline.test.tsx index 47f05602799e4..69a1b7c2c126d 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/test_pipeline.test.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/test_pipeline.test.tsx @@ -22,6 +22,27 @@ describe('Test pipeline', () => { const { server, httpRequestsMockHelpers } = setupEnvironment(); + // This is a hack + // We need to provide the processor id in the mocked output; + // this is generated dynamically + // As a workaround, the value is added as a data attribute in the UI + // and we retrieve it to generate the mocked output. + const addProcessorTagtoMockOutput = (output: VerboseTestOutput) => { + const { find } = testBed; + + const docs = output.docs.map((doc) => { + const results = doc.processor_results.map((result, index) => { + const tag = find(`processors>${index}`).props()['data-processor-id']; + return { + ...result, + tag, + }; + }); + return { processor_results: results }; + }); + return { docs }; + }; + beforeAll(() => { jest.useFakeTimers(); }); @@ -236,30 +257,77 @@ describe('Test pipeline', () => { expect(find('addDocumentError').text()).toContain(error.message); }); }); - }); - describe('Processors', () => { - // This is a hack - // We need to provide the processor id in the mocked output; - // this is generated dynamically and not something we can stub. - // As a workaround, the value is added as a data attribute in the UI - // and we retrieve it to generate the mocked output. - const addProcessorTagtoMockOutput = (output: VerboseTestOutput) => { - const { find } = testBed; + describe('Documents dropdown', () => { + beforeEach(async () => { + const { actions } = testBed; - const docs = output.docs.map((doc) => { - const results = doc.processor_results.map((result, index) => { - const tag = find(`processors>${index}`).props()['data-processor-id']; - return { - ...result, - tag, - }; - }); - return { processor_results: results }; + httpRequestsMockHelpers.setSimulatePipelineResponse( + addProcessorTagtoMockOutput(SIMULATE_RESPONSE) + ); + + // Open flyout + actions.clickAddDocumentsButton(); + // Add sample documents and click run + actions.addDocumentsJson(JSON.stringify(DOCUMENTS)); + await actions.clickRunPipelineButton(); + // Close flyout + actions.closeTestPipelineFlyout(); }); - return { docs }; - }; + it('should open flyout to edit documents', () => { + const { exists, actions } = testBed; + + // Dropdown should be visible + expect(exists('documentsDropdown')).toBe(true); + + // Open dropdown and edit documents + actions.clickDocumentsDropdown(); + actions.clickEditDocumentsButton(); + + // Flyout should be visible with "Documents" tab enabled + expect(exists('testPipelineFlyout')).toBe(true); + expect(exists('documentsTabContent')).toBe(true); + }); + + it('should clear all documents and stop pipeline simulation', async () => { + const { exists, actions, find } = testBed; + + // Dropdown should be visible and processor status should equal "success" + expect(exists('documentsDropdown')).toBe(true); + const initialProcessorStatusLabel = find('processors>0.processorStatusIcon').props()[ + 'aria-label' + ]; + expect(initialProcessorStatusLabel).toEqual('Success'); + + // Open flyout and click clear all button + actions.clickDocumentsDropdown(); + actions.clickEditDocumentsButton(); + actions.clickClearAllButton(); + + // Verify modal + const modal = document.body.querySelector( + '[data-test-subj="resetDocumentsConfirmationModal"]' + ); + + expect(modal).not.toBe(null); + expect(modal!.textContent).toContain('Clear documents'); + + // Confirm reset and close modal + await actions.clickConfirmResetButton(); + + // Verify documents and processors were reset + expect(exists('documentsDropdown')).toBe(false); + expect(exists('addDocumentsButton')).toBe(true); + const resetProcessorStatusIconLabel = find('processors>0.processorStatusIcon').props()[ + 'aria-label' + ]; + expect(resetProcessorStatusIconLabel).toEqual('Not run'); + }); + }); + }); + + describe('Processors', () => { it('should show "inactive" processor status by default', async () => { const { find } = testBed; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/edit_processor_form.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/edit_processor_form.tsx index d9feaaffa5aec..3df73b54b8cce 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/edit_processor_form.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/edit_processor_form.tsx @@ -102,7 +102,7 @@ export const EditProcessorForm: FunctionComponent = ({ handleSubmit, resetProcessors, }) => { - const { testPipelineData, setCurrentTestPipelineData } = useTestPipelineContext(); + const { testPipelineData, testPipelineDataDispatch } = useTestPipelineContext(); const { testOutputPerProcessor, config: { selectedDocumentIndex, documents }, @@ -117,7 +117,7 @@ export const EditProcessorForm: FunctionComponent = ({ testOutputPerProcessor[selectedDocumentIndex][processor.id]; const updateSelectedDocument = (index: number) => { - setCurrentTestPipelineData({ + testPipelineDataDispatch({ type: 'updateActiveDocument', payload: { config: { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processor_output/processor_output.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processor_output/processor_output.tsx index bd0ce6ca2cd52..f6b13c2ba7228 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processor_output/processor_output.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processor_form/processor_output/processor_output.tsx @@ -32,8 +32,7 @@ export interface Props { const i18nTexts = { tabDescription: i18n.translate('xpack.ingestPipelines.processorOutput.descriptionText', { - defaultMessage: - 'View how the processor affects the ingest document as it passes through the pipeline.', + defaultMessage: 'Preview changes to the test document.', }), skippedCalloutTitle: i18n.translate('xpack.ingestPipelines.processorOutput.skippedCalloutTitle', { defaultMessage: 'The processor was not run.', @@ -68,7 +67,7 @@ const i18nTexts = { processorIgnoredErrorTitle: i18n.translate( 'xpack.ingestPipelines.processorOutput.ignoredErrorCodeBlockLabel', { - defaultMessage: 'There was an error that was ignored', + defaultMessage: 'There was an ignored error', } ), documentsDropdownLabel: i18n.translate( diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processors_empty_prompt.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processors_empty_prompt.tsx index 3750ddda25d10..58d2df518f547 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processors_empty_prompt.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/processors_empty_prompt.tsx @@ -35,7 +35,7 @@ export const ProcessorsEmptyPrompt: FunctionComponent = ({ onLoadJson })

= ({ onLoadJson, hasProc = ({ > ({ key: index.toString(), + 'data-test-subj': 'documentListItem', checked: selectedDocumentIndex === index ? 'on' : undefined, label: i18n.translate('xpack.ingestPipelines.pipelineEditor.testPipeline.documentLabel', { defaultMessage: 'Document {documentNumber}', @@ -107,32 +106,27 @@ export const DocumentsDropdown: FunctionComponent = ({ setShowPopover(false); }} > - {(list, search) => ( -

+ {(list) => ( + <> {i18nTexts.popoverTitle} {list} -
+ )} - - - - - { - openFlyout('documents'); - setShowPopover(false); - }} - data-test-subj="addDocumentsButton" - > - {i18nTexts.addDocumentsButtonLabel} - - - - - + + { + openFlyout('documents'); + setShowPopover(false); + }} + data-test-subj="editDocumentsButton" + > + {i18nTexts.addDocumentsButtonLabel} + + ); }; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_output_button.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_output_button.tsx index 9018042229590..d2fc9c51be699 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_output_button.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_output_button.tsx @@ -6,7 +6,7 @@ import { i18n } from '@kbn/i18n'; import React, { FunctionComponent } from 'react'; import { EuiButton } from '@elastic/eui'; -import { TestPipelineFlyoutTab } from './test_pipeline_flyout_tabs'; +import { TestPipelineFlyoutTab } from './test_pipeline_tabs'; const i18nTexts = { buttonLabel: i18n.translate( diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_actions.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_actions.tsx index cec02db26729d..83a9303859d2a 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_actions.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_actions.tsx @@ -9,7 +9,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; import { useTestPipelineContext, usePipelineProcessorsContext } from '../../context'; import { DocumentsDropdown } from './documents_dropdown'; -import { TestPipelineFlyoutTab } from './test_pipeline_flyout_tabs'; +import { TestPipelineFlyoutTab } from './test_pipeline_tabs'; import { AddDocumentsButton } from './add_documents_button'; import { TestOutputButton } from './test_output_button'; import { TestPipelineFlyout } from './test_pipeline_flyout.container'; @@ -24,7 +24,7 @@ const i18nTexts = { }; export const TestPipelineActions: FunctionComponent = () => { - const { testPipelineData, setCurrentTestPipelineData } = useTestPipelineContext(); + const { testPipelineData, testPipelineDataDispatch } = useTestPipelineContext(); const { state: { processors }, @@ -39,7 +39,7 @@ export const TestPipelineActions: FunctionComponent = () => { const [activeFlyoutTab, setActiveFlyoutTab] = useState('documents'); const updateSelectedDocument = (index: number) => { - setCurrentTestPipelineData({ + testPipelineDataDispatch({ type: 'updateActiveDocument', payload: { config: { diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout.container.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout.container.tsx index 23dda55db41f8..e7ccb9d17f2b1 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout.container.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout.container.tsx @@ -15,8 +15,7 @@ import { Document } from '../../types'; import { useIsMounted } from '../../use_is_mounted'; import { TestPipelineFlyout as ViewComponent } from './test_pipeline_flyout'; -import { TestPipelineFlyoutTab } from './test_pipeline_flyout_tabs'; -import { documentsSchema } from './test_pipeline_flyout_tabs/documents_schema'; +import { TestPipelineFlyoutTab } from './test_pipeline_tabs'; export interface Props { activeTab: TestPipelineFlyoutTab; @@ -39,7 +38,7 @@ export const TestPipelineFlyout: React.FunctionComponent = ({ const { testPipelineData, - setCurrentTestPipelineData, + testPipelineDataDispatch, updateTestOutputPerProcessor, } = useTestPipelineContext(); @@ -48,7 +47,6 @@ export const TestPipelineFlyout: React.FunctionComponent = ({ } = testPipelineData; const { form } = useForm({ - schema: documentsSchema, defaultValue: { documents: cachedDocuments || '', }, @@ -88,7 +86,7 @@ export const TestPipelineFlyout: React.FunctionComponent = ({ // reset the per-processor output // this is needed in the scenario where the pipeline has already executed, // but you modified the sample documents and there was an error on re-execution - setCurrentTestPipelineData({ + testPipelineDataDispatch({ type: 'updateOutputPerProcessor', payload: { isExecutingPipeline: false, @@ -99,7 +97,7 @@ export const TestPipelineFlyout: React.FunctionComponent = ({ return { isSuccessful: false }; } - setCurrentTestPipelineData({ + testPipelineDataDispatch({ type: 'updateConfig', payload: { config: { @@ -133,7 +131,7 @@ export const TestPipelineFlyout: React.FunctionComponent = ({ processors, services.api, services.notifications.toasts, - setCurrentTestPipelineData, + testPipelineDataDispatch, updateTestOutputPerProcessor, ] ); @@ -157,6 +155,12 @@ export const TestPipelineFlyout: React.FunctionComponent = ({ } }; + const resetTestOutput = () => { + testPipelineDataDispatch({ + type: 'reset', + }); + }; + useEffect(() => { if (cachedDocuments && activeTab === 'output') { handleTestPipeline({ documents: cachedDocuments, verbose: cachedVerbose }, true); @@ -169,6 +173,7 @@ export const TestPipelineFlyout: React.FunctionComponent = ({ return ( void; handleTestPipeline: ( @@ -31,11 +30,14 @@ export interface Props { cachedVerbose?: boolean; cachedDocuments?: Document[]; testOutput?: any; - form: FormHook; + form: FormHook<{ + documents: string | Document[]; + }>; validateAndTestPipeline: () => Promise; selectedTab: TestPipelineFlyoutTab; setSelectedTab: (selectedTa: TestPipelineFlyoutTab) => void; testingError: any; + resetTestOutput: () => void; } export interface TestPipelineConfig { @@ -45,6 +47,7 @@ export interface TestPipelineConfig { export const TestPipelineFlyout: React.FunctionComponent = ({ handleTestPipeline, + resetTestOutput, isRunningTest, cachedVerbose, cachedDocuments, @@ -75,6 +78,7 @@ export const TestPipelineFlyout: React.FunctionComponent = ({ form={form} validateAndTestPipeline={validateAndTestPipeline} isRunningTest={isRunningTest} + resetTestOutput={resetTestOutput} /> ); } diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/documents_schema.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/documents_schema.tsx deleted file mode 100644 index d0e0596375cb2..0000000000000 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/documents_schema.tsx +++ /dev/null @@ -1,111 +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 { FormattedMessage } from '@kbn/i18n/react'; -import { i18n } from '@kbn/i18n'; -import { EuiCode } from '@elastic/eui'; - -import { FormSchema, fieldValidators, ValidationFuncArg } from '../../../../../../shared_imports'; -import { parseJson, stringifyJson } from '../../../../../lib'; - -const { emptyField, isJsonField } = fieldValidators; - -export const documentsSchema: FormSchema = { - documents: { - label: i18n.translate( - 'xpack.ingestPipelines.testPipelineFlyout.documentsForm.documentsFieldLabel', - { - defaultMessage: 'Documents', - } - ), - helpText: ( - - {JSON.stringify([ - { - _index: 'index', - _id: 'id', - _source: { - foo: 'bar', - }, - }, - ])} - - ), - }} - /> - ), - serializer: parseJson, - deserializer: stringifyJson, - validations: [ - { - validator: emptyField( - i18n.translate( - 'xpack.ingestPipelines.testPipelineFlyout.documentsForm.noDocumentsError', - { - defaultMessage: 'Documents are required.', - } - ) - ), - }, - { - validator: isJsonField( - i18n.translate( - 'xpack.ingestPipelines.testPipelineFlyout.documentsForm.documentsJsonError', - { - defaultMessage: 'The documents JSON is not valid.', - } - ) - ), - }, - { - validator: ({ value }: ValidationFuncArg) => { - const parsedJSON = JSON.parse(value); - - if (!parsedJSON.length) { - return { - message: i18n.translate( - 'xpack.ingestPipelines.testPipelineFlyout.documentsForm.oneDocumentRequiredError', - { - defaultMessage: 'At least one document is required.', - } - ), - }; - } - }, - }, - { - validator: ({ value }: ValidationFuncArg) => { - const parsedJSON = JSON.parse(value); - - const isMissingSourceField = parsedJSON.find((document: { _source?: object }) => { - if (!document._source) { - return true; - } - - return false; - }); - - if (isMissingSourceField) { - return { - message: i18n.translate( - 'xpack.ingestPipelines.testPipelineFlyout.documentsForm.sourceFieldRequiredError', - { - defaultMessage: 'Documents require a _source field.', - } - ), - }; - } - }, - }, - ], - }, -}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/tab_documents.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/tab_documents.tsx deleted file mode 100644 index 6fd340054d2a4..0000000000000 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/tab_documents.tsx +++ /dev/null @@ -1,134 +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, { FunctionComponent, useCallback } from 'react'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { i18n } from '@kbn/i18n'; - -import { EuiSpacer, EuiText, EuiButton, EuiLink } from '@elastic/eui'; - -import { - getUseField, - Field, - JsonEditorField, - useKibana, - useFormData, - FormHook, - Form, -} from '../../../../../../shared_imports'; - -import { AddDocumentsAccordion } from './add_documents_accordion'; - -const UseField = getUseField({ component: Field }); - -interface Props { - validateAndTestPipeline: () => Promise; - isRunningTest: boolean; - form: FormHook; -} - -export const DocumentsTab: FunctionComponent = ({ - validateAndTestPipeline, - isRunningTest, - form, -}) => { - const { services } = useKibana(); - - const [, formatData] = useFormData({ form }); - - const onAddDocumentHandler = useCallback( - (document) => { - const { documents: existingDocuments = [] } = formatData(); - - form.reset({ defaultValue: { documents: [...existingDocuments, document] } }); - }, - [form, formatData] - ); - - return ( -
-
- -

- - {i18n.translate( - 'xpack.ingestPipelines.testPipelineFlyout.documentsTab.simulateDocumentionLink', - { - defaultMessage: 'Learn more.', - } - )} - - ), - }} - /> -

-
- - - - - - - - {/* Documents editor */} - - - - - - {isRunningTest ? ( - - ) : ( - - )} - -
-
- ); -}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/index.ts similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/index.ts rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/index.ts diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/add_document_form.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/add_document_form.tsx similarity index 97% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/add_document_form.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/add_document_form.tsx index 340cf1af92300..7bb860facfeb2 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/add_document_form.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/add_document_form.tsx @@ -25,9 +25,9 @@ import { TextField, fieldValidators, FieldConfig, -} from '../../../../../../shared_imports'; -import { useIsMounted } from '../../../use_is_mounted'; -import { Document } from '../../../types'; +} from '../../../../../../../shared_imports'; +import { useIsMounted } from '../../../../use_is_mounted'; +import { Document } from '../../../../types'; const UseField = getUseField({ component: Field }); diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/add_documents_accordion/add_documents_accordion.scss b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/add_documents_accordion/add_documents_accordion.scss similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/add_documents_accordion/add_documents_accordion.scss rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/add_documents_accordion/add_documents_accordion.scss diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/add_documents_accordion/add_documents_accordion.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/add_documents_accordion/add_documents_accordion.tsx similarity index 87% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/add_documents_accordion/add_documents_accordion.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/add_documents_accordion/add_documents_accordion.tsx index 88ced6e9e94dd..9519d849e5d90 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/add_documents_accordion/add_documents_accordion.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/add_documents_accordion/add_documents_accordion.tsx @@ -11,8 +11,8 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { EuiAccordion, EuiText, EuiSpacer, EuiLink } from '@elastic/eui'; import { UrlGeneratorsDefinition } from 'src/plugins/share/public'; -import { useKibana } from '../../../../../../../shared_imports'; -import { useIsMounted } from '../../../../use_is_mounted'; +import { useKibana } from '../../../../../../../../shared_imports'; +import { useIsMounted } from '../../../../../use_is_mounted'; import { AddDocumentForm } from '../add_document_form'; import './add_documents_accordion.scss'; @@ -23,7 +23,13 @@ const i18nTexts = { addDocumentsButton: i18n.translate( 'xpack.ingestPipelines.pipelineEditor.addDocumentsAccordion.addDocumentsButtonLabel', { - defaultMessage: 'Add documents from index', + defaultMessage: 'Add a test document from an index', + } + ), + addDocumentsDescription: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.addDocumentsAccordion.contentDescriptionText', + { + defaultMessage: `Provide the document's index and document ID.`, } ), }; @@ -79,10 +85,7 @@ export const AddDocumentsAccordion: FunctionComponent = ({ onAddDocuments

- + {i18nTexts.addDocumentsDescription} {discoverLink && ( <> {' '} diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/add_documents_accordion/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/add_documents_accordion/index.ts similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/add_documents_accordion/index.ts rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/add_documents_accordion/index.ts diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/index.ts new file mode 100644 index 0000000000000..1c3b6df577f4d --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/index.ts @@ -0,0 +1,7 @@ +/* + * 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 { DocumentsTab } from './tab_documents'; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/reset_documents_modal.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/reset_documents_modal.tsx new file mode 100644 index 0000000000000..2dbc6c56849dd --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/reset_documents_modal.tsx @@ -0,0 +1,61 @@ +/* + * 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 React, { FunctionComponent } from 'react'; +import { EuiConfirmModal, EuiOverlayMask } from '@elastic/eui'; + +interface Props { + confirmResetTestOutput: () => void; + closeModal: () => void; +} + +const i18nTexts = { + modalTitle: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.testPipeline.resetDocumentsModal.title', + { + defaultMessage: 'Clear documents', + } + ), + modalDescription: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.testPipeline.resetDocumentsModal.description', + { + defaultMessage: 'This will reset the output.', + } + ), + cancelButtonLabel: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.testPipeline.resetDocumentsModal.cancelButtonLabel', + { + defaultMessage: 'Cancel', + } + ), + resetButtonLabel: i18n.translate( + 'xpack.ingestPipelines.pipelineEditor.testPipeline.resetDocumentsModal.resetButtonLabel', + { + defaultMessage: 'Clear documents', + } + ), +}; + +export const ResetDocumentsModal: FunctionComponent = ({ + confirmResetTestOutput, + closeModal, +}) => { + return ( + + +

{i18nTexts.modalDescription}

+ + + ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/tab_documents.scss b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/tab_documents.scss new file mode 100644 index 0000000000000..c07f58d280e2a --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/tab_documents.scss @@ -0,0 +1,11 @@ +.documentsTab { + &__documentField { + position: relative; + + &__button { + position: absolute; + right: 0; + top: 0; + } + } +} diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/tab_documents.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/tab_documents.tsx new file mode 100644 index 0000000000000..ae784472ebbd9 --- /dev/null +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/tab_documents/tab_documents.tsx @@ -0,0 +1,251 @@ +/* + * 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, { FunctionComponent, useCallback, useState } from 'react'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { i18n } from '@kbn/i18n'; + +import { EuiSpacer, EuiText, EuiButton, EuiLink, EuiCode, EuiButtonEmpty } from '@elastic/eui'; + +import { parseJson, stringifyJson } from '../../../../../../lib'; +import { + getUseField, + Field, + JsonEditorField, + useKibana, + FieldConfig, + fieldValidators, + ValidationFuncArg, + FormHook, + Form, + useFormData, +} from '../../../../../../../shared_imports'; +import { Document } from '../../../../types'; +import { AddDocumentsAccordion } from './add_documents_accordion'; +import { ResetDocumentsModal } from './reset_documents_modal'; + +import './tab_documents.scss'; + +const UseField = getUseField({ component: Field }); + +const { emptyField, isJsonField } = fieldValidators; + +interface Props { + validateAndTestPipeline: () => Promise; + resetTestOutput: () => void; + isRunningTest: boolean; + form: FormHook<{ + documents: string | Document[]; + }>; +} + +const i18nTexts = { + learnMoreLink: i18n.translate( + 'xpack.ingestPipelines.testPipelineFlyout.documentsTab.simulateDocumentionLink', + { + defaultMessage: 'Learn more.', + } + ), + documentsEditorAriaLabel: i18n.translate( + 'xpack.ingestPipelines.testPipelineFlyout.documentsTab.editorFieldAriaLabel', + { + defaultMessage: 'Documents JSON editor', + } + ), + documentsEditorClearAllButton: i18n.translate( + 'xpack.ingestPipelines.testPipelineFlyout.documentsTab.editorFieldClearAllButtonLabel', + { + defaultMessage: 'Clear all', + } + ), + runButton: i18n.translate( + 'xpack.ingestPipelines.testPipelineFlyout.documentsTab.runButtonLabel', + { + defaultMessage: 'Run the pipeline', + } + ), + runningButton: i18n.translate( + 'xpack.ingestPipelines.testPipelineFlyout.documentsTab.runningButtonLabel', + { + defaultMessage: 'Running', + } + ), +}; + +const documentFieldConfig: FieldConfig = { + label: i18n.translate( + 'xpack.ingestPipelines.testPipelineFlyout.documentsForm.documentsFieldLabel', + { + defaultMessage: 'Documents', + } + ), + helpText: ( + + {JSON.stringify([ + { + _index: 'index', + _id: 'id', + _source: { + foo: 'bar', + }, + }, + ])} + + ), + }} + /> + ), + serializer: parseJson, + deserializer: stringifyJson, + validations: [ + { + validator: emptyField( + i18n.translate('xpack.ingestPipelines.testPipelineFlyout.documentsForm.noDocumentsError', { + defaultMessage: 'Documents are required.', + }) + ), + }, + { + validator: isJsonField( + i18n.translate( + 'xpack.ingestPipelines.testPipelineFlyout.documentsForm.documentsJsonError', + { + defaultMessage: 'The documents JSON is not valid.', + } + ) + ), + }, + { + validator: ({ value }: ValidationFuncArg) => { + const parsedJSON = JSON.parse(value); + + if (!parsedJSON.length) { + return { + message: i18n.translate( + 'xpack.ingestPipelines.testPipelineFlyout.documentsForm.oneDocumentRequiredError', + { + defaultMessage: 'At least one document is required.', + } + ), + }; + } + }, + }, + ], +}; + +export const DocumentsTab: FunctionComponent = ({ + validateAndTestPipeline, + isRunningTest, + form, + resetTestOutput, +}) => { + const { services } = useKibana(); + + const [, formatData] = useFormData({ form }); + + const onAddDocumentHandler = useCallback( + (document) => { + const { documents: existingDocuments = [] } = formatData(); + + form.reset({ defaultValue: { documents: [...existingDocuments, document] } }); + }, + [form, formatData] + ); + + const [showResetModal, setShowResetModal] = useState(false); + + return ( +
+
+ +

+ + {i18nTexts.learnMoreLink} + + ), + }} + /> +

+
+ + + + + + + + {/* Documents editor */} + + {(field) => ( +
+ setShowResetModal(true)} + data-test-subj="clearAllDocumentsButton" + className="documentsTab__documentField__button" + > + {i18nTexts.documentsEditorClearAllButton} + + +
+ )} +
+ + + + + {isRunningTest ? i18nTexts.runningButton : i18nTexts.runButton} + + + {showResetModal && ( + { + resetTestOutput(); + form.reset({ defaultValue: { documents: [] } }); + setShowResetModal(false); + }} + closeModal={() => setShowResetModal(false)} + /> + )} +
+
+ ); +}; diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/tab_output.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/tab_output.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/tab_output.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/tab_output.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/test_pipeline_tabs.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/test_pipeline_tabs.tsx similarity index 100% rename from x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout_tabs/test_pipeline_tabs.tsx rename to x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_tabs/test_pipeline_tabs.tsx diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/context/test_pipeline_context.tsx b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/context/test_pipeline_context.tsx index 314964f808e44..a20cde5b1fb72 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/context/test_pipeline_context.tsx +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/context/test_pipeline_context.tsx @@ -51,11 +51,14 @@ type Action = | { type: 'updateIsExecutingPipeline'; payload: Pick; + } + | { + type: 'reset'; }; export interface TestPipelineContext { testPipelineData: TestPipelineData; - setCurrentTestPipelineData: (data: Action) => void; + testPipelineDataDispatch: (data: Action) => void; updateTestOutputPerProcessor: ( documents: Document[] | undefined, processors: DeserializeResult @@ -69,7 +72,7 @@ const DEFAULT_TEST_PIPELINE_CONTEXT = { }, isExecutingPipeline: false, }, - setCurrentTestPipelineData: () => {}, + testPipelineDataDispatch: () => {}, updateTestOutputPerProcessor: () => {}, }; @@ -122,6 +125,10 @@ export const reducer: Reducer = (state, action) => { }; } + if (action.type === 'reset') { + return DEFAULT_TEST_PIPELINE_CONTEXT.testPipelineData; + } + return state; }; @@ -193,7 +200,7 @@ export const TestPipelineContextProvider = ({ children }: { children: React.Reac diff --git a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/index.ts b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/index.ts index ca5184da25a07..ae3dd9d673ebe 100644 --- a/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/index.ts +++ b/x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/index.ts @@ -4,16 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -export { PipelineProcessorsContextProvider, Props } from './context'; - -export { ProcessorsEditorContextProvider } from './context'; - -export { ProcessorsEditor, GlobalOnFailureProcessorsEditor } from './editors'; +export { Props, ProcessorsEditorContextProvider } from './context'; export { OnUpdateHandlerArg, OnUpdateHandler } from './types'; export { SerializeResult } from './serialize'; -export { LoadFromJsonButton, OnDoneLoadJsonHandler, TestPipelineActions } from './components'; +export { OnDoneLoadJsonHandler } from './components'; export { PipelineProcessorsEditor } from './pipeline_processors_editor'; diff --git a/x-pack/plugins/lens/public/_mixins.scss b/x-pack/plugins/lens/public/_mixins.scss index a3cf6caa5a429..0db72d118cef1 100644 --- a/x-pack/plugins/lens/public/_mixins.scss +++ b/x-pack/plugins/lens/public/_mixins.scss @@ -11,3 +11,39 @@ transparentize(red, .9) 100% ); } + +// Static styles for a draggable item +@mixin lnsDraggable { + @include euiSlightShadow; + background: lightOrDarkTheme($euiColorEmptyShade, $euiColorLightestShade); + border: $euiBorderWidthThin dashed transparent; + cursor: grab; +} + +// Static styles for a drop area +@mixin lnsDroppable { + border: $euiBorderWidthThin dashed $euiBorderColor; +} + +// Hovering state for drag item and drop area +@mixin lnsDragDropHover { + &:hover { + border: $euiBorderWidthThin dashed $euiColorMediumShade; + } +} + +// Style for drop area when there's an item being dragged +@mixin lnsDroppableActive { + background-color: transparentize($euiColorVis0, .9); +} + +// Style for drop area while hovering with item +@mixin lnsDroppableActiveHover { + background-color: transparentize($euiColorVis0, .75); + border: $euiBorderWidthThin dashed $euiColorVis0; +} + +// Style for drop area that is not allowed for current item +@mixin lnsDroppableNotAllowed { + opacity: .5; +} diff --git a/x-pack/plugins/lens/public/app_plugin/_index.scss b/x-pack/plugins/lens/public/app_plugin/_index.scss deleted file mode 100644 index e72e824224956..0000000000000 --- a/x-pack/plugins/lens/public/app_plugin/_index.scss +++ /dev/null @@ -1 +0,0 @@ -@import 'app'; diff --git a/x-pack/plugins/lens/public/app_plugin/_app.scss b/x-pack/plugins/lens/public/app_plugin/app.scss similarity index 100% rename from x-pack/plugins/lens/public/app_plugin/_app.scss rename to x-pack/plugins/lens/public/app_plugin/app.scss diff --git a/x-pack/plugins/lens/public/app_plugin/app.tsx b/x-pack/plugins/lens/public/app_plugin/app.tsx index d2ccbe0cb2fee..e4af2a33ec68b 100644 --- a/x-pack/plugins/lens/public/app_plugin/app.tsx +++ b/x-pack/plugins/lens/public/app_plugin/app.tsx @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import './app.scss'; + import _ from 'lodash'; import React, { useState, useEffect, useCallback } from 'react'; import { i18n } from '@kbn/i18n'; diff --git a/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx b/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx index f6234d063d8cd..9162af52052ee 100644 --- a/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx +++ b/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx @@ -30,24 +30,22 @@ export function getLensTopNavConfig(options: { defaultMessage: 'Save', }); - if (showSaveAndReturn) { + if (showCancel) { topNavMenu.push({ - label: i18n.translate('xpack.lens.app.saveAndReturn', { - defaultMessage: 'Save and return', + label: i18n.translate('xpack.lens.app.cancel', { + defaultMessage: 'cancel', }), - emphasize: true, - iconType: 'check', - run: actions.saveAndReturn, - testId: 'lnsApp_saveAndReturnButton', - disableButton: !savingPermitted, - description: i18n.translate('xpack.lens.app.saveAndReturnButtonAriaLabel', { - defaultMessage: 'Save the current lens visualization and return to the last app', + run: actions.cancel, + testId: 'lnsApp_cancelButton', + description: i18n.translate('xpack.lens.app.cancelButtonAriaLabel', { + defaultMessage: 'Return to the last app without saving changes', }), }); } topNavMenu.push({ label: saveButtonLabel, + iconType: !showSaveAndReturn ? 'save' : undefined, emphasize: !showSaveAndReturn, run: actions.showSaveModal, testId: 'lnsApp_saveButton', @@ -57,17 +55,21 @@ export function getLensTopNavConfig(options: { disableButton: !savingPermitted, }); - if (showCancel) { + if (showSaveAndReturn) { topNavMenu.push({ - label: i18n.translate('xpack.lens.app.cancel', { - defaultMessage: 'cancel', + label: i18n.translate('xpack.lens.app.saveAndReturn', { + defaultMessage: 'Save and return', }), - run: actions.cancel, - testId: 'lnsApp_cancelButton', - description: i18n.translate('xpack.lens.app.cancelButtonAriaLabel', { - defaultMessage: 'Return to the last app without saving changes', + emphasize: true, + iconType: 'checkInCircleFilled', + run: actions.saveAndReturn, + testId: 'lnsApp_saveAndReturnButton', + disableButton: !savingPermitted, + description: i18n.translate('xpack.lens.app.saveAndReturnButtonAriaLabel', { + defaultMessage: 'Save the current lens visualization and return to the last app', }), }); } + return topNavMenu; } diff --git a/x-pack/plugins/lens/public/async_services.ts b/x-pack/plugins/lens/public/async_services.ts new file mode 100644 index 0000000000000..09b9233197d2f --- /dev/null +++ b/x-pack/plugins/lens/public/async_services.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +/** + * This file re-exports all parts of visualizations and datasources which can be loaded lazily + * (to reduce page load bundle size) when Lens is actually accessed via editor or embeddable. + * + * It's also possible for each visualization and datasource to resolve this locally, but this causes + * a burst of bundles being loaded on Lens startup at once (and in some scenarios cascading bundle loads). + * This file causes all of them to be served in a single request. + */ + +export * from './datatable_visualization/datatable_visualization'; +export * from './metric_visualization/metric_visualization'; +export * from './pie_visualization/pie_visualization'; +export * from './xy_visualization/xy_visualization'; + +export * from './indexpattern_datasource/indexpattern'; + +export * from './editor_frame_service/editor_frame'; +export * from './editor_frame_service/embeddable'; +export * from './app_plugin/mounter'; diff --git a/x-pack/plugins/lens/public/datatable_visualization/__snapshots__/expression.test.tsx.snap b/x-pack/plugins/lens/public/datatable_visualization/__snapshots__/expression.test.tsx.snap index c0210c3915ce8..9c7bdc3397f9c 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/__snapshots__/expression.test.tsx.snap +++ b/x-pack/plugins/lens/public/datatable_visualization/__snapshots__/expression.test.tsx.snap @@ -1,7 +1,9 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`datatable_expression DatatableComponent it renders the title and value 1`] = ` - + + , { expressions, formatFactory, editorFrame }: DatatableVisualizationPluginSetupPlugins ) { - expressions.registerFunction(() => datatableColumns); - expressions.registerFunction(() => datatable); - expressions.registerRenderer(() => - getDatatableRenderer({ - formatFactory, - getType: core - .getStartServices() - .then(([_, { data: dataStart }]) => dataStart.search.aggs.types.get), - }) - ); - editorFrame.registerVisualization(datatableVisualization); + editorFrame.registerVisualization(async () => { + const { + datatable, + datatableColumns, + getDatatableRenderer, + datatableVisualization, + } = await import('../async_services'); + expressions.registerFunction(() => datatableColumns); + expressions.registerFunction(() => datatable); + expressions.registerRenderer(() => + getDatatableRenderer({ + formatFactory, + getType: core + .getStartServices() + .then(([_, { data: dataStart }]) => dataStart.search.aggs.types.get), + }) + ); + return datatableVisualization; + }); } } diff --git a/x-pack/plugins/lens/public/datatable_visualization/visualization.tsx b/x-pack/plugins/lens/public/datatable_visualization/visualization.tsx index 5b462f44b3dd5..1464ae6988a2d 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/visualization.tsx +++ b/x-pack/plugins/lens/public/datatable_visualization/visualization.tsx @@ -194,7 +194,7 @@ export const datatableVisualization: Visualization }; }, - toExpression(state, datasourceLayers): Ast { + toExpression(state, datasourceLayers, { title, description } = {}): Ast { const layer = state.layers[0]; const datasource = datasourceLayers[layer.layerId]; const originalOrder = datasource.getTableSpec().map(({ columnId }) => columnId); @@ -211,6 +211,8 @@ export const datatableVisualization: Visualization type: 'function', function: 'lens_datatable', arguments: { + title: [title || ''], + description: [description || ''], columns: [ { type: 'expression', diff --git a/x-pack/plugins/lens/public/drag_drop/__snapshots__/drag_drop.test.tsx.snap b/x-pack/plugins/lens/public/drag_drop/__snapshots__/drag_drop.test.tsx.snap index 3581151dd5f76..dc53f3a2bc2a7 100644 --- a/x-pack/plugins/lens/public/drag_drop/__snapshots__/drag_drop.test.tsx.snap +++ b/x-pack/plugins/lens/public/drag_drop/__snapshots__/drag_drop.test.tsx.snap @@ -1,17 +1,17 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`DragDrop droppable is reflected in the className 1`] = ` -
Hello! -
+ `; exports[`DragDrop items that have droppable=false get special styling when another item is dragged 1`] = ` -
Hello! -
+ `; exports[`DragDrop renders if nothing is being dragged 1`] = ` -
Hello! -
+ `; diff --git a/x-pack/plugins/lens/public/drag_drop/_drag_drop.scss b/x-pack/plugins/lens/public/drag_drop/_drag_drop.scss deleted file mode 100644 index c971540e165c1..0000000000000 --- a/x-pack/plugins/lens/public/drag_drop/_drag_drop.scss +++ /dev/null @@ -1,13 +0,0 @@ -.lnsDragDrop-isNotDroppable { - opacity: .5; -} - -// Fix specificity by chaining classes - -.lnsDragDrop.lnsDragDrop-isDropTarget { - background-color: transparentize($euiColorSecondary, .9); -} - -.lnsDragDrop.lnsDragDrop-isActiveDropTarget { - background-color: transparentize($euiColorSecondary, .75); -} diff --git a/x-pack/plugins/lens/public/drag_drop/_index.scss b/x-pack/plugins/lens/public/drag_drop/_index.scss deleted file mode 100644 index ddf9b9aa3e429..0000000000000 --- a/x-pack/plugins/lens/public/drag_drop/_index.scss +++ /dev/null @@ -1 +0,0 @@ -@import 'drag_drop'; diff --git a/x-pack/plugins/lens/public/drag_drop/drag_drop.scss b/x-pack/plugins/lens/public/drag_drop/drag_drop.scss new file mode 100644 index 0000000000000..410aaef9a5195 --- /dev/null +++ b/x-pack/plugins/lens/public/drag_drop/drag_drop.scss @@ -0,0 +1,54 @@ +@import '../variables'; +@import '../mixins'; + +.lnsDragDrop { + transition: background-color $euiAnimSpeedFast ease-in-out, border-color $euiAnimSpeedFast ease-in-out; +} + +// Draggable item +.lnsDragDrop-isDraggable { + @include lnsDraggable; + @include lnsDragDropHover; + + // Include a possible nested button like when using FieldButton + > .kbnFieldButton__button { + cursor: grab; + } + + &:focus { + @include euiFocusRing; + } +} + +// Draggable item when it is moving +.lnsDragDrop-isHidden { + opacity: 0; +} + +// Drop area +.lnsDragDrop-isDroppable { + @include lnsDroppable; +} + +// Drop area when there's an item being dragged +.lnsDragDrop-isDropTarget { + @include lnsDroppableActive; +} + +// Drop area while hovering with item +.lnsDragDrop-isActiveDropTarget { + @include lnsDroppableActiveHover; +} + +// Drop area that is not allowed for current item +.lnsDragDrop-isNotDroppable { + @include lnsDroppableNotAllowed; +} + +// Drop area will be replacing existing content +.lnsDragDrop-isReplacing { + &, + .lnsLayerPanel__triggerLink { + text-decoration: line-through; + } +} diff --git a/x-pack/plugins/lens/public/drag_drop/drag_drop.test.tsx b/x-pack/plugins/lens/public/drag_drop/drag_drop.test.tsx index 3240357c254ea..b1cc4c06c2165 100644 --- a/x-pack/plugins/lens/public/drag_drop/drag_drop.test.tsx +++ b/x-pack/plugins/lens/public/drag_drop/drag_drop.test.tsx @@ -15,7 +15,7 @@ describe('DragDrop', () => { test('renders if nothing is being dragged', () => { const component = render( - Hello! + ); @@ -24,7 +24,11 @@ describe('DragDrop', () => { test('dragover calls preventDefault if droppable is true', () => { const preventDefault = jest.fn(); - const component = mount(Hello!); + const component = mount( + + + + ); component.find('[data-test-subj="lnsDragDrop"]').simulate('dragover', { preventDefault }); @@ -33,7 +37,11 @@ describe('DragDrop', () => { test('dragover does not call preventDefault if droppable is false', () => { const preventDefault = jest.fn(); - const component = mount(Hello!); + const component = mount( + + + + ); component.find('[data-test-subj="lnsDragDrop"]').simulate('dragover', { preventDefault }); @@ -51,7 +59,7 @@ describe('DragDrop', () => { const component = mount( - Hello! + ); @@ -74,7 +82,7 @@ describe('DragDrop', () => { const component = mount( - Hello! + ); @@ -98,7 +106,7 @@ describe('DragDrop', () => { const component = mount( - Hello! + ); @@ -121,7 +129,7 @@ describe('DragDrop', () => { }} droppable > - Hello! + ); @@ -132,10 +140,10 @@ describe('DragDrop', () => { const component = mount( {}}> - Ignored + {}} droppable={false}> - Hello! + ); @@ -154,14 +162,14 @@ describe('DragDrop', () => { }} > - Ignored + {}} droppable getAdditionalClassesOnEnter={getAdditionalClasses} > - Hello! + ); diff --git a/x-pack/plugins/lens/public/drag_drop/drag_drop.tsx b/x-pack/plugins/lens/public/drag_drop/drag_drop.tsx index 85bdd24bd4f80..b36415fee5b15 100644 --- a/x-pack/plugins/lens/public/drag_drop/drag_drop.tsx +++ b/x-pack/plugins/lens/public/drag_drop/drag_drop.tsx @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import './drag_drop.scss'; + import React, { useState, useContext } from 'react'; import classNames from 'classnames'; import { DragContext } from './providers'; @@ -39,9 +41,14 @@ interface BaseProps { value?: unknown; /** - * The React children. + * Optional comparison function to check whether a value is the dragged one */ - children: React.ReactNode; + isValueEqual?: (value1: unknown, value2: unknown) => boolean; + + /** + * The React element which will be passed the draggable handlers + */ + children: React.ReactElement; /** * Indicates whether or not the currently dragged item @@ -58,6 +65,18 @@ interface BaseProps { * The optional test subject associated with this DOM element. */ 'data-test-subj'?: string; + + /** + * Indicates to the user whether the currently dragged item + * will be moved or copied + */ + dragType?: 'copy' | 'move'; + + /** + * Indicates to the user whether the drop action will + * replace something that is existing or add a new one + */ + dropType?: 'add' | 'replace'; } /** @@ -96,12 +115,14 @@ type Props = DraggableProps | NonDraggableProps; export const DragDrop = (props: Props) => { const { dragging, setDragging } = useContext(DragContext); - const { value, draggable, droppable } = props; + const { value, draggable, droppable, isValueEqual } = props; return ( - {children} -
- ); + return React.cloneElement(children, { + 'data-test-subj': props['data-test-subj'] || 'lnsDragDrop', + className: classNames(children.props.className, classes), + onDragOver: dragOver, + onDragLeave: dragLeave, + onDrop: drop, + draggable, + onDragEnd: dragEnd, + onDragStart: dragStart, + }); }); diff --git a/x-pack/plugins/lens/public/editor_frame_service/_index.scss b/x-pack/plugins/lens/public/editor_frame_service/_index.scss deleted file mode 100644 index 199cbe35e25fa..0000000000000 --- a/x-pack/plugins/lens/public/editor_frame_service/_index.scss +++ /dev/null @@ -1 +0,0 @@ -@import 'editor_frame/index'; diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/_expression_renderer.scss b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/_expression_renderer.scss deleted file mode 100644 index 9519544ece575..0000000000000 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/_expression_renderer.scss +++ /dev/null @@ -1,12 +0,0 @@ -.lnsExpressionRenderer { - @include euiScrollBar; - position: relative; - width: 100%; - height: 100%; - display: flex; - overflow: auto; - - .lnsExpressionRenderer__component { - position: static; // Let the progress indicator position itself against the outer parent - } -} diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/_frame_layout.scss b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/_frame_layout.scss deleted file mode 100644 index 9367e59b11717..0000000000000 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/_frame_layout.scss +++ /dev/null @@ -1,54 +0,0 @@ -.lnsFrameLayout { - padding: 0; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - overflow: hidden; - flex-direction: column; -} - -.lnsFrameLayout__pageContent { - display: flex; - overflow: hidden; - flex-grow: 1; -} - -.lnsFrameLayout__pageBody { - @include euiScrollBar; - min-width: $lnsPanelMinWidth + $euiSizeXL; - overflow: hidden; - // Leave out bottom padding so the suggestions scrollbar stays flush to window edge - // Leave out left padding so the left sidebar's focus states are visible outside of content bounds - // This also means needing to add same amount of margin to page content and suggestion items - padding: $euiSize $euiSize 0; - - &:first-child { - padding-left: $euiSize; - } -} - -.lnsFrameLayout__sidebar { - margin: 0; - flex: 1 0 18%; - min-width: $lnsPanelMinWidth + $euiSize; - display: flex; - flex-direction: column; - position: relative; -} - -.lnsFrameLayout__sidebar--right { - flex-basis: 25%; - background-color: lightOrDarkTheme($euiColorLightestShade, $euiColorInk); - min-width: $lnsPanelMinWidth + $euiSizeXL; - max-width: $euiFormMaxWidth + $euiSizeXXL; - max-height: 100%; - - .lnsConfigPanel { - @include euiScrollBar; - padding: $euiSize 0 $euiSize $euiSize; - overflow-x: hidden; - overflow-y: scroll; - } -} diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/_suggestion_panel.scss b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/_suggestion_panel.scss deleted file mode 100644 index 9d018076dc320..0000000000000 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/_suggestion_panel.scss +++ /dev/null @@ -1,68 +0,0 @@ -.lnsSuggestionPanel__title { - margin-left: $euiSizeXS / 2; -} - -.lnsSuggestionPanel__suggestions { - @include euiScrollBar; - @include lnsOverflowShadowHorizontal; - padding-top: $euiSizeXS; - overflow-x: scroll; - overflow-y: hidden; - display: flex; - - // Padding / negative margins to make room for overflow shadow - padding-left: $euiSizeXS; - margin-left: -$euiSizeXS; -} - -.lnsSuggestionPanel__button { - position: relative; // Let the expression progress indicator position itself against the button - flex: 0 0 auto; - width: $lnsSuggestionWidth !important; // sass-lint:disable-line no-important - height: $lnsSuggestionHeight; - margin-right: $euiSizeS; - margin-left: $euiSizeXS / 2; - margin-bottom: $euiSizeXS / 2; - - .lnsSuggestionPanel__expressionRenderer { - position: static; // Let the progress indicator position itself against the button - } -} - -.lnsSuggestionPanel__button-isSelected { - @include euiFocusRing; -} - -.lnsSuggestionPanel__suggestionIcon { - color: $euiColorDarkShade; - width: 100%; - height: 100%; - display: flex; - align-items: center; - justify-content: center; - padding: $euiSizeS; - - &:not(:only-child) { - height: calc(100% - #{$euiSizeL}); - } -} - -.lnsSuggestionPanel__chartWrapper { - display: flex; - height: 100%; - width: 100%; - pointer-events: none; -} - -.lnsSuggestionPanel__chartWrapper--withLabel { - height: calc(100% - #{$euiSizeL}); -} - -.lnsSuggestionPanel__buttonLabel { - @include euiTextTruncate; - @include euiFontSizeXS; - display: block; - font-weight: $euiFontWeightBold; - text-align: center; - flex-grow: 0; -} diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/_workspace_panel_wrapper.scss b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/_workspace_panel_wrapper.scss deleted file mode 100644 index 7f7385f029ed4..0000000000000 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/_workspace_panel_wrapper.scss +++ /dev/null @@ -1,127 +0,0 @@ -.lnsWorkspacePanelWrapper { - @include euiScrollBar; - overflow: hidden; - // Override panel size padding - padding: 0 !important; // sass-lint:disable-line no-important - margin-bottom: $euiSize; - display: flex; - flex-direction: column; - position: relative; // For positioning the dnd overlay - - .lnsWorkspacePanelWrapper__pageContentHeader { - @include euiTitle('xs'); - padding: $euiSizeM; - // override EuiPage - margin-bottom: 0 !important; // sass-lint:disable-line no-important - } - - .lnsWorkspacePanelWrapper__pageContentHeader--unsaved { - color: $euiTextSubduedColor; - } - - .lnsWorkspacePanelWrapper__pageContentBody { - @include euiScrollBar; - flex-grow: 1; - display: flex; - align-items: stretch; - justify-content: stretch; - overflow: hidden; - - > * { - flex: 1 1 100%; - display: flex; - align-items: center; - justify-content: center; - overflow: hidden; - } - } -} - -.lnsWorkspacePanel__dragDrop { - // Disable the coloring of the DnD for this element as we'll - // Color the whole panel instead - background-color: transparent !important; // sass-lint:disable-line no-important -} - -.lnsExpressionRenderer { - .lnsDragDrop-isDropTarget & { - transition: filter $euiAnimSpeedNormal ease-in-out, opacity $euiAnimSpeedNormal ease-in-out; - filter: blur($euiSizeXS); - opacity: .25; - } -} - -.lnsWorkspacePanel__emptyContent { - position: absolute; - left: 0; - right: 0; - bottom: 0; - top: 0; - display: flex; - justify-content: center; - align-items: center; - transition: background-color $euiAnimSpeedNormal ease-in-out; - - .lnsDragDrop-isDropTarget & { - background-color: transparentize($euiColorSecondary, .9); - - p { - transition: filter $euiAnimSpeedNormal ease-in-out; - filter: blur(5px); - } - } - - .lnsDragDrop-isActiveDropTarget & { - background-color: transparentize($euiColorSecondary, .75); - - .lnsDropIllustration__hand { - animation: pulseArrowContinuous 1.5s ease-in-out 0s infinite normal forwards; - } - } - - &.lnsWorkspacePanel__emptyContent-onTop p { - display: none; - } -} - -.lnsWorkspacePanelWrapper__toolbar { - margin-bottom: 0; -} - -.lnsDropIllustration__adjustFill { - fill: $euiColorFullShade; -} - -.lnsWorkspacePanel__dropIllustration { - overflow: visible; // Shows arrow animation when it gets out of bounds - margin-top: $euiSizeL; - margin-bottom: $euiSizeXXL; - // Drop shadow values is a dupe of @euiBottomShadowMedium but used as a filter - // Hard-coded px values OK (@cchaos) - // sass-lint:disable-block indentation - filter: - drop-shadow(0 6px 12px transparentize($euiShadowColor, .8)) - drop-shadow(0 4px 4px transparentize($euiShadowColor, .8)) - drop-shadow(0 2px 2px transparentize($euiShadowColor, .8)); -} - -.lnsDropIllustration__hand { - animation: pulseArrow 5s ease-in-out 0s infinite normal forwards; -} - -@keyframes pulseArrow { - 0% { transform: translateY(0%); } - 65% { transform: translateY(0%); } - 72% { transform: translateY(10%); } - 79% { transform: translateY(7%); } - 86% { transform: translateY(10%); } - 95% { transform: translateY(0); } -} - -@keyframes pulseArrowContinuous { - 0% { transform: translateY(10%); } - 25% { transform: translateY(15%); } - 50% { transform: translateY(10%); } - 75% { transform: translateY(15%); } - 100% { transform: translateY(10%); } -} diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.scss b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.scss index 1965b51f97034..a58b5c21e7724 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.scss +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.scss @@ -3,5 +3,5 @@ // Remove EuiButton's default shadow to make button more subtle // sass-lint:disable-block no-important box-shadow: none !important; - border: 1px dashed currentColor; + border-color: $euiColorLightShade; } diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx index ad16038f44911..6b7e5ba8ea89d 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx @@ -121,6 +121,9 @@ function LayerPanels( { dispatch({ type: 'UPDATE_STATE', diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/dimension_container.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/dimension_container.tsx index d6b395ac74cce..19f4c0428260e 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/dimension_container.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/dimension_container.tsx @@ -13,6 +13,7 @@ import { EuiButtonEmpty, EuiFlexItem, EuiFocusTrap, + EuiOutsideClickDetector, } from '@elastic/eui'; import classNames from 'classnames'; @@ -91,43 +92,45 @@ export function DimensionContainer({ const flyout = flyoutIsVisible && ( -
- - - - {panelTitle} + +
+ + + + {panelTitle} + + + + + {panel} + + + + {i18n.translate('xpack.lens.dimensionContainer.close', { + defaultMessage: 'Close', + })} - - - - {panel} - - - - {i18n.translate('xpack.lens.dimensionContainer.close', { - defaultMessage: 'Close', - })} - - -
+ +
+
); return ( <> -
{trigger}
+ {trigger} {flyout} ); diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.scss b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.scss index b85c3e843613d..c77db2e65ce2d 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.scss +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.scss @@ -27,36 +27,41 @@ .lnsLayerPanel__dimension { @include euiFontSizeS; - background: lightOrDarkTheme($euiColorEmptyShade, $euiColorLightestShade); border-radius: $euiBorderRadius; display: flex; align-items: center; margin-top: $euiSizeXS; overflow: hidden; -} + width: 100%; + min-height: $euiSizeXXL; -.lnsLayerPanel__dimension-isHidden { - opacity: 0; -} + // NativeRenderer is messing this up + > div { + flex-grow: 1; + } -.lnsLayerPanel__dimension-isReplacing { - text-decoration: line-through; + &:focus, + &:focus-within { + @include euiFocusRing; + } } .lnsLayerPanel__triggerLink { - padding: $euiSizeS; width: 100%; - display: flex; - align-items: center; - min-height: $euiSizeXXL; -} + padding: $euiSizeS; + min-height: $euiSizeXXL - 2; -.lnsLayerPanel__anchor { - width: 100%; + &:focus { + background-color: transparent !important; // sass-lint:disable-line no-important + outline: none !important; // sass-lint:disable-line no-important + } } -.lnsLayerPanel__dndGrab { - padding: $euiSizeS; +.lnsLayerPanel__triggerLinkContent { + // Make EUI button content not centered + justify-content: flex-start; + padding: 0 !important; // sass-lint:disable-line no-important + color: $euiTextSubduedColor; } .lnsLayerPanel__styleEditor { diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx index 46cd0292f2459..ce2955da890d7 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx @@ -17,7 +17,6 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import classNames from 'classnames'; import { NativeRenderer } from '../../../native_renderer'; import { StateSetter, isDraggedOperation } from '../../../types'; import { DragContext, DragDrop, ChildDragDropProvider } from '../../../drag_drop'; @@ -33,6 +32,28 @@ const initialDimensionContainerState = { addingToGroupId: null, }; +function isConfiguration( + value: unknown +): value is { columnId: string; groupId: string; layerId: string } { + return ( + value && + typeof value === 'object' && + 'columnId' in value && + 'groupId' in value && + 'layerId' in value + ); +} + +function isSameConfiguration(config1: unknown, config2: unknown) { + return ( + isConfiguration(config1) && + isConfiguration(config2) && + config1.columnId === config2.columnId && + config1.groupId === config2.groupId && + config1.layerId === config2.layerId + ); +} + export function LayerPanel( props: Exclude & { layerId: string; @@ -203,25 +224,22 @@ export function LayerPanel( return ( { - // If we are dragging another column, add an indication that the behavior will be a replacement' - if ( - isDraggedOperation(dragDropContext.dragging) && - group.groupId !== dragDropContext.dragging.groupId - ) { - return 'lnsLayerPanel__dimension-isReplacing'; - } - return ''; - }} + dragType={ + isDraggedOperation(dragDropContext.dragging) && + accessor === dragDropContext.dragging.columnId + ? 'move' + : 'copy' + } + dropType={ + isDraggedOperation(dragDropContext.dragging) && + group.groupId !== dragDropContext.dragging.groupId + ? 'replace' + : 'add' + } data-test-subj={group.dataTestSubj} draggable={!dimensionContainerState.isOpen} value={{ columnId: accessor, groupId: group.groupId, layerId }} + isValueEqual={isSameConfiguration} label={group.groupLabel} droppable={ Boolean(dragDropContext.dragging) && @@ -254,83 +272,84 @@ export function LayerPanel( } }} > - { - if (dimensionContainerState.isOpen) { - setDimensionContainerState(initialDimensionContainerState); - } else { - setDimensionContainerState({ - isOpen: true, - openId: accessor, - addingToGroupId: null, // not set for existing dimension - }); - } - }, - }} - /> - } - panel={ - <> - {datasourceDimensionEditor} - {visDimensionEditor} - - } - panelTitle={i18n.translate('xpack.lens.configure.configurePanelTitle', { - defaultMessage: '{groupLabel} configuration', - values: { - groupLabel: group.groupLabel, - }, - })} - /> +
+ { + if (dimensionContainerState.isOpen) { + setDimensionContainerState(initialDimensionContainerState); + } else { + setDimensionContainerState({ + isOpen: true, + openId: accessor, + addingToGroupId: null, // not set for existing dimension + }); + } + }, + }} + /> + } + panel={ + <> + {datasourceDimensionEditor} + {visDimensionEditor} + + } + panelTitle={i18n.translate('xpack.lens.configure.configurePanelTitle', { + defaultMessage: '{groupLabel} configuration', + values: { + groupLabel: group.groupLabel, + }, + })} + /> - { - trackUiEvent('indexpattern_dimension_removed'); - props.updateAll( - datasourceId, - layerDatasource.removeColumn({ - layerId, - columnId: accessor, - prevState: layerDatasourceState, - }), - activeVisualization.removeDimension({ - layerId, - columnId: accessor, - prevState: props.visualizationState, - }) - ); - }} - /> + { + trackUiEvent('indexpattern_dimension_removed'); + props.updateAll( + datasourceId, + layerDatasource.removeColumn({ + layerId, + columnId: accessor, + prevState: layerDatasourceState, + }), + activeVisualization.removeDimension({ + layerId, + columnId: accessor, + prevState: props.visualizationState, + }) + ); + }} + /> +
); })} {group.supportsMoreColumns ? ( - +
+ { if (dimensionContainerState.isOpen) { setDimensionContainerState(initialDimensionContainerState); @@ -402,52 +421,51 @@ export function LayerPanel( }); } }} - size="xs" > -
- } - panelTitle={i18n.translate('xpack.lens.configure.configurePanelTitle', { - defaultMessage: '{groupLabel} configuration', - values: { - groupLabel: group.groupLabel, - }, - })} - panel={ - { - props.updateAll( - datasourceId, - newState, - activeVisualization.setDimension({ - layerId, - groupId: group.groupId, - columnId: newId, - prevState: props.visualizationState, - }) - ); - setDimensionContainerState({ - isOpen: true, - openId: newId, - addingToGroupId: null, // clear now that dimension exists - }); - }, - }} - /> - } - /> + setState: (newState: unknown) => { + props.updateAll( + datasourceId, + newState, + activeVisualization.setDimension({ + layerId, + groupId: group.groupId, + columnId: newId, + prevState: props.visualizationState, + }) + ); + setDimensionContainerState({ + isOpen: true, + openId: newId, + addingToGroupId: null, // clear now that dimension exists + }); + }, + }} + /> + } + /> +
) : null} diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/_data_panel_wrapper.scss b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.scss similarity index 100% rename from x-pack/plugins/lens/public/editor_frame_service/editor_frame/_data_panel_wrapper.scss rename to x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.scss diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.tsx index 5a92f7b5ed524..d00357058bb57 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/data_panel_wrapper.tsx @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import './data_panel_wrapper.scss'; + import React, { useMemo, memo, useContext, useState } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiPopover, EuiButtonIcon, EuiContextMenuPanel, EuiContextMenuItem } from '@elastic/eui'; diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/expression_helpers.ts b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/expression_helpers.ts index 952718e13c8cf..e7568147dc568 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/expression_helpers.ts +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/expression_helpers.ts @@ -73,7 +73,11 @@ export function buildExpression({ datasourceMap, datasourceStates, datasourceLayers, + title, + description, }: { + title?: string; + description?: string; visualization: Visualization | null; visualizationState: unknown; datasourceMap: Record; @@ -89,7 +93,10 @@ export function buildExpression({ if (visualization === null) { return null; } - const visualizationExpression = visualization.toExpression(visualizationState, datasourceLayers); + const visualizationExpression = visualization.toExpression(visualizationState, datasourceLayers, { + title, + description, + }); const completeExpression = prependDatasourceExpression( visualizationExpression, diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/frame_layout.scss b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/frame_layout.scss new file mode 100644 index 0000000000000..ac52190dc7b0d --- /dev/null +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/frame_layout.scss @@ -0,0 +1,56 @@ +@import '../../variables'; + +.lnsFrameLayout { + padding: 0; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + overflow: hidden; + flex-direction: column; +} + +.lnsFrameLayout__pageContent { + display: flex; + overflow: hidden; + flex-grow: 1; +} + +.lnsFrameLayout__pageBody { + @include euiScrollBar; + min-width: $lnsPanelMinWidth + $euiSizeXL; + overflow: hidden auto; + // Leave out bottom padding so the suggestions scrollbar stays flush to window edge + // Leave out left padding so the left sidebar's focus states are visible outside of content bounds + // This also means needing to add same amount of margin to page content and suggestion items + padding: $euiSize $euiSize 0; + + &:first-child { + padding-left: $euiSize; + } +} + +.lnsFrameLayout__sidebar { + margin: 0; + flex: 1 0 18%; + min-width: $lnsPanelMinWidth + $euiSize; + display: flex; + flex-direction: column; + position: relative; +} + +.lnsFrameLayout__sidebar--right { + flex-basis: 25%; + background-color: lightOrDarkTheme($euiColorLightestShade, $euiColorInk); + min-width: $lnsPanelMinWidth + $euiSizeXL; + max-width: $euiFormMaxWidth + $euiSizeXXL; + max-height: 100%; + + .lnsConfigPanel { + @include euiScrollBar; + padding: $euiSize 0 $euiSize $euiSize; + overflow-x: hidden; + overflow-y: scroll; + } +} diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/frame_layout.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/frame_layout.tsx index 56afe3ed69a73..6a0b2c3301119 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/frame_layout.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/frame_layout.tsx @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import './frame_layout.scss'; + import React from 'react'; import { EuiPage, EuiPageSideBar, EuiPageBody } from '@elastic/eui'; diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/index.scss b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/index.scss deleted file mode 100644 index ea58a51073d53..0000000000000 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/index.scss +++ /dev/null @@ -1,5 +0,0 @@ -@import 'data_panel_wrapper'; -@import 'expression_renderer'; -@import 'frame_layout'; -@import 'suggestion_panel'; -@import 'workspace_panel_wrapper'; diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/index.ts b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/index.ts index 41558caafc64c..04d4bc9c25de5 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/index.ts +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/index.ts @@ -5,3 +5,5 @@ */ export * from './editor_frame'; +export * from './state_helpers'; +export * from './state_management'; diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_helpers.ts b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_helpers.ts index 6deb9ffd37a06..1fe5224d0b1b4 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_helpers.ts +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/state_helpers.ts @@ -61,6 +61,8 @@ export async function persistedStateToExpression( state: { visualization: visualizationState, datasourceStates: persistedDatasourceStates }, visualizationType, references, + title, + description, } = doc; if (!visualizationType) return null; const visualization = visualizations[visualizationType!]; @@ -78,6 +80,8 @@ export async function persistedStateToExpression( const datasourceLayers = createDatasourceLayers(datasources, datasourceStates); return buildExpression({ + title, + description, visualization, visualizationState, datasourceMap: datasources, diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.scss b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.scss new file mode 100644 index 0000000000000..007d833e97e9d --- /dev/null +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.scss @@ -0,0 +1,71 @@ +@import '../../mixins'; +@import '../../variables'; + +.lnsSuggestionPanel__title { + margin-left: $euiSizeXS / 2; +} + +.lnsSuggestionPanel__suggestions { + @include euiScrollBar; + @include lnsOverflowShadowHorizontal; + padding-top: $euiSizeXS; + overflow-x: scroll; + overflow-y: hidden; + display: flex; + + // Padding / negative margins to make room for overflow shadow + padding-left: $euiSizeXS; + margin-left: -$euiSizeXS; +} + +.lnsSuggestionPanel__button { + position: relative; // Let the expression progress indicator position itself against the button + flex: 0 0 auto; + width: $lnsSuggestionWidth !important; // sass-lint:disable-line no-important + height: $lnsSuggestionHeight; + margin-right: $euiSizeS; + margin-left: $euiSizeXS / 2; + margin-bottom: $euiSizeXS / 2; + + .lnsSuggestionPanel__expressionRenderer { + position: static; // Let the progress indicator position itself against the button + } +} + +.lnsSuggestionPanel__button-isSelected { + @include euiFocusRing; +} + +.lnsSuggestionPanel__suggestionIcon { + color: $euiColorDarkShade; + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + padding: $euiSizeS; + + &:not(:only-child) { + height: calc(100% - #{$euiSizeL}); + } +} + +.lnsSuggestionPanel__chartWrapper { + display: flex; + height: 100%; + width: 100%; + pointer-events: none; +} + +.lnsSuggestionPanel__chartWrapper--withLabel { + height: calc(100% - #{$euiSizeL}); +} + +.lnsSuggestionPanel__buttonLabel { + @include euiTextTruncate; + @include euiFontSizeXS; + display: block; + font-weight: $euiFontWeightBold; + text-align: center; + flex-grow: 0; +} diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx index e6503cb793a8e..5e5e9cda954ee 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import './suggestion_panel.scss'; + import _, { camelCase } from 'lodash'; import React, { useState, useEffect, useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx index e56e55fdd5d6c..3993b4ffc02b0 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx @@ -208,27 +208,22 @@ export function InnerWorkspacePanel({ >

- {expression === null ? ( - - ) : ( - - )} + {expression === null + ? i18n.translate('xpack.lens.editorFrame.emptyWorkspace', { + defaultMessage: 'Drop some fields here to start', + }) + : i18n.translate('xpack.lens.editorFrame.emptyWorkspaceSimple', { + defaultMessage: 'Drop field here', + })}

- + {expression === null && ( <>

- + {i18n.translate('xpack.lens.editorFrame.emptyWorkspaceHeading', { + defaultMessage: 'Lens is a new tool for creating visualization', + })}

@@ -237,10 +232,9 @@ export function InnerWorkspacePanel({ target="_blank" external > - + {i18n.translate('xpack.lens.editorFrame.goToForums', { + defaultMessage: 'Make requests and give feedback', + })}

@@ -257,7 +251,7 @@ export function InnerWorkspacePanel({ if (localState.expressionBuildError) { return ( - + @@ -283,7 +277,7 @@ export function InnerWorkspacePanel({ onEvent={onEvent} renderError={(errorMessage?: string | null) => { return ( - + @@ -338,8 +332,10 @@ export function InnerWorkspacePanel({ droppable={Boolean(suggestionForDraggedField)} onDrop={onDrop} > - {renderVisualization()} - {Boolean(suggestionForDraggedField) && expression !== null && renderEmptyWorkspace()} +
+ {renderVisualization()} + {Boolean(suggestionForDraggedField) && expression !== null && renderEmptyWorkspace()} +
); diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.scss b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.scss new file mode 100644 index 0000000000000..33b9b2fe1dbf0 --- /dev/null +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.scss @@ -0,0 +1,128 @@ +@import '../../../mixins'; + +.lnsWorkspacePanelWrapper { + @include euiScrollBar; + overflow: hidden; + // Override panel size padding + padding: 0 !important; // sass-lint:disable-line no-important + margin-bottom: $euiSize; + display: flex; + flex-direction: column; + position: relative; // For positioning the dnd overlay + min-height: $euiSizeXXL * 10; + + .lnsWorkspacePanelWrapper__pageContentHeader { + @include euiTitle('xs'); + padding: $euiSizeM; + // override EuiPage + margin-bottom: 0 !important; // sass-lint:disable-line no-important + } + + .lnsWorkspacePanelWrapper__pageContentHeader--unsaved { + color: $euiTextSubduedColor; + } + + .lnsWorkspacePanelWrapper__pageContentBody { + @include euiScrollBar; + flex-grow: 1; + display: flex; + align-items: stretch; + justify-content: stretch; + overflow: auto; + + > * { + flex: 1 1 100%; + display: flex; + align-items: center; + justify-content: center; + overflow: hidden; + } + } +} + +.lnsWorkspacePanel__dragDrop { + // Disable the coloring of the DnD for this element as we'll + // Color the whole panel instead + background-color: transparent !important; // sass-lint:disable-line no-important + border: none !important; // sass-lint:disable-line no-important +} + +.lnsExpressionRenderer { + .lnsDragDrop-isDropTarget & { + transition: filter $euiAnimSpeedNormal ease-in-out, opacity $euiAnimSpeedNormal ease-in-out; + filter: blur($euiSizeXS); + opacity: .25; + } +} + +.lnsWorkspacePanel__emptyContent { + position: absolute; + left: 0; + right: 0; + bottom: 0; + top: 0; + display: flex; + justify-content: center; + align-items: center; + transition: background-color $euiAnimSpeedFast ease-in-out; + + .lnsDragDrop-isDropTarget & { + @include lnsDroppable; + @include lnsDroppableActive; + + p { + transition: filter $euiAnimSpeedFast ease-in-out; + filter: blur(5px); + } + } + + .lnsDragDrop-isActiveDropTarget & { + @include lnsDroppableActiveHover; + + .lnsDropIllustration__hand { + animation: lnsWorkspacePanel__illustrationPulseContinuous 1.5s ease-in-out 0s infinite normal forwards; + } + } +} + +.lnsWorkspacePanelWrapper__toolbar { + margin-bottom: 0; +} + +.lnsDropIllustration__adjustFill { + fill: $euiColorFullShade; +} + +.lnsWorkspacePanel__dropIllustration { + overflow: visible; // Shows arrow animation when it gets out of bounds + margin-top: $euiSizeL; + margin-bottom: $euiSizeXXL; + // Drop shadow values is a dupe of @euiBottomShadowMedium but used as a filter + // Hard-coded px values OK (@cchaos) + // sass-lint:disable-block indentation + filter: + drop-shadow(0 6px 12px transparentize($euiShadowColor, .8)) + drop-shadow(0 4px 4px transparentize($euiShadowColor, .8)) + drop-shadow(0 2px 2px transparentize($euiShadowColor, .8)); +} + +.lnsDropIllustration__hand { + animation: lnsWorkspacePanel__illustrationPulseArrow 5s ease-in-out 0s infinite normal forwards; +} + +@keyframes lnsWorkspacePanel__illustrationPulseArrow { + 0% { transform: translateY(0%); } + 65% { transform: translateY(0%); } + 72% { transform: translateY(10%); } + 79% { transform: translateY(7%); } + 86% { transform: translateY(10%); } + 95% { transform: translateY(0); } +} + +@keyframes lnsWorkspacePanel__illustrationPulseContinuous { + 0% { transform: translateY(10%); } + 25% { transform: translateY(15%); } + 50% { transform: translateY(10%); } + 75% { transform: translateY(15%); } + 100% { transform: translateY(10%); } +} diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx index 8e7d504ff7677..fa63cd3c6f1e0 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import './workspace_panel_wrapper.scss'; + import React, { useCallback } from 'react'; import { i18n } from '@kbn/i18n'; import classNames from 'classnames'; diff --git a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.test.tsx index d48f9ed713caf..151f85e817c70 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.test.tsx @@ -26,7 +26,6 @@ import { VIS_EVENT_TO_TRIGGER } from '../../../../../../src/plugins/visualizatio import { coreMock, httpServiceMock } from '../../../../../../src/core/public/mocks'; import { IBasePath } from '../../../../../../src/core/public'; import { AttributeService } from '../../../../../../src/plugins/dashboard/public'; -import { Ast } from '@kbn/interpreter/common'; import { LensAttributeService } from '../../lens_attribute_service'; jest.mock('../../../../../../src/plugins/inspector/public/', () => ({ @@ -103,8 +102,14 @@ describe('embeddable', () => { indexPatternService: {} as IndexPatternsContract, editable: true, getTrigger, - documentToExpression: () => Promise.resolve({} as Ast), - toExpressionString: () => 'my | expression', + documentToExpression: () => + Promise.resolve({ + type: 'expression', + chain: [ + { type: 'function', function: 'my', arguments: {} }, + { type: 'function', function: 'expression', arguments: {} }, + ], + }), }, {} as LensEmbeddableInput ); @@ -112,7 +117,8 @@ describe('embeddable', () => { embeddable.render(mountpoint); expect(expressionRenderer).toHaveBeenCalledTimes(1); - expect(expressionRenderer.mock.calls[0][0]!.expression).toEqual('my | expression'); + expect(expressionRenderer.mock.calls[0][0]!.expression).toEqual(`my +| expression`); }); it('should re-render if new input is pushed', async () => { @@ -129,8 +135,14 @@ describe('embeddable', () => { indexPatternService: {} as IndexPatternsContract, editable: true, getTrigger, - documentToExpression: () => Promise.resolve({} as Ast), - toExpressionString: () => 'my | expression', + documentToExpression: () => + Promise.resolve({ + type: 'expression', + chain: [ + { type: 'function', function: 'my', arguments: {} }, + { type: 'function', function: 'expression', arguments: {} }, + ], + }), }, { id: '123' } as LensEmbeddableInput ); @@ -162,8 +174,14 @@ describe('embeddable', () => { indexPatternService: {} as IndexPatternsContract, editable: true, getTrigger, - documentToExpression: () => Promise.resolve({} as Ast), - toExpressionString: () => 'my | expression', + documentToExpression: () => + Promise.resolve({ + type: 'expression', + chain: [ + { type: 'function', function: 'my', arguments: {} }, + { type: 'function', function: 'expression', arguments: {} }, + ], + }), }, input ); @@ -208,8 +226,14 @@ describe('embeddable', () => { indexPatternService: {} as IndexPatternsContract, editable: true, getTrigger, - documentToExpression: () => Promise.resolve({} as Ast), - toExpressionString: () => 'my | expression', + documentToExpression: () => + Promise.resolve({ + type: 'expression', + chain: [ + { type: 'function', function: 'my', arguments: {} }, + { type: 'function', function: 'expression', arguments: {} }, + ], + }), }, input ); @@ -237,8 +261,14 @@ describe('embeddable', () => { indexPatternService: {} as IndexPatternsContract, editable: true, getTrigger, - documentToExpression: () => Promise.resolve({} as Ast), - toExpressionString: () => 'my | expression', + documentToExpression: () => + Promise.resolve({ + type: 'expression', + chain: [ + { type: 'function', function: 'my', arguments: {} }, + { type: 'function', function: 'expression', arguments: {} }, + ], + }), }, { id: '123' } as LensEmbeddableInput ); @@ -270,8 +300,14 @@ describe('embeddable', () => { indexPatternService: {} as IndexPatternsContract, editable: true, getTrigger, - documentToExpression: () => Promise.resolve({} as Ast), - toExpressionString: () => 'my | expression', + documentToExpression: () => + Promise.resolve({ + type: 'expression', + chain: [ + { type: 'function', function: 'my', arguments: {} }, + { type: 'function', function: 'expression', arguments: {} }, + ], + }), }, { id: '123', timeRange, query, filters } as LensEmbeddableInput ); @@ -311,8 +347,14 @@ describe('embeddable', () => { indexPatternService: {} as IndexPatternsContract, editable: true, getTrigger, - documentToExpression: () => Promise.resolve({} as Ast), - toExpressionString: () => 'my | expression', + documentToExpression: () => + Promise.resolve({ + type: 'expression', + chain: [ + { type: 'function', function: 'my', arguments: {} }, + { type: 'function', function: 'expression', arguments: {} }, + ], + }), }, { id: '123', timeRange, query, filters } as LensEmbeddableInput ); diff --git a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx index 61a5d8cacdc4f..1297c1da6e1b6 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable.tsx @@ -18,7 +18,7 @@ import { import { ExecutionContextSearch } from 'src/plugins/expressions'; import { Subscription } from 'rxjs'; -import { Ast } from '@kbn/interpreter/common'; +import { toExpression, Ast } from '@kbn/interpreter/common'; import { ExpressionRendererEvent, ReactExpressionRendererType, @@ -59,7 +59,6 @@ export interface LensEmbeddableOutput extends EmbeddableOutput { export interface LensEmbeddableDeps { attributeService: LensAttributeService; documentToExpression: (doc: Document) => Promise; - toExpressionString: (astObj: Ast, type?: string) => string; editable: boolean; indexPatternService: IndexPatternsContract; expressionRenderer: ReactExpressionRendererType; @@ -135,7 +134,7 @@ export class Embeddable savedObjectId: (input as LensByReferenceInput)?.savedObjectId, }; const expression = await this.deps.documentToExpression(this.savedVis); - this.expression = expression ? this.deps.toExpressionString(expression) : null; + this.expression = expression ? toExpression(expression) : null; await this.initializeOutput(); this.isInitialized = true; if (this.domNode) { @@ -295,6 +294,12 @@ export class Embeddable return this.deps.attributeService.getInputAsValueType(input); }; + // same API as Visualize + public getDescription() { + // mind that savedViz is loaded in async way here + return this.savedVis && this.savedVis.description; + } + destroy() { super.destroy(); if (this.domNode) { diff --git a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable_factory.ts b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable_factory.ts index 8771d1ebaddb1..35d120e5c4f45 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable_factory.ts +++ b/x-pack/plugins/lens/public/editor_frame_service/embeddable/embeddable_factory.ts @@ -7,7 +7,7 @@ import { Capabilities, HttpSetup } from 'kibana/public'; import { i18n } from '@kbn/i18n'; import { RecursiveReadonly } from '@kbn/utility-types'; -import { toExpression, Ast } from '@kbn/interpreter/target/common'; +import { Ast } from '@kbn/interpreter/target/common'; import { IndexPatternsContract, TimefilterContract, @@ -17,7 +17,7 @@ import { EmbeddableFactoryDefinition, IContainer, } from '../../../../../../src/plugins/embeddable/public'; -import { Embeddable, LensByReferenceInput, LensEmbeddableInput } from './embeddable'; +import { LensByReferenceInput, LensEmbeddableInput } from './embeddable'; import { DOC_TYPE } from '../../persistence'; import { UiActionsStart } from '../../../../../../src/plugins/ui_actions/public'; import { Document } from '../../persistence/saved_object_store'; @@ -83,6 +83,8 @@ export class EmbeddableFactory implements EmbeddableFactoryDefinition { indexPatternService, } = await this.getStartServices(); + const { Embeddable } = await import('../../async_services'); + return new Embeddable( { attributeService, @@ -93,7 +95,6 @@ export class EmbeddableFactory implements EmbeddableFactoryDefinition { basePath: coreHttp.basePath, getTrigger: uiActions?.getTrigger, documentToExpression, - toExpressionString: toExpression, }, input, parent diff --git a/x-pack/plugins/lens/public/editor_frame_service/embeddable/index.ts b/x-pack/plugins/lens/public/editor_frame_service/embeddable/index.ts new file mode 100644 index 0000000000000..460341365094e --- /dev/null +++ b/x-pack/plugins/lens/public/editor_frame_service/embeddable/index.ts @@ -0,0 +1,7 @@ +/* + * 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 * from './embeddable'; diff --git a/x-pack/plugins/lens/public/editor_frame_service/service.tsx b/x-pack/plugins/lens/public/editor_frame_service/service.tsx index bebc3e6989902..e6d7f78f5ad07 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/service.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/service.tsx @@ -22,14 +22,11 @@ import { EditorFrameStart, } from '../types'; import { Document } from '../persistence/saved_object_store'; -import { EditorFrame } from './editor_frame'; import { mergeTables } from './merge_tables'; import { formatColumn } from './format_column'; import { EmbeddableFactory, LensEmbeddableStartServices } from './embeddable/embeddable_factory'; -import { getActiveDatasourceIdFromDoc } from './editor_frame/state_management'; import { UiActionsStart } from '../../../../../src/plugins/ui_actions/public'; import { DashboardStart } from '../../../../../src/plugins/dashboard/public'; -import { persistedStateToExpression } from './editor_frame/state_helpers'; import { LensAttributeService } from '../lens_attribute_service'; export interface EditorFrameSetupPlugins { @@ -47,9 +44,11 @@ export interface EditorFrameStartPlugins { } async function collectAsyncDefinitions( - definitions: Array> + definitions: Array Promise)> ) { - const resolvedDefinitions = await Promise.all(definitions); + const resolvedDefinitions = await Promise.all( + definitions.map((definition) => (typeof definition === 'function' ? definition() : definition)) + ); const definitionMap: Record = {}; resolvedDefinitions.forEach((definition) => { definitionMap[definition.id] = definition; @@ -61,8 +60,8 @@ async function collectAsyncDefinitions( export class EditorFrameService { constructor() {} - private readonly datasources: Array> = []; - private readonly visualizations: Array> = []; + private readonly datasources: Array Promise)> = []; + private readonly visualizations: Array Promise)> = []; /** * This method takes a Lens saved object as returned from the persistence helper, @@ -76,6 +75,8 @@ export class EditorFrameService { collectAsyncDefinitions(this.visualizations), ]); + const { persistedStateToExpression } = await import('../async_services'); + return await persistedStateToExpression(resolvedDatasources, resolvedVisualizations, doc); } @@ -124,7 +125,7 @@ export class EditorFrameService { ]); return { - mount: ( + mount: async ( element, { doc, onError, dateRange, query, filters, savedQuery, onChange, showNoDataPopover } ) => { @@ -132,6 +133,8 @@ export class EditorFrameService { const firstDatasourceId = Object.keys(resolvedDatasources)[0]; const firstVisualizationId = Object.keys(resolvedVisualizations)[0]; + const { EditorFrame, getActiveDatasourceIdFromDoc } = await import('../async_services'); + render(
diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/bucket_nesting_editor.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/bucket_nesting_editor.tsx index 3d692b1f7f5a8..962abd8d943db 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/bucket_nesting_editor.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/bucket_nesting_editor.tsx @@ -9,6 +9,7 @@ import { i18n } from '@kbn/i18n'; import { EuiFormRow, EuiHorizontalRule, EuiRadio, EuiSelect, htmlIdGenerator } from '@elastic/eui'; import { IndexPatternLayer, IndexPatternField } from '../types'; import { hasField } from '../utils'; +import { IndexPatternColumn } from '../operations'; const generator = htmlIdGenerator('lens-nesting'); @@ -21,6 +22,10 @@ function nestColumn(columnOrder: string[], outer: string, inner: string) { return result; } +function getFieldName(fieldMap: Record, column: IndexPatternColumn) { + return hasField(column) ? fieldMap[column.sourceField]?.displayName || column.sourceField : ''; +} + export function BucketNestingEditor({ columnId, layer, @@ -39,7 +44,7 @@ export function BucketNestingEditor({ .map(([value, c]) => ({ value, text: c.label, - fieldName: hasField(c) ? fieldMap[c.sourceField].displayName : '', + fieldName: getFieldName(fieldMap, c), operationType: c.operationType, })); @@ -47,7 +52,7 @@ export function BucketNestingEditor({ return null; } - const fieldName = hasField(column) ? fieldMap[column.sourceField].displayName : ''; + const fieldName = getFieldName(fieldMap, column); const prevColumn = layer.columnOrder[layer.columnOrder.indexOf(columnId) - 1]; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.tsx index 2572f732aa1b3..0e33c20faff7e 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.tsx @@ -26,7 +26,7 @@ import { } from '../operations'; import { deleteColumn, changeColumn, updateColumnParam } from '../state_helpers'; import { FieldSelect } from './field_select'; -import { hasField } from '../utils'; +import { hasField, fieldIsInvalid } from '../utils'; import { BucketNestingEditor } from './bucket_nesting_editor'; import { IndexPattern, IndexPatternField } from '../types'; import { trackUiEvent } from '../../lens_ui_telemetry'; @@ -40,19 +40,6 @@ export interface DimensionEditorProps extends IndexPatternDimensionEditorProps { currentIndexPattern: IndexPattern; } -function asOperationOptions(operationTypes: OperationType[], compatibleWithCurrentField: boolean) { - return [...operationTypes] - .sort((opType1, opType2) => { - return operationPanels[opType1].displayName.localeCompare( - operationPanels[opType2].displayName - ); - }) - .map((operationType) => ({ - operationType, - compatibleWithCurrentField, - })); -} - const LabelInput = ({ value, onChange }: { value: string; onChange: (value: string) => void }) => { const [inputValue, setInputValue] = useState(value); @@ -98,7 +85,7 @@ export function DimensionEditor(props: DimensionEditorProps) { currentIndexPattern, hideGrouping, } = props; - const { operationByField, fieldByOperation } = operationSupportMatrix; + const { fieldByOperation, operationWithoutField } = operationSupportMatrix; const [ incompatibleSelectedOperationType, setInvalidOperationType, @@ -117,30 +104,44 @@ export function DimensionEditor(props: DimensionEditorProps) { return fields; }, [currentIndexPattern]); - function getOperationTypes() { - const possibleOperationTypes = Object.keys(fieldByOperation) as OperationType[]; - const validOperationTypes: OperationType[] = []; + const possibleOperations = useMemo(() => { + return Object.values(operationDefinitionMap) + .sort((op1, op2) => { + return op1.displayName.localeCompare(op2.displayName); + }) + .map((def) => def.type) + .filter( + (type) => fieldByOperation[type]?.length || operationWithoutField.indexOf(type) !== -1 + ); + }, [fieldByOperation, operationWithoutField]); - if (!selectedColumn) { - validOperationTypes.push(...(Object.keys(fieldByOperation) as OperationType[])); - } else if (hasField(selectedColumn) && operationByField[selectedColumn.sourceField]) { - validOperationTypes.push(...operationByField[selectedColumn.sourceField]!); - } + // Operations are compatible if they match inputs. They are always compatible in + // the empty state. Field-based operations are not compatible with field-less operations. + const operationsWithCompatibility = [...possibleOperations].map((operationType) => { + const definition = operationDefinitionMap[operationType]; - return _.uniqBy( - [ - ...asOperationOptions(validOperationTypes, true), - ...asOperationOptions(possibleOperationTypes, false), - ...asOperationOptions( - operationSupportMatrix.operationWithoutField, - !selectedColumn || !hasField(selectedColumn) - ), - ], - 'operationType' - ); - } + return { + operationType, + compatibleWithCurrentField: + !selectedColumn || + (selectedColumn && + hasField(selectedColumn) && + definition.input === 'field' && + fieldByOperation[operationType]?.indexOf(selectedColumn.sourceField) !== -1) || + (selectedColumn && !hasField(selectedColumn) && definition.input !== 'field'), + }; + }); + + const selectedColumnSourceField = + selectedColumn && 'sourceField' in selectedColumn ? selectedColumn.sourceField : undefined; + + const currentFieldIsInvalid = useMemo( + () => + fieldIsInvalid(selectedColumnSourceField, selectedColumn?.operationType, currentIndexPattern), + [selectedColumnSourceField, selectedColumn?.operationType, currentIndexPattern] + ); - const sideNavItems: EuiListGroupItemProps[] = getOperationTypes().map( + const sideNavItems: EuiListGroupItemProps[] = operationsWithCompatibility.map( ({ operationType, compatibleWithCurrentField }) => { const isActive = Boolean( incompatibleSelectedOperationType === operationType || @@ -256,7 +257,7 @@ export function DimensionEditor(props: DimensionEditorProps) {
{i18n.translate('xpack.lens.indexPattern.functionsLabel', { - defaultMessage: 'Choose a function', + defaultMessage: 'Select a function', })} @@ -276,23 +277,19 @@ export function DimensionEditor(props: DimensionEditorProps) { ) : null} - {!incompatibleSelectedOperationType && selectedColumn && ParamEditor && ( - <> - - - )} + {!currentFieldIsInvalid && + !incompatibleSelectedOperationType && + selectedColumn && + ParamEditor && ( + <> + + + )}
-
- {!incompatibleSelectedOperationType && selectedColumn && ( - { - setState({ - ...state, - layers: { - ...state.layers, - [layerId]: { - ...state.layers[layerId], - columns: { - ...state.layers[layerId].columns, - [columnId]: { - ...selectedColumn, - label: value, - customLabel: true, + {!currentFieldIsInvalid && ( +
+ {!incompatibleSelectedOperationType && selectedColumn && ( + { + setState({ + ...state, + layers: { + ...state.layers, + [layerId]: { + ...state.layers[layerId], + columns: { + ...state.layers[layerId].columns, + [columnId]: { + ...selectedColumn, + label: value, + customLabel: true, + }, }, }, }, - }, - }); - }} - /> - )} - - {!hideGrouping && ( - { - setState({ - ...state, - layers: { - ...state.layers, - [props.layerId]: { - ...state.layers[props.layerId], - columnOrder, + }); + }} + /> + )} + + {!hideGrouping && ( + { + setState({ + ...state, + layers: { + ...state.layers, + [props.layerId]: { + ...state.layers[props.layerId], + columnOrder, + }, }, - }, - }); - }} - /> - )} - - {selectedColumn && selectedColumn.dataType === 'number' ? ( - { - setState( - updateColumnParam({ - state, - layerId, - currentColumn: selectedColumn, - paramName: 'format', - value: newFormat, - }) - ); - }} - /> - ) : null} -
+ }); + }} + /> + )} + + {selectedColumn && selectedColumn.dataType === 'number' ? ( + { + setState( + updateColumnParam({ + state, + layerId, + currentColumn: selectedColumn, + paramName: 'format', + value: newFormat, + }) + ); + }} + /> + ) : null} +
+ )}
); } +function getErrorMessage( + selectedColumn: IndexPatternColumn | undefined, + incompatibleSelectedOperationType: boolean, + input: 'none' | 'field' | undefined, + fieldInvalid: boolean +) { + if (selectedColumn && incompatibleSelectedOperationType) { + if (input === 'field') { + return i18n.translate('xpack.lens.indexPattern.invalidOperationLabel', { + defaultMessage: 'To use this function, select a different field.', + }); + } + return i18n.translate('xpack.lens.indexPattern.chooseFieldLabel', { + defaultMessage: 'To use this function, select a field.', + }); + } + if (fieldInvalid) { + return i18n.translate('xpack.lens.indexPattern.invalidFieldLabel', { + defaultMessage: 'Invalid field. Check your index pattern or pick another field.', + }); + } +} diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.test.tsx index 2d7539a9e3ee8..d15825718682c 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.test.tsx @@ -25,6 +25,7 @@ import { IndexPatternPrivateState } from '../types'; import { IndexPatternColumn } from '../operations'; import { documentField } from '../document_field'; import { OperationMetadata } from '../../types'; +import { DateHistogramIndexPatternColumn } from '../operations/definitions/date_histogram'; jest.mock('../loader'); jest.mock('../state_helpers'); @@ -801,6 +802,35 @@ describe('IndexPatternDimensionEditorPanel', () => { }); }); + it('should render invalid field if field reference is broken', () => { + wrapper = mount( + + ); + + expect(wrapper.find(EuiComboBox).prop('selectedOptions')).toEqual([ + { + label: 'nonexistent', + value: { type: 'field', field: 'nonexistent' }, + }, + ]); + }); + it('should support selecting the operation before the field', () => { wrapper = mount(); @@ -960,12 +990,12 @@ describe('IndexPatternDimensionEditorPanel', () => { const items: EuiListGroupItemProps[] = wrapper.find(EuiListGroup).prop('listItems') || []; expect(items.map(({ label }: { label: React.ReactNode }) => label)).toEqual([ - 'Unique count', 'Average', 'Count', 'Maximum', 'Minimum', 'Sum', + 'Unique count', ]); }); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.tsx index c4d8300722f83..12b8d91c35ade 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_panel.tsx @@ -5,9 +5,9 @@ */ import _ from 'lodash'; -import React, { memo } from 'react'; +import React, { memo, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiLink } from '@elastic/eui'; +import { EuiLink, EuiIcon, EuiToolTip, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from 'kibana/public'; import { IStorageWrapper } from 'src/plugins/kibana_utils/public'; import { @@ -22,7 +22,7 @@ import { IndexPatternColumn, OperationType } from '../indexpattern'; import { getAvailableOperationsByMetadata, buildColumn, changeField } from '../operations'; import { DimensionEditor } from './dimension_editor'; import { changeColumn } from '../state_helpers'; -import { isDraggedField, hasField } from '../utils'; +import { isDraggedField, hasField, fieldIsInvalid } from '../utils'; import { IndexPatternPrivateState, IndexPatternField } from '../types'; import { trackUiEvent } from '../../lens_ui_telemetry'; import { DateRange } from '../../../common'; @@ -233,26 +233,71 @@ export const IndexPatternDimensionTriggerComponent = function IndexPatternDimens props: IndexPatternDimensionTriggerProps ) { const layerId = props.layerId; - - const selectedColumn: IndexPatternColumn | null = - props.state.layers[layerId].columns[props.columnId] || null; + const layer = props.state.layers[layerId]; + const selectedColumn: IndexPatternColumn | null = layer.columns[props.columnId] || null; + const currentIndexPattern = props.state.indexPatterns[layer.indexPatternId]; + + const selectedColumnSourceField = + selectedColumn && 'sourceField' in selectedColumn ? selectedColumn.sourceField : undefined; + const currentFieldIsInvalid = useMemo( + () => + fieldIsInvalid(selectedColumnSourceField, selectedColumn?.operationType, currentIndexPattern), + [selectedColumnSourceField, selectedColumn?.operationType, currentIndexPattern] + ); const { columnId, uniqueLabel } = props; if (!selectedColumn) { return null; } + + const triggerLinkA11yText = i18n.translate('xpack.lens.configure.editConfig', { + defaultMessage: 'Click to edit configuration or drag to move', + }); + + if (currentFieldIsInvalid) { + return ( + + {i18n.translate('xpack.lens.configure.invalidConfigTooltip', { + defaultMessage: 'Invalid configuration.', + })} +
+ {i18n.translate('xpack.lens.configure.invalidConfigTooltipClick', { + defaultMessage: 'Click for more details.', + })} +

+ } + anchorClassName="eui-displayBlock" + > + + + + + + {selectedColumn.label} + + +
+ ); + } + return ( {uniqueLabel} diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx index de472cb09cdfe..c2e179fd13a2f 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/field_select.tsx @@ -41,6 +41,7 @@ export interface FieldSelectProps extends EuiComboBoxProps<{}> { onChoose: (choice: FieldChoice) => void; onDeleteColumn: () => void; existingFields: IndexPatternPrivateState['existingFields']; + fieldIsInvalid: boolean; } export function FieldSelect({ @@ -53,6 +54,7 @@ export function FieldSelect({ onChoose, onDeleteColumn, existingFields, + fieldIsInvalid, ...rest }: FieldSelectProps) { const { operationByField } = operationSupportMatrix; @@ -171,12 +173,14 @@ export function FieldSelect({ defaultMessage: 'Field', })} options={(memoizedFieldOptions as unknown) as EuiComboBoxOptionOption[]} - isInvalid={Boolean(incompatibleSelectedOperationType)} + isInvalid={Boolean(incompatibleSelectedOperationType || fieldIsInvalid)} selectedOptions={ ((selectedColumnOperationType && selectedColumnSourceField ? [ { - label: fieldMap[selectedColumnSourceField].displayName, + label: fieldIsInvalid + ? selectedColumnSourceField + : fieldMap[selectedColumnSourceField]?.displayName, value: { type: 'field', field: selectedColumnSourceField }, }, ] diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.scss b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.scss new file mode 100644 index 0000000000000..1b55d9623e223 --- /dev/null +++ b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.scss @@ -0,0 +1,48 @@ +.lnsFieldItem { + .lnsFieldItem__infoIcon { + visibility: hidden; + opacity: 0; + } + + &:hover:not([class*='isActive']) { + cursor: grab; + + .lnsFieldItem__infoIcon { + visibility: visible; + opacity: 1; + transition: opacity $euiAnimSpeedFast ease-in-out 1s; + } + } +} + +.lnsFieldItem--missing { + background: lightOrDarkTheme(transparentize($euiColorMediumShade, .9), $euiColorEmptyShade); + color: $euiColorDarkShade; +} + +.lnsFieldItem__topValue { + margin-bottom: $euiSizeS; + + &:last-of-type { + margin-bottom: 0; + } +} + +.lnsFieldItem__topValueProgress { + background-color: $euiColorLightestShade; + + // sass-lint:disable-block no-vendor-prefixes + &::-webkit-progress-bar { + background-color: $euiColorLightestShade; + } +} + +.lnsFieldItem__fieldPanel { + min-width: 260px; + max-width: 300px; +} + +.lnsFieldItem__buttonGroup { + // Enforce lowercase for buttons or else some browsers inherit all caps from flyout title + text-transform: none; +} diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx index f141d3f8ecb9e..2fbe23f9085f2 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import './field_item.scss'; + import React, { useState } from 'react'; import DateMath from '@elastic/datemath'; import { @@ -31,6 +33,7 @@ import { } from '@elastic/charts'; import { i18n } from '@kbn/i18n'; import { DataPublicPluginStart } from 'src/plugins/data/public'; +import { EuiHighlight } from '@elastic/eui'; import { Query, KBN_FIELD_TYPES, @@ -100,22 +103,6 @@ export const InnerFieldItem = function InnerFieldItem(props: FieldItemProps) { isLoading: false, }); - const wrappableName = wrapOnDot(field.displayName)!; - const wrappableHighlight = wrapOnDot(highlight); - const highlightIndex = wrappableHighlight - ? wrappableName.toLowerCase().indexOf(wrappableHighlight.toLowerCase()) - : -1; - const wrappableHighlightableFieldName = - highlightIndex < 0 ? ( - wrappableName - ) : ( - - {wrappableName.substr(0, highlightIndex)} - {wrappableName.substr(highlightIndex, wrappableHighlight.length)} - {wrappableName.substr(highlightIndex + wrappableHighlight.length)} - - ); - function fetchData() { if (state.isLoading) { return; @@ -198,22 +185,20 @@ export const InnerFieldItem = function InnerFieldItem(props: FieldItemProps) { ownFocus className="lnsFieldItem__popoverAnchor" display="block" + data-test-subj="lnsFieldListPanelField" container={document.querySelector('.application') || undefined} button={ + {wrapOnDot(field.displayName)} + + } fieldInfoIcon={lensInfoIcon} /> @@ -525,7 +514,7 @@ function FieldItemPopoverContents(props: State & FieldItemProps) { - + {Math.round((otherCount / props.sampledValues!) * 100)}% diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/field_list.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/field_list.tsx index 4a9b3a0c63e3f..63809218a1dd0 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/field_list.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/field_list.tsx @@ -52,6 +52,7 @@ export function FieldList({ hasSyncedExistingFields, filter, currentIndexPatternId, + existFieldsInIndex, }: { exists: (field: IndexPatternField) => boolean; fieldGroups: FieldGroups; @@ -63,6 +64,7 @@ export function FieldList({ typeFilter: string[]; }; currentIndexPatternId: string; + existFieldsInIndex: boolean; }) { const [pageSize, setPageSize] = useState(PAGINATION_SIZE); const [scrollContainer, setScrollContainer] = useState(undefined); @@ -180,7 +182,7 @@ export function FieldList({ isAffectedByGlobalFilter={fieldGroup.isAffectedByGlobalFilter} isAffectedByFieldFilter={isAffectedByFieldFilter} isAffectedByTimerange={fieldGroup.isAffectedByTimeFilter} - existFieldsInIndex={!!fieldGroup.fieldCount} + existFieldsInIndex={!!existFieldsInIndex} /> } /> diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/index.ts b/x-pack/plugins/lens/public/indexpattern_datasource/index.ts index 45d0ee45fab4c..4fbed04112632 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/index.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/index.ts @@ -6,8 +6,6 @@ import { CoreSetup } from 'kibana/public'; import { Storage } from '../../../../../src/plugins/kibana_utils/public'; -import { getIndexPatternDatasource } from './indexpattern'; -import { renameColumns } from './rename_columns'; import { ExpressionsSetup } from '../../../../../src/plugins/expressions/public'; import { ChartsPluginSetup } from '../../../../../src/plugins/charts/public'; import { @@ -34,17 +32,17 @@ export class IndexPatternDatasource { core: CoreSetup, { expressions, editorFrame, charts }: IndexPatternDatasourceSetupPlugins ) { - expressions.registerFunction(renameColumns); - - editorFrame.registerDatasource( - core.getStartServices().then(([coreStart, { data }]) => + editorFrame.registerDatasource(async () => { + const { getIndexPatternDatasource, renameColumns } = await import('../async_services'); + expressions.registerFunction(renameColumns); + return core.getStartServices().then(([coreStart, { data }]) => getIndexPatternDatasource({ core: coreStart, storage: new Storage(localStorage), data, charts, }) - ) as Promise - ); + ) as Promise; + }); } } diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx index 3b3750cf7c560..7f7eb0bc0fdac 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx @@ -104,6 +104,8 @@ export function uniqueLabels(layers: Record) { return columnLabelMap; } +export * from './rename_columns'; + export function getIndexPatternDatasource({ core, storage, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx index 663d7c18bb370..80765627c1fc2 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.test.tsx @@ -147,7 +147,7 @@ function testInitialState(): IndexPatternPrivateState { // Private operationType: 'terms', - sourceField: 'op', + sourceField: 'dest', params: { size: 5, orderBy: { type: 'alphabetical' }, @@ -1115,7 +1115,7 @@ describe('IndexPattern Data Source suggestions', () => { // Private operationType: 'terms', - sourceField: 'op', + sourceField: 'dest', params: { size: 5, orderBy: { type: 'alphabetical' }, @@ -1615,7 +1615,7 @@ describe('IndexPattern Data Source suggestions', () => { isBucketed: true, operationType: 'date_histogram', - sourceField: 'field2', + sourceField: 'timestamp', params: { interval: 'd', }, @@ -1626,7 +1626,7 @@ describe('IndexPattern Data Source suggestions', () => { isBucketed: true, operationType: 'terms', - sourceField: 'field1', + sourceField: 'dest', params: { size: 5, orderBy: { type: 'alphabetical' }, orderDirection: 'asc' }, }, id3: { @@ -1635,7 +1635,7 @@ describe('IndexPattern Data Source suggestions', () => { isBucketed: false, operationType: 'avg', - sourceField: 'field1', + sourceField: 'bytes', }, }, columnOrder: ['id1', 'id2', 'id3'], @@ -1652,6 +1652,38 @@ describe('IndexPattern Data Source suggestions', () => { }) ); }); + + it('does not generate suggestions if invalid fields are referenced', () => { + const initialState = testInitialState(); + const state: IndexPatternPrivateState = { + indexPatternRefs: [], + existingFields: {}, + currentIndexPatternId: '1', + indexPatterns: expectedIndexPatterns, + isFirstExistenceFetch: false, + layers: { + first: { + ...initialState.layers.first, + columns: { + ...initialState.layers.first.columns, + col2: { + label: 'Top 5', + dataType: 'string', + isBucketed: true, + + operationType: 'terms', + sourceField: 'nonExistingField', + params: { size: 5, orderBy: { type: 'alphabetical' }, orderDirection: 'asc' }, + }, + }, + columnOrder: ['col1', 'col2'], + }, + }, + }; + + const suggestions = getDatasourceSuggestionsFromCurrentState(state); + expect(suggestions).toEqual([]); + }); }); }); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts index f5e64149c2c76..75945529ffb34 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts @@ -18,7 +18,7 @@ import { } from './operations'; import { operationDefinitions } from './operations/definitions'; import { TermsIndexPatternColumn } from './operations/definitions/terms'; -import { hasField } from './utils'; +import { hasField, hasInvalidReference } from './utils'; import { IndexPattern, IndexPatternPrivateState, @@ -90,6 +90,7 @@ export function getDatasourceSuggestionsForField( indexPatternId: string, field: IndexPatternField ): IndexPatternSugestion[] { + if (hasInvalidReference(state)) return []; const layers = Object.keys(state.layers); const layerIds = layers.filter((id) => state.layers[id].indexPatternId === indexPatternId); @@ -380,6 +381,7 @@ function createNewLayerWithMetricAggregation( export function getDatasourceSuggestionsFromCurrentState( state: IndexPatternPrivateState ): Array> { + if (hasInvalidReference(state)) return []; const layers = Object.entries(state.layers || {}); if (layers.length > 1) { // Return suggestions that reduce the data to each layer individually diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/advanced_editor.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/advanced_editor.tsx index af07f33ec175e..16b861ae034fa 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/advanced_editor.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/advanced_editor.tsx @@ -132,11 +132,11 @@ export const RangePopover = ({ { const newRange = { ...tempRange, - to: target.value !== '' ? Number(target.value) : -Infinity, + to: target.value !== '' ? Number(target.value) : Infinity, }; setTempRange(newRange); saveRangeAndReset(newRange); @@ -208,15 +208,15 @@ export const AdvancedRangeEditor = ({ return ( {' '} - {i18n.translate('xpack.lens.indexPattern.ranges.customIntervalsRemoval', { - defaultMessage: 'Remove custom intervals', + {i18n.translate('xpack.lens.indexPattern.ranges.customRangesRemoval', { + defaultMessage: 'Remove custom ranges', })} @@ -286,8 +286,8 @@ export const AdvancedRangeEditor = ({ addNewRange(); setIsOpenByCreation(true); }} - label={i18n.translate('xpack.lens.indexPattern.ranges.addInterval', { - defaultMessage: 'Add interval', + label={i18n.translate('xpack.lens.indexPattern.ranges.addRange', { + defaultMessage: 'Add range', })} /> diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/range_editor.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/range_editor.tsx index 5d5acf7778973..8ed17a813e7fd 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/range_editor.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/range_editor.tsx @@ -15,6 +15,7 @@ import { EuiFlexGroup, EuiButtonIcon, EuiToolTip, + EuiIconTip, } from '@elastic/eui'; import { IFieldFormat } from 'src/plugins/data/public'; import { RangeColumnParams, UpdateParamsFnType, MODES_TYPES } from './ranges'; @@ -45,8 +46,14 @@ const BaseRangeEditor = ({ ); const granularityLabel = i18n.translate('xpack.lens.indexPattern.ranges.granularity', { - defaultMessage: 'Granularity', + defaultMessage: 'Intervals granularity', }); + const granularityLabelDescription = i18n.translate( + 'xpack.lens.indexPattern.ranges.granularityDescription', + { + defaultMessage: 'Divides the field into evenly spaced intervals.', + } + ); const decreaseButtonLabel = i18n.translate('xpack.lens.indexPattern.ranges.decreaseButtonLabel', { defaultMessage: 'Decrease granularity', }); @@ -57,7 +64,17 @@ const BaseRangeEditor = ({ return ( <> + {granularityLabel}{' '} + + + } data-test-subj="indexPattern-ranges-section-label" labelType="legend" fullWidth @@ -91,7 +108,7 @@ const BaseRangeEditor = ({ /> - + onToggleEditor()}> {i18n.translate('xpack.lens.indexPattern.ranges.customIntervalsToggle', { - defaultMessage: 'Create custom intervals', + defaultMessage: 'Create custom ranges', })} diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.test.tsx index 2409406afcdbc..fb6cf6df8573f 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.test.tsx @@ -485,7 +485,7 @@ describe('ranges', () => { /> ); - // This series of act clojures are made to make it work properly the update flush + // This series of act closures are made to make it work properly the update flush act(() => { instance.find(RangePopover).find(EuiLink).prop('onClick')!({} as ReactMouseEvent); }); @@ -550,6 +550,46 @@ describe('ranges', () => { expect(instance.find(RangePopover)).toHaveLength(1); }); }); + + it('should handle correctly open ranges when saved', () => { + const setStateSpy = jest.fn(); + + // Add an extra open range: + (state.layers.first.columns.col1 as RangeIndexPatternColumn).params.ranges.push({ + from: null, + to: null, + label: '', + }); + + const instance = mount( + + ); + + act(() => { + instance.find(RangePopover).last().find(EuiLink).prop('onClick')!({} as ReactMouseEvent); + }); + + act(() => { + // need another wrapping for this in order to work + instance.update(); + + // Check UI values for open ranges + expect( + instance.find(RangePopover).last().find(EuiFieldNumber).first().prop('value') + ).toBe(''); + + expect(instance.find(RangePopover).last().find(EuiFieldNumber).last().prop('value')).toBe( + '' + ); + }); + }); }); }); }); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.tsx index 1971fb2875bed..a8304456262eb 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.tsx @@ -16,7 +16,13 @@ import { updateColumnParam, changeColumn } from '../../../state_helpers'; import { MODES, AUTO_BARS, DEFAULT_INTERVAL, MIN_HISTOGRAM_BARS, SLICES } from './constants'; type RangeType = Omit; -export type RangeTypeLens = RangeType & { label: string }; +// Try to cover all possible serialized states for ranges +export type RangeTypeLens = (RangeType | { from: Range['from'] | null; to: Range['to'] | null }) & { + label: string; +}; + +// This is a subset of RangeTypeLens which has both from and to defined +type FullRangeTypeLens = Extract>; export type MODES_TYPES = typeof MODES[keyof typeof MODES]; @@ -35,10 +41,13 @@ export type UpdateParamsFnType = ( value: RangeColumnParams[K] ) => void; -export const isValidNumber = (value: number | '') => - value !== '' && !isNaN(value) && isFinite(value); -export const isRangeWithin = (range: RangeTypeLens): boolean => range.from <= range.to; -const isFullRange = ({ from, to }: RangeType) => isValidNumber(from) && isValidNumber(to); +// on initialization values can be null (from the Infinity serialization), so handle it correctly +// or they will be casted to 0 by the editor ( see #78867 ) +export const isValidNumber = (value: number | '' | null): value is number => + value != null && value !== '' && !isNaN(value) && isFinite(value); +export const isRangeWithin = (range: RangeType): boolean => range.from <= range.to; +const isFullRange = (range: RangeTypeLens): range is FullRangeTypeLens => + isValidNumber(range.from) && isValidNumber(range.to); export const isValidRange = (range: RangeTypeLens): boolean => { if (isFullRange(range)) { return isRangeWithin(range); @@ -78,8 +87,8 @@ function getEsAggsParams({ sourceField, params }: RangeIndexPatternColumn) { export const rangeOperation: OperationDefinition = { type: 'range', - displayName: i18n.translate('xpack.lens.indexPattern.ranges', { - defaultMessage: 'Ranges', + displayName: i18n.translate('xpack.lens.indexPattern.intervals', { + defaultMessage: 'Intervals', }), priority: 4, // Higher than terms, so numbers get histogram input: 'field', diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/shared_components/buckets.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/shared_components/buckets.tsx index 47380f7865578..50471ca84c0d8 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/shared_components/buckets.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/shared_components/buckets.tsx @@ -96,7 +96,13 @@ export const DraggableBucketContainer = ({ children: React.ReactNode; } & BucketContainerProps) => { return ( - + {(provided) => {children}} ); @@ -134,7 +140,7 @@ export const DragDropBuckets = ({ }; return ( - + {children} diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.tsx deleted file mode 100644 index c147029bbd3c7..0000000000000 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.tsx +++ /dev/null @@ -1,283 +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 { i18n } from '@kbn/i18n'; -import { EuiFormRow, EuiRange, EuiSelect } from '@elastic/eui'; -import { IndexPatternColumn } from '../../indexpattern'; -import { updateColumnParam } from '../../state_helpers'; -import { DataType } from '../../../types'; -import { OperationDefinition } from './index'; -import { FieldBasedIndexPatternColumn } from './column_types'; - -type PropType = C extends React.ComponentType ? P : unknown; - -// Add ticks to EuiRange component props -const FixedEuiRange = (EuiRange as unknown) as React.ComponentType< - PropType & { - ticks?: Array<{ - label: string; - value: number; - }>; - } ->; - -function ofName(name: string) { - return i18n.translate('xpack.lens.indexPattern.termsOf', { - defaultMessage: 'Top values of {name}', - values: { name }, - }); -} - -function isSortableByColumn(column: IndexPatternColumn) { - return !column.isBucketed; -} - -const DEFAULT_SIZE = 3; -const supportedTypes = new Set(['string', 'boolean', 'number', 'ip']); - -export interface TermsIndexPatternColumn extends FieldBasedIndexPatternColumn { - operationType: 'terms'; - params: { - size: number; - orderBy: { type: 'alphabetical' } | { type: 'column'; columnId: string }; - orderDirection: 'asc' | 'desc'; - }; -} - -export const termsOperation: OperationDefinition = { - type: 'terms', - displayName: i18n.translate('xpack.lens.indexPattern.terms', { - defaultMessage: 'Top values', - }), - priority: 3, // Higher than any metric - input: 'field', - getPossibleOperationForField: ({ aggregationRestrictions, aggregatable, type }) => { - if ( - supportedTypes.has(type) && - aggregatable && - (!aggregationRestrictions || aggregationRestrictions.terms) - ) { - return { dataType: type as DataType, isBucketed: true, scale: 'ordinal' }; - } - }, - isTransferable: (column, newIndexPattern) => { - const newField = newIndexPattern.fields.find((field) => field.name === column.sourceField); - - return Boolean( - newField && - supportedTypes.has(newField.type) && - newField.aggregatable && - (!newField.aggregationRestrictions || newField.aggregationRestrictions.terms) - ); - }, - buildColumn({ suggestedPriority, columns, field }) { - const existingMetricColumn = Object.entries(columns) - .filter(([_columnId, column]) => column && isSortableByColumn(column)) - .map(([id]) => id)[0]; - - return { - label: ofName(field.displayName), - dataType: field.type as DataType, - operationType: 'terms', - scale: 'ordinal', - suggestedPriority, - sourceField: field.name, - isBucketed: true, - params: { - size: DEFAULT_SIZE, - orderBy: existingMetricColumn - ? { type: 'column', columnId: existingMetricColumn } - : { type: 'alphabetical' }, - orderDirection: existingMetricColumn ? 'desc' : 'asc', - }, - }; - }, - toEsAggsConfig: (column, columnId, _indexPattern) => { - return { - id: columnId, - enabled: true, - type: 'terms', - schema: 'segment', - params: { - field: column.sourceField, - orderBy: - column.params.orderBy.type === 'alphabetical' ? '_key' : column.params.orderBy.columnId, - order: column.params.orderDirection, - size: column.params.size, - otherBucket: false, - otherBucketLabel: 'Other', - missingBucket: false, - missingBucketLabel: 'Missing', - }, - }; - }, - onFieldChange: (oldColumn, indexPattern, field) => { - return { - ...oldColumn, - label: ofName(field.displayName), - sourceField: field.name, - }; - }, - onOtherColumnChanged: (currentColumn, columns) => { - if (currentColumn.params.orderBy.type === 'column') { - // check whether the column is still there and still a metric - const columnSortedBy = columns[currentColumn.params.orderBy.columnId]; - if (!columnSortedBy || !isSortableByColumn(columnSortedBy)) { - return { - ...currentColumn, - params: { - ...currentColumn.params, - orderBy: { type: 'alphabetical' }, - orderDirection: 'asc', - }, - }; - } - } - return currentColumn; - }, - paramEditor: ({ state, setState, currentColumn, layerId }) => { - const SEPARATOR = '$$$'; - function toValue(orderBy: TermsIndexPatternColumn['params']['orderBy']) { - if (orderBy.type === 'alphabetical') { - return orderBy.type; - } - return `${orderBy.type}${SEPARATOR}${orderBy.columnId}`; - } - - function fromValue(value: string): TermsIndexPatternColumn['params']['orderBy'] { - if (value === 'alphabetical') { - return { type: 'alphabetical' }; - } - const parts = value.split(SEPARATOR); - return { - type: 'column', - columnId: parts[1], - }; - } - - const orderOptions = Object.entries(state.layers[layerId].columns) - .filter(([_columnId, column]) => isSortableByColumn(column)) - .map(([columnId, column]) => { - return { - value: toValue({ type: 'column', columnId }), - text: column.label, - }; - }); - orderOptions.push({ - value: toValue({ type: 'alphabetical' }), - text: i18n.translate('xpack.lens.indexPattern.terms.orderAlphabetical', { - defaultMessage: 'Alphabetical', - }), - }); - return ( - <> - - | React.MouseEvent - ) => - setState( - updateColumnParam({ - state, - layerId, - currentColumn, - paramName: 'size', - value: Number((e.target as HTMLInputElement).value), - }) - ) - } - aria-label={i18n.translate('xpack.lens.indexPattern.terms.size', { - defaultMessage: 'Number of values', - })} - /> - - - ) => - setState( - updateColumnParam({ - state, - layerId, - currentColumn, - paramName: 'orderBy', - value: fromValue(e.target.value), - }) - ) - } - aria-label={i18n.translate('xpack.lens.indexPattern.terms.orderBy', { - defaultMessage: 'Order by', - })} - /> - - - ) => - setState( - updateColumnParam({ - state, - layerId, - currentColumn, - paramName: 'orderDirection', - value: e.target.value as 'asc' | 'desc', - }) - ) - } - aria-label={i18n.translate('xpack.lens.indexPattern.terms.orderBy', { - defaultMessage: 'Order by', - })} - /> - - - ); - }, -}; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/index.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/index.tsx new file mode 100644 index 0000000000000..85deb2bac25ca --- /dev/null +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/index.tsx @@ -0,0 +1,261 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { EuiFormRow, EuiSelect } from '@elastic/eui'; +import { IndexPatternColumn } from '../../../indexpattern'; +import { updateColumnParam } from '../../../state_helpers'; +import { DataType } from '../../../../types'; +import { OperationDefinition } from '../index'; +import { FieldBasedIndexPatternColumn } from '../column_types'; +import { ValuesRangeInput } from './values_range_input'; + +function ofName(name: string) { + return i18n.translate('xpack.lens.indexPattern.termsOf', { + defaultMessage: 'Top values of {name}', + values: { name }, + }); +} + +function isSortableByColumn(column: IndexPatternColumn) { + return !column.isBucketed; +} + +const DEFAULT_SIZE = 3; +const supportedTypes = new Set(['string', 'boolean', 'number', 'ip']); + +export interface TermsIndexPatternColumn extends FieldBasedIndexPatternColumn { + operationType: 'terms'; + params: { + size: number; + orderBy: { type: 'alphabetical' } | { type: 'column'; columnId: string }; + orderDirection: 'asc' | 'desc'; + }; +} + +export const termsOperation: OperationDefinition = { + type: 'terms', + displayName: i18n.translate('xpack.lens.indexPattern.terms', { + defaultMessage: 'Top values', + }), + priority: 3, // Higher than any metric + input: 'field', + getPossibleOperationForField: ({ aggregationRestrictions, aggregatable, type }) => { + if ( + supportedTypes.has(type) && + aggregatable && + (!aggregationRestrictions || aggregationRestrictions.terms) + ) { + return { dataType: type as DataType, isBucketed: true, scale: 'ordinal' }; + } + }, + isTransferable: (column, newIndexPattern) => { + const newField = newIndexPattern.fields.find((field) => field.name === column.sourceField); + + return Boolean( + newField && + supportedTypes.has(newField.type) && + newField.aggregatable && + (!newField.aggregationRestrictions || newField.aggregationRestrictions.terms) + ); + }, + buildColumn({ suggestedPriority, columns, field }) { + const existingMetricColumn = Object.entries(columns) + .filter(([_columnId, column]) => column && isSortableByColumn(column)) + .map(([id]) => id)[0]; + + return { + label: ofName(field.displayName), + dataType: field.type as DataType, + operationType: 'terms', + scale: 'ordinal', + suggestedPriority, + sourceField: field.name, + isBucketed: true, + params: { + size: DEFAULT_SIZE, + orderBy: existingMetricColumn + ? { type: 'column', columnId: existingMetricColumn } + : { type: 'alphabetical' }, + orderDirection: existingMetricColumn ? 'desc' : 'asc', + }, + }; + }, + toEsAggsConfig: (column, columnId, _indexPattern) => { + return { + id: columnId, + enabled: true, + type: 'terms', + schema: 'segment', + params: { + field: column.sourceField, + orderBy: + column.params.orderBy.type === 'alphabetical' ? '_key' : column.params.orderBy.columnId, + order: column.params.orderDirection, + size: column.params.size, + otherBucket: false, + otherBucketLabel: 'Other', + missingBucket: false, + missingBucketLabel: 'Missing', + }, + }; + }, + onFieldChange: (oldColumn, indexPattern, field) => { + return { + ...oldColumn, + label: ofName(field.displayName), + sourceField: field.name, + }; + }, + onOtherColumnChanged: (currentColumn, columns) => { + if (currentColumn.params.orderBy.type === 'column') { + // check whether the column is still there and still a metric + const columnSortedBy = columns[currentColumn.params.orderBy.columnId]; + if (!columnSortedBy || !isSortableByColumn(columnSortedBy)) { + return { + ...currentColumn, + params: { + ...currentColumn.params, + orderBy: { type: 'alphabetical' }, + orderDirection: 'asc', + }, + }; + } + } + return currentColumn; + }, + paramEditor: ({ state, setState, currentColumn, layerId }) => { + const SEPARATOR = '$$$'; + function toValue(orderBy: TermsIndexPatternColumn['params']['orderBy']) { + if (orderBy.type === 'alphabetical') { + return orderBy.type; + } + return `${orderBy.type}${SEPARATOR}${orderBy.columnId}`; + } + + function fromValue(value: string): TermsIndexPatternColumn['params']['orderBy'] { + if (value === 'alphabetical') { + return { type: 'alphabetical' }; + } + const parts = value.split(SEPARATOR); + return { + type: 'column', + columnId: parts[1], + }; + } + + const orderOptions = Object.entries(state.layers[layerId].columns) + .filter(([_columnId, column]) => isSortableByColumn(column)) + .map(([columnId, column]) => { + return { + value: toValue({ type: 'column', columnId }), + text: column.label, + }; + }); + orderOptions.push({ + value: toValue({ type: 'alphabetical' }), + text: i18n.translate('xpack.lens.indexPattern.terms.orderAlphabetical', { + defaultMessage: 'Alphabetical', + }), + }); + return ( + <> + + { + setState( + updateColumnParam({ + state, + layerId, + currentColumn, + paramName: 'size', + value, + }) + ); + }} + /> + + + ) => + setState( + updateColumnParam({ + state, + layerId, + currentColumn, + paramName: 'orderBy', + value: fromValue(e.target.value), + }) + ) + } + aria-label={i18n.translate('xpack.lens.indexPattern.terms.orderBy', { + defaultMessage: 'Order by', + })} + /> + + + ) => + setState( + updateColumnParam({ + state, + layerId, + currentColumn, + paramName: 'orderDirection', + value: e.target.value as 'asc' | 'desc', + }) + ) + } + aria-label={i18n.translate('xpack.lens.indexPattern.terms.orderBy', { + defaultMessage: 'Order by', + })} + /> + + + ); + }, +}; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/terms.test.tsx similarity index 95% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.test.tsx rename to x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/terms.test.tsx index 6f67cb7531e1c..2c4e67ef0d9b9 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/terms.test.tsx @@ -5,15 +5,17 @@ */ import React from 'react'; -import { shallow } from 'enzyme'; +import { act } from 'react-dom/test-utils'; +import { shallow, mount } from 'enzyme'; import { EuiRange, EuiSelect } from '@elastic/eui'; import { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from 'kibana/public'; import { IStorageWrapper } from 'src/plugins/kibana_utils/public'; -import { dataPluginMock } from '../../../../../../../src/plugins/data/public/mocks'; -import { createMockedIndexPattern } from '../../mocks'; -import { TermsIndexPatternColumn } from './terms'; -import { termsOperation } from './index'; -import { IndexPatternPrivateState, IndexPattern } from '../../types'; +import { dataPluginMock } from '../../../../../../../../src/plugins/data/public/mocks'; +import { createMockedIndexPattern } from '../../../mocks'; +import { ValuesRangeInput } from './values_range_input'; +import { TermsIndexPatternColumn } from '.'; +import { termsOperation } from '../index'; +import { IndexPatternPrivateState, IndexPattern } from '../../../types'; const defaultProps = { storage: {} as IStorageWrapper, @@ -479,7 +481,7 @@ describe('terms', () => { it('should render current size value', () => { const setStateSpy = jest.fn(); - const instance = shallow( + const instance = mount( { /> ); - expect(instance.find(EuiRange).prop('value')).toEqual(3); + expect(instance.find(EuiRange).prop('value')).toEqual('3'); }); it('should update state with the size value', () => { const setStateSpy = jest.fn(); - const instance = shallow( + const instance = mount( { /> ); - instance.find(EuiRange).prop('onChange')!( - { - target: { - value: '7', - }, - } as React.ChangeEvent, - true - ); + act(() => { + instance.find(ValuesRangeInput).prop('onChange')!(7); + }); + expect(setStateSpy).toHaveBeenCalledWith({ ...state, layers: { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/values_range_input.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/values_range_input.test.tsx new file mode 100644 index 0000000000000..c1620dd316a60 --- /dev/null +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/values_range_input.test.tsx @@ -0,0 +1,56 @@ +/* + * 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 { act } from 'react-dom/test-utils'; +import { shallow } from 'enzyme'; +import { EuiRange } from '@elastic/eui'; +import { ValuesRangeInput } from './values_range_input'; + +jest.mock('react-use', () => ({ + useDebounce: (fn: () => void) => fn(), +})); + +describe('ValuesRangeInput', () => { + it('should render EuiRange correctly', () => { + const onChangeSpy = jest.fn(); + const instance = shallow(); + + expect(instance.find(EuiRange).prop('value')).toEqual('5'); + }); + + it('should run onChange function on update', () => { + const onChangeSpy = jest.fn(); + const instance = shallow(); + act(() => { + instance.find(EuiRange).prop('onChange')!( + { currentTarget: { value: '7' } } as React.ChangeEvent, + true + ); + }); + expect(instance.find(EuiRange).prop('value')).toEqual('7'); + // useDebounce runs on initialization and on change + expect(onChangeSpy.mock.calls.length).toBe(2); + expect(onChangeSpy.mock.calls[0][0]).toBe(5); + expect(onChangeSpy.mock.calls[1][0]).toBe(7); + }); + it('should not run onChange function on update when value is out of 1-100 range', () => { + const onChangeSpy = jest.fn(); + const instance = shallow(); + act(() => { + instance.find(EuiRange).prop('onChange')!( + { currentTarget: { value: '107' } } as React.ChangeEvent, + true + ); + }); + instance.update(); + expect(instance.find(EuiRange).prop('value')).toEqual('107'); + // useDebounce only runs on initialization + expect(onChangeSpy.mock.calls.length).toBe(2); + expect(onChangeSpy.mock.calls[0][0]).toBe(5); + expect(onChangeSpy.mock.calls[1][0]).toBe(100); + }); +}); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/values_range_input.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/values_range_input.tsx new file mode 100644 index 0000000000000..6bfde4b652571 --- /dev/null +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/values_range_input.tsx @@ -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 React, { useState } from 'react'; +import { useDebounce } from 'react-use'; +import { i18n } from '@kbn/i18n'; +import { EuiRange } from '@elastic/eui'; + +export const ValuesRangeInput = ({ + value, + onChange, +}: { + value: number; + onChange: (value: number) => void; +}) => { + const MIN_NUMBER_OF_VALUES = 1; + const MAX_NUMBER_OF_VALUES = 100; + + const [inputValue, setInputValue] = useState(String(value)); + useDebounce( + () => { + if (inputValue === '') { + return; + } + const inputNumber = Number(inputValue); + onChange(Math.min(MAX_NUMBER_OF_VALUES, Math.max(inputNumber, MIN_NUMBER_OF_VALUES))); + }, + 256, + [inputValue] + ); + + return ( + setInputValue(currentTarget.value)} + aria-label={i18n.translate('xpack.lens.indexPattern.terms.size', { + defaultMessage: 'Number of values', + })} + /> + ); +}; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/utils.ts b/x-pack/plugins/lens/public/indexpattern_datasource/utils.ts index 374dbe77b4ca3..f1d2e7765d99f 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/utils.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/utils.ts @@ -5,11 +5,13 @@ */ import { DataType } from '../types'; +import { IndexPatternPrivateState, IndexPattern } from './types'; import { DraggedField } from './indexpattern'; import { BaseIndexPatternColumn, FieldBasedIndexPatternColumn, } from './operations/definitions/column_types'; +import { operationDefinitionMap, OperationType } from './operations'; /** * Normalizes the specified operation type. (e.g. document operations @@ -40,3 +42,37 @@ export function isDraggedField(fieldCandidate: unknown): fieldCandidate is Dragg 'indexPatternId' in fieldCandidate ); } + +export function hasInvalidReference(state: IndexPatternPrivateState) { + return Object.values(state.layers).some((layer) => { + return layer.columnOrder.some((columnId) => { + const column = layer.columns[columnId]; + return ( + hasField(column) && + fieldIsInvalid( + column.sourceField, + column.operationType, + state.indexPatterns[layer.indexPatternId] + ) + ); + }); + }); +} + +export function fieldIsInvalid( + sourceField: string | undefined, + operationType: OperationType | undefined, + indexPattern: IndexPattern +) { + const operationDefinition = operationType && operationDefinitionMap[operationType]; + return Boolean( + sourceField && + operationDefinition && + !indexPattern.fields.some( + (field) => + field.name === sourceField && + operationDefinition.input === 'field' && + operationDefinition.getPossibleOperationForField(field) !== undefined + ) + ); +} diff --git a/x-pack/plugins/lens/public/metric_visualization/index.scss b/x-pack/plugins/lens/public/metric_visualization/expression.scss similarity index 100% rename from x-pack/plugins/lens/public/metric_visualization/index.scss rename to x-pack/plugins/lens/public/metric_visualization/expression.scss diff --git a/x-pack/plugins/lens/public/metric_visualization/expression.test.tsx b/x-pack/plugins/lens/public/metric_visualization/expression.test.tsx new file mode 100644 index 0000000000000..77a8ce64b21a2 --- /dev/null +++ b/x-pack/plugins/lens/public/metric_visualization/expression.test.tsx @@ -0,0 +1,183 @@ +/* + * 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 { metricChart, MetricChart } from './expression'; +import { LensMultiTable } from '../types'; +import React from 'react'; +import { shallow } from 'enzyme'; +import { MetricConfig } from './types'; +import { createMockExecutionContext } from '../../../../../src/plugins/expressions/common/mocks'; +import { IFieldFormat } from '../../../../../src/plugins/data/public'; + +function sampleArgs() { + const data: LensMultiTable = { + type: 'lens_multitable', + tables: { + l1: { + type: 'kibana_datatable', + columns: [ + { id: 'a', name: 'a' }, + { id: 'b', name: 'b' }, + { id: 'c', name: 'c' }, + ], + rows: [{ a: 10110, b: 2, c: 3 }], + }, + }, + }; + + const args: MetricConfig = { + accessor: 'a', + layerId: 'l1', + title: 'My fanci metric chart', + description: 'Fancy chart description', + metricTitle: 'My fanci metric chart', + mode: 'full', + }; + + const noAttributesArgs: MetricConfig = { + accessor: 'a', + layerId: 'l1', + title: '', + description: '', + metricTitle: 'My fanci metric chart', + mode: 'full', + }; + + return { data, args, noAttributesArgs }; +} + +describe('metric_expression', () => { + describe('metricChart', () => { + test('it renders with the specified data and args', () => { + const { data, args } = sampleArgs(); + const result = metricChart.fn(data, args, createMockExecutionContext()); + + expect(result).toEqual({ + type: 'render', + as: 'lens_metric_chart_renderer', + value: { data, args }, + }); + }); + }); + + describe('MetricChart component', () => { + test('it renders the all attributes when passed (title, description, metricTitle, value)', () => { + const { data, args } = sampleArgs(); + + expect( + shallow( x as IFieldFormat} />) + ).toMatchInlineSnapshot(` + + +
+ 10110 +
+
+ My fanci metric chart +
+
+
+ `); + }); + + test('it renders only chart content when title and description are empty strings', () => { + const { data, noAttributesArgs } = sampleArgs(); + + expect( + shallow( + x as IFieldFormat} + /> + ) + ).toMatchInlineSnapshot(` + + +
+ 10110 +
+
+ My fanci metric chart +
+
+
+ `); + }); + + test('it does not render metricTitle in reduced mode', () => { + const { data, noAttributesArgs } = sampleArgs(); + + expect( + shallow( + x as IFieldFormat} + /> + ) + ).toMatchInlineSnapshot(` + + +
+ 10110 +
+
+
+ `); + }); + }); +}); diff --git a/x-pack/plugins/lens/public/metric_visualization/expression.tsx b/x-pack/plugins/lens/public/metric_visualization/expression.tsx new file mode 100644 index 0000000000000..29c9cc3e454c7 --- /dev/null +++ b/x-pack/plugins/lens/public/metric_visualization/expression.tsx @@ -0,0 +1,151 @@ +/* + * 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 './expression.scss'; + +import React from 'react'; +import ReactDOM from 'react-dom'; +import { + ExpressionFunctionDefinition, + ExpressionRenderDefinition, + IInterpreterRenderHandlers, +} from '../../../../../src/plugins/expressions/public'; +import { MetricConfig } from './types'; +import { FormatFactory, LensMultiTable } from '../types'; +import { AutoScale } from './auto_scale'; +import { VisualizationContainer } from '../visualization_container'; + +export interface MetricChartProps { + data: LensMultiTable; + args: MetricConfig; +} + +export interface MetricRender { + type: 'render'; + as: 'lens_metric_chart_renderer'; + value: MetricChartProps; +} + +export const metricChart: ExpressionFunctionDefinition< + 'lens_metric_chart', + LensMultiTable, + Omit, + MetricRender +> = { + name: 'lens_metric_chart', + type: 'render', + help: 'A metric chart', + args: { + title: { + types: ['string'], + help: 'The chart title.', + }, + description: { + types: ['string'], + help: '', + }, + metricTitle: { + types: ['string'], + help: 'The title of the metric shown.', + }, + accessor: { + types: ['string'], + help: 'The column whose value is being displayed', + }, + mode: { + types: ['string'], + options: ['reduced', 'full'], + default: 'full', + help: + 'The display mode of the chart - reduced will only show the metric itself without min size', + }, + }, + inputTypes: ['lens_multitable'], + fn(data, args) { + return { + type: 'render', + as: 'lens_metric_chart_renderer', + value: { + data, + args, + }, + } as MetricRender; + }, +}; + +export const getMetricChartRenderer = ( + formatFactory: Promise +): ExpressionRenderDefinition => ({ + name: 'lens_metric_chart_renderer', + displayName: 'Metric chart', + help: 'Metric chart renderer', + validate: () => undefined, + reuseDomNode: true, + render: async ( + domNode: Element, + config: MetricChartProps, + handlers: IInterpreterRenderHandlers + ) => { + const resolvedFormatFactory = await formatFactory; + ReactDOM.render( + , + domNode, + () => { + handlers.done(); + } + ); + handlers.onDestroy(() => ReactDOM.unmountComponentAtNode(domNode)); + }, +}); + +export function MetricChart({ + data, + args, + formatFactory, +}: MetricChartProps & { formatFactory: FormatFactory }) { + const { metricTitle, title, description, accessor, mode } = args; + let value = '-'; + const firstTable = Object.values(data.tables)[0]; + if (!accessor) { + return ( + + ); + } + + if (firstTable) { + const column = firstTable.columns[0]; + const row = firstTable.rows[0]; + if (row[accessor]) { + value = + column && column.formatHint + ? formatFactory(column.formatHint).convert(row[accessor]) + : Number(Number(row[accessor]).toFixed(3)).toString(); + } + } + + return ( + + +
+ {value} +
+ {mode === 'full' && ( +
+ {metricTitle} +
+ )} +
+
+ ); +} diff --git a/x-pack/plugins/lens/public/metric_visualization/index.ts b/x-pack/plugins/lens/public/metric_visualization/index.ts index 2960da52191e4..f6245669b9964 100644 --- a/x-pack/plugins/lens/public/metric_visualization/index.ts +++ b/x-pack/plugins/lens/public/metric_visualization/index.ts @@ -5,9 +5,7 @@ */ import { CoreSetup } from 'kibana/public'; -import { metricVisualization } from './metric_visualization'; import { ExpressionsSetup } from '../../../../../src/plugins/expressions/public'; -import { metricChart, getMetricChartRenderer } from './metric_expression'; import { EditorFrameSetup, FormatFactory } from '../types'; export interface MetricVisualizationPluginSetupPlugins { @@ -23,10 +21,15 @@ export class MetricVisualization { _core: CoreSetup | null, { expressions, formatFactory, editorFrame }: MetricVisualizationPluginSetupPlugins ) { - expressions.registerFunction(() => metricChart); + editorFrame.registerVisualization(async () => { + const { metricVisualization, metricChart, getMetricChartRenderer } = await import( + '../async_services' + ); - expressions.registerRenderer(() => getMetricChartRenderer(formatFactory)); + expressions.registerFunction(() => metricChart); - editorFrame.registerVisualization(metricVisualization); + expressions.registerRenderer(() => getMetricChartRenderer(formatFactory)); + return metricVisualization; + }); } } diff --git a/x-pack/plugins/lens/public/metric_visualization/metric_expression.test.tsx b/x-pack/plugins/lens/public/metric_visualization/metric_expression.test.tsx deleted file mode 100644 index 27f971c2ba11a..0000000000000 --- a/x-pack/plugins/lens/public/metric_visualization/metric_expression.test.tsx +++ /dev/null @@ -1,126 +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 { metricChart, MetricChart } from './metric_expression'; -import { LensMultiTable } from '../types'; -import React from 'react'; -import { shallow } from 'enzyme'; -import { MetricConfig } from './types'; -import { createMockExecutionContext } from '../../../../../src/plugins/expressions/common/mocks'; -import { IFieldFormat } from '../../../../../src/plugins/data/public'; - -function sampleArgs() { - const data: LensMultiTable = { - type: 'lens_multitable', - tables: { - l1: { - type: 'kibana_datatable', - columns: [ - { id: 'a', name: 'a' }, - { id: 'b', name: 'b' }, - { id: 'c', name: 'c' }, - ], - rows: [{ a: 10110, b: 2, c: 3 }], - }, - }, - }; - - const args: MetricConfig = { - accessor: 'a', - layerId: 'l1', - title: 'My fanci metric chart', - mode: 'full', - }; - - return { data, args }; -} - -describe('metric_expression', () => { - describe('metricChart', () => { - test('it renders with the specified data and args', () => { - const { data, args } = sampleArgs(); - const result = metricChart.fn(data, args, createMockExecutionContext()); - - expect(result).toEqual({ - type: 'render', - as: 'lens_metric_chart_renderer', - value: { data, args }, - }); - }); - }); - - describe('MetricChart component', () => { - test('it renders the title and value', () => { - const { data, args } = sampleArgs(); - - expect( - shallow( x as IFieldFormat} />) - ).toMatchInlineSnapshot(` - - -
- 10110 -
-
- My fanci metric chart -
-
-
- `); - }); - - test('it does not render title in reduced mode', () => { - const { data, args } = sampleArgs(); - - expect( - shallow( - x as IFieldFormat} - /> - ) - ).toMatchInlineSnapshot(` - - -
- 10110 -
-
-
- `); - }); - }); -}); diff --git a/x-pack/plugins/lens/public/metric_visualization/metric_expression.tsx b/x-pack/plugins/lens/public/metric_visualization/metric_expression.tsx deleted file mode 100644 index 3484837f65b43..0000000000000 --- a/x-pack/plugins/lens/public/metric_visualization/metric_expression.tsx +++ /dev/null @@ -1,133 +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 ReactDOM from 'react-dom'; -import { - ExpressionFunctionDefinition, - ExpressionRenderDefinition, - IInterpreterRenderHandlers, -} from '../../../../../src/plugins/expressions/public'; -import { MetricConfig } from './types'; -import { FormatFactory, LensMultiTable } from '../types'; -import { AutoScale } from './auto_scale'; -import { VisualizationContainer } from '../visualization_container'; - -export interface MetricChartProps { - data: LensMultiTable; - args: MetricConfig; -} - -export interface MetricRender { - type: 'render'; - as: 'lens_metric_chart_renderer'; - value: MetricChartProps; -} - -export const metricChart: ExpressionFunctionDefinition< - 'lens_metric_chart', - LensMultiTable, - Omit, - MetricRender -> = { - name: 'lens_metric_chart', - type: 'render', - help: 'A metric chart', - args: { - title: { - types: ['string'], - help: 'The chart title.', - }, - accessor: { - types: ['string'], - help: 'The column whose value is being displayed', - }, - mode: { - types: ['string'], - options: ['reduced', 'full'], - default: 'full', - help: - 'The display mode of the chart - reduced will only show the metric itself without min size', - }, - }, - inputTypes: ['lens_multitable'], - fn(data, args) { - return { - type: 'render', - as: 'lens_metric_chart_renderer', - value: { - data, - args, - }, - } as MetricRender; - }, -}; - -export const getMetricChartRenderer = ( - formatFactory: Promise -): ExpressionRenderDefinition => ({ - name: 'lens_metric_chart_renderer', - displayName: 'Metric chart', - help: 'Metric chart renderer', - validate: () => undefined, - reuseDomNode: true, - render: async ( - domNode: Element, - config: MetricChartProps, - handlers: IInterpreterRenderHandlers - ) => { - const resolvedFormatFactory = await formatFactory; - ReactDOM.render( - , - domNode, - () => { - handlers.done(); - } - ); - handlers.onDestroy(() => ReactDOM.unmountComponentAtNode(domNode)); - }, -}); - -export function MetricChart({ - data, - args, - formatFactory, -}: MetricChartProps & { formatFactory: FormatFactory }) { - const { title, accessor, mode } = args; - let value = '-'; - const firstTable = Object.values(data.tables)[0]; - if (!accessor) { - return ( - - ); - } - - if (firstTable) { - const column = firstTable.columns[0]; - const row = firstTable.rows[0]; - if (row[accessor]) { - value = - column && column.formatHint - ? formatFactory(column.formatHint).convert(row[accessor]) - : Number(Number(row[accessor]).toFixed(3)).toString(); - } - } - - return ( - - -
- {value} -
- {mode === 'full' && ( -
- {title} -
- )} -
-
- ); -} diff --git a/x-pack/plugins/lens/public/metric_visualization/metric_visualization.test.ts b/x-pack/plugins/lens/public/metric_visualization/metric_visualization.test.ts deleted file mode 100644 index f3c9a725ee2e2..0000000000000 --- a/x-pack/plugins/lens/public/metric_visualization/metric_visualization.test.ts +++ /dev/null @@ -1,190 +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 { metricVisualization } from './metric_visualization'; -import { State } from './types'; -import { createMockDatasource, createMockFramePublicAPI } from '../editor_frame_service/mocks'; -import { generateId } from '../id_generator'; -import { DatasourcePublicAPI, FramePublicAPI } from '../types'; - -jest.mock('../id_generator'); - -function exampleState(): State { - return { - accessor: 'a', - layerId: 'l1', - }; -} - -function mockFrame(): FramePublicAPI { - return { - ...createMockFramePublicAPI(), - addNewLayer: () => 'l42', - datasourceLayers: { - l1: createMockDatasource('l1').publicAPIMock, - l42: createMockDatasource('l42').publicAPIMock, - }, - }; -} - -describe('metric_visualization', () => { - describe('#initialize', () => { - it('loads default state', () => { - (generateId as jest.Mock).mockReturnValueOnce('test-id1'); - const initialState = metricVisualization.initialize(mockFrame()); - - expect(initialState.accessor).not.toBeDefined(); - expect(initialState).toMatchInlineSnapshot(` - Object { - "accessor": undefined, - "layerId": "l42", - } - `); - }); - - it('loads from persisted state', () => { - expect(metricVisualization.initialize(mockFrame(), exampleState())).toEqual(exampleState()); - }); - }); - - describe('#getLayerIds', () => { - it('returns the layer id', () => { - expect(metricVisualization.getLayerIds(exampleState())).toEqual(['l1']); - }); - }); - - describe('#clearLayer', () => { - it('returns a clean layer', () => { - (generateId as jest.Mock).mockReturnValueOnce('test-id1'); - expect(metricVisualization.clearLayer(exampleState(), 'l1')).toEqual({ - accessor: undefined, - layerId: 'l1', - }); - }); - }); - - describe('#getConfiguration', () => { - it('can add a metric when there is no accessor', () => { - expect( - metricVisualization.getConfiguration({ - state: { - accessor: undefined, - layerId: 'l1', - }, - layerId: 'l1', - frame: mockFrame(), - }) - ).toEqual({ - groups: [ - expect.objectContaining({ - supportsMoreColumns: true, - }), - ], - }); - }); - - it('is not allowed to add a metric once one accessor is set', () => { - expect( - metricVisualization.getConfiguration({ - state: { - accessor: 'a', - layerId: 'l1', - }, - layerId: 'l1', - frame: mockFrame(), - }) - ).toEqual({ - groups: [ - expect.objectContaining({ - supportsMoreColumns: false, - }), - ], - }); - }); - }); - - describe('#setDimension', () => { - it('sets the accessor', () => { - expect( - metricVisualization.setDimension({ - prevState: { - accessor: undefined, - layerId: 'l1', - }, - layerId: 'l1', - groupId: '', - columnId: 'newDimension', - }) - ).toEqual({ - accessor: 'newDimension', - layerId: 'l1', - }); - }); - }); - - describe('#removeDimension', () => { - it('removes the accessor', () => { - expect( - metricVisualization.removeDimension({ - prevState: { - accessor: 'a', - layerId: 'l1', - }, - layerId: 'l1', - columnId: 'a', - }) - ).toEqual({ - accessor: undefined, - layerId: 'l1', - }); - }); - }); - - describe('#toExpression', () => { - it('should map to a valid AST', () => { - const datasource: DatasourcePublicAPI = { - ...createMockDatasource('l1').publicAPIMock, - getOperationForColumnId(_: string) { - return { - id: 'a', - dataType: 'number', - isBucketed: false, - label: 'shazm', - }; - }, - }; - - const frame = { - ...mockFrame(), - datasourceLayers: { l1: datasource }, - }; - - expect(metricVisualization.toExpression(exampleState(), frame.datasourceLayers)) - .toMatchInlineSnapshot(` - Object { - "chain": Array [ - Object { - "arguments": Object { - "accessor": Array [ - "a", - ], - "mode": Array [ - "full", - ], - "title": Array [ - "shazm", - ], - }, - "function": "lens_metric_chart", - "type": "function", - }, - ], - "type": "expression", - } - `); - }); - }); -}); diff --git a/x-pack/plugins/lens/public/metric_visualization/metric_visualization.ts b/x-pack/plugins/lens/public/metric_visualization/metric_visualization.ts new file mode 100644 index 0000000000000..c6fe54a82e2d1 --- /dev/null +++ b/x-pack/plugins/lens/public/metric_visualization/metric_visualization.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export * from './expression'; +export * from './visualization'; diff --git a/x-pack/plugins/lens/public/metric_visualization/metric_visualization.tsx b/x-pack/plugins/lens/public/metric_visualization/metric_visualization.tsx deleted file mode 100644 index 72c07bed1acb2..0000000000000 --- a/x-pack/plugins/lens/public/metric_visualization/metric_visualization.tsx +++ /dev/null @@ -1,116 +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 { i18n } from '@kbn/i18n'; -import { Ast } from '@kbn/interpreter/target/common'; -import { getSuggestions } from './metric_suggestions'; -import { LensIconChartMetric } from '../assets/chart_metric'; -import { Visualization, OperationMetadata, DatasourcePublicAPI } from '../types'; -import { State } from './types'; - -const toExpression = ( - state: State, - datasourceLayers: Record, - mode: 'reduced' | 'full' = 'full' -): Ast | null => { - if (!state.accessor) { - return null; - } - - const [datasource] = Object.values(datasourceLayers); - const operation = datasource && datasource.getOperationForColumnId(state.accessor); - - return { - type: 'expression', - chain: [ - { - type: 'function', - function: 'lens_metric_chart', - arguments: { - title: [(operation && operation.label) || ''], - accessor: [state.accessor], - mode: [mode], - }, - }, - ], - }; -}; - -export const metricVisualization: Visualization = { - id: 'lnsMetric', - - visualizationTypes: [ - { - id: 'lnsMetric', - icon: LensIconChartMetric, - label: i18n.translate('xpack.lens.metric.label', { - defaultMessage: 'Metric', - }), - }, - ], - - getVisualizationTypeId() { - return 'lnsMetric'; - }, - - clearLayer(state) { - return { - ...state, - accessor: undefined, - }; - }, - - getLayerIds(state) { - return [state.layerId]; - }, - - getDescription() { - return { - icon: LensIconChartMetric, - label: i18n.translate('xpack.lens.metric.label', { - defaultMessage: 'Metric', - }), - }; - }, - - getSuggestions, - - initialize(frame, state) { - return ( - state || { - layerId: frame.addNewLayer(), - accessor: undefined, - } - ); - }, - - getConfiguration(props) { - return { - groups: [ - { - groupId: 'metric', - groupLabel: i18n.translate('xpack.lens.metric.label', { defaultMessage: 'Metric' }), - layerId: props.state.layerId, - accessors: props.state.accessor ? [props.state.accessor] : [], - supportsMoreColumns: !props.state.accessor, - filterOperations: (op: OperationMetadata) => !op.isBucketed && op.dataType === 'number', - }, - ], - }; - }, - - toExpression, - toPreviewExpression: (state, datasourceLayers) => - toExpression(state, datasourceLayers, 'reduced'), - - setDimension({ prevState, columnId }) { - return { ...prevState, accessor: columnId }; - }, - - removeDimension({ prevState }) { - return { ...prevState, accessor: undefined }; - }, -}; diff --git a/x-pack/plugins/lens/public/metric_visualization/types.ts b/x-pack/plugins/lens/public/metric_visualization/types.ts index 86a781716b345..c4a3fd094abe6 100644 --- a/x-pack/plugins/lens/public/metric_visualization/types.ts +++ b/x-pack/plugins/lens/public/metric_visualization/types.ts @@ -11,5 +11,7 @@ export interface State { export interface MetricConfig extends State { title: string; + description: string; + metricTitle: string; mode: 'reduced' | 'full'; } diff --git a/x-pack/plugins/lens/public/metric_visualization/visualization.test.ts b/x-pack/plugins/lens/public/metric_visualization/visualization.test.ts new file mode 100644 index 0000000000000..80c7a174b3264 --- /dev/null +++ b/x-pack/plugins/lens/public/metric_visualization/visualization.test.ts @@ -0,0 +1,196 @@ +/* + * 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 { metricVisualization } from './visualization'; +import { State } from './types'; +import { createMockDatasource, createMockFramePublicAPI } from '../editor_frame_service/mocks'; +import { generateId } from '../id_generator'; +import { DatasourcePublicAPI, FramePublicAPI } from '../types'; + +jest.mock('../id_generator'); + +function exampleState(): State { + return { + accessor: 'a', + layerId: 'l1', + }; +} + +function mockFrame(): FramePublicAPI { + return { + ...createMockFramePublicAPI(), + addNewLayer: () => 'l42', + datasourceLayers: { + l1: createMockDatasource('l1').publicAPIMock, + l42: createMockDatasource('l42').publicAPIMock, + }, + }; +} + +describe('metric_visualization', () => { + describe('#initialize', () => { + it('loads default state', () => { + (generateId as jest.Mock).mockReturnValueOnce('test-id1'); + const initialState = metricVisualization.initialize(mockFrame()); + + expect(initialState.accessor).not.toBeDefined(); + expect(initialState).toMatchInlineSnapshot(` + Object { + "accessor": undefined, + "layerId": "l42", + } + `); + }); + + it('loads from persisted state', () => { + expect(metricVisualization.initialize(mockFrame(), exampleState())).toEqual(exampleState()); + }); + }); + + describe('#getLayerIds', () => { + it('returns the layer id', () => { + expect(metricVisualization.getLayerIds(exampleState())).toEqual(['l1']); + }); + }); + + describe('#clearLayer', () => { + it('returns a clean layer', () => { + (generateId as jest.Mock).mockReturnValueOnce('test-id1'); + expect(metricVisualization.clearLayer(exampleState(), 'l1')).toEqual({ + accessor: undefined, + layerId: 'l1', + }); + }); + }); + + describe('#getConfiguration', () => { + it('can add a metric when there is no accessor', () => { + expect( + metricVisualization.getConfiguration({ + state: { + accessor: undefined, + layerId: 'l1', + }, + layerId: 'l1', + frame: mockFrame(), + }) + ).toEqual({ + groups: [ + expect.objectContaining({ + supportsMoreColumns: true, + }), + ], + }); + }); + + it('is not allowed to add a metric once one accessor is set', () => { + expect( + metricVisualization.getConfiguration({ + state: { + accessor: 'a', + layerId: 'l1', + }, + layerId: 'l1', + frame: mockFrame(), + }) + ).toEqual({ + groups: [ + expect.objectContaining({ + supportsMoreColumns: false, + }), + ], + }); + }); + }); + + describe('#setDimension', () => { + it('sets the accessor', () => { + expect( + metricVisualization.setDimension({ + prevState: { + accessor: undefined, + layerId: 'l1', + }, + layerId: 'l1', + groupId: '', + columnId: 'newDimension', + }) + ).toEqual({ + accessor: 'newDimension', + layerId: 'l1', + }); + }); + }); + + describe('#removeDimension', () => { + it('removes the accessor', () => { + expect( + metricVisualization.removeDimension({ + prevState: { + accessor: 'a', + layerId: 'l1', + }, + layerId: 'l1', + columnId: 'a', + }) + ).toEqual({ + accessor: undefined, + layerId: 'l1', + }); + }); + }); + + describe('#toExpression', () => { + it('should map to a valid AST', () => { + const datasource: DatasourcePublicAPI = { + ...createMockDatasource('l1').publicAPIMock, + getOperationForColumnId(_: string) { + return { + id: 'a', + dataType: 'number', + isBucketed: false, + label: 'shazm', + }; + }, + }; + + const frame = { + ...mockFrame(), + datasourceLayers: { l1: datasource }, + }; + + expect(metricVisualization.toExpression(exampleState(), frame.datasourceLayers)) + .toMatchInlineSnapshot(` + Object { + "chain": Array [ + Object { + "arguments": Object { + "accessor": Array [ + "a", + ], + "description": Array [ + "", + ], + "metricTitle": Array [ + "shazm", + ], + "mode": Array [ + "full", + ], + "title": Array [ + "", + ], + }, + "function": "lens_metric_chart", + "type": "function", + }, + ], + "type": "expression", + } + `); + }); + }); +}); diff --git a/x-pack/plugins/lens/public/metric_visualization/visualization.tsx b/x-pack/plugins/lens/public/metric_visualization/visualization.tsx new file mode 100644 index 0000000000000..77d189ce53d01 --- /dev/null +++ b/x-pack/plugins/lens/public/metric_visualization/visualization.tsx @@ -0,0 +1,118 @@ +/* + * 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 { Ast } from '@kbn/interpreter/target/common'; +import { getSuggestions } from './metric_suggestions'; +import { LensIconChartMetric } from '../assets/chart_metric'; +import { Visualization, OperationMetadata, DatasourcePublicAPI } from '../types'; +import { State } from './types'; + +const toExpression = ( + state: State, + datasourceLayers: Record, + attributes?: { mode?: 'reduced' | 'full'; title?: string; description?: string } +): Ast | null => { + if (!state.accessor) { + return null; + } + + const [datasource] = Object.values(datasourceLayers); + const operation = datasource && datasource.getOperationForColumnId(state.accessor); + + return { + type: 'expression', + chain: [ + { + type: 'function', + function: 'lens_metric_chart', + arguments: { + title: [attributes?.title || ''], + description: [attributes?.description || ''], + metricTitle: [(operation && operation.label) || ''], + accessor: [state.accessor], + mode: [attributes?.mode || 'full'], + }, + }, + ], + }; +}; + +export const metricVisualization: Visualization = { + id: 'lnsMetric', + + visualizationTypes: [ + { + id: 'lnsMetric', + icon: LensIconChartMetric, + label: i18n.translate('xpack.lens.metric.label', { + defaultMessage: 'Metric', + }), + }, + ], + + getVisualizationTypeId() { + return 'lnsMetric'; + }, + + clearLayer(state) { + return { + ...state, + accessor: undefined, + }; + }, + + getLayerIds(state) { + return [state.layerId]; + }, + + getDescription() { + return { + icon: LensIconChartMetric, + label: i18n.translate('xpack.lens.metric.label', { + defaultMessage: 'Metric', + }), + }; + }, + + getSuggestions, + + initialize(frame, state) { + return ( + state || { + layerId: frame.addNewLayer(), + accessor: undefined, + } + ); + }, + + getConfiguration(props) { + return { + groups: [ + { + groupId: 'metric', + groupLabel: i18n.translate('xpack.lens.metric.label', { defaultMessage: 'Metric' }), + layerId: props.state.layerId, + accessors: props.state.accessor ? [props.state.accessor] : [], + supportsMoreColumns: !props.state.accessor, + filterOperations: (op: OperationMetadata) => !op.isBucketed && op.dataType === 'number', + }, + ], + }; + }, + + toExpression, + toPreviewExpression: (state, datasourceLayers) => + toExpression(state, datasourceLayers, { mode: 'reduced' }), + + setDimension({ prevState, columnId }) { + return { ...prevState, accessor: columnId }; + }, + + removeDimension({ prevState }) { + return { ...prevState, accessor: undefined }; + }, +}; diff --git a/x-pack/plugins/lens/public/pie_visualization/expression.tsx b/x-pack/plugins/lens/public/pie_visualization/expression.tsx new file mode 100644 index 0000000000000..d93145f29aa89 --- /dev/null +++ b/x-pack/plugins/lens/public/pie_visualization/expression.tsx @@ -0,0 +1,146 @@ +/* + * 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 ReactDOM from 'react-dom'; +import { i18n } from '@kbn/i18n'; +import { Position } from '@elastic/charts'; +import { I18nProvider } from '@kbn/i18n/react'; +import { + IInterpreterRenderHandlers, + ExpressionRenderDefinition, + ExpressionFunctionDefinition, +} from 'src/plugins/expressions/public'; +import { LensMultiTable, FormatFactory, LensFilterEvent } from '../types'; +import { PieExpressionProps, PieExpressionArgs } from './types'; +import { PieComponent } from './render_function'; +import { ChartsPluginSetup } from '../../../../../src/plugins/charts/public'; + +export interface PieRender { + type: 'render'; + as: 'lens_pie_renderer'; + value: PieExpressionProps; +} + +export const pie: ExpressionFunctionDefinition< + 'lens_pie', + LensMultiTable, + PieExpressionArgs, + PieRender +> = { + name: 'lens_pie', + type: 'render', + help: i18n.translate('xpack.lens.pie.expressionHelpLabel', { + defaultMessage: 'Pie renderer', + }), + args: { + title: { + types: ['string'], + help: 'The chart title.', + }, + description: { + types: ['string'], + help: '', + }, + groups: { + types: ['string'], + multi: true, + help: '', + }, + metric: { + types: ['string'], + help: '', + }, + shape: { + types: ['string'], + options: ['pie', 'donut', 'treemap'], + help: '', + }, + hideLabels: { + types: ['boolean'], + help: '', + }, + numberDisplay: { + types: ['string'], + options: ['hidden', 'percent', 'value'], + help: '', + }, + categoryDisplay: { + types: ['string'], + options: ['default', 'inside', 'hide'], + help: '', + }, + legendDisplay: { + types: ['string'], + options: ['default', 'show', 'hide'], + help: '', + }, + nestedLegend: { + types: ['boolean'], + help: '', + }, + legendPosition: { + types: ['string'], + options: [Position.Top, Position.Right, Position.Bottom, Position.Left], + help: '', + }, + percentDecimals: { + types: ['number'], + help: '', + }, + }, + inputTypes: ['lens_multitable'], + fn(data: LensMultiTable, args: PieExpressionArgs) { + return { + type: 'render', + as: 'lens_pie_renderer', + value: { + data, + args, + }, + }; + }, +}; + +export const getPieRenderer = (dependencies: { + formatFactory: Promise; + chartsThemeService: ChartsPluginSetup['theme']; +}): ExpressionRenderDefinition => ({ + name: 'lens_pie_renderer', + displayName: i18n.translate('xpack.lens.pie.visualizationName', { + defaultMessage: 'Pie', + }), + help: '', + validate: () => undefined, + reuseDomNode: true, + render: async ( + domNode: Element, + config: PieExpressionProps, + handlers: IInterpreterRenderHandlers + ) => { + const onClickValue = (data: LensFilterEvent['data']) => { + handlers.event({ name: 'filter', data }); + }; + const formatFactory = await dependencies.formatFactory; + ReactDOM.render( + + + , + domNode, + () => { + handlers.done(); + } + ); + handlers.onDestroy(() => ReactDOM.unmountComponentAtNode(domNode)); + }, +}); + +const MemoizedChart = React.memo(PieComponent); diff --git a/x-pack/plugins/lens/public/pie_visualization/index.ts b/x-pack/plugins/lens/public/pie_visualization/index.ts index 401b6d634c696..36dd9b93c3e39 100644 --- a/x-pack/plugins/lens/public/pie_visualization/index.ts +++ b/x-pack/plugins/lens/public/pie_visualization/index.ts @@ -6,8 +6,6 @@ import { CoreSetup } from 'src/core/public'; import { ExpressionsSetup } from 'src/plugins/expressions/public'; -import { pieVisualization } from './pie_visualization'; -import { pie, getPieRenderer } from './register_expression'; import { EditorFrameSetup, FormatFactory } from '../types'; import { UiActionsStart } from '../../../../../src/plugins/ui_actions/public'; import { ChartsPluginSetup } from '../../../../../src/plugins/charts/public'; @@ -30,15 +28,18 @@ export class PieVisualization { core: CoreSetup, { expressions, formatFactory, editorFrame, charts }: PieVisualizationPluginSetupPlugins ) { - expressions.registerFunction(() => pie); + editorFrame.registerVisualization(async () => { + const { pieVisualization, pie, getPieRenderer } = await import('../async_services'); - expressions.registerRenderer( - getPieRenderer({ - formatFactory, - chartsThemeService: charts.theme, - }) - ); + expressions.registerFunction(() => pie); - editorFrame.registerVisualization(pieVisualization); + expressions.registerRenderer( + getPieRenderer({ + formatFactory, + chartsThemeService: charts.theme, + }) + ); + return pieVisualization; + }); } } diff --git a/x-pack/plugins/lens/public/pie_visualization/pie_visualization.ts b/x-pack/plugins/lens/public/pie_visualization/pie_visualization.ts new file mode 100644 index 0000000000000..c6fe54a82e2d1 --- /dev/null +++ b/x-pack/plugins/lens/public/pie_visualization/pie_visualization.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export * from './expression'; +export * from './visualization'; diff --git a/x-pack/plugins/lens/public/pie_visualization/register_expression.tsx b/x-pack/plugins/lens/public/pie_visualization/register_expression.tsx deleted file mode 100644 index 89d93ab79233f..0000000000000 --- a/x-pack/plugins/lens/public/pie_visualization/register_expression.tsx +++ /dev/null @@ -1,138 +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 ReactDOM from 'react-dom'; -import { i18n } from '@kbn/i18n'; -import { Position } from '@elastic/charts'; -import { I18nProvider } from '@kbn/i18n/react'; -import { - IInterpreterRenderHandlers, - ExpressionRenderDefinition, - ExpressionFunctionDefinition, -} from 'src/plugins/expressions/public'; -import { LensMultiTable, FormatFactory, LensFilterEvent } from '../types'; -import { PieExpressionProps, PieExpressionArgs } from './types'; -import { PieComponent } from './render_function'; -import { ChartsPluginSetup } from '../../../../../src/plugins/charts/public'; - -export interface PieRender { - type: 'render'; - as: 'lens_pie_renderer'; - value: PieExpressionProps; -} - -export const pie: ExpressionFunctionDefinition< - 'lens_pie', - LensMultiTable, - PieExpressionArgs, - PieRender -> = { - name: 'lens_pie', - type: 'render', - help: i18n.translate('xpack.lens.pie.expressionHelpLabel', { - defaultMessage: 'Pie renderer', - }), - args: { - groups: { - types: ['string'], - multi: true, - help: '', - }, - metric: { - types: ['string'], - help: '', - }, - shape: { - types: ['string'], - options: ['pie', 'donut', 'treemap'], - help: '', - }, - hideLabels: { - types: ['boolean'], - help: '', - }, - numberDisplay: { - types: ['string'], - options: ['hidden', 'percent', 'value'], - help: '', - }, - categoryDisplay: { - types: ['string'], - options: ['default', 'inside', 'hide'], - help: '', - }, - legendDisplay: { - types: ['string'], - options: ['default', 'show', 'hide'], - help: '', - }, - nestedLegend: { - types: ['boolean'], - help: '', - }, - legendPosition: { - types: ['string'], - options: [Position.Top, Position.Right, Position.Bottom, Position.Left], - help: '', - }, - percentDecimals: { - types: ['number'], - help: '', - }, - }, - inputTypes: ['lens_multitable'], - fn(data: LensMultiTable, args: PieExpressionArgs) { - return { - type: 'render', - as: 'lens_pie_renderer', - value: { - data, - args, - }, - }; - }, -}; - -export const getPieRenderer = (dependencies: { - formatFactory: Promise; - chartsThemeService: ChartsPluginSetup['theme']; -}): ExpressionRenderDefinition => ({ - name: 'lens_pie_renderer', - displayName: i18n.translate('xpack.lens.pie.visualizationName', { - defaultMessage: 'Pie', - }), - help: '', - validate: () => undefined, - reuseDomNode: true, - render: async ( - domNode: Element, - config: PieExpressionProps, - handlers: IInterpreterRenderHandlers - ) => { - const onClickValue = (data: LensFilterEvent['data']) => { - handlers.event({ name: 'filter', data }); - }; - const formatFactory = await dependencies.formatFactory; - ReactDOM.render( - - - , - domNode, - () => { - handlers.done(); - } - ); - handlers.onDestroy(() => ReactDOM.unmountComponentAtNode(domNode)); - }, -}); - -const MemoizedChart = React.memo(PieComponent); diff --git a/x-pack/plugins/lens/public/pie_visualization/render_function.tsx b/x-pack/plugins/lens/public/pie_visualization/render_function.tsx index d97ab146e000d..8de810f9aa5d3 100644 --- a/x-pack/plugins/lens/public/pie_visualization/render_function.tsx +++ b/x-pack/plugins/lens/public/pie_visualization/render_function.tsx @@ -228,7 +228,12 @@ export function PieComponent( ); } return ( - +

+``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [id](./kibana-plugin-plugins-embeddable-server.enhancementregistrydefinition.id.md) | string | | + diff --git a/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.md b/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.md new file mode 100644 index 0000000000000..19ee57d677250 --- /dev/null +++ b/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-server](./kibana-plugin-plugins-embeddable-server.md) + +## kibana-plugin-plugins-embeddable-server package + +## Interfaces + +| Interface | Description | +| --- | --- | +| [EmbeddableRegistryDefinition](./kibana-plugin-plugins-embeddable-server.embeddableregistrydefinition.md) | | +| [EmbeddableSetup](./kibana-plugin-plugins-embeddable-server.embeddablesetup.md) | | +| [EnhancementRegistryDefinition](./kibana-plugin-plugins-embeddable-server.enhancementregistrydefinition.md) | | + +## Variables + +| Variable | Description | +| --- | --- | +| [plugin](./kibana-plugin-plugins-embeddable-server.plugin.md) | | + diff --git a/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.plugin.md b/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.plugin.md new file mode 100644 index 0000000000000..989f3c3e60963 --- /dev/null +++ b/docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.plugin.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-embeddable-server](./kibana-plugin-plugins-embeddable-server.md) > [plugin](./kibana-plugin-plugins-embeddable-server.plugin.md) + +## plugin variable + +Signature: + +```typescript +plugin: () => EmbeddableServerPlugin +``` diff --git a/docs/development/plugins/expressions/public/index.md b/docs/development/plugins/expressions/public/index.md new file mode 100644 index 0000000000000..ade7a9e90b517 --- /dev/null +++ b/docs/development/plugins/expressions/public/index.md @@ -0,0 +1,12 @@ + + +[Home](./index.md) + +## API Reference + +## Packages + +| Package | Description | +| --- | --- | +| [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.anyexpressionfunctiondefinition.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.anyexpressionfunctiondefinition.md new file mode 100644 index 0000000000000..f905a1028d217 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.anyexpressionfunctiondefinition.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [AnyExpressionFunctionDefinition](./kibana-plugin-plugins-expressions-public.anyexpressionfunctiondefinition.md) + +## AnyExpressionFunctionDefinition type + +Type to capture every possible expression function definition. + +Signature: + +```typescript +export declare type AnyExpressionFunctionDefinition = ExpressionFunctionDefinition, any>; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.anyexpressiontypedefinition.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.anyexpressiontypedefinition.md new file mode 100644 index 0000000000000..c213de4341a6a --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.anyexpressiontypedefinition.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [AnyExpressionTypeDefinition](./kibana-plugin-plugins-expressions-public.anyexpressiontypedefinition.md) + +## AnyExpressionTypeDefinition type + +Signature: + +```typescript +export declare type AnyExpressionTypeDefinition = ExpressionTypeDefinition; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.argumenttype.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.argumenttype.md new file mode 100644 index 0000000000000..bf80b863fda90 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.argumenttype.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ArgumentType](./kibana-plugin-plugins-expressions-public.argumenttype.md) + +## ArgumentType type + +This type represents all of the possible combinations of properties of an Argument in an Expression Function. The presence or absence of certain fields influence the shape and presence of others within each `arg` in the specification. + +Signature: + +```typescript +export declare type ArgumentType = SingleArgumentType | MultipleArgumentType | UnresolvedSingleArgumentType | UnresolvedMultipleArgumentType; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.buildexpression.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.buildexpression.md new file mode 100644 index 0000000000000..e1d522588aae8 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.buildexpression.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [buildExpression](./kibana-plugin-plugins-expressions-public.buildexpression.md) + +## buildExpression() function + +Makes it easy to progressively build, update, and traverse an expression AST. You can either start with an empty AST, or provide an expression string, AST, or array of expression function builders to use as initial state. + +Signature: + +```typescript +export declare function buildExpression(initialState?: ExpressionAstFunctionBuilder[] | ExpressionAstExpression | string): ExpressionAstExpressionBuilder; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| initialState | ExpressionAstFunctionBuilder[] | ExpressionAstExpression | string | | + +Returns: + +`ExpressionAstExpressionBuilder` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.buildexpressionfunction.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.buildexpressionfunction.md new file mode 100644 index 0000000000000..79deb7157130e --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.buildexpressionfunction.md @@ -0,0 +1,30 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [buildExpressionFunction](./kibana-plugin-plugins-expressions-public.buildexpressionfunction.md) + +## buildExpressionFunction() function + +Manages an AST for a single expression function. The return value can be provided to `buildExpression` to add this function to an expression. + +Note that to preserve type safety and ensure no args are missing, all required arguments for the specified function must be provided up front. If desired, they can be changed or removed later. + +Signature: + +```typescript +export declare function buildExpressionFunction(fnName: InferFunctionDefinition['name'], +initialArgs: { + [K in keyof FunctionArgs]: FunctionArgs[K] | ExpressionAstExpressionBuilder | ExpressionAstExpressionBuilder[]; +}): ExpressionAstFunctionBuilder; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| fnName | InferFunctionDefinition<FnDef>['name'] | | +| initialArgs | {
[K in keyof FunctionArgs<FnDef>]: FunctionArgs<FnDef>[K] | ExpressionAstExpressionBuilder | ExpressionAstExpressionBuilder[];
} | | + +Returns: + +`ExpressionAstFunctionBuilder` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatable.columns.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatable.columns.md new file mode 100644 index 0000000000000..d24c4f4dfb176 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatable.columns.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Datatable](./kibana-plugin-plugins-expressions-public.datatable.md) > [columns](./kibana-plugin-plugins-expressions-public.datatable.columns.md) + +## Datatable.columns property + +Signature: + +```typescript +columns: DatatableColumn[]; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatable.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatable.md new file mode 100644 index 0000000000000..f2daf656dfa73 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatable.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Datatable](./kibana-plugin-plugins-expressions-public.datatable.md) + +## Datatable interface + +A `Datatable` in Canvas is a unique structure that represents tabulated data. + +Signature: + +```typescript +export interface Datatable +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [columns](./kibana-plugin-plugins-expressions-public.datatable.columns.md) | DatatableColumn[] | | +| [rows](./kibana-plugin-plugins-expressions-public.datatable.rows.md) | DatatableRow[] | | +| [type](./kibana-plugin-plugins-expressions-public.datatable.type.md) | typeof name | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatable.rows.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatable.rows.md new file mode 100644 index 0000000000000..0d52e446b09fd --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatable.rows.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Datatable](./kibana-plugin-plugins-expressions-public.datatable.md) > [rows](./kibana-plugin-plugins-expressions-public.datatable.rows.md) + +## Datatable.rows property + +Signature: + +```typescript +rows: DatatableRow[]; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatable.type.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatable.type.md new file mode 100644 index 0000000000000..e0ee6fd5d8372 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatable.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Datatable](./kibana-plugin-plugins-expressions-public.datatable.md) > [type](./kibana-plugin-plugins-expressions-public.datatable.type.md) + +## Datatable.type property + +Signature: + +```typescript +type: typeof name; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatablecolumn.id.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatablecolumn.id.md new file mode 100644 index 0000000000000..d9b98e6cf939e --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatablecolumn.id.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [DatatableColumn](./kibana-plugin-plugins-expressions-public.datatablecolumn.md) > [id](./kibana-plugin-plugins-expressions-public.datatablecolumn.id.md) + +## DatatableColumn.id property + +Signature: + +```typescript +id: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatablecolumn.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatablecolumn.md new file mode 100644 index 0000000000000..d67a5d9b36b12 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatablecolumn.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [DatatableColumn](./kibana-plugin-plugins-expressions-public.datatablecolumn.md) + +## DatatableColumn interface + +This type represents the shape of a column in a `Datatable`. + +Signature: + +```typescript +export interface DatatableColumn +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [id](./kibana-plugin-plugins-expressions-public.datatablecolumn.id.md) | string | | +| [meta](./kibana-plugin-plugins-expressions-public.datatablecolumn.meta.md) | DatatableColumnMeta | | +| [name](./kibana-plugin-plugins-expressions-public.datatablecolumn.name.md) | string | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatablecolumn.meta.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatablecolumn.meta.md new file mode 100644 index 0000000000000..a5414dde86f97 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatablecolumn.meta.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [DatatableColumn](./kibana-plugin-plugins-expressions-public.datatablecolumn.md) > [meta](./kibana-plugin-plugins-expressions-public.datatablecolumn.meta.md) + +## DatatableColumn.meta property + +Signature: + +```typescript +meta: DatatableColumnMeta; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatablecolumn.name.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatablecolumn.name.md new file mode 100644 index 0000000000000..74c3883e7a172 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatablecolumn.name.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [DatatableColumn](./kibana-plugin-plugins-expressions-public.datatablecolumn.md) > [name](./kibana-plugin-plugins-expressions-public.datatablecolumn.name.md) + +## DatatableColumn.name property + +Signature: + +```typescript +name: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatablecolumntype.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatablecolumntype.md new file mode 100644 index 0000000000000..a06ab351e62c3 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatablecolumntype.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [DatatableColumnType](./kibana-plugin-plugins-expressions-public.datatablecolumntype.md) + +## DatatableColumnType type + +This type represents the `type` of any `DatatableColumn` in a `Datatable`. + +Signature: + +```typescript +export declare type DatatableColumnType = 'string' | 'number' | 'boolean' | 'date' | 'null'; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatablerow.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatablerow.md new file mode 100644 index 0000000000000..87cc15d0d4091 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.datatablerow.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [DatatableRow](./kibana-plugin-plugins-expressions-public.datatablerow.md) + +## DatatableRow type + +This type represents a row in a `Datatable`. + +Signature: + +```typescript +export declare type DatatableRow = Record; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution._constructor_.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution._constructor_.md new file mode 100644 index 0000000000000..1d0c9f99169db --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution._constructor_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Execution](./kibana-plugin-plugins-expressions-public.execution.md) > [(constructor)](./kibana-plugin-plugins-expressions-public.execution._constructor_.md) + +## Execution.(constructor) + +Constructs a new instance of the `Execution` class + +Signature: + +```typescript +constructor(params: ExecutionParams); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| params | ExecutionParams<ExtraContext> | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.cancel.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.cancel.md new file mode 100644 index 0000000000000..e87cea30dd5b6 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.cancel.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Execution](./kibana-plugin-plugins-expressions-public.execution.md) > [cancel](./kibana-plugin-plugins-expressions-public.execution.cancel.md) + +## Execution.cancel() method + +Stop execution of expression. + +Signature: + +```typescript +cancel(): void; +``` +Returns: + +`void` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.cast.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.cast.md new file mode 100644 index 0000000000000..632849af7c82b --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.cast.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Execution](./kibana-plugin-plugins-expressions-public.execution.md) > [cast](./kibana-plugin-plugins-expressions-public.execution.cast.md) + +## Execution.cast() method + +Signature: + +```typescript +cast(value: any, toTypeNames?: string[]): any; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| value | any | | +| toTypeNames | string[] | | + +Returns: + +`any` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.context.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.context.md new file mode 100644 index 0000000000000..732fe94d65617 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.context.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Execution](./kibana-plugin-plugins-expressions-public.execution.md) > [context](./kibana-plugin-plugins-expressions-public.execution.context.md) + +## Execution.context property + +Execution context - object that allows to do side-effects. Context is passed to every function. + +Signature: + +```typescript +readonly context: ExecutionContext & ExtraContext; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.contract.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.contract.md new file mode 100644 index 0000000000000..fa03297ea22a7 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.contract.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Execution](./kibana-plugin-plugins-expressions-public.execution.md) > [contract](./kibana-plugin-plugins-expressions-public.execution.contract.md) + +## Execution.contract property + +Contract is a public representation of `Execution` instances. Contract we can return to other plugins for their consumption. + +Signature: + +```typescript +readonly contract: ExecutionContract; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.expression.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.expression.md new file mode 100644 index 0000000000000..a30cc89e8b649 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.expression.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Execution](./kibana-plugin-plugins-expressions-public.execution.md) > [expression](./kibana-plugin-plugins-expressions-public.execution.expression.md) + +## Execution.expression property + +Signature: + +```typescript +readonly expression: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.input.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.input.md new file mode 100644 index 0000000000000..553a463a2b931 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.input.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Execution](./kibana-plugin-plugins-expressions-public.execution.md) > [input](./kibana-plugin-plugins-expressions-public.execution.input.md) + +## Execution.input property + +Initial input of the execution. + +N.B. It is initialized to `null` rather than `undefined` for legacy reasons, because in legacy interpreter it was set to `null` by default. + +Signature: + +```typescript +input: Input; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.inspectoradapters.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.inspectoradapters.md new file mode 100644 index 0000000000000..728015011f7d9 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.inspectoradapters.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Execution](./kibana-plugin-plugins-expressions-public.execution.md) > [inspectorAdapters](./kibana-plugin-plugins-expressions-public.execution.inspectoradapters.md) + +## Execution.inspectorAdapters property + +Signature: + +```typescript +get inspectorAdapters(): InspectorAdapters; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.interpret.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.interpret.md new file mode 100644 index 0000000000000..31f38b7069812 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.interpret.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Execution](./kibana-plugin-plugins-expressions-public.execution.md) > [interpret](./kibana-plugin-plugins-expressions-public.execution.interpret.md) + +## Execution.interpret() method + +Signature: + +```typescript +interpret(ast: ExpressionAstNode, input: T, options?: ExpressionExecOptions): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| ast | ExpressionAstNode | | +| input | T | | +| options | ExpressionExecOptions | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.invokechain.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.invokechain.md new file mode 100644 index 0000000000000..5078baf2ca526 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.invokechain.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Execution](./kibana-plugin-plugins-expressions-public.execution.md) > [invokeChain](./kibana-plugin-plugins-expressions-public.execution.invokechain.md) + +## Execution.invokeChain() method + +Signature: + +```typescript +invokeChain(chainArr: ExpressionAstFunction[], input: unknown): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| chainArr | ExpressionAstFunction[] | | +| input | unknown | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.invokefunction.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.invokefunction.md new file mode 100644 index 0000000000000..e90cee8b626d6 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.invokefunction.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Execution](./kibana-plugin-plugins-expressions-public.execution.md) > [invokeFunction](./kibana-plugin-plugins-expressions-public.execution.invokefunction.md) + +## Execution.invokeFunction() method + +Signature: + +```typescript +invokeFunction(fn: ExpressionFunction, input: unknown, args: Record): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| fn | ExpressionFunction | | +| input | unknown | | +| args | Record<string, unknown> | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.md new file mode 100644 index 0000000000000..4d227e6ab85b8 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.md @@ -0,0 +1,43 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Execution](./kibana-plugin-plugins-expressions-public.execution.md) + +## Execution class + +Signature: + +```typescript +export declare class Execution = Record, Input = unknown, Output = unknown, InspectorAdapters extends Adapters = ExtraContext['inspectorAdapters'] extends object ? ExtraContext['inspectorAdapters'] : DefaultInspectorAdapters> +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(params)](./kibana-plugin-plugins-expressions-public.execution._constructor_.md) | | Constructs a new instance of the Execution class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [context](./kibana-plugin-plugins-expressions-public.execution.context.md) | | ExecutionContext<Input, InspectorAdapters> & ExtraContext | Execution context - object that allows to do side-effects. Context is passed to every function. | +| [contract](./kibana-plugin-plugins-expressions-public.execution.contract.md) | | ExecutionContract<ExtraContext, Input, Output, InspectorAdapters> | Contract is a public representation of Execution instances. Contract we can return to other plugins for their consumption. | +| [expression](./kibana-plugin-plugins-expressions-public.execution.expression.md) | | string | | +| [input](./kibana-plugin-plugins-expressions-public.execution.input.md) | | Input | Initial input of the execution.N.B. It is initialized to null rather than undefined for legacy reasons, because in legacy interpreter it was set to null by default. | +| [inspectorAdapters](./kibana-plugin-plugins-expressions-public.execution.inspectoradapters.md) | | InspectorAdapters | | +| [params](./kibana-plugin-plugins-expressions-public.execution.params.md) | | ExecutionParams<ExtraContext> | | +| [result](./kibana-plugin-plugins-expressions-public.execution.result.md) | | Promise<Output | ExpressionValueError> | | +| [state](./kibana-plugin-plugins-expressions-public.execution.state.md) | | ExecutionContainer<Output | ExpressionValueError> | Dynamic state of the execution. | + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [cancel()](./kibana-plugin-plugins-expressions-public.execution.cancel.md) | | Stop execution of expression. | +| [cast(value, toTypeNames)](./kibana-plugin-plugins-expressions-public.execution.cast.md) | | | +| [interpret(ast, input, options)](./kibana-plugin-plugins-expressions-public.execution.interpret.md) | | | +| [invokeChain(chainArr, input)](./kibana-plugin-plugins-expressions-public.execution.invokechain.md) | | | +| [invokeFunction(fn, input, args)](./kibana-plugin-plugins-expressions-public.execution.invokefunction.md) | | | +| [resolveArgs(fnDef, input, argAsts)](./kibana-plugin-plugins-expressions-public.execution.resolveargs.md) | | | +| [start(input)](./kibana-plugin-plugins-expressions-public.execution.start.md) | | Call this method to start execution.N.B. input is initialized to null rather than undefined for legacy reasons, because in legacy interpreter it was set to null by default. | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.params.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.params.md new file mode 100644 index 0000000000000..cd90bf6adab47 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.params.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Execution](./kibana-plugin-plugins-expressions-public.execution.md) > [params](./kibana-plugin-plugins-expressions-public.execution.params.md) + +## Execution.params property + +Signature: + +```typescript +readonly params: ExecutionParams; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.resolveargs.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.resolveargs.md new file mode 100644 index 0000000000000..ab67dff604a86 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.resolveargs.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Execution](./kibana-plugin-plugins-expressions-public.execution.md) > [resolveArgs](./kibana-plugin-plugins-expressions-public.execution.resolveargs.md) + +## Execution.resolveArgs() method + +Signature: + +```typescript +resolveArgs(fnDef: ExpressionFunction, input: unknown, argAsts: any): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| fnDef | ExpressionFunction | | +| input | unknown | | +| argAsts | any | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.result.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.result.md new file mode 100644 index 0000000000000..e0167a3a378fe --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.result.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Execution](./kibana-plugin-plugins-expressions-public.execution.md) > [result](./kibana-plugin-plugins-expressions-public.execution.result.md) + +## Execution.result property + +Signature: + +```typescript +get result(): Promise; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.start.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.start.md new file mode 100644 index 0000000000000..c6edc43d423dc --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.start.md @@ -0,0 +1,26 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Execution](./kibana-plugin-plugins-expressions-public.execution.md) > [start](./kibana-plugin-plugins-expressions-public.execution.start.md) + +## Execution.start() method + +Call this method to start execution. + +N.B. `input` is initialized to `null` rather than `undefined` for legacy reasons, because in legacy interpreter it was set to `null` by default. + +Signature: + +```typescript +start(input?: Input): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| input | Input | | + +Returns: + +`void` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.state.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.state.md new file mode 100644 index 0000000000000..ca8b57b760f29 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.execution.state.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Execution](./kibana-plugin-plugins-expressions-public.execution.md) > [state](./kibana-plugin-plugins-expressions-public.execution.state.md) + +## Execution.state property + +Dynamic state of the execution. + +Signature: + +```typescript +readonly state: ExecutionContainer; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontainer.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontainer.md new file mode 100644 index 0000000000000..5cea6c4bc4b8f --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontainer.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionContainer](./kibana-plugin-plugins-expressions-public.executioncontainer.md) + +## ExecutionContainer type + +Signature: + +```typescript +export declare type ExecutionContainer = StateContainer, ExecutionPureTransitions>; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.abortsignal.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.abortsignal.md new file mode 100644 index 0000000000000..caedf4344dc35 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.abortsignal.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionContext](./kibana-plugin-plugins-expressions-public.executioncontext.md) > [abortSignal](./kibana-plugin-plugins-expressions-public.executioncontext.abortsignal.md) + +## ExecutionContext.abortSignal property + +Adds ability to abort current execution. + +Signature: + +```typescript +abortSignal: AbortSignal; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.getinitialinput.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.getinitialinput.md new file mode 100644 index 0000000000000..460b1622c6fbd --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.getinitialinput.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionContext](./kibana-plugin-plugins-expressions-public.executioncontext.md) > [getInitialInput](./kibana-plugin-plugins-expressions-public.executioncontext.getinitialinput.md) + +## ExecutionContext.getInitialInput property + +Get initial input with which execution started. + +Signature: + +```typescript +getInitialInput: () => Input; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.getsavedobject.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.getsavedobject.md new file mode 100644 index 0000000000000..dffce4a091718 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.getsavedobject.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionContext](./kibana-plugin-plugins-expressions-public.executioncontext.md) > [getSavedObject](./kibana-plugin-plugins-expressions-public.executioncontext.getsavedobject.md) + +## ExecutionContext.getSavedObject property + +Allows to fetch saved objects from ElasticSearch. In browser `getSavedObject` function is provided automatically by the Expressions plugin. On the server the caller of the expression has to provide this context function. The reason is because on the browser we always know the user who tries to fetch a saved object, thus saved object client is scoped automatically to that user. However, on the server we can scope that saved object client to any user, or even not scope it at all and execute it as an "internal" user. + +Signature: + +```typescript +getSavedObject?: (type: string, id: string) => Promise>; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.inspectoradapters.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.inspectoradapters.md new file mode 100644 index 0000000000000..6f0db6af5616e --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.inspectoradapters.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionContext](./kibana-plugin-plugins-expressions-public.executioncontext.md) > [inspectorAdapters](./kibana-plugin-plugins-expressions-public.executioncontext.inspectoradapters.md) + +## ExecutionContext.inspectorAdapters property + +Adapters for `inspector` plugin. + +Signature: + +```typescript +inspectorAdapters: InspectorAdapters; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.md new file mode 100644 index 0000000000000..786e94455c600 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.md @@ -0,0 +1,26 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionContext](./kibana-plugin-plugins-expressions-public.executioncontext.md) + +## ExecutionContext interface + +`ExecutionContext` is an object available to all functions during a single execution; it provides various methods to perform side-effects. + +Signature: + +```typescript +export interface ExecutionContext +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [abortSignal](./kibana-plugin-plugins-expressions-public.executioncontext.abortsignal.md) | AbortSignal | Adds ability to abort current execution. | +| [getInitialInput](./kibana-plugin-plugins-expressions-public.executioncontext.getinitialinput.md) | () => Input | Get initial input with which execution started. | +| [getSavedObject](./kibana-plugin-plugins-expressions-public.executioncontext.getsavedobject.md) | <T extends SavedObjectAttributes = SavedObjectAttributes>(type: string, id: string) => Promise<SavedObject<T>> | Allows to fetch saved objects from ElasticSearch. In browser getSavedObject function is provided automatically by the Expressions plugin. On the server the caller of the expression has to provide this context function. The reason is because on the browser we always know the user who tries to fetch a saved object, thus saved object client is scoped automatically to that user. However, on the server we can scope that saved object client to any user, or even not scope it at all and execute it as an "internal" user. | +| [inspectorAdapters](./kibana-plugin-plugins-expressions-public.executioncontext.inspectoradapters.md) | InspectorAdapters | Adapters for inspector plugin. | +| [search](./kibana-plugin-plugins-expressions-public.executioncontext.search.md) | ExecutionContextSearch | Search context in which expression should operate. | +| [types](./kibana-plugin-plugins-expressions-public.executioncontext.types.md) | Record<string, ExpressionType> | A map of available expression types. | +| [variables](./kibana-plugin-plugins-expressions-public.executioncontext.variables.md) | Record<string, unknown> | Context variables that can be consumed using var and var_set functions. | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.search.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.search.md new file mode 100644 index 0000000000000..05501a475cbd4 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.search.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionContext](./kibana-plugin-plugins-expressions-public.executioncontext.md) > [search](./kibana-plugin-plugins-expressions-public.executioncontext.search.md) + +## ExecutionContext.search property + +Search context in which expression should operate. + +Signature: + +```typescript +search?: ExecutionContextSearch; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.types.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.types.md new file mode 100644 index 0000000000000..0bddaf8455635 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.types.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionContext](./kibana-plugin-plugins-expressions-public.executioncontext.md) > [types](./kibana-plugin-plugins-expressions-public.executioncontext.types.md) + +## ExecutionContext.types property + +A map of available expression types. + +Signature: + +```typescript +types: Record; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.variables.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.variables.md new file mode 100644 index 0000000000000..3f8a87152f9fe --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontext.variables.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionContext](./kibana-plugin-plugins-expressions-public.executioncontext.md) > [variables](./kibana-plugin-plugins-expressions-public.executioncontext.variables.md) + +## ExecutionContext.variables property + +Context variables that can be consumed using `var` and `var_set` functions. + +Signature: + +```typescript +variables: Record; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract._constructor_.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract._constructor_.md new file mode 100644 index 0000000000000..89a99ef2f8ef8 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract._constructor_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionContract](./kibana-plugin-plugins-expressions-public.executioncontract.md) > [(constructor)](./kibana-plugin-plugins-expressions-public.executioncontract._constructor_.md) + +## ExecutionContract.(constructor) + +Constructs a new instance of the `ExecutionContract` class + +Signature: + +```typescript +constructor(execution: Execution); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| execution | Execution<ExtraContext, Input, Output, InspectorAdapters> | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract.cancel.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract.cancel.md new file mode 100644 index 0000000000000..7ddfb824288d1 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract.cancel.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionContract](./kibana-plugin-plugins-expressions-public.executioncontract.md) > [cancel](./kibana-plugin-plugins-expressions-public.executioncontract.cancel.md) + +## ExecutionContract.cancel property + +Cancel the execution of the expression. This will set abort signal (available in execution context) to aborted state, letting expression functions to stop their execution. + +Signature: + +```typescript +cancel: () => void; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract.execution.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract.execution.md new file mode 100644 index 0000000000000..f7911250488f2 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract.execution.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionContract](./kibana-plugin-plugins-expressions-public.executioncontract.md) > [execution](./kibana-plugin-plugins-expressions-public.executioncontract.execution.md) + +## ExecutionContract.execution property + +Signature: + +```typescript +protected readonly execution: Execution; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract.getast.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract.getast.md new file mode 100644 index 0000000000000..d873614d779a9 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract.getast.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionContract](./kibana-plugin-plugins-expressions-public.executioncontract.md) > [getAst](./kibana-plugin-plugins-expressions-public.executioncontract.getast.md) + +## ExecutionContract.getAst property + +Get AST used to execute the expression. + +Signature: + +```typescript +getAst: () => ExpressionAstExpression; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract.getdata.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract.getdata.md new file mode 100644 index 0000000000000..dcd96cf5767bf --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract.getdata.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionContract](./kibana-plugin-plugins-expressions-public.executioncontract.md) > [getData](./kibana-plugin-plugins-expressions-public.executioncontract.getdata.md) + +## ExecutionContract.getData property + +Returns the final output of expression, if any error happens still wraps that error into `ExpressionValueError` type and returns that. This function never throws. + +Signature: + +```typescript +getData: () => Promise; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract.getexpression.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract.getexpression.md new file mode 100644 index 0000000000000..41dbe72fa69b2 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract.getexpression.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionContract](./kibana-plugin-plugins-expressions-public.executioncontract.md) > [getExpression](./kibana-plugin-plugins-expressions-public.executioncontract.getexpression.md) + +## ExecutionContract.getExpression property + +Get string representation of the expression. Returns the original string if execution was started from a string. If execution was started from an AST this method returns a string generated from AST. + +Signature: + +```typescript +getExpression: () => string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract.inspect.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract.inspect.md new file mode 100644 index 0000000000000..d5202b02b0dfd --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract.inspect.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionContract](./kibana-plugin-plugins-expressions-public.executioncontract.md) > [inspect](./kibana-plugin-plugins-expressions-public.executioncontract.inspect.md) + +## ExecutionContract.inspect property + +Get Inspector adapters provided to all functions of expression through execution context. + +Signature: + +```typescript +inspect: () => InspectorAdapters; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract.ispending.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract.ispending.md new file mode 100644 index 0000000000000..409c31b3fbc2c --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract.ispending.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionContract](./kibana-plugin-plugins-expressions-public.executioncontract.md) > [isPending](./kibana-plugin-plugins-expressions-public.executioncontract.ispending.md) + +## ExecutionContract.isPending property + +Signature: + +```typescript +get isPending(): boolean; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract.md new file mode 100644 index 0000000000000..d05620eace208 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executioncontract.md @@ -0,0 +1,32 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionContract](./kibana-plugin-plugins-expressions-public.executioncontract.md) + +## ExecutionContract class + +`ExecutionContract` is a wrapper around `Execution` class. It provides the same functionality but does not expose Expressions plugin internals. + +Signature: + +```typescript +export declare class ExecutionContract = Record, Input = unknown, Output = unknown, InspectorAdapters = unknown> +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(execution)](./kibana-plugin-plugins-expressions-public.executioncontract._constructor_.md) | | Constructs a new instance of the ExecutionContract class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [cancel](./kibana-plugin-plugins-expressions-public.executioncontract.cancel.md) | | () => void | Cancel the execution of the expression. This will set abort signal (available in execution context) to aborted state, letting expression functions to stop their execution. | +| [execution](./kibana-plugin-plugins-expressions-public.executioncontract.execution.md) | | Execution<ExtraContext, Input, Output, InspectorAdapters> | | +| [getAst](./kibana-plugin-plugins-expressions-public.executioncontract.getast.md) | | () => ExpressionAstExpression | Get AST used to execute the expression. | +| [getData](./kibana-plugin-plugins-expressions-public.executioncontract.getdata.md) | | () => Promise<Output | ExpressionValueError> | Returns the final output of expression, if any error happens still wraps that error into ExpressionValueError type and returns that. This function never throws. | +| [getExpression](./kibana-plugin-plugins-expressions-public.executioncontract.getexpression.md) | | () => string | Get string representation of the expression. Returns the original string if execution was started from a string. If execution was started from an AST this method returns a string generated from AST. | +| [inspect](./kibana-plugin-plugins-expressions-public.executioncontract.inspect.md) | | () => InspectorAdapters | Get Inspector adapters provided to all functions of expression through execution context. | +| [isPending](./kibana-plugin-plugins-expressions-public.executioncontract.ispending.md) | | boolean | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionparams.ast.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionparams.ast.md new file mode 100644 index 0000000000000..63487bc4c753e --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionparams.ast.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionParams](./kibana-plugin-plugins-expressions-public.executionparams.md) > [ast](./kibana-plugin-plugins-expressions-public.executionparams.ast.md) + +## ExecutionParams.ast property + +Signature: + +```typescript +ast?: ExpressionAstExpression; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionparams.context.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionparams.context.md new file mode 100644 index 0000000000000..b6013162ef2ae --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionparams.context.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionParams](./kibana-plugin-plugins-expressions-public.executionparams.md) > [context](./kibana-plugin-plugins-expressions-public.executionparams.context.md) + +## ExecutionParams.context property + +Signature: + +```typescript +context?: ExtraContext; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionparams.debug.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionparams.debug.md new file mode 100644 index 0000000000000..61ec72465f55e --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionparams.debug.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionParams](./kibana-plugin-plugins-expressions-public.executionparams.md) > [debug](./kibana-plugin-plugins-expressions-public.executionparams.debug.md) + +## ExecutionParams.debug property + +Whether to execute expression in \*debug mode\*. In \*debug mode\* inputs and outputs as well as all resolved arguments and time it took to execute each function are saved and are available for introspection. + +Signature: + +```typescript +debug?: boolean; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionparams.executor.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionparams.executor.md new file mode 100644 index 0000000000000..ec070842692fe --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionparams.executor.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionParams](./kibana-plugin-plugins-expressions-public.executionparams.md) > [executor](./kibana-plugin-plugins-expressions-public.executionparams.executor.md) + +## ExecutionParams.executor property + +Signature: + +```typescript +executor: Executor; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionparams.expression.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionparams.expression.md new file mode 100644 index 0000000000000..f79728bacd336 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionparams.expression.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionParams](./kibana-plugin-plugins-expressions-public.executionparams.md) > [expression](./kibana-plugin-plugins-expressions-public.executionparams.expression.md) + +## ExecutionParams.expression property + +Signature: + +```typescript +expression?: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionparams.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionparams.md new file mode 100644 index 0000000000000..e39dc231fbf96 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionparams.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionParams](./kibana-plugin-plugins-expressions-public.executionparams.md) + +## ExecutionParams interface + +Signature: + +```typescript +export interface ExecutionParams = Record> +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [ast](./kibana-plugin-plugins-expressions-public.executionparams.ast.md) | ExpressionAstExpression | | +| [context](./kibana-plugin-plugins-expressions-public.executionparams.context.md) | ExtraContext | | +| [debug](./kibana-plugin-plugins-expressions-public.executionparams.debug.md) | boolean | Whether to execute expression in \*debug mode\*. In \*debug mode\* inputs and outputs as well as all resolved arguments and time it took to execute each function are saved and are available for introspection. | +| [executor](./kibana-plugin-plugins-expressions-public.executionparams.executor.md) | Executor<any> | | +| [expression](./kibana-plugin-plugins-expressions-public.executionparams.expression.md) | string | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionstate.ast.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionstate.ast.md new file mode 100644 index 0000000000000..bd77c959bde63 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionstate.ast.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionState](./kibana-plugin-plugins-expressions-public.executionstate.md) > [ast](./kibana-plugin-plugins-expressions-public.executionstate.ast.md) + +## ExecutionState.ast property + +Signature: + +```typescript +ast: ExpressionAstExpression; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionstate.error.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionstate.error.md new file mode 100644 index 0000000000000..3ec804b3f0f2e --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionstate.error.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionState](./kibana-plugin-plugins-expressions-public.executionstate.md) > [error](./kibana-plugin-plugins-expressions-public.executionstate.error.md) + +## ExecutionState.error property + +Error happened during the execution. + +Signature: + +```typescript +error?: Error; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionstate.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionstate.md new file mode 100644 index 0000000000000..a7848a65fb94b --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionstate.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionState](./kibana-plugin-plugins-expressions-public.executionstate.md) + +## ExecutionState interface + +Signature: + +```typescript +export interface ExecutionState extends ExecutorState +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [ast](./kibana-plugin-plugins-expressions-public.executionstate.ast.md) | ExpressionAstExpression | | +| [error](./kibana-plugin-plugins-expressions-public.executionstate.error.md) | Error | Error happened during the execution. | +| [result](./kibana-plugin-plugins-expressions-public.executionstate.result.md) | Output | Result of the expression execution. | +| [state](./kibana-plugin-plugins-expressions-public.executionstate.state.md) | 'not-started' | 'pending' | 'result' | 'error' | Tracks state of execution.- not-started - before .start() method was called. - pending - immediately after .start() method is called. - result - when expression execution completed. - error - when execution failed with error. | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionstate.result.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionstate.result.md new file mode 100644 index 0000000000000..571f95211b8bf --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionstate.result.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionState](./kibana-plugin-plugins-expressions-public.executionstate.md) > [result](./kibana-plugin-plugins-expressions-public.executionstate.result.md) + +## ExecutionState.result property + +Result of the expression execution. + +Signature: + +```typescript +result?: Output; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionstate.state.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionstate.state.md new file mode 100644 index 0000000000000..9b6403590e60b --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executionstate.state.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutionState](./kibana-plugin-plugins-expressions-public.executionstate.md) > [state](./kibana-plugin-plugins-expressions-public.executionstate.state.md) + +## ExecutionState.state property + +Tracks state of execution. + +- `not-started` - before .start() method was called. - `pending` - immediately after .start() method is called. - `result` - when expression execution completed. - `error` - when execution failed with error. + +Signature: + +```typescript +state: 'not-started' | 'pending' | 'result' | 'error'; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor._constructor_.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor._constructor_.md new file mode 100644 index 0000000000000..2d776c9536c82 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor._constructor_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Executor](./kibana-plugin-plugins-expressions-public.executor.md) > [(constructor)](./kibana-plugin-plugins-expressions-public.executor._constructor_.md) + +## Executor.(constructor) + +Constructs a new instance of the `Executor` class + +Signature: + +```typescript +constructor(state?: ExecutorState); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| state | ExecutorState<Context> | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.context.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.context.md new file mode 100644 index 0000000000000..9a35931bbb26b --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.context.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Executor](./kibana-plugin-plugins-expressions-public.executor.md) > [context](./kibana-plugin-plugins-expressions-public.executor.context.md) + +## Executor.context property + +Signature: + +```typescript +get context(): Record; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.createexecution.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.createexecution.md new file mode 100644 index 0000000000000..e6765064d4a27 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.createexecution.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Executor](./kibana-plugin-plugins-expressions-public.executor.md) > [createExecution](./kibana-plugin-plugins-expressions-public.executor.createexecution.md) + +## Executor.createExecution() method + +Signature: + +```typescript +createExecution = Record, Input = unknown, Output = unknown>(ast: string | ExpressionAstExpression, context?: ExtraContext, { debug }?: ExpressionExecOptions): Execution; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| ast | string | ExpressionAstExpression | | +| context | ExtraContext | | +| { debug } | ExpressionExecOptions | | + +Returns: + +`Execution` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.createwithdefaults.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.createwithdefaults.md new file mode 100644 index 0000000000000..a058d1c9f830e --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.createwithdefaults.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Executor](./kibana-plugin-plugins-expressions-public.executor.md) > [createWithDefaults](./kibana-plugin-plugins-expressions-public.executor.createwithdefaults.md) + +## Executor.createWithDefaults() method + +Signature: + +```typescript +static createWithDefaults = Record>(state?: ExecutorState): Executor; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| state | ExecutorState<Ctx> | | + +Returns: + +`Executor` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.extendcontext.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.extendcontext.md new file mode 100644 index 0000000000000..a08fcc839110d --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.extendcontext.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Executor](./kibana-plugin-plugins-expressions-public.executor.md) > [extendContext](./kibana-plugin-plugins-expressions-public.executor.extendcontext.md) + +## Executor.extendContext() method + +Signature: + +```typescript +extendContext(extraContext: Record): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| extraContext | Record<string, unknown> | | + +Returns: + +`void` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.fork.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.fork.md new file mode 100644 index 0000000000000..65aa7978a5910 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.fork.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Executor](./kibana-plugin-plugins-expressions-public.executor.md) > [fork](./kibana-plugin-plugins-expressions-public.executor.fork.md) + +## Executor.fork() method + +Signature: + +```typescript +fork(): Executor; +``` +Returns: + +`Executor` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.functions.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.functions.md new file mode 100644 index 0000000000000..3c55c246c91f8 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.functions.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Executor](./kibana-plugin-plugins-expressions-public.executor.md) > [functions](./kibana-plugin-plugins-expressions-public.executor.functions.md) + +## Executor.functions property + +> Warning: This API is now obsolete. +> +> + +Signature: + +```typescript +readonly functions: FunctionsRegistry; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.getfunction.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.getfunction.md new file mode 100644 index 0000000000000..11d04edc9c97d --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.getfunction.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Executor](./kibana-plugin-plugins-expressions-public.executor.md) > [getFunction](./kibana-plugin-plugins-expressions-public.executor.getfunction.md) + +## Executor.getFunction() method + +Signature: + +```typescript +getFunction(name: string): ExpressionFunction | undefined; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| name | string | | + +Returns: + +`ExpressionFunction | undefined` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.getfunctions.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.getfunctions.md new file mode 100644 index 0000000000000..1098c867e4c86 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.getfunctions.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Executor](./kibana-plugin-plugins-expressions-public.executor.md) > [getFunctions](./kibana-plugin-plugins-expressions-public.executor.getfunctions.md) + +## Executor.getFunctions() method + +Signature: + +```typescript +getFunctions(): Record; +``` +Returns: + +`Record` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.gettype.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.gettype.md new file mode 100644 index 0000000000000..a0dc6deb21d2c --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.gettype.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Executor](./kibana-plugin-plugins-expressions-public.executor.md) > [getType](./kibana-plugin-plugins-expressions-public.executor.gettype.md) + +## Executor.getType() method + +Signature: + +```typescript +getType(name: string): ExpressionType | undefined; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| name | string | | + +Returns: + +`ExpressionType | undefined` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.gettypes.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.gettypes.md new file mode 100644 index 0000000000000..a3c72b135cd31 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.gettypes.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Executor](./kibana-plugin-plugins-expressions-public.executor.md) > [getTypes](./kibana-plugin-plugins-expressions-public.executor.gettypes.md) + +## Executor.getTypes() method + +Signature: + +```typescript +getTypes(): Record; +``` +Returns: + +`Record` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.md new file mode 100644 index 0000000000000..b71c8c79c068f --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.md @@ -0,0 +1,43 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Executor](./kibana-plugin-plugins-expressions-public.executor.md) + +## Executor class + +Signature: + +```typescript +export declare class Executor = Record> +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(state)](./kibana-plugin-plugins-expressions-public.executor._constructor_.md) | | Constructs a new instance of the Executor class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [context](./kibana-plugin-plugins-expressions-public.executor.context.md) | | Record<string, unknown> | | +| [functions](./kibana-plugin-plugins-expressions-public.executor.functions.md) | | FunctionsRegistry | | +| [state](./kibana-plugin-plugins-expressions-public.executor.state.md) | | ExecutorContainer<Context> | | +| [types](./kibana-plugin-plugins-expressions-public.executor.types.md) | | TypesRegistry | | + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [createExecution(ast, context, { debug })](./kibana-plugin-plugins-expressions-public.executor.createexecution.md) | | | +| [createWithDefaults(state)](./kibana-plugin-plugins-expressions-public.executor.createwithdefaults.md) | static | | +| [extendContext(extraContext)](./kibana-plugin-plugins-expressions-public.executor.extendcontext.md) | | | +| [fork()](./kibana-plugin-plugins-expressions-public.executor.fork.md) | | | +| [getFunction(name)](./kibana-plugin-plugins-expressions-public.executor.getfunction.md) | | | +| [getFunctions()](./kibana-plugin-plugins-expressions-public.executor.getfunctions.md) | | | +| [getType(name)](./kibana-plugin-plugins-expressions-public.executor.gettype.md) | | | +| [getTypes()](./kibana-plugin-plugins-expressions-public.executor.gettypes.md) | | | +| [registerFunction(functionDefinition)](./kibana-plugin-plugins-expressions-public.executor.registerfunction.md) | | | +| [registerType(typeDefinition)](./kibana-plugin-plugins-expressions-public.executor.registertype.md) | | | +| [run(ast, input, context)](./kibana-plugin-plugins-expressions-public.executor.run.md) | | Execute expression and return result. | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.registerfunction.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.registerfunction.md new file mode 100644 index 0000000000000..b4217fa492a20 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.registerfunction.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Executor](./kibana-plugin-plugins-expressions-public.executor.md) > [registerFunction](./kibana-plugin-plugins-expressions-public.executor.registerfunction.md) + +## Executor.registerFunction() method + +Signature: + +```typescript +registerFunction(functionDefinition: AnyExpressionFunctionDefinition | (() => AnyExpressionFunctionDefinition)): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| functionDefinition | AnyExpressionFunctionDefinition | (() => AnyExpressionFunctionDefinition) | | + +Returns: + +`void` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.registertype.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.registertype.md new file mode 100644 index 0000000000000..f56e5ffcfb9ee --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.registertype.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Executor](./kibana-plugin-plugins-expressions-public.executor.md) > [registerType](./kibana-plugin-plugins-expressions-public.executor.registertype.md) + +## Executor.registerType() method + +Signature: + +```typescript +registerType(typeDefinition: AnyExpressionTypeDefinition | (() => AnyExpressionTypeDefinition)): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| typeDefinition | AnyExpressionTypeDefinition | (() => AnyExpressionTypeDefinition) | | + +Returns: + +`void` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.run.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.run.md new file mode 100644 index 0000000000000..e06ce733acd43 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.run.md @@ -0,0 +1,26 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Executor](./kibana-plugin-plugins-expressions-public.executor.md) > [run](./kibana-plugin-plugins-expressions-public.executor.run.md) + +## Executor.run() method + +Execute expression and return result. + +Signature: + +```typescript +run = Record>(ast: string | ExpressionAstExpression, input: Input, context?: ExtraContext): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| ast | string | ExpressionAstExpression | | +| input | Input | | +| context | ExtraContext | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.state.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.state.md new file mode 100644 index 0000000000000..e9b7006980ceb --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.state.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Executor](./kibana-plugin-plugins-expressions-public.executor.md) > [state](./kibana-plugin-plugins-expressions-public.executor.state.md) + +## Executor.state property + +Signature: + +```typescript +readonly state: ExecutorContainer; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.types.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.types.md new file mode 100644 index 0000000000000..1ab9a5c4621be --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executor.types.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Executor](./kibana-plugin-plugins-expressions-public.executor.md) > [types](./kibana-plugin-plugins-expressions-public.executor.types.md) + +## Executor.types property + +> Warning: This API is now obsolete. +> +> + +Signature: + +```typescript +readonly types: TypesRegistry; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executorcontainer.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executorcontainer.md new file mode 100644 index 0000000000000..f48b001593f94 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executorcontainer.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutorContainer](./kibana-plugin-plugins-expressions-public.executorcontainer.md) + +## ExecutorContainer type + +Signature: + +```typescript +export declare type ExecutorContainer = Record> = StateContainer, ExecutorPureTransitions, ExecutorPureSelectors>; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executorstate.context.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executorstate.context.md new file mode 100644 index 0000000000000..d52074b0eecdd --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executorstate.context.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutorState](./kibana-plugin-plugins-expressions-public.executorstate.md) > [context](./kibana-plugin-plugins-expressions-public.executorstate.context.md) + +## ExecutorState.context property + +Signature: + +```typescript +context: Context; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executorstate.functions.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executorstate.functions.md new file mode 100644 index 0000000000000..034caf27aaef7 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executorstate.functions.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutorState](./kibana-plugin-plugins-expressions-public.executorstate.md) > [functions](./kibana-plugin-plugins-expressions-public.executorstate.functions.md) + +## ExecutorState.functions property + +Signature: + +```typescript +functions: Record; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executorstate.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executorstate.md new file mode 100644 index 0000000000000..e120631285887 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executorstate.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutorState](./kibana-plugin-plugins-expressions-public.executorstate.md) + +## ExecutorState interface + +Signature: + +```typescript +export interface ExecutorState = Record> +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [context](./kibana-plugin-plugins-expressions-public.executorstate.context.md) | Context | | +| [functions](./kibana-plugin-plugins-expressions-public.executorstate.functions.md) | Record<string, ExpressionFunction> | | +| [types](./kibana-plugin-plugins-expressions-public.executorstate.types.md) | Record<string, ExpressionType> | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executorstate.types.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executorstate.types.md new file mode 100644 index 0000000000000..00cf80c271684 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.executorstate.types.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExecutorState](./kibana-plugin-plugins-expressions-public.executorstate.md) > [types](./kibana-plugin-plugins-expressions-public.executorstate.types.md) + +## ExecutorState.types property + +Signature: + +```typescript +types: Record; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastargument.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastargument.md new file mode 100644 index 0000000000000..559cec0e841ac --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastargument.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstArgument](./kibana-plugin-plugins-expressions-public.expressionastargument.md) + +## ExpressionAstArgument type + +Signature: + +```typescript +export declare type ExpressionAstArgument = string | boolean | number | ExpressionAstExpression; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpression.chain.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpression.chain.md new file mode 100644 index 0000000000000..b50ac83036ffe --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpression.chain.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstExpression](./kibana-plugin-plugins-expressions-public.expressionastexpression.md) > [chain](./kibana-plugin-plugins-expressions-public.expressionastexpression.chain.md) + +## ExpressionAstExpression.chain property + +Signature: + +```typescript +chain: ExpressionAstFunction[]; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpression.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpression.md new file mode 100644 index 0000000000000..537659c51dce8 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpression.md @@ -0,0 +1,19 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstExpression](./kibana-plugin-plugins-expressions-public.expressionastexpression.md) + +## ExpressionAstExpression interface + +Signature: + +```typescript +export interface ExpressionAstExpression +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [chain](./kibana-plugin-plugins-expressions-public.expressionastexpression.chain.md) | ExpressionAstFunction[] | | +| [type](./kibana-plugin-plugins-expressions-public.expressionastexpression.type.md) | 'expression' | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpression.type.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpression.type.md new file mode 100644 index 0000000000000..34a86e235a911 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpression.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstExpression](./kibana-plugin-plugins-expressions-public.expressionastexpression.md) > [type](./kibana-plugin-plugins-expressions-public.expressionastexpression.type.md) + +## ExpressionAstExpression.type property + +Signature: + +```typescript +type: 'expression'; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.findfunction.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.findfunction.md new file mode 100644 index 0000000000000..d31f04ad5bf77 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.findfunction.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstExpressionBuilder](./kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.md) > [findFunction](./kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.findfunction.md) + +## ExpressionAstExpressionBuilder.findFunction property + +Recursively searches expression for all ocurrences of the function, including in subexpressions. + +Useful when performing migrations on a specific function, as you can iterate over the array of references and update all functions at once. + +Signature: + +```typescript +findFunction: (fnName: InferFunctionDefinition['name']) => Array> | []; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.functions.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.functions.md new file mode 100644 index 0000000000000..ceaa4c89fb237 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.functions.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstExpressionBuilder](./kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.md) > [functions](./kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.functions.md) + +## ExpressionAstExpressionBuilder.functions property + +Array of each of the `buildExpressionFunction()` instances in this expression. Use this to remove or reorder functions in the expression. + +Signature: + +```typescript +functions: ExpressionAstFunctionBuilder[]; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.md new file mode 100644 index 0000000000000..079e0b3dd8ac1 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstExpressionBuilder](./kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.md) + +## ExpressionAstExpressionBuilder interface + +Signature: + +```typescript +export interface ExpressionAstExpressionBuilder +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [findFunction](./kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.findfunction.md) | <FnDef extends AnyExpressionFunctionDefinition = AnyExpressionFunctionDefinition>(fnName: InferFunctionDefinition<FnDef>['name']) => Array<ExpressionAstFunctionBuilder<FnDef>> | [] | Recursively searches expression for all ocurrences of the function, including in subexpressions.Useful when performing migrations on a specific function, as you can iterate over the array of references and update all functions at once. | +| [functions](./kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.functions.md) | ExpressionAstFunctionBuilder[] | Array of each of the buildExpressionFunction() instances in this expression. Use this to remove or reorder functions in the expression. | +| [toAst](./kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.toast.md) | () => ExpressionAstExpression | Converts expression to an AST. ExpressionAstExpression | +| [toString](./kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.tostring.md) | () => string | Converts expression to an expression string. string | +| [type](./kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.type.md) | 'expression_builder' | Used to identify expression builder objects. | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.toast.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.toast.md new file mode 100644 index 0000000000000..e0b10033f6f3a --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.toast.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstExpressionBuilder](./kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.md) > [toAst](./kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.toast.md) + +## ExpressionAstExpressionBuilder.toAst property + +Converts expression to an AST. + + `ExpressionAstExpression` + +Signature: + +```typescript +toAst: () => ExpressionAstExpression; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.tostring.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.tostring.md new file mode 100644 index 0000000000000..6a9a25256c0a3 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.tostring.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstExpressionBuilder](./kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.md) > [toString](./kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.tostring.md) + +## ExpressionAstExpressionBuilder.toString property + +Converts expression to an expression string. + + `string` + +Signature: + +```typescript +toString: () => string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.type.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.type.md new file mode 100644 index 0000000000000..2aa8d5089aa29 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.type.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstExpressionBuilder](./kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.md) > [type](./kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.type.md) + +## ExpressionAstExpressionBuilder.type property + +Used to identify expression builder objects. + +Signature: + +```typescript +type: 'expression_builder'; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunction.arguments.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunction.arguments.md new file mode 100644 index 0000000000000..72b44e8319542 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunction.arguments.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstFunction](./kibana-plugin-plugins-expressions-public.expressionastfunction.md) > [arguments](./kibana-plugin-plugins-expressions-public.expressionastfunction.arguments.md) + +## ExpressionAstFunction.arguments property + +Signature: + +```typescript +arguments: Record; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunction.debug.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunction.debug.md new file mode 100644 index 0000000000000..36101a110979a --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunction.debug.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstFunction](./kibana-plugin-plugins-expressions-public.expressionastfunction.md) > [debug](./kibana-plugin-plugins-expressions-public.expressionastfunction.debug.md) + +## ExpressionAstFunction.debug property + +Debug information added to each function when expression is executed in \*debug mode\*. + +Signature: + +```typescript +debug?: ExpressionAstFunctionDebug; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunction.function.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunction.function.md new file mode 100644 index 0000000000000..1840fff4b625f --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunction.function.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstFunction](./kibana-plugin-plugins-expressions-public.expressionastfunction.md) > [function](./kibana-plugin-plugins-expressions-public.expressionastfunction.function.md) + +## ExpressionAstFunction.function property + +Signature: + +```typescript +function: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunction.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunction.md new file mode 100644 index 0000000000000..1004e58759806 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunction.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstFunction](./kibana-plugin-plugins-expressions-public.expressionastfunction.md) + +## ExpressionAstFunction interface + +Signature: + +```typescript +export interface ExpressionAstFunction +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [arguments](./kibana-plugin-plugins-expressions-public.expressionastfunction.arguments.md) | Record<string, ExpressionAstArgument[]> | | +| [debug](./kibana-plugin-plugins-expressions-public.expressionastfunction.debug.md) | ExpressionAstFunctionDebug | Debug information added to each function when expression is executed in \*debug mode\*. | +| [function](./kibana-plugin-plugins-expressions-public.expressionastfunction.function.md) | string | | +| [type](./kibana-plugin-plugins-expressions-public.expressionastfunction.type.md) | 'function' | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunction.type.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunction.type.md new file mode 100644 index 0000000000000..f7f8786430191 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunction.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstFunction](./kibana-plugin-plugins-expressions-public.expressionastfunction.md) > [type](./kibana-plugin-plugins-expressions-public.expressionastfunction.type.md) + +## ExpressionAstFunction.type property + +Signature: + +```typescript +type: 'function'; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.addargument.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.addargument.md new file mode 100644 index 0000000000000..da7f0ebc826c1 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.addargument.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstFunctionBuilder](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.md) > [addArgument](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.addargument.md) + +## ExpressionAstFunctionBuilder.addArgument property + +Adds an additional argument to the function. For multi-args, this should be called once for each new arg. Note that TS will not enforce whether multi-args are available, so only use this to update an existing arg if you are certain it is a multi-arg. + +Signature: + +```typescript +addArgument:
>(name: A, value: FunctionArgs[A] | ExpressionAstExpressionBuilder) => this; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.arguments.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.arguments.md new file mode 100644 index 0000000000000..4a95d20d6c983 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.arguments.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstFunctionBuilder](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.md) > [arguments](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.arguments.md) + +## ExpressionAstFunctionBuilder.arguments property + +Object of all args currently added to the function. This is structured similarly to `ExpressionAstFunction['arguments']`, however any subexpressions are returned as expression builder instances instead of expression ASTs. + +Signature: + +```typescript +arguments: FunctionBuilderArguments; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.getargument.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.getargument.md new file mode 100644 index 0000000000000..0df9c80c632b1 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.getargument.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstFunctionBuilder](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.md) > [getArgument](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.getargument.md) + +## ExpressionAstFunctionBuilder.getArgument property + +Retrieves an existing argument by name. Useful when you want to retrieve the current array of args and add something to it before calling `replaceArgument`. Any subexpression arguments will be returned as expression builder instances. + +Signature: + +```typescript +getArgument: >(name: A) => Array[A] | ExpressionAstExpressionBuilder> | undefined; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.md new file mode 100644 index 0000000000000..b05504af28d9b --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.md @@ -0,0 +1,26 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstFunctionBuilder](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.md) + +## ExpressionAstFunctionBuilder interface + +Signature: + +```typescript +export interface ExpressionAstFunctionBuilder +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [addArgument](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.addargument.md) | <A extends FunctionArgName<FnDef>>(name: A, value: FunctionArgs<FnDef>[A] | ExpressionAstExpressionBuilder) => this | Adds an additional argument to the function. For multi-args, this should be called once for each new arg. Note that TS will not enforce whether multi-args are available, so only use this to update an existing arg if you are certain it is a multi-arg. | +| [arguments](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.arguments.md) | FunctionBuilderArguments<FnDef> | Object of all args currently added to the function. This is structured similarly to ExpressionAstFunction['arguments'], however any subexpressions are returned as expression builder instances instead of expression ASTs. | +| [getArgument](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.getargument.md) | <A extends FunctionArgName<FnDef>>(name: A) => Array<FunctionArgs<FnDef>[A] | ExpressionAstExpressionBuilder> | undefined | Retrieves an existing argument by name. Useful when you want to retrieve the current array of args and add something to it before calling replaceArgument. Any subexpression arguments will be returned as expression builder instances. | +| [name](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.name.md) | InferFunctionDefinition<FnDef>['name'] | Name of this expression function. | +| [removeArgument](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.removeargument.md) | <A extends OptionalKeys<FunctionArgs<FnDef>>>(name: A) => this | Removes an (optional) argument from the function.TypeScript will enforce that you only remove optional arguments. For manipulating required args, use replaceArgument. | +| [replaceArgument](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.replaceargument.md) | <A extends FunctionArgName<FnDef>>(name: A, value: Array<FunctionArgs<FnDef>[A] | ExpressionAstExpressionBuilder>) => this | Overwrites an existing argument with a new value. In order to support multi-args, the value given must always be an array. | +| [toAst](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.toast.md) | () => ExpressionAstFunction | Converts function to an AST. ExpressionAstFunction | +| [toString](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.tostring.md) | () => string | Converts function to an expression string. string | +| [type](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.type.md) | 'expression_function_builder' | Used to identify expression function builder objects. | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.name.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.name.md new file mode 100644 index 0000000000000..5bcf965426dbd --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.name.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstFunctionBuilder](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.md) > [name](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.name.md) + +## ExpressionAstFunctionBuilder.name property + +Name of this expression function. + +Signature: + +```typescript +name: InferFunctionDefinition['name']; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.removeargument.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.removeargument.md new file mode 100644 index 0000000000000..1883618c96d53 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.removeargument.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstFunctionBuilder](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.md) > [removeArgument](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.removeargument.md) + +## ExpressionAstFunctionBuilder.removeArgument property + +Removes an (optional) argument from the function. + +TypeScript will enforce that you only remove optional arguments. For manipulating required args, use `replaceArgument`. + +Signature: + +```typescript +removeArgument: >>(name: A) => this; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.replaceargument.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.replaceargument.md new file mode 100644 index 0000000000000..81709f6e94f0a --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.replaceargument.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstFunctionBuilder](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.md) > [replaceArgument](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.replaceargument.md) + +## ExpressionAstFunctionBuilder.replaceArgument property + +Overwrites an existing argument with a new value. In order to support multi-args, the value given must always be an array. + +Signature: + +```typescript +replaceArgument: >(name: A, value: Array[A] | ExpressionAstExpressionBuilder>) => this; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.toast.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.toast.md new file mode 100644 index 0000000000000..bf79726c881ae --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.toast.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstFunctionBuilder](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.md) > [toAst](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.toast.md) + +## ExpressionAstFunctionBuilder.toAst property + +Converts function to an AST. + + `ExpressionAstFunction` + +Signature: + +```typescript +toAst: () => ExpressionAstFunction; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.tostring.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.tostring.md new file mode 100644 index 0000000000000..5c8d0c806d372 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.tostring.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstFunctionBuilder](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.md) > [toString](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.tostring.md) + +## ExpressionAstFunctionBuilder.toString property + +Converts function to an expression string. + + `string` + +Signature: + +```typescript +toString: () => string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.type.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.type.md new file mode 100644 index 0000000000000..b88876b14f367 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.type.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstFunctionBuilder](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.md) > [type](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.type.md) + +## ExpressionAstFunctionBuilder.type property + +Used to identify expression function builder objects. + +Signature: + +```typescript +type: 'expression_function_builder'; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastnode.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastnode.md new file mode 100644 index 0000000000000..4e05b6a18374c --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionastnode.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionAstNode](./kibana-plugin-plugins-expressions-public.expressionastnode.md) + +## ExpressionAstNode type + +Signature: + +```typescript +export declare type ExpressionAstNode = ExpressionAstExpression | ExpressionAstFunction | ExpressionAstArgument; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionexecutor.interpreter.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionexecutor.interpreter.md new file mode 100644 index 0000000000000..6741634379dc1 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionexecutor.interpreter.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionExecutor](./kibana-plugin-plugins-expressions-public.expressionexecutor.md) > [interpreter](./kibana-plugin-plugins-expressions-public.expressionexecutor.interpreter.md) + +## ExpressionExecutor.interpreter property + +Signature: + +```typescript +interpreter: ExpressionInterpreter; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionexecutor.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionexecutor.md new file mode 100644 index 0000000000000..f0c457af52d22 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionexecutor.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionExecutor](./kibana-plugin-plugins-expressions-public.expressionexecutor.md) + +## ExpressionExecutor interface + +> Warning: This API is now obsolete. +> +> This type if remainder from legacy platform, will be deleted going further. +> + +Signature: + +```typescript +export interface ExpressionExecutor +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [interpreter](./kibana-plugin-plugins-expressions-public.expressionexecutor.interpreter.md) | ExpressionInterpreter | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction._constructor_.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction._constructor_.md new file mode 100644 index 0000000000000..9c711b47c89d0 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction._constructor_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunction](./kibana-plugin-plugins-expressions-public.expressionfunction.md) > [(constructor)](./kibana-plugin-plugins-expressions-public.expressionfunction._constructor_.md) + +## ExpressionFunction.(constructor) + +Constructs a new instance of the `ExpressionFunction` class + +Signature: + +```typescript +constructor(functionDefinition: AnyExpressionFunctionDefinition); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| functionDefinition | AnyExpressionFunctionDefinition | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.accepts.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.accepts.md new file mode 100644 index 0000000000000..7a65878cd5a2d --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.accepts.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunction](./kibana-plugin-plugins-expressions-public.expressionfunction.md) > [accepts](./kibana-plugin-plugins-expressions-public.expressionfunction.accepts.md) + +## ExpressionFunction.accepts property + +Signature: + +```typescript +accepts: (type: string) => boolean; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.aliases.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.aliases.md new file mode 100644 index 0000000000000..550620386a892 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.aliases.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunction](./kibana-plugin-plugins-expressions-public.expressionfunction.md) > [aliases](./kibana-plugin-plugins-expressions-public.expressionfunction.aliases.md) + +## ExpressionFunction.aliases property + +Aliases that can be used instead of `name`. + +Signature: + +```typescript +aliases: string[]; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.args.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.args.md new file mode 100644 index 0000000000000..e14c08b8b7079 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.args.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunction](./kibana-plugin-plugins-expressions-public.expressionfunction.md) > [args](./kibana-plugin-plugins-expressions-public.expressionfunction.args.md) + +## ExpressionFunction.args property + +Specification of expression function parameters. + +Signature: + +```typescript +args: Record; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.fn.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.fn.md new file mode 100644 index 0000000000000..d94d9af9bf0f9 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.fn.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunction](./kibana-plugin-plugins-expressions-public.expressionfunction.md) > [fn](./kibana-plugin-plugins-expressions-public.expressionfunction.fn.md) + +## ExpressionFunction.fn property + +Function to run function (context, args) + +Signature: + +```typescript +fn: (input: ExpressionValue, params: Record, handlers: object) => ExpressionValue; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.help.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.help.md new file mode 100644 index 0000000000000..bbf70e11192eb --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.help.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunction](./kibana-plugin-plugins-expressions-public.expressionfunction.md) > [help](./kibana-plugin-plugins-expressions-public.expressionfunction.help.md) + +## ExpressionFunction.help property + +A short help text. + +Signature: + +```typescript +help: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.inputtypes.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.inputtypes.md new file mode 100644 index 0000000000000..865c856746062 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.inputtypes.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunction](./kibana-plugin-plugins-expressions-public.expressionfunction.md) > [inputTypes](./kibana-plugin-plugins-expressions-public.expressionfunction.inputtypes.md) + +## ExpressionFunction.inputTypes property + +Type of inputs that this function supports. + +Signature: + +```typescript +inputTypes: string[] | undefined; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.md new file mode 100644 index 0000000000000..5ca67e40c93ec --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.md @@ -0,0 +1,31 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunction](./kibana-plugin-plugins-expressions-public.expressionfunction.md) + +## ExpressionFunction class + +Signature: + +```typescript +export declare class ExpressionFunction +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(functionDefinition)](./kibana-plugin-plugins-expressions-public.expressionfunction._constructor_.md) | | Constructs a new instance of the ExpressionFunction class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [accepts](./kibana-plugin-plugins-expressions-public.expressionfunction.accepts.md) | | (type: string) => boolean | | +| [aliases](./kibana-plugin-plugins-expressions-public.expressionfunction.aliases.md) | | string[] | Aliases that can be used instead of name. | +| [args](./kibana-plugin-plugins-expressions-public.expressionfunction.args.md) | | Record<string, ExpressionFunctionParameter> | Specification of expression function parameters. | +| [fn](./kibana-plugin-plugins-expressions-public.expressionfunction.fn.md) | | (input: ExpressionValue, params: Record<string, any>, handlers: object) => ExpressionValue | Function to run function (context, args) | +| [help](./kibana-plugin-plugins-expressions-public.expressionfunction.help.md) | | string | A short help text. | +| [inputTypes](./kibana-plugin-plugins-expressions-public.expressionfunction.inputtypes.md) | | string[] | undefined | Type of inputs that this function supports. | +| [name](./kibana-plugin-plugins-expressions-public.expressionfunction.name.md) | | string | Name of function | +| [type](./kibana-plugin-plugins-expressions-public.expressionfunction.type.md) | | string | Return type of function. This SHOULD be supplied. We use it for UI and autocomplete hinting. We may also use it for optimizations in the future. | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.name.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.name.md new file mode 100644 index 0000000000000..2858089ea67de --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.name.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunction](./kibana-plugin-plugins-expressions-public.expressionfunction.md) > [name](./kibana-plugin-plugins-expressions-public.expressionfunction.name.md) + +## ExpressionFunction.name property + +Name of function + +Signature: + +```typescript +name: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.type.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.type.md new file mode 100644 index 0000000000000..7a7bc129a1719 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunction.type.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunction](./kibana-plugin-plugins-expressions-public.expressionfunction.md) > [type](./kibana-plugin-plugins-expressions-public.expressionfunction.type.md) + +## ExpressionFunction.type property + +Return type of function. This SHOULD be supplied. We use it for UI and autocomplete hinting. We may also use it for optimizations in the future. + +Signature: + +```typescript +type: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.aliases.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.aliases.md new file mode 100644 index 0000000000000..bca3600b6d416 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.aliases.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionDefinition](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.md) > [aliases](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.aliases.md) + +## ExpressionFunctionDefinition.aliases property + + What is this? + +Signature: + +```typescript +aliases?: string[]; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.args.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.args.md new file mode 100644 index 0000000000000..65ead35adf0d6 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.args.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionDefinition](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.md) > [args](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.args.md) + +## ExpressionFunctionDefinition.args property + +Specification of arguments that function supports. This list will also be used for autocomplete functionality when your function is being edited. + +Signature: + +```typescript +args: { + [key in keyof Arguments]: ArgumentType; + }; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.context.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.context.md new file mode 100644 index 0000000000000..34bbfc7976007 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.context.md @@ -0,0 +1,18 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionDefinition](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.md) > [context](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.context.md) + +## ExpressionFunctionDefinition.context property + +> Warning: This API is now obsolete. +> +> Use `inputTypes` instead. +> + +Signature: + +```typescript +context?: { + types: AnyExpressionFunctionDefinition['inputTypes']; + }; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.fn.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.fn.md new file mode 100644 index 0000000000000..a2180c0cee665 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.fn.md @@ -0,0 +1,26 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionDefinition](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.md) > [fn](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.fn.md) + +## ExpressionFunctionDefinition.fn() method + +The actual implementation of the function. + +Signature: + +```typescript +fn(input: Input, args: Arguments, context: Context): Output; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| input | Input | | +| args | Arguments | | +| context | Context | | + +Returns: + +`Output` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.help.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.help.md new file mode 100644 index 0000000000000..ad99bb3a14a0b --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.help.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionDefinition](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.md) > [help](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.help.md) + +## ExpressionFunctionDefinition.help property + +Help text displayed in the Expression editor. This text should be internationalized. + +Signature: + +```typescript +help: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.inputtypes.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.inputtypes.md new file mode 100644 index 0000000000000..06c15dba514c2 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.inputtypes.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionDefinition](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.md) > [inputTypes](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.inputtypes.md) + +## ExpressionFunctionDefinition.inputTypes property + +List of allowed type names for input value of this function. If this property is set the input of function will be cast to the first possible type in this list. If this property is missing the input will be provided to the function as-is. + +Signature: + +```typescript +inputTypes?: Array>; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.md new file mode 100644 index 0000000000000..bc801542f81ac --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.md @@ -0,0 +1,32 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionDefinition](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.md) + +## ExpressionFunctionDefinition interface + +`ExpressionFunctionDefinition` is the interface plugins have to implement to register a function in `expressions` plugin. + +Signature: + +```typescript +export interface ExpressionFunctionDefinition, Output, Context extends ExecutionContext = ExecutionContext> +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [aliases](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.aliases.md) | string[] | What is this? | +| [args](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.args.md) | {
[key in keyof Arguments]: ArgumentType<Arguments[key]>;
} | Specification of arguments that function supports. This list will also be used for autocomplete functionality when your function is being edited. | +| [context](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.context.md) | {
types: AnyExpressionFunctionDefinition['inputTypes'];
} | | +| [help](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.help.md) | string | Help text displayed in the Expression editor. This text should be internationalized. | +| [inputTypes](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.inputtypes.md) | Array<TypeToString<Input>> | List of allowed type names for input value of this function. If this property is set the input of function will be cast to the first possible type in this list. If this property is missing the input will be provided to the function as-is. | +| [name](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.name.md) | Name | The name of the function, as will be used in expression. | +| [type](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.type.md) | TypeToString<UnwrapPromiseOrReturn<Output>> | Name of type of value this function outputs. | + +## Methods + +| Method | Description | +| --- | --- | +| [fn(input, args, context)](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.fn.md) | The actual implementation of the function. | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.name.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.name.md new file mode 100644 index 0000000000000..1c74a25851c96 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.name.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionDefinition](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.md) > [name](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.name.md) + +## ExpressionFunctionDefinition.name property + +The name of the function, as will be used in expression. + +Signature: + +```typescript +name: Name; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.type.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.type.md new file mode 100644 index 0000000000000..4831f24a418bc --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.type.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionDefinition](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.md) > [type](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.type.md) + +## ExpressionFunctionDefinition.type property + +Name of type of value this function outputs. + +Signature: + +```typescript +type?: TypeToString>; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.clog.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.clog.md new file mode 100644 index 0000000000000..3b3b5520ab3ab --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.clog.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionDefinitions](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.md) > [clog](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.clog.md) + +## ExpressionFunctionDefinitions.clog property + +Signature: + +```typescript +clog: ExpressionFunctionClog; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.font.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.font.md new file mode 100644 index 0000000000000..06674eeaf9d7a --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.font.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionDefinitions](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.md) > [font](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.font.md) + +## ExpressionFunctionDefinitions.font property + +Signature: + +```typescript +font: ExpressionFunctionFont; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.kibana.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.kibana.md new file mode 100644 index 0000000000000..abe8e0ae161ad --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.kibana.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionDefinitions](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.md) > [kibana](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.kibana.md) + +## ExpressionFunctionDefinitions.kibana property + +Signature: + +```typescript +kibana: ExpressionFunctionKibana; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.kibana_context.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.kibana_context.md new file mode 100644 index 0000000000000..4b58fd84e160d --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.kibana_context.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionDefinitions](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.md) > [kibana\_context](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.kibana_context.md) + +## ExpressionFunctionDefinitions.kibana\_context property + +Signature: + +```typescript +kibana_context: ExpressionFunctionKibanaContext; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.md new file mode 100644 index 0000000000000..914c5d6ebe2f6 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.md @@ -0,0 +1,26 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionDefinitions](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.md) + +## ExpressionFunctionDefinitions interface + +A mapping of `ExpressionFunctionDefinition`s for functions which the Expressions services provides out-of-the-box. Any new functions registered by the Expressions plugin should have their types added here. + +Signature: + +```typescript +export interface ExpressionFunctionDefinitions +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [clog](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.clog.md) | ExpressionFunctionClog | | +| [font](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.font.md) | ExpressionFunctionFont | | +| [kibana\_context](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.kibana_context.md) | ExpressionFunctionKibanaContext | | +| [kibana](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.kibana.md) | ExpressionFunctionKibana | | +| [theme](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.theme.md) | ExpressionFunctionTheme | | +| [var\_set](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.var_set.md) | ExpressionFunctionVarSet | | +| [var](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.var.md) | ExpressionFunctionVar | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.theme.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.theme.md new file mode 100644 index 0000000000000..766aee8f80809 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.theme.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionDefinitions](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.md) > [theme](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.theme.md) + +## ExpressionFunctionDefinitions.theme property + +Signature: + +```typescript +theme: ExpressionFunctionTheme; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.var.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.var.md new file mode 100644 index 0000000000000..4c3f4bb98a51e --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.var.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionDefinitions](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.md) > [var](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.var.md) + +## ExpressionFunctionDefinitions.var property + +Signature: + +```typescript +var: ExpressionFunctionVar; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.var_set.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.var_set.md new file mode 100644 index 0000000000000..a45d58242e4f3 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.var_set.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionDefinitions](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.md) > [var\_set](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.var_set.md) + +## ExpressionFunctionDefinitions.var\_set property + +Signature: + +```typescript +var_set: ExpressionFunctionVarSet; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionkibana.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionkibana.md new file mode 100644 index 0000000000000..8ccf48ba28527 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionkibana.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionKibana](./kibana-plugin-plugins-expressions-public.expressionfunctionkibana.md) + +## ExpressionFunctionKibana type + +Signature: + +```typescript +export declare type ExpressionFunctionKibana = ExpressionFunctionDefinition<'kibana', ExpressionValueSearchContext | null, object, ExpressionValueSearchContext>; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter._constructor_.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter._constructor_.md new file mode 100644 index 0000000000000..476ae51dd50f7 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter._constructor_.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.md) > [(constructor)](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter._constructor_.md) + +## ExpressionFunctionParameter.(constructor) + +Constructs a new instance of the `ExpressionFunctionParameter` class + +Signature: + +```typescript +constructor(name: string, arg: ArgumentType); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| name | string | | +| arg | ArgumentType<any> | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.accepts.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.accepts.md new file mode 100644 index 0000000000000..13b658d86855e --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.accepts.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.md) > [accepts](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.accepts.md) + +## ExpressionFunctionParameter.accepts() method + +Signature: + +```typescript +accepts(type: string): boolean; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| type | string | | + +Returns: + +`boolean` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.aliases.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.aliases.md new file mode 100644 index 0000000000000..03d6daac044b8 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.aliases.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.md) > [aliases](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.aliases.md) + +## ExpressionFunctionParameter.aliases property + +Signature: + +```typescript +aliases: string[]; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.default.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.default.md new file mode 100644 index 0000000000000..20cb697c182ae --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.default.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.md) > [default](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.default.md) + +## ExpressionFunctionParameter.default property + +Signature: + +```typescript +default: any; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.help.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.help.md new file mode 100644 index 0000000000000..102715264d5a9 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.help.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.md) > [help](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.help.md) + +## ExpressionFunctionParameter.help property + +Signature: + +```typescript +help: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.md new file mode 100644 index 0000000000000..eb99255b09328 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.md @@ -0,0 +1,38 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.md) + +## ExpressionFunctionParameter class + +Signature: + +```typescript +export declare class ExpressionFunctionParameter +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(name, arg)](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter._constructor_.md) | | Constructs a new instance of the ExpressionFunctionParameter class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [aliases](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.aliases.md) | | string[] | | +| [default](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.default.md) | | any | | +| [help](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.help.md) | | string | | +| [multi](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.multi.md) | | boolean | | +| [name](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.name.md) | | string | | +| [options](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.options.md) | | any[] | | +| [required](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.required.md) | | boolean | | +| [resolve](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.resolve.md) | | boolean | | +| [types](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.types.md) | | string[] | | + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [accepts(type)](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.accepts.md) | | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.multi.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.multi.md new file mode 100644 index 0000000000000..cc0bfbaac05a1 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.multi.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.md) > [multi](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.multi.md) + +## ExpressionFunctionParameter.multi property + +Signature: + +```typescript +multi: boolean; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.name.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.name.md new file mode 100644 index 0000000000000..6a7d120a169dc --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.name.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.md) > [name](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.name.md) + +## ExpressionFunctionParameter.name property + +Signature: + +```typescript +name: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.options.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.options.md new file mode 100644 index 0000000000000..c1596becd2f5b --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.options.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.md) > [options](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.options.md) + +## ExpressionFunctionParameter.options property + +Signature: + +```typescript +options: any[]; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.required.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.required.md new file mode 100644 index 0000000000000..b4c494704edd7 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.required.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.md) > [required](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.required.md) + +## ExpressionFunctionParameter.required property + +Signature: + +```typescript +required: boolean; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.resolve.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.resolve.md new file mode 100644 index 0000000000000..a5689aa2d4226 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.resolve.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.md) > [resolve](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.resolve.md) + +## ExpressionFunctionParameter.resolve property + +Signature: + +```typescript +resolve: boolean; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.types.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.types.md new file mode 100644 index 0000000000000..63d73001b7285 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionfunctionparameter.types.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.md) > [types](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.types.md) + +## ExpressionFunctionParameter.types property + +Signature: + +```typescript +types: string[]; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionimage.dataurl.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionimage.dataurl.md new file mode 100644 index 0000000000000..b6b34720a7dd8 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionimage.dataurl.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionImage](./kibana-plugin-plugins-expressions-public.expressionimage.md) > [dataurl](./kibana-plugin-plugins-expressions-public.expressionimage.dataurl.md) + +## ExpressionImage.dataurl property + +Signature: + +```typescript +dataurl: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionimage.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionimage.md new file mode 100644 index 0000000000000..430273cca7edd --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionimage.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionImage](./kibana-plugin-plugins-expressions-public.expressionimage.md) + +## ExpressionImage interface + +Signature: + +```typescript +export interface ExpressionImage +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [dataurl](./kibana-plugin-plugins-expressions-public.expressionimage.dataurl.md) | string | | +| [mode](./kibana-plugin-plugins-expressions-public.expressionimage.mode.md) | string | | +| [type](./kibana-plugin-plugins-expressions-public.expressionimage.type.md) | 'image' | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionimage.mode.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionimage.mode.md new file mode 100644 index 0000000000000..f56a58ee71e98 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionimage.mode.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionImage](./kibana-plugin-plugins-expressions-public.expressionimage.md) > [mode](./kibana-plugin-plugins-expressions-public.expressionimage.mode.md) + +## ExpressionImage.mode property + +Signature: + +```typescript +mode: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionimage.type.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionimage.type.md new file mode 100644 index 0000000000000..e3b6e135233ef --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionimage.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionImage](./kibana-plugin-plugins-expressions-public.expressionimage.md) > [type](./kibana-plugin-plugins-expressions-public.expressionimage.type.md) + +## ExpressionImage.type property + +Signature: + +```typescript +type: 'image'; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.displayname.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.displayname.md new file mode 100644 index 0000000000000..a957ecd63f043 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.displayname.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderDefinition](./kibana-plugin-plugins-expressions-public.expressionrenderdefinition.md) > [displayName](./kibana-plugin-plugins-expressions-public.expressionrenderdefinition.displayname.md) + +## ExpressionRenderDefinition.displayName property + +A user friendly name of the renderer as will be displayed to user in UI. + +Signature: + +```typescript +displayName?: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.help.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.help.md new file mode 100644 index 0000000000000..ca67f18c0591f --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.help.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderDefinition](./kibana-plugin-plugins-expressions-public.expressionrenderdefinition.md) > [help](./kibana-plugin-plugins-expressions-public.expressionrenderdefinition.help.md) + +## ExpressionRenderDefinition.help property + +Help text as will be displayed to user. A sentence or few about what this element does. + +Signature: + +```typescript +help?: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.md new file mode 100644 index 0000000000000..3c3322914cebe --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderDefinition](./kibana-plugin-plugins-expressions-public.expressionrenderdefinition.md) + +## ExpressionRenderDefinition interface + +Signature: + +```typescript +export interface ExpressionRenderDefinition +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [displayName](./kibana-plugin-plugins-expressions-public.expressionrenderdefinition.displayname.md) | string | A user friendly name of the renderer as will be displayed to user in UI. | +| [help](./kibana-plugin-plugins-expressions-public.expressionrenderdefinition.help.md) | string | Help text as will be displayed to user. A sentence or few about what this element does. | +| [name](./kibana-plugin-plugins-expressions-public.expressionrenderdefinition.name.md) | string | Technical name of the renderer, used as ID to identify renderer in expression renderer registry. This must match the name of the expression function that is used to create the type: render object. | +| [render](./kibana-plugin-plugins-expressions-public.expressionrenderdefinition.render.md) | (domNode: HTMLElement, config: Config, handlers: IInterpreterRenderHandlers) => void | Promise<void> | The function called to render the output data of an expression. | +| [reuseDomNode](./kibana-plugin-plugins-expressions-public.expressionrenderdefinition.reusedomnode.md) | boolean | Tell the renderer if the dom node should be reused, it's recreated each time by default. | +| [validate](./kibana-plugin-plugins-expressions-public.expressionrenderdefinition.validate.md) | () => undefined | Error | Used to validate the data before calling the render function. | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.name.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.name.md new file mode 100644 index 0000000000000..25b782549fe7b --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.name.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderDefinition](./kibana-plugin-plugins-expressions-public.expressionrenderdefinition.md) > [name](./kibana-plugin-plugins-expressions-public.expressionrenderdefinition.name.md) + +## ExpressionRenderDefinition.name property + +Technical name of the renderer, used as ID to identify renderer in expression renderer registry. This must match the name of the expression function that is used to create the `type: render` object. + +Signature: + +```typescript +name: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.render.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.render.md new file mode 100644 index 0000000000000..d476ae15d4237 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.render.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderDefinition](./kibana-plugin-plugins-expressions-public.expressionrenderdefinition.md) > [render](./kibana-plugin-plugins-expressions-public.expressionrenderdefinition.render.md) + +## ExpressionRenderDefinition.render property + +The function called to render the output data of an expression. + +Signature: + +```typescript +render: (domNode: HTMLElement, config: Config, handlers: IInterpreterRenderHandlers) => void | Promise; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.reusedomnode.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.reusedomnode.md new file mode 100644 index 0000000000000..515cb2c1c078d --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.reusedomnode.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderDefinition](./kibana-plugin-plugins-expressions-public.expressionrenderdefinition.md) > [reuseDomNode](./kibana-plugin-plugins-expressions-public.expressionrenderdefinition.reusedomnode.md) + +## ExpressionRenderDefinition.reuseDomNode property + +Tell the renderer if the dom node should be reused, it's recreated each time by default. + +Signature: + +```typescript +reuseDomNode: boolean; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.validate.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.validate.md new file mode 100644 index 0000000000000..616a0dcc0a94f --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.validate.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderDefinition](./kibana-plugin-plugins-expressions-public.expressionrenderdefinition.md) > [validate](./kibana-plugin-plugins-expressions-public.expressionrenderdefinition.validate.md) + +## ExpressionRenderDefinition.validate property + +Used to validate the data before calling the render function. + +Signature: + +```typescript +validate?: () => undefined | Error; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderer._constructor_.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderer._constructor_.md new file mode 100644 index 0000000000000..de74ee631fcf1 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderer._constructor_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderer](./kibana-plugin-plugins-expressions-public.expressionrenderer.md) > [(constructor)](./kibana-plugin-plugins-expressions-public.expressionrenderer._constructor_.md) + +## ExpressionRenderer.(constructor) + +Constructs a new instance of the `ExpressionRenderer` class + +Signature: + +```typescript +constructor(config: ExpressionRenderDefinition); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| config | ExpressionRenderDefinition<Config> | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderer.displayname.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderer.displayname.md new file mode 100644 index 0000000000000..710bcc60a47e7 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderer.displayname.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderer](./kibana-plugin-plugins-expressions-public.expressionrenderer.md) > [displayName](./kibana-plugin-plugins-expressions-public.expressionrenderer.displayname.md) + +## ExpressionRenderer.displayName property + +Signature: + +```typescript +readonly displayName: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderer.help.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderer.help.md new file mode 100644 index 0000000000000..f5b3f248e71fe --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderer.help.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderer](./kibana-plugin-plugins-expressions-public.expressionrenderer.md) > [help](./kibana-plugin-plugins-expressions-public.expressionrenderer.help.md) + +## ExpressionRenderer.help property + +Signature: + +```typescript +readonly help: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderer.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderer.md new file mode 100644 index 0000000000000..017d88c0cda69 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderer.md @@ -0,0 +1,29 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderer](./kibana-plugin-plugins-expressions-public.expressionrenderer.md) + +## ExpressionRenderer class + +Signature: + +```typescript +export declare class ExpressionRenderer +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(config)](./kibana-plugin-plugins-expressions-public.expressionrenderer._constructor_.md) | | Constructs a new instance of the ExpressionRenderer class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [displayName](./kibana-plugin-plugins-expressions-public.expressionrenderer.displayname.md) | | string | | +| [help](./kibana-plugin-plugins-expressions-public.expressionrenderer.help.md) | | string | | +| [name](./kibana-plugin-plugins-expressions-public.expressionrenderer.name.md) | | string | | +| [render](./kibana-plugin-plugins-expressions-public.expressionrenderer.render.md) | | ExpressionRenderDefinition<Config>['render'] | | +| [reuseDomNode](./kibana-plugin-plugins-expressions-public.expressionrenderer.reusedomnode.md) | | boolean | | +| [validate](./kibana-plugin-plugins-expressions-public.expressionrenderer.validate.md) | | () => void | Error | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderer.name.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderer.name.md new file mode 100644 index 0000000000000..2ed6677cf6ec4 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderer.name.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderer](./kibana-plugin-plugins-expressions-public.expressionrenderer.md) > [name](./kibana-plugin-plugins-expressions-public.expressionrenderer.name.md) + +## ExpressionRenderer.name property + +Signature: + +```typescript +readonly name: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderer.render.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderer.render.md new file mode 100644 index 0000000000000..2491cb31d7659 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderer.render.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderer](./kibana-plugin-plugins-expressions-public.expressionrenderer.md) > [render](./kibana-plugin-plugins-expressions-public.expressionrenderer.render.md) + +## ExpressionRenderer.render property + +Signature: + +```typescript +readonly render: ExpressionRenderDefinition['render']; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderer.reusedomnode.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderer.reusedomnode.md new file mode 100644 index 0000000000000..b5c3a89cc3ed1 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderer.reusedomnode.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderer](./kibana-plugin-plugins-expressions-public.expressionrenderer.md) > [reuseDomNode](./kibana-plugin-plugins-expressions-public.expressionrenderer.reusedomnode.md) + +## ExpressionRenderer.reuseDomNode property + +Signature: + +```typescript +readonly reuseDomNode: boolean; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderer.validate.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderer.validate.md new file mode 100644 index 0000000000000..7c1a7ac65809f --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderer.validate.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderer](./kibana-plugin-plugins-expressions-public.expressionrenderer.md) > [validate](./kibana-plugin-plugins-expressions-public.expressionrenderer.validate.md) + +## ExpressionRenderer.validate property + +Signature: + +```typescript +readonly validate: () => void | Error; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderercomponent.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderercomponent.md new file mode 100644 index 0000000000000..c49a74abe57f3 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderercomponent.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRendererComponent](./kibana-plugin-plugins-expressions-public.expressionrenderercomponent.md) + +## ExpressionRendererComponent type + +Signature: + +```typescript +export declare type ExpressionRendererComponent = React.FC; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererevent.data.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererevent.data.md new file mode 100644 index 0000000000000..537a3f278863d --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererevent.data.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRendererEvent](./kibana-plugin-plugins-expressions-public.expressionrendererevent.md) > [data](./kibana-plugin-plugins-expressions-public.expressionrendererevent.data.md) + +## ExpressionRendererEvent.data property + +Signature: + +```typescript +data: any; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererevent.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererevent.md new file mode 100644 index 0000000000000..952d2f92496c3 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererevent.md @@ -0,0 +1,19 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRendererEvent](./kibana-plugin-plugins-expressions-public.expressionrendererevent.md) + +## ExpressionRendererEvent interface + +Signature: + +```typescript +export interface ExpressionRendererEvent +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [data](./kibana-plugin-plugins-expressions-public.expressionrendererevent.data.md) | any | | +| [name](./kibana-plugin-plugins-expressions-public.expressionrendererevent.name.md) | string | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererevent.name.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererevent.name.md new file mode 100644 index 0000000000000..bbff92108358a --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererevent.name.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRendererEvent](./kibana-plugin-plugins-expressions-public.expressionrendererevent.md) > [name](./kibana-plugin-plugins-expressions-public.expressionrendererevent.name.md) + +## ExpressionRendererEvent.name property + +Signature: + +```typescript +name: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererregistry.get.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererregistry.get.md new file mode 100644 index 0000000000000..cff44001f0a1f --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererregistry.get.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRendererRegistry](./kibana-plugin-plugins-expressions-public.expressionrendererregistry.md) > [get](./kibana-plugin-plugins-expressions-public.expressionrendererregistry.get.md) + +## ExpressionRendererRegistry.get() method + +Signature: + +```typescript +get(id: string): ExpressionRenderer | null; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| id | string | | + +Returns: + +`ExpressionRenderer | null` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererregistry.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererregistry.md new file mode 100644 index 0000000000000..e53f2a7970723 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererregistry.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRendererRegistry](./kibana-plugin-plugins-expressions-public.expressionrendererregistry.md) + +## ExpressionRendererRegistry class + +Signature: + +```typescript +export declare class ExpressionRendererRegistry implements IRegistry +``` + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [get(id)](./kibana-plugin-plugins-expressions-public.expressionrendererregistry.get.md) | | | +| [register(definition)](./kibana-plugin-plugins-expressions-public.expressionrendererregistry.register.md) | | | +| [toArray()](./kibana-plugin-plugins-expressions-public.expressionrendererregistry.toarray.md) | | | +| [toJS()](./kibana-plugin-plugins-expressions-public.expressionrendererregistry.tojs.md) | | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererregistry.register.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererregistry.register.md new file mode 100644 index 0000000000000..13cabb0410861 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererregistry.register.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRendererRegistry](./kibana-plugin-plugins-expressions-public.expressionrendererregistry.md) > [register](./kibana-plugin-plugins-expressions-public.expressionrendererregistry.register.md) + +## ExpressionRendererRegistry.register() method + +Signature: + +```typescript +register(definition: AnyExpressionRenderDefinition | (() => AnyExpressionRenderDefinition)): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| definition | AnyExpressionRenderDefinition | (() => AnyExpressionRenderDefinition) | | + +Returns: + +`void` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererregistry.toarray.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererregistry.toarray.md new file mode 100644 index 0000000000000..b29fd46265d16 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererregistry.toarray.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRendererRegistry](./kibana-plugin-plugins-expressions-public.expressionrendererregistry.md) > [toArray](./kibana-plugin-plugins-expressions-public.expressionrendererregistry.toarray.md) + +## ExpressionRendererRegistry.toArray() method + +Signature: + +```typescript +toArray(): ExpressionRenderer[]; +``` +Returns: + +`ExpressionRenderer[]` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererregistry.tojs.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererregistry.tojs.md new file mode 100644 index 0000000000000..930ef7f8d89d2 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererregistry.tojs.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRendererRegistry](./kibana-plugin-plugins-expressions-public.expressionrendererregistry.md) > [toJS](./kibana-plugin-plugins-expressions-public.expressionrendererregistry.tojs.md) + +## ExpressionRendererRegistry.toJS() method + +Signature: + +```typescript +toJS(): Record; +``` +Returns: + +`Record` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererror.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererror.md new file mode 100644 index 0000000000000..3b3c1644adbef --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererror.md @@ -0,0 +1,18 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderError](./kibana-plugin-plugins-expressions-public.expressionrendererror.md) + +## ExpressionRenderError interface + +Signature: + +```typescript +export interface ExpressionRenderError extends Error +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [type](./kibana-plugin-plugins-expressions-public.expressionrendererror.type.md) | string | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererror.type.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererror.type.md new file mode 100644 index 0000000000000..b1939299a9d37 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrendererror.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderError](./kibana-plugin-plugins-expressions-public.expressionrendererror.md) > [type](./kibana-plugin-plugins-expressions-public.expressionrendererror.type.md) + +## ExpressionRenderError.type property + +Signature: + +```typescript +type?: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler._constructor_.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler._constructor_.md new file mode 100644 index 0000000000000..fb6ba7ee2621c --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler._constructor_.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderHandler](./kibana-plugin-plugins-expressions-public.expressionrenderhandler.md) > [(constructor)](./kibana-plugin-plugins-expressions-public.expressionrenderhandler._constructor_.md) + +## ExpressionRenderHandler.(constructor) + +Constructs a new instance of the `ExpressionRenderHandler` class + +Signature: + +```typescript +constructor(element: HTMLElement, { onRenderError }?: Partial); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| element | HTMLElement | | +| { onRenderError } | Partial<ExpressionRenderHandlerParams> | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler.destroy.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler.destroy.md new file mode 100644 index 0000000000000..df949324b3b45 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler.destroy.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderHandler](./kibana-plugin-plugins-expressions-public.expressionrenderhandler.md) > [destroy](./kibana-plugin-plugins-expressions-public.expressionrenderhandler.destroy.md) + +## ExpressionRenderHandler.destroy property + +Signature: + +```typescript +destroy: () => void; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler.events_.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler.events_.md new file mode 100644 index 0000000000000..c462724a4fdd9 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler.events_.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderHandler](./kibana-plugin-plugins-expressions-public.expressionrenderhandler.md) > [events$](./kibana-plugin-plugins-expressions-public.expressionrenderhandler.events_.md) + +## ExpressionRenderHandler.events$ property + +Signature: + +```typescript +events$: Observable; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler.getelement.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler.getelement.md new file mode 100644 index 0000000000000..42262938502d8 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler.getelement.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderHandler](./kibana-plugin-plugins-expressions-public.expressionrenderhandler.md) > [getElement](./kibana-plugin-plugins-expressions-public.expressionrenderhandler.getelement.md) + +## ExpressionRenderHandler.getElement property + +Signature: + +```typescript +getElement: () => HTMLElement; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler.handlerendererror.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler.handlerendererror.md new file mode 100644 index 0000000000000..6a70cac98ef8a --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler.handlerendererror.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderHandler](./kibana-plugin-plugins-expressions-public.expressionrenderhandler.md) > [handleRenderError](./kibana-plugin-plugins-expressions-public.expressionrenderhandler.handlerendererror.md) + +## ExpressionRenderHandler.handleRenderError property + +Signature: + +```typescript +handleRenderError: (error: ExpressionRenderError) => void; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler.md new file mode 100644 index 0000000000000..7f7d5792ba684 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler.md @@ -0,0 +1,30 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderHandler](./kibana-plugin-plugins-expressions-public.expressionrenderhandler.md) + +## ExpressionRenderHandler class + +Signature: + +```typescript +export declare class ExpressionRenderHandler +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(element, { onRenderError })](./kibana-plugin-plugins-expressions-public.expressionrenderhandler._constructor_.md) | | Constructs a new instance of the ExpressionRenderHandler class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [destroy](./kibana-plugin-plugins-expressions-public.expressionrenderhandler.destroy.md) | | () => void | | +| [events$](./kibana-plugin-plugins-expressions-public.expressionrenderhandler.events_.md) | | Observable<ExpressionRendererEvent> | | +| [getElement](./kibana-plugin-plugins-expressions-public.expressionrenderhandler.getelement.md) | | () => HTMLElement | | +| [handleRenderError](./kibana-plugin-plugins-expressions-public.expressionrenderhandler.handlerendererror.md) | | (error: ExpressionRenderError) => void | | +| [render](./kibana-plugin-plugins-expressions-public.expressionrenderhandler.render.md) | | (data: any, uiState?: any) => Promise<void> | | +| [render$](./kibana-plugin-plugins-expressions-public.expressionrenderhandler.render_.md) | | Observable<number> | | +| [update$](./kibana-plugin-plugins-expressions-public.expressionrenderhandler.update_.md) | | Observable<UpdateValue | null> | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler.render.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler.render.md new file mode 100644 index 0000000000000..dec17d60ffd14 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler.render.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderHandler](./kibana-plugin-plugins-expressions-public.expressionrenderhandler.md) > [render](./kibana-plugin-plugins-expressions-public.expressionrenderhandler.render.md) + +## ExpressionRenderHandler.render property + +Signature: + +```typescript +render: (data: any, uiState?: any) => Promise; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler.render_.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler.render_.md new file mode 100644 index 0000000000000..631dcbfcf89c1 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler.render_.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderHandler](./kibana-plugin-plugins-expressions-public.expressionrenderhandler.md) > [render$](./kibana-plugin-plugins-expressions-public.expressionrenderhandler.render_.md) + +## ExpressionRenderHandler.render$ property + +Signature: + +```typescript +render$: Observable; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler.update_.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler.update_.md new file mode 100644 index 0000000000000..527e64f8e4815 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderhandler.update_.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionRenderHandler](./kibana-plugin-plugins-expressions-public.expressionrenderhandler.md) > [update$](./kibana-plugin-plugins-expressions-public.expressionrenderhandler.update_.md) + +## ExpressionRenderHandler.update$ property + +Signature: + +```typescript +update$: Observable; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionspublicplugin._constructor_.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionspublicplugin._constructor_.md new file mode 100644 index 0000000000000..f49ae9b8166e7 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionspublicplugin._constructor_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsPublicPlugin](./kibana-plugin-plugins-expressions-public.expressionspublicplugin.md) > [(constructor)](./kibana-plugin-plugins-expressions-public.expressionspublicplugin._constructor_.md) + +## ExpressionsPublicPlugin.(constructor) + +Constructs a new instance of the `ExpressionsPublicPlugin` class + +Signature: + +```typescript +constructor(initializerContext: PluginInitializerContext); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| initializerContext | PluginInitializerContext | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionspublicplugin.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionspublicplugin.md new file mode 100644 index 0000000000000..dc8c961ceecc4 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionspublicplugin.md @@ -0,0 +1,26 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsPublicPlugin](./kibana-plugin-plugins-expressions-public.expressionspublicplugin.md) + +## ExpressionsPublicPlugin class + +Signature: + +```typescript +export declare class ExpressionsPublicPlugin implements Plugin +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(initializerContext)](./kibana-plugin-plugins-expressions-public.expressionspublicplugin._constructor_.md) | | Constructs a new instance of the ExpressionsPublicPlugin class | + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [setup(core)](./kibana-plugin-plugins-expressions-public.expressionspublicplugin.setup.md) | | | +| [start(core)](./kibana-plugin-plugins-expressions-public.expressionspublicplugin.start.md) | | | +| [stop()](./kibana-plugin-plugins-expressions-public.expressionspublicplugin.stop.md) | | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionspublicplugin.setup.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionspublicplugin.setup.md new file mode 100644 index 0000000000000..11f72a737aa44 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionspublicplugin.setup.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsPublicPlugin](./kibana-plugin-plugins-expressions-public.expressionspublicplugin.md) > [setup](./kibana-plugin-plugins-expressions-public.expressionspublicplugin.setup.md) + +## ExpressionsPublicPlugin.setup() method + +Signature: + +```typescript +setup(core: CoreSetup): ExpressionsSetup; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| core | CoreSetup | | + +Returns: + +`ExpressionsSetup` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionspublicplugin.start.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionspublicplugin.start.md new file mode 100644 index 0000000000000..75599e2575809 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionspublicplugin.start.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsPublicPlugin](./kibana-plugin-plugins-expressions-public.expressionspublicplugin.md) > [start](./kibana-plugin-plugins-expressions-public.expressionspublicplugin.start.md) + +## ExpressionsPublicPlugin.start() method + +Signature: + +```typescript +start(core: CoreStart): ExpressionsStart; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| core | CoreStart | | + +Returns: + +`ExpressionsStart` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionspublicplugin.stop.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionspublicplugin.stop.md new file mode 100644 index 0000000000000..2de33ef166b96 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionspublicplugin.stop.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsPublicPlugin](./kibana-plugin-plugins-expressions-public.expressionspublicplugin.md) > [stop](./kibana-plugin-plugins-expressions-public.expressionspublicplugin.stop.md) + +## ExpressionsPublicPlugin.stop() method + +Signature: + +```typescript +stop(): void; +``` +Returns: + +`void` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice._constructor_.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice._constructor_.md new file mode 100644 index 0000000000000..695adad8cbeaf --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice._constructor_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) > [(constructor)](./kibana-plugin-plugins-expressions-public.expressionsservice._constructor_.md) + +## ExpressionsService.(constructor) + +Constructs a new instance of the `ExpressionsService` class + +Signature: + +```typescript +constructor({ executor, renderers, }?: ExpressionServiceParams); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| { executor, renderers, } | ExpressionServiceParams | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.execute.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.execute.md new file mode 100644 index 0000000000000..e4ab0aa32516c --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.execute.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) > [execute](./kibana-plugin-plugins-expressions-public.expressionsservice.execute.md) + +## ExpressionsService.execute property + +Signature: + +```typescript +readonly execute: ExpressionsServiceStart['execute']; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.executor.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.executor.md new file mode 100644 index 0000000000000..f206a0a5c4bb3 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.executor.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) > [executor](./kibana-plugin-plugins-expressions-public.expressionsservice.executor.md) + +## ExpressionsService.executor property + +Signature: + +```typescript +readonly executor: Executor; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.fork.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.fork.md new file mode 100644 index 0000000000000..5273f8d79f5cf --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.fork.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) > [fork](./kibana-plugin-plugins-expressions-public.expressionsservice.fork.md) + +## ExpressionsService.fork property + +Signature: + +```typescript +readonly fork: () => ExpressionsService; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.getfunction.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.getfunction.md new file mode 100644 index 0000000000000..7d79a1e407a46 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.getfunction.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) > [getFunction](./kibana-plugin-plugins-expressions-public.expressionsservice.getfunction.md) + +## ExpressionsService.getFunction property + +Signature: + +```typescript +readonly getFunction: ExpressionsServiceStart['getFunction']; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.getfunctions.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.getfunctions.md new file mode 100644 index 0000000000000..6e1b1ca3e1c6d --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.getfunctions.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) > [getFunctions](./kibana-plugin-plugins-expressions-public.expressionsservice.getfunctions.md) + +## ExpressionsService.getFunctions property + +Returns POJO map of all registered expression functions, where keys are names of the functions and values are `ExpressionFunction` instances. + +Signature: + +```typescript +readonly getFunctions: () => ReturnType; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.getrenderer.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.getrenderer.md new file mode 100644 index 0000000000000..5821654cf8ec5 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.getrenderer.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) > [getRenderer](./kibana-plugin-plugins-expressions-public.expressionsservice.getrenderer.md) + +## ExpressionsService.getRenderer property + +Signature: + +```typescript +readonly getRenderer: ExpressionsServiceStart['getRenderer']; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.getrenderers.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.getrenderers.md new file mode 100644 index 0000000000000..3258717759c90 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.getrenderers.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) > [getRenderers](./kibana-plugin-plugins-expressions-public.expressionsservice.getrenderers.md) + +## ExpressionsService.getRenderers property + +Returns POJO map of all registered expression renderers, where keys are names of the renderers and values are `ExpressionRenderer` instances. + +Signature: + +```typescript +readonly getRenderers: () => ReturnType; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.gettype.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.gettype.md new file mode 100644 index 0000000000000..e8c451ab88e9f --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.gettype.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) > [getType](./kibana-plugin-plugins-expressions-public.expressionsservice.gettype.md) + +## ExpressionsService.getType property + +Signature: + +```typescript +readonly getType: ExpressionsServiceStart['getType']; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.gettypes.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.gettypes.md new file mode 100644 index 0000000000000..844f581240d45 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.gettypes.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) > [getTypes](./kibana-plugin-plugins-expressions-public.expressionsservice.gettypes.md) + +## ExpressionsService.getTypes property + +Returns POJO map of all registered expression types, where keys are names of the types and values are `ExpressionType` instances. + +Signature: + +```typescript +readonly getTypes: () => ReturnType; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.md new file mode 100644 index 0000000000000..fa93435bffc38 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.md @@ -0,0 +1,72 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) + +## ExpressionsService class + +`ExpressionsService` class is used for multiple purposes: + +1. It implements the same Expressions service that can be used on both: (1) server-side and (2) browser-side. 2. It implements the same Expressions service that users can fork/clone, thus have their own instance of the Expressions plugin. 3. `ExpressionsService` defines the public contracts of \*setup\* and \*start\* Kibana Platform life-cycles for ease-of-use on server-side and browser-side. 4. `ExpressionsService` creates a bound version of all exported contract functions. 5. Functions are bound the way there are: + +\`\`\`ts registerFunction = (...args: Parameters<Executor\['registerFunction'\]> ): ReturnType<Executor\['registerFunction'\]> => this.executor.registerFunction(...args); \`\`\` + +so that JSDoc appears in developers IDE when they use those `plugins.expressions.registerFunction(`. + +Signature: + +```typescript +export declare class ExpressionsService +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)({ executor, renderers, })](./kibana-plugin-plugins-expressions-public.expressionsservice._constructor_.md) | | Constructs a new instance of the ExpressionsService class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [execute](./kibana-plugin-plugins-expressions-public.expressionsservice.execute.md) | | ExpressionsServiceStart['execute'] | | +| [executor](./kibana-plugin-plugins-expressions-public.expressionsservice.executor.md) | | Executor | | +| [fork](./kibana-plugin-plugins-expressions-public.expressionsservice.fork.md) | | () => ExpressionsService | | +| [getFunction](./kibana-plugin-plugins-expressions-public.expressionsservice.getfunction.md) | | ExpressionsServiceStart['getFunction'] | | +| [getFunctions](./kibana-plugin-plugins-expressions-public.expressionsservice.getfunctions.md) | | () => ReturnType<Executor['getFunctions']> | Returns POJO map of all registered expression functions, where keys are names of the functions and values are ExpressionFunction instances. | +| [getRenderer](./kibana-plugin-plugins-expressions-public.expressionsservice.getrenderer.md) | | ExpressionsServiceStart['getRenderer'] | | +| [getRenderers](./kibana-plugin-plugins-expressions-public.expressionsservice.getrenderers.md) | | () => ReturnType<ExpressionRendererRegistry['toJS']> | Returns POJO map of all registered expression renderers, where keys are names of the renderers and values are ExpressionRenderer instances. | +| [getType](./kibana-plugin-plugins-expressions-public.expressionsservice.gettype.md) | | ExpressionsServiceStart['getType'] | | +| [getTypes](./kibana-plugin-plugins-expressions-public.expressionsservice.gettypes.md) | | () => ReturnType<Executor['getTypes']> | Returns POJO map of all registered expression types, where keys are names of the types and values are ExpressionType instances. | +| [registerFunction](./kibana-plugin-plugins-expressions-public.expressionsservice.registerfunction.md) | | (functionDefinition: AnyExpressionFunctionDefinition | (() => AnyExpressionFunctionDefinition)) => void | Register an expression function, which will be possible to execute as part of the expression pipeline.Below we register a function which simply sleeps for given number of milliseconds to delay the execution and outputs its input as-is. +```ts +expressions.registerFunction({ + name: 'sleep', + args: { + time: { + aliases: ['_'], + help: 'Time in milliseconds for how long to sleep', + types: ['number'], + }, + }, + help: '', + fn: async (input, args, context) => { + await new Promise(r => setTimeout(r, args.time)); + return input; + }, +} + +``` +The actual function is defined in the fn key. The function can be \*async\*. It receives three arguments: (1) input is the output of the previous function or the initial input of the expression if the function is first in chain; (2) args are function arguments as defined in expression string, that can be edited by user (e.g in case of Canvas); (3) context is a shared object passed to all functions that can be used for side-effects. | +| [registerRenderer](./kibana-plugin-plugins-expressions-public.expressionsservice.registerrenderer.md) | | (definition: AnyExpressionRenderDefinition | (() => AnyExpressionRenderDefinition)) => void | | +| [registerType](./kibana-plugin-plugins-expressions-public.expressionsservice.registertype.md) | | (typeDefinition: AnyExpressionTypeDefinition | (() => AnyExpressionTypeDefinition)) => void | | +| [renderers](./kibana-plugin-plugins-expressions-public.expressionsservice.renderers.md) | | ExpressionRendererRegistry | | +| [run](./kibana-plugin-plugins-expressions-public.expressionsservice.run.md) | | ExpressionsServiceStart['run'] | | + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [setup()](./kibana-plugin-plugins-expressions-public.expressionsservice.setup.md) | | Returns Kibana Platform \*setup\* life-cycle contract. Useful to return the same contract on server-side and browser-side. | +| [start()](./kibana-plugin-plugins-expressions-public.expressionsservice.start.md) | | Returns Kibana Platform \*start\* life-cycle contract. Useful to return the same contract on server-side and browser-side. | +| [stop()](./kibana-plugin-plugins-expressions-public.expressionsservice.stop.md) | | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.registerfunction.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.registerfunction.md new file mode 100644 index 0000000000000..0653e68bb4837 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.registerfunction.md @@ -0,0 +1,35 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) > [registerFunction](./kibana-plugin-plugins-expressions-public.expressionsservice.registerfunction.md) + +## ExpressionsService.registerFunction property + +Register an expression function, which will be possible to execute as part of the expression pipeline. + +Below we register a function which simply sleeps for given number of milliseconds to delay the execution and outputs its input as-is. + +```ts +expressions.registerFunction({ + name: 'sleep', + args: { + time: { + aliases: ['_'], + help: 'Time in milliseconds for how long to sleep', + types: ['number'], + }, + }, + help: '', + fn: async (input, args, context) => { + await new Promise(r => setTimeout(r, args.time)); + return input; + }, +} + +``` +The actual function is defined in the `fn` key. The function can be \*async\*. It receives three arguments: (1) `input` is the output of the previous function or the initial input of the expression if the function is first in chain; (2) `args` are function arguments as defined in expression string, that can be edited by user (e.g in case of Canvas); (3) `context` is a shared object passed to all functions that can be used for side-effects. + +Signature: + +```typescript +readonly registerFunction: (functionDefinition: AnyExpressionFunctionDefinition | (() => AnyExpressionFunctionDefinition)) => void; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.registerrenderer.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.registerrenderer.md new file mode 100644 index 0000000000000..7aff36e7fd817 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.registerrenderer.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) > [registerRenderer](./kibana-plugin-plugins-expressions-public.expressionsservice.registerrenderer.md) + +## ExpressionsService.registerRenderer property + +Signature: + +```typescript +readonly registerRenderer: (definition: AnyExpressionRenderDefinition | (() => AnyExpressionRenderDefinition)) => void; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.registertype.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.registertype.md new file mode 100644 index 0000000000000..e6e71e5e7e7e9 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.registertype.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) > [registerType](./kibana-plugin-plugins-expressions-public.expressionsservice.registertype.md) + +## ExpressionsService.registerType property + +Signature: + +```typescript +readonly registerType: (typeDefinition: AnyExpressionTypeDefinition | (() => AnyExpressionTypeDefinition)) => void; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.renderers.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.renderers.md new file mode 100644 index 0000000000000..e43e9a21050ea --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.renderers.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) > [renderers](./kibana-plugin-plugins-expressions-public.expressionsservice.renderers.md) + +## ExpressionsService.renderers property + +Signature: + +```typescript +readonly renderers: ExpressionRendererRegistry; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.run.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.run.md new file mode 100644 index 0000000000000..47469167f6360 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.run.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) > [run](./kibana-plugin-plugins-expressions-public.expressionsservice.run.md) + +## ExpressionsService.run property + +Signature: + +```typescript +readonly run: ExpressionsServiceStart['run']; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.setup.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.setup.md new file mode 100644 index 0000000000000..a51f3f073d518 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.setup.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) > [setup](./kibana-plugin-plugins-expressions-public.expressionsservice.setup.md) + +## ExpressionsService.setup() method + +Returns Kibana Platform \*setup\* life-cycle contract. Useful to return the same contract on server-side and browser-side. + +Signature: + +```typescript +setup(): ExpressionsServiceSetup; +``` +Returns: + +`ExpressionsServiceSetup` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.start.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.start.md new file mode 100644 index 0000000000000..766d703a0729d --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.start.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) > [start](./kibana-plugin-plugins-expressions-public.expressionsservice.start.md) + +## ExpressionsService.start() method + +Returns Kibana Platform \*start\* life-cycle contract. Useful to return the same contract on server-side and browser-side. + +Signature: + +```typescript +start(): ExpressionsServiceStart; +``` +Returns: + +`ExpressionsServiceStart` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.stop.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.stop.md new file mode 100644 index 0000000000000..a32bb4a8bb009 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservice.stop.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) > [stop](./kibana-plugin-plugins-expressions-public.expressionsservice.stop.md) + +## ExpressionsService.stop() method + +Signature: + +```typescript +stop(): void; +``` +Returns: + +`void` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservicesetup.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservicesetup.md new file mode 100644 index 0000000000000..4cf3fb9b53978 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservicesetup.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsServiceSetup](./kibana-plugin-plugins-expressions-public.expressionsservicesetup.md) + +## ExpressionsServiceSetup type + +The public contract that `ExpressionsService` provides to other plugins in Kibana Platform in \*setup\* life-cycle. + +Signature: + +```typescript +export declare type ExpressionsServiceSetup = Pick; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservicestart.execute.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservicestart.execute.md new file mode 100644 index 0000000000000..b8211a6bff27c --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservicestart.execute.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsServiceStart](./kibana-plugin-plugins-expressions-public.expressionsservicestart.md) > [execute](./kibana-plugin-plugins-expressions-public.expressionsservicestart.execute.md) + +## ExpressionsServiceStart.execute property + +Starts expression execution and immediately returns `ExecutionContract` instance that tracks the progress of the execution and can be used to interact with the execution. + +Signature: + +```typescript +execute: = Record>(ast: string | ExpressionAstExpression, input: Input, context?: ExtraContext) => ExecutionContract; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservicestart.fork.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservicestart.fork.md new file mode 100644 index 0000000000000..dd18daceb9539 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservicestart.fork.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsServiceStart](./kibana-plugin-plugins-expressions-public.expressionsservicestart.md) > [fork](./kibana-plugin-plugins-expressions-public.expressionsservicestart.fork.md) + +## ExpressionsServiceStart.fork property + +Create a new instance of `ExpressionsService`. The new instance inherits all state of the original `ExpressionsService`, including all expression types, expression functions and context. Also, all new types and functions registered in the original services AFTER the forking event will be available in the forked instance. However, all new types and functions registered in the forked instances will NOT be available to the original service. + +Signature: + +```typescript +fork: () => ExpressionsService; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservicestart.getfunction.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservicestart.getfunction.md new file mode 100644 index 0000000000000..d1a9bbce2a27e --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservicestart.getfunction.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsServiceStart](./kibana-plugin-plugins-expressions-public.expressionsservicestart.md) > [getFunction](./kibana-plugin-plugins-expressions-public.expressionsservicestart.getfunction.md) + +## ExpressionsServiceStart.getFunction property + +Get a registered `ExpressionFunction` by its name, which was registered using the `registerFunction` method. The returned `ExpressionFunction` instance is an internal representation of the function in Expressions service - do not mutate that object. + +Signature: + +```typescript +getFunction: (name: string) => ReturnType; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservicestart.getrenderer.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservicestart.getrenderer.md new file mode 100644 index 0000000000000..ef98fd633cb0c --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservicestart.getrenderer.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsServiceStart](./kibana-plugin-plugins-expressions-public.expressionsservicestart.md) > [getRenderer](./kibana-plugin-plugins-expressions-public.expressionsservicestart.getrenderer.md) + +## ExpressionsServiceStart.getRenderer property + +Get a registered `ExpressionRenderer` by its name, which was registered using the `registerRenderer` method. The returned `ExpressionRenderer` instance is an internal representation of the renderer in Expressions service - do not mutate that object. + +Signature: + +```typescript +getRenderer: (name: string) => ReturnType; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservicestart.gettype.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservicestart.gettype.md new file mode 100644 index 0000000000000..e9ec1733513ba --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservicestart.gettype.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsServiceStart](./kibana-plugin-plugins-expressions-public.expressionsservicestart.md) > [getType](./kibana-plugin-plugins-expressions-public.expressionsservicestart.gettype.md) + +## ExpressionsServiceStart.getType property + +Get a registered `ExpressionType` by its name, which was registered using the `registerType` method. The returned `ExpressionType` instance is an internal representation of the type in Expressions service - do not mutate that object. + +Signature: + +```typescript +getType: (name: string) => ReturnType; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservicestart.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservicestart.md new file mode 100644 index 0000000000000..34bf16c121326 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservicestart.md @@ -0,0 +1,35 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsServiceStart](./kibana-plugin-plugins-expressions-public.expressionsservicestart.md) + +## ExpressionsServiceStart interface + +The public contract that `ExpressionsService` provides to other plugins in Kibana Platform in \*start\* life-cycle. + +Signature: + +```typescript +export interface ExpressionsServiceStart +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [execute](./kibana-plugin-plugins-expressions-public.expressionsservicestart.execute.md) | <Input = unknown, Output = unknown, ExtraContext extends Record<string, unknown> = Record<string, unknown>>(ast: string | ExpressionAstExpression, input: Input, context?: ExtraContext) => ExecutionContract<ExtraContext, Input, Output> | Starts expression execution and immediately returns ExecutionContract instance that tracks the progress of the execution and can be used to interact with the execution. | +| [fork](./kibana-plugin-plugins-expressions-public.expressionsservicestart.fork.md) | () => ExpressionsService | Create a new instance of ExpressionsService. The new instance inherits all state of the original ExpressionsService, including all expression types, expression functions and context. Also, all new types and functions registered in the original services AFTER the forking event will be available in the forked instance. However, all new types and functions registered in the forked instances will NOT be available to the original service. | +| [getFunction](./kibana-plugin-plugins-expressions-public.expressionsservicestart.getfunction.md) | (name: string) => ReturnType<Executor['getFunction']> | Get a registered ExpressionFunction by its name, which was registered using the registerFunction method. The returned ExpressionFunction instance is an internal representation of the function in Expressions service - do not mutate that object. | +| [getRenderer](./kibana-plugin-plugins-expressions-public.expressionsservicestart.getrenderer.md) | (name: string) => ReturnType<ExpressionRendererRegistry['get']> | Get a registered ExpressionRenderer by its name, which was registered using the registerRenderer method. The returned ExpressionRenderer instance is an internal representation of the renderer in Expressions service - do not mutate that object. | +| [getType](./kibana-plugin-plugins-expressions-public.expressionsservicestart.gettype.md) | (name: string) => ReturnType<Executor['getType']> | Get a registered ExpressionType by its name, which was registered using the registerType method. The returned ExpressionType instance is an internal representation of the type in Expressions service - do not mutate that object. | +| [run](./kibana-plugin-plugins-expressions-public.expressionsservicestart.run.md) | <Input, Output, ExtraContext extends Record<string, unknown> = Record<string, unknown>>(ast: string | ExpressionAstExpression, input: Input, context?: ExtraContext) => Promise<Output> | Executes expression string or a parsed expression AST and immediately returns the result.Below example will execute sleep 100 | clog expression with 123 initial input to the first function. +```ts +expressions.run('sleep 100 | clog', 123); + +``` +- sleep 100 will delay execution by 100 milliseconds and pass the 123 input as its output. - clog will print to console 123 and pass it as its output. - The final result of the execution will be 123.Optionally, you can pass an object as the third argument which will be used to extend the ExecutionContext&mdash;an object passed to each function as the third argument, that allows functions to perform side-effects. +```ts +expressions.run('...', null, { elasticsearchClient }); + +``` + | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservicestart.run.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservicestart.run.md new file mode 100644 index 0000000000000..578c583624ad0 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsservicestart.run.md @@ -0,0 +1,28 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsServiceStart](./kibana-plugin-plugins-expressions-public.expressionsservicestart.md) > [run](./kibana-plugin-plugins-expressions-public.expressionsservicestart.run.md) + +## ExpressionsServiceStart.run property + +Executes expression string or a parsed expression AST and immediately returns the result. + +Below example will execute `sleep 100 | clog` expression with `123` initial input to the first function. + +```ts +expressions.run('sleep 100 | clog', 123); + +``` +- `sleep 100` will delay execution by 100 milliseconds and pass the `123` input as its output. - `clog` will print to console `123` and pass it as its output. - The final result of the execution will be `123`. + +Optionally, you can pass an object as the third argument which will be used to extend the `ExecutionContext`&mdash;an object passed to each function as the third argument, that allows functions to perform side-effects. + +```ts +expressions.run('...', null, { elasticsearchClient }); + +``` + +Signature: + +```typescript +run: = Record>(ast: string | ExpressionAstExpression, input: Input, context?: ExtraContext) => Promise; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionssetup.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionssetup.md new file mode 100644 index 0000000000000..01a894ae8fba6 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionssetup.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsSetup](./kibana-plugin-plugins-expressions-public.expressionssetup.md) + +## ExpressionsSetup type + +Expressions public setup contract, extends [ExpressionsServiceSetup](./kibana-plugin-plugins-expressions-public.expressionsservicesetup.md) + +Signature: + +```typescript +export declare type ExpressionsSetup = ExpressionsServiceSetup; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsstart.expressionloader.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsstart.expressionloader.md new file mode 100644 index 0000000000000..b7226b12b0d2b --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsstart.expressionloader.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsStart](./kibana-plugin-plugins-expressions-public.expressionsstart.md) > [ExpressionLoader](./kibana-plugin-plugins-expressions-public.expressionsstart.expressionloader.md) + +## ExpressionsStart.ExpressionLoader property + +Signature: + +```typescript +ExpressionLoader: typeof ExpressionLoader; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsstart.expressionrenderhandler.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsstart.expressionrenderhandler.md new file mode 100644 index 0000000000000..a78bb6f154c46 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsstart.expressionrenderhandler.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsStart](./kibana-plugin-plugins-expressions-public.expressionsstart.md) > [ExpressionRenderHandler](./kibana-plugin-plugins-expressions-public.expressionsstart.expressionrenderhandler.md) + +## ExpressionsStart.ExpressionRenderHandler property + +Signature: + +```typescript +ExpressionRenderHandler: typeof ExpressionRenderHandler; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsstart.loader.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsstart.loader.md new file mode 100644 index 0000000000000..109d8e8bcab66 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsstart.loader.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsStart](./kibana-plugin-plugins-expressions-public.expressionsstart.md) > [loader](./kibana-plugin-plugins-expressions-public.expressionsstart.loader.md) + +## ExpressionsStart.loader property + +Signature: + +```typescript +loader: IExpressionLoader; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsstart.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsstart.md new file mode 100644 index 0000000000000..ac4004590b5a6 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsstart.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsStart](./kibana-plugin-plugins-expressions-public.expressionsstart.md) + +## ExpressionsStart interface + +Expressions public start contrect, extends + +Signature: + +```typescript +export interface ExpressionsStart extends ExpressionsServiceStart +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [ExpressionLoader](./kibana-plugin-plugins-expressions-public.expressionsstart.expressionloader.md) | typeof ExpressionLoader | | +| [ExpressionRenderHandler](./kibana-plugin-plugins-expressions-public.expressionsstart.expressionrenderhandler.md) | typeof ExpressionRenderHandler | | +| [loader](./kibana-plugin-plugins-expressions-public.expressionsstart.loader.md) | IExpressionLoader | | +| [ReactExpressionRenderer](./kibana-plugin-plugins-expressions-public.expressionsstart.reactexpressionrenderer.md) | typeof ReactExpressionRenderer | | +| [render](./kibana-plugin-plugins-expressions-public.expressionsstart.render.md) | typeof render | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsstart.reactexpressionrenderer.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsstart.reactexpressionrenderer.md new file mode 100644 index 0000000000000..bbd7253a747c4 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsstart.reactexpressionrenderer.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsStart](./kibana-plugin-plugins-expressions-public.expressionsstart.md) > [ReactExpressionRenderer](./kibana-plugin-plugins-expressions-public.expressionsstart.reactexpressionrenderer.md) + +## ExpressionsStart.ReactExpressionRenderer property + +Signature: + +```typescript +ReactExpressionRenderer: typeof ReactExpressionRenderer; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsstart.render.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsstart.render.md new file mode 100644 index 0000000000000..fcf279206119e --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionsstart.render.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionsStart](./kibana-plugin-plugins-expressions-public.expressionsstart.md) > [render](./kibana-plugin-plugins-expressions-public.expressionsstart.render.md) + +## ExpressionsStart.render property + +Signature: + +```typescript +render: typeof render; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype._constructor_.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype._constructor_.md new file mode 100644 index 0000000000000..2302be5643722 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype._constructor_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionType](./kibana-plugin-plugins-expressions-public.expressiontype.md) > [(constructor)](./kibana-plugin-plugins-expressions-public.expressiontype._constructor_.md) + +## ExpressionType.(constructor) + +Constructs a new instance of the `ExpressionType` class + +Signature: + +```typescript +constructor(definition: AnyExpressionTypeDefinition); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| definition | AnyExpressionTypeDefinition | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.castsfrom.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.castsfrom.md new file mode 100644 index 0000000000000..e238db1b45086 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.castsfrom.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionType](./kibana-plugin-plugins-expressions-public.expressiontype.md) > [castsFrom](./kibana-plugin-plugins-expressions-public.expressiontype.castsfrom.md) + +## ExpressionType.castsFrom property + +Signature: + +```typescript +castsFrom: (value: ExpressionValue) => boolean; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.caststo.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.caststo.md new file mode 100644 index 0000000000000..36e03e6f3d53f --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.caststo.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionType](./kibana-plugin-plugins-expressions-public.expressiontype.md) > [castsTo](./kibana-plugin-plugins-expressions-public.expressiontype.caststo.md) + +## ExpressionType.castsTo property + +Signature: + +```typescript +castsTo: (value: ExpressionValue) => boolean; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.create.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.create.md new file mode 100644 index 0000000000000..e2da70b50b0d4 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.create.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionType](./kibana-plugin-plugins-expressions-public.expressiontype.md) > [create](./kibana-plugin-plugins-expressions-public.expressiontype.create.md) + +## ExpressionType.create property + +Signature: + +```typescript +create: unknown; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.deserialize.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.deserialize.md new file mode 100644 index 0000000000000..d47056817358c --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.deserialize.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionType](./kibana-plugin-plugins-expressions-public.expressiontype.md) > [deserialize](./kibana-plugin-plugins-expressions-public.expressiontype.deserialize.md) + +## ExpressionType.deserialize property + +Signature: + +```typescript +deserialize?: (serialized: any) => ExpressionValue; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.from.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.from.md new file mode 100644 index 0000000000000..51a36f614fbbf --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.from.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionType](./kibana-plugin-plugins-expressions-public.expressiontype.md) > [from](./kibana-plugin-plugins-expressions-public.expressiontype.from.md) + +## ExpressionType.from property + +Signature: + +```typescript +from: (value: ExpressionValue, types: Record) => any; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.getfromfn.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.getfromfn.md new file mode 100644 index 0000000000000..10d7bb4331916 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.getfromfn.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionType](./kibana-plugin-plugins-expressions-public.expressiontype.md) > [getFromFn](./kibana-plugin-plugins-expressions-public.expressiontype.getfromfn.md) + +## ExpressionType.getFromFn property + +Signature: + +```typescript +getFromFn: (typeName: string) => undefined | ExpressionValueConverter; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.gettofn.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.gettofn.md new file mode 100644 index 0000000000000..25b71163e5709 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.gettofn.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionType](./kibana-plugin-plugins-expressions-public.expressiontype.md) > [getToFn](./kibana-plugin-plugins-expressions-public.expressiontype.gettofn.md) + +## ExpressionType.getToFn property + +Signature: + +```typescript +getToFn: (typeName: string) => undefined | ExpressionValueConverter; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.help.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.help.md new file mode 100644 index 0000000000000..e27e1dea2a872 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.help.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionType](./kibana-plugin-plugins-expressions-public.expressiontype.md) > [help](./kibana-plugin-plugins-expressions-public.expressiontype.help.md) + +## ExpressionType.help property + +A short help text. + +Signature: + +```typescript +help: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.md new file mode 100644 index 0000000000000..acb72b796cf1d --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.md @@ -0,0 +1,35 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionType](./kibana-plugin-plugins-expressions-public.expressiontype.md) + +## ExpressionType class + +Signature: + +```typescript +export declare class ExpressionType +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(definition)](./kibana-plugin-plugins-expressions-public.expressiontype._constructor_.md) | | Constructs a new instance of the ExpressionType class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [castsFrom](./kibana-plugin-plugins-expressions-public.expressiontype.castsfrom.md) | | (value: ExpressionValue) => boolean | | +| [castsTo](./kibana-plugin-plugins-expressions-public.expressiontype.caststo.md) | | (value: ExpressionValue) => boolean | | +| [create](./kibana-plugin-plugins-expressions-public.expressiontype.create.md) | | unknown | | +| [deserialize](./kibana-plugin-plugins-expressions-public.expressiontype.deserialize.md) | | (serialized: any) => ExpressionValue | | +| [from](./kibana-plugin-plugins-expressions-public.expressiontype.from.md) | | (value: ExpressionValue, types: Record<string, ExpressionType>) => any | | +| [getFromFn](./kibana-plugin-plugins-expressions-public.expressiontype.getfromfn.md) | | (typeName: string) => undefined | ExpressionValueConverter<ExpressionValue, ExpressionValue> | | +| [getToFn](./kibana-plugin-plugins-expressions-public.expressiontype.gettofn.md) | | (typeName: string) => undefined | ExpressionValueConverter<ExpressionValue, ExpressionValue> | | +| [help](./kibana-plugin-plugins-expressions-public.expressiontype.help.md) | | string | A short help text. | +| [name](./kibana-plugin-plugins-expressions-public.expressiontype.name.md) | | string | | +| [serialize](./kibana-plugin-plugins-expressions-public.expressiontype.serialize.md) | | (value: ExpressionValue) => any | Optional serialization (used when passing context around client/server). | +| [to](./kibana-plugin-plugins-expressions-public.expressiontype.to.md) | | (value: ExpressionValue, toTypeName: string, types: Record<string, ExpressionType>) => any | | +| [validate](./kibana-plugin-plugins-expressions-public.expressiontype.validate.md) | | (type: any) => void | Error | Type validation, useful for checking function output. | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.name.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.name.md new file mode 100644 index 0000000000000..8d14f6e4f6bd8 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.name.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionType](./kibana-plugin-plugins-expressions-public.expressiontype.md) > [name](./kibana-plugin-plugins-expressions-public.expressiontype.name.md) + +## ExpressionType.name property + +Signature: + +```typescript +name: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.serialize.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.serialize.md new file mode 100644 index 0000000000000..cb4821b97e022 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.serialize.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionType](./kibana-plugin-plugins-expressions-public.expressiontype.md) > [serialize](./kibana-plugin-plugins-expressions-public.expressiontype.serialize.md) + +## ExpressionType.serialize property + +Optional serialization (used when passing context around client/server). + +Signature: + +```typescript +serialize?: (value: ExpressionValue) => any; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.to.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.to.md new file mode 100644 index 0000000000000..8045c5df638b0 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.to.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionType](./kibana-plugin-plugins-expressions-public.expressiontype.md) > [to](./kibana-plugin-plugins-expressions-public.expressiontype.to.md) + +## ExpressionType.to property + +Signature: + +```typescript +to: (value: ExpressionValue, toTypeName: string, types: Record) => any; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.validate.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.validate.md new file mode 100644 index 0000000000000..7214467b2b444 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontype.validate.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionType](./kibana-plugin-plugins-expressions-public.expressiontype.md) > [validate](./kibana-plugin-plugins-expressions-public.expressiontype.validate.md) + +## ExpressionType.validate property + +Type validation, useful for checking function output. + +Signature: + +```typescript +validate: (type: any) => void | Error; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypedefinition.deserialize.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypedefinition.deserialize.md new file mode 100644 index 0000000000000..75dac1e991f65 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypedefinition.deserialize.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionTypeDefinition](./kibana-plugin-plugins-expressions-public.expressiontypedefinition.md) > [deserialize](./kibana-plugin-plugins-expressions-public.expressiontypedefinition.deserialize.md) + +## ExpressionTypeDefinition.deserialize property + +Signature: + +```typescript +deserialize?: (type: SerializedType) => Value; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypedefinition.from.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypedefinition.from.md new file mode 100644 index 0000000000000..ac8920066eda7 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypedefinition.from.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionTypeDefinition](./kibana-plugin-plugins-expressions-public.expressiontypedefinition.md) > [from](./kibana-plugin-plugins-expressions-public.expressiontypedefinition.from.md) + +## ExpressionTypeDefinition.from property + +Signature: + +```typescript +from?: { + [type: string]: ExpressionValueConverter; + }; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypedefinition.help.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypedefinition.help.md new file mode 100644 index 0000000000000..ad5e5eb38fa72 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypedefinition.help.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionTypeDefinition](./kibana-plugin-plugins-expressions-public.expressiontypedefinition.md) > [help](./kibana-plugin-plugins-expressions-public.expressiontypedefinition.help.md) + +## ExpressionTypeDefinition.help property + +Signature: + +```typescript +help?: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypedefinition.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypedefinition.md new file mode 100644 index 0000000000000..8c183e9a6de80 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypedefinition.md @@ -0,0 +1,26 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionTypeDefinition](./kibana-plugin-plugins-expressions-public.expressiontypedefinition.md) + +## ExpressionTypeDefinition interface + +A generic type which represents a custom Expression Type Definition that's registered to the Interpreter. + +Signature: + +```typescript +export interface ExpressionTypeDefinition +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [deserialize](./kibana-plugin-plugins-expressions-public.expressiontypedefinition.deserialize.md) | (type: SerializedType) => Value | | +| [from](./kibana-plugin-plugins-expressions-public.expressiontypedefinition.from.md) | {
[type: string]: ExpressionValueConverter<any, Value>;
} | | +| [help](./kibana-plugin-plugins-expressions-public.expressiontypedefinition.help.md) | string | | +| [name](./kibana-plugin-plugins-expressions-public.expressiontypedefinition.name.md) | Name | | +| [serialize](./kibana-plugin-plugins-expressions-public.expressiontypedefinition.serialize.md) | (type: Value) => SerializedType | | +| [to](./kibana-plugin-plugins-expressions-public.expressiontypedefinition.to.md) | {
[type: string]: ExpressionValueConverter<Value, any>;
} | | +| [validate](./kibana-plugin-plugins-expressions-public.expressiontypedefinition.validate.md) | (type: any) => void | Error | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypedefinition.name.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypedefinition.name.md new file mode 100644 index 0000000000000..eb79d01040373 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypedefinition.name.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionTypeDefinition](./kibana-plugin-plugins-expressions-public.expressiontypedefinition.md) > [name](./kibana-plugin-plugins-expressions-public.expressiontypedefinition.name.md) + +## ExpressionTypeDefinition.name property + +Signature: + +```typescript +name: Name; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypedefinition.serialize.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypedefinition.serialize.md new file mode 100644 index 0000000000000..5881ddbe5a6c4 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypedefinition.serialize.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionTypeDefinition](./kibana-plugin-plugins-expressions-public.expressiontypedefinition.md) > [serialize](./kibana-plugin-plugins-expressions-public.expressiontypedefinition.serialize.md) + +## ExpressionTypeDefinition.serialize property + +Signature: + +```typescript +serialize?: (type: Value) => SerializedType; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypedefinition.to.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypedefinition.to.md new file mode 100644 index 0000000000000..282cdcdfb342d --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypedefinition.to.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionTypeDefinition](./kibana-plugin-plugins-expressions-public.expressiontypedefinition.md) > [to](./kibana-plugin-plugins-expressions-public.expressiontypedefinition.to.md) + +## ExpressionTypeDefinition.to property + +Signature: + +```typescript +to?: { + [type: string]: ExpressionValueConverter; + }; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypedefinition.validate.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypedefinition.validate.md new file mode 100644 index 0000000000000..67d5e832c6284 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypedefinition.validate.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionTypeDefinition](./kibana-plugin-plugins-expressions-public.expressiontypedefinition.md) > [validate](./kibana-plugin-plugins-expressions-public.expressiontypedefinition.validate.md) + +## ExpressionTypeDefinition.validate property + +Signature: + +```typescript +validate?: (type: any) => void | Error; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypestyle.css.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypestyle.css.md new file mode 100644 index 0000000000000..ca8e881ef7e46 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypestyle.css.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionTypeStyle](./kibana-plugin-plugins-expressions-public.expressiontypestyle.md) > [css](./kibana-plugin-plugins-expressions-public.expressiontypestyle.css.md) + +## ExpressionTypeStyle.css property + +Signature: + +```typescript +css: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypestyle.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypestyle.md new file mode 100644 index 0000000000000..4e1cc86699f2d --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypestyle.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionTypeStyle](./kibana-plugin-plugins-expressions-public.expressiontypestyle.md) + +## ExpressionTypeStyle interface + +An object that represents style information, typically CSS. + +Signature: + +```typescript +export interface ExpressionTypeStyle +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [css](./kibana-plugin-plugins-expressions-public.expressiontypestyle.css.md) | string | | +| [spec](./kibana-plugin-plugins-expressions-public.expressiontypestyle.spec.md) | CSSStyle | | +| [type](./kibana-plugin-plugins-expressions-public.expressiontypestyle.type.md) | 'style' | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypestyle.spec.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypestyle.spec.md new file mode 100644 index 0000000000000..e732893366a36 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypestyle.spec.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionTypeStyle](./kibana-plugin-plugins-expressions-public.expressiontypestyle.md) > [spec](./kibana-plugin-plugins-expressions-public.expressiontypestyle.spec.md) + +## ExpressionTypeStyle.spec property + +Signature: + +```typescript +spec: CSSStyle; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypestyle.type.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypestyle.type.md new file mode 100644 index 0000000000000..01dd9b0da1072 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressiontypestyle.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionTypeStyle](./kibana-plugin-plugins-expressions-public.expressiontypestyle.md) > [type](./kibana-plugin-plugins-expressions-public.expressiontypestyle.type.md) + +## ExpressionTypeStyle.type property + +Signature: + +```typescript +type: 'style'; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvalue.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvalue.md new file mode 100644 index 0000000000000..53ab339df902a --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvalue.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionValue](./kibana-plugin-plugins-expressions-public.expressionvalue.md) + +## ExpressionValue type + +Signature: + +```typescript +export declare type ExpressionValue = ExpressionValueUnboxed | ExpressionValueBoxed; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvalueboxed.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvalueboxed.md new file mode 100644 index 0000000000000..6d8f060d4f91f --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvalueboxed.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionValueBoxed](./kibana-plugin-plugins-expressions-public.expressionvalueboxed.md) + +## ExpressionValueBoxed type + +Signature: + +```typescript +export declare type ExpressionValueBoxed = { + type: Type; +} & Value; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvalueconverter.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvalueconverter.md new file mode 100644 index 0000000000000..95e69645b53ee --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvalueconverter.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionValueConverter](./kibana-plugin-plugins-expressions-public.expressionvalueconverter.md) + +## ExpressionValueConverter type + +Signature: + +```typescript +export declare type ExpressionValueConverter = (input: I, availableTypes: Record) => O; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvalueerror.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvalueerror.md new file mode 100644 index 0000000000000..4a714fe62424f --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvalueerror.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionValueError](./kibana-plugin-plugins-expressions-public.expressionvalueerror.md) + +## ExpressionValueError type + +Signature: + +```typescript +export declare type ExpressionValueError = ExpressionValueBoxed<'error', { + error: { + message: string; + type?: string; + name?: string; + stack?: string; + original?: Error; + }; + info?: unknown; +}>; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvaluefilter.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvaluefilter.md new file mode 100644 index 0000000000000..07c1bfe9a96d6 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvaluefilter.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionValueFilter](./kibana-plugin-plugins-expressions-public.expressionvaluefilter.md) + +## ExpressionValueFilter type + +Represents an object that is a Filter. + +Signature: + +```typescript +export declare type ExpressionValueFilter = ExpressionValueBoxed<'filter', { + filterType?: string; + value?: string; + column?: string; + and: ExpressionValueFilter[]; + to?: string; + from?: string; + query?: string | null; +}>; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvaluenum.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvaluenum.md new file mode 100644 index 0000000000000..fc92777ffd5b6 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvaluenum.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionValueNum](./kibana-plugin-plugins-expressions-public.expressionvaluenum.md) + +## ExpressionValueNum type + +Signature: + +```typescript +export declare type ExpressionValueNum = ExpressionValueBoxed<'num', { + value: number; +}>; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvaluerender.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvaluerender.md new file mode 100644 index 0000000000000..be9e7f859daec --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvaluerender.md @@ -0,0 +1,16 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionValueRender](./kibana-plugin-plugins-expressions-public.expressionvaluerender.md) + +## ExpressionValueRender type + +Represents an object that is intended to be rendered. + +Signature: + +```typescript +export declare type ExpressionValueRender = ExpressionValueBoxed; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvaluesearchcontext.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvaluesearchcontext.md new file mode 100644 index 0000000000000..bf64dfe4c86f7 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvaluesearchcontext.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionValueSearchContext](./kibana-plugin-plugins-expressions-public.expressionvaluesearchcontext.md) + +## ExpressionValueSearchContext type + +Signature: + +```typescript +export declare type ExpressionValueSearchContext = ExpressionValueBoxed<'kibana_context', ExecutionContextSearch>; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvalueunboxed.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvalueunboxed.md new file mode 100644 index 0000000000000..fbc37fe667d5e --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionvalueunboxed.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ExpressionValueUnboxed](./kibana-plugin-plugins-expressions-public.expressionvalueunboxed.md) + +## ExpressionValueUnboxed type + +Signature: + +```typescript +export declare type ExpressionValueUnboxed = any; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.font.label.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.font.label.md new file mode 100644 index 0000000000000..87294ce59feb6 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.font.label.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Font](./kibana-plugin-plugins-expressions-public.font.md) > [label](./kibana-plugin-plugins-expressions-public.font.label.md) + +## Font.label property + +Signature: + +```typescript +label: FontLabel; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.font.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.font.md new file mode 100644 index 0000000000000..ef63d28fe6fba --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.font.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Font](./kibana-plugin-plugins-expressions-public.font.md) + +## Font interface + +An interface representing a font in Canvas, with a textual label and the CSS `font-value`. + +Signature: + +```typescript +export interface Font +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [label](./kibana-plugin-plugins-expressions-public.font.label.md) | FontLabel | | +| [value](./kibana-plugin-plugins-expressions-public.font.value.md) | FontValue | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.font.value.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.font.value.md new file mode 100644 index 0000000000000..cada244174785 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.font.value.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Font](./kibana-plugin-plugins-expressions-public.font.md) > [value](./kibana-plugin-plugins-expressions-public.font.value.md) + +## Font.value property + +Signature: + +```typescript +value: FontValue; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.fontlabel.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.fontlabel.md new file mode 100644 index 0000000000000..5af3427730ad1 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.fontlabel.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [FontLabel](./kibana-plugin-plugins-expressions-public.fontlabel.md) + +## FontLabel type + +This type contains a unions of all supported font labels, or the the name of the font the user would see in a UI. + +Signature: + +```typescript +export declare type FontLabel = typeof fonts[number]['label']; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.fontstyle.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.fontstyle.md new file mode 100644 index 0000000000000..9f70d91c7ac9b --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.fontstyle.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [FontStyle](./kibana-plugin-plugins-expressions-public.fontstyle.md) + +## FontStyle enum + +Enum of supported CSS `font-style` properties. + +Signature: + +```typescript +export declare enum FontStyle +``` + +## Enumeration Members + +| Member | Value | Description | +| --- | --- | --- | +| ITALIC | "italic" | | +| NORMAL | "normal" | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.fontvalue.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.fontvalue.md new file mode 100644 index 0000000000000..f03c9b61cb733 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.fontvalue.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [FontValue](./kibana-plugin-plugins-expressions-public.fontvalue.md) + +## FontValue type + +This type contains a union of all supported font values, equivalent to the CSS `font-value` property. + +Signature: + +```typescript +export declare type FontValue = typeof fonts[number]['value']; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.fontweight.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.fontweight.md new file mode 100644 index 0000000000000..43388a3de11cc --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.fontweight.md @@ -0,0 +1,32 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [FontWeight](./kibana-plugin-plugins-expressions-public.fontweight.md) + +## FontWeight enum + +Enum of supported CSS `font-weight` properties. + +Signature: + +```typescript +export declare enum FontWeight +``` + +## Enumeration Members + +| Member | Value | Description | +| --- | --- | --- | +| BOLD | "bold" | | +| BOLDER | "bolder" | | +| EIGHT | "800" | | +| FIVE | "500" | | +| FOUR | "400" | | +| LIGHTER | "lighter" | | +| NINE | "900" | | +| NORMAL | "normal" | | +| ONE | "100" | | +| SEVEN | "700" | | +| SIX | "600" | | +| THREE | "300" | | +| TWO | "200" | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.format.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.format.md new file mode 100644 index 0000000000000..27a9690e6fb0d --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.format.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [format](./kibana-plugin-plugins-expressions-public.format.md) + +## format() function + +Signature: + +```typescript +export declare function format(ast: T, type: T extends ExpressionAstExpression ? 'expression' : 'argument'): string; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| ast | T | | +| type | T extends ExpressionAstExpression ? 'expression' : 'argument' | | + +Returns: + +`string` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.formatexpression.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.formatexpression.md new file mode 100644 index 0000000000000..425aa9c6171fc --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.formatexpression.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [formatExpression](./kibana-plugin-plugins-expressions-public.formatexpression.md) + +## formatExpression() function + +Given expression pipeline AST, returns formatted string. + +Signature: + +```typescript +export declare function formatExpression(ast: ExpressionAstExpression): string; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| ast | ExpressionAstExpression | | + +Returns: + +`string` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.functionsregistry._constructor_.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.functionsregistry._constructor_.md new file mode 100644 index 0000000000000..2ab299e3d32f4 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.functionsregistry._constructor_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [FunctionsRegistry](./kibana-plugin-plugins-expressions-public.functionsregistry.md) > [(constructor)](./kibana-plugin-plugins-expressions-public.functionsregistry._constructor_.md) + +## FunctionsRegistry.(constructor) + +Constructs a new instance of the `FunctionsRegistry` class + +Signature: + +```typescript +constructor(executor: Executor); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| executor | Executor<any> | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.functionsregistry.get.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.functionsregistry.get.md new file mode 100644 index 0000000000000..3ed2807028299 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.functionsregistry.get.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [FunctionsRegistry](./kibana-plugin-plugins-expressions-public.functionsregistry.md) > [get](./kibana-plugin-plugins-expressions-public.functionsregistry.get.md) + +## FunctionsRegistry.get() method + +Signature: + +```typescript +get(id: string): ExpressionFunction | null; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| id | string | | + +Returns: + +`ExpressionFunction | null` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.functionsregistry.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.functionsregistry.md new file mode 100644 index 0000000000000..b32623934ee92 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.functionsregistry.md @@ -0,0 +1,27 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [FunctionsRegistry](./kibana-plugin-plugins-expressions-public.functionsregistry.md) + +## FunctionsRegistry class + +Signature: + +```typescript +export declare class FunctionsRegistry implements IRegistry +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(executor)](./kibana-plugin-plugins-expressions-public.functionsregistry._constructor_.md) | | Constructs a new instance of the FunctionsRegistry class | + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [get(id)](./kibana-plugin-plugins-expressions-public.functionsregistry.get.md) | | | +| [register(functionDefinition)](./kibana-plugin-plugins-expressions-public.functionsregistry.register.md) | | | +| [toArray()](./kibana-plugin-plugins-expressions-public.functionsregistry.toarray.md) | | | +| [toJS()](./kibana-plugin-plugins-expressions-public.functionsregistry.tojs.md) | | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.functionsregistry.register.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.functionsregistry.register.md new file mode 100644 index 0000000000000..32f7f389e8958 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.functionsregistry.register.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [FunctionsRegistry](./kibana-plugin-plugins-expressions-public.functionsregistry.md) > [register](./kibana-plugin-plugins-expressions-public.functionsregistry.register.md) + +## FunctionsRegistry.register() method + +Signature: + +```typescript +register(functionDefinition: AnyExpressionFunctionDefinition | (() => AnyExpressionFunctionDefinition)): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| functionDefinition | AnyExpressionFunctionDefinition | (() => AnyExpressionFunctionDefinition) | | + +Returns: + +`void` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.functionsregistry.toarray.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.functionsregistry.toarray.md new file mode 100644 index 0000000000000..5bc482097a175 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.functionsregistry.toarray.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [FunctionsRegistry](./kibana-plugin-plugins-expressions-public.functionsregistry.md) > [toArray](./kibana-plugin-plugins-expressions-public.functionsregistry.toarray.md) + +## FunctionsRegistry.toArray() method + +Signature: + +```typescript +toArray(): ExpressionFunction[]; +``` +Returns: + +`ExpressionFunction[]` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.functionsregistry.tojs.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.functionsregistry.tojs.md new file mode 100644 index 0000000000000..d6790fb8f726e --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.functionsregistry.tojs.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [FunctionsRegistry](./kibana-plugin-plugins-expressions-public.functionsregistry.md) > [toJS](./kibana-plugin-plugins-expressions-public.functionsregistry.tojs.md) + +## FunctionsRegistry.toJS() method + +Signature: + +```typescript +toJS(): Record; +``` +Returns: + +`Record` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.context.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.context.md new file mode 100644 index 0000000000000..40dcf07667b1b --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.context.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [IExpressionLoaderParams](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.md) > [context](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.context.md) + +## IExpressionLoaderParams.context property + +Signature: + +```typescript +context?: ExpressionValue; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.customfunctions.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.customfunctions.md new file mode 100644 index 0000000000000..00ff3d498eb5c --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.customfunctions.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [IExpressionLoaderParams](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.md) > [customFunctions](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.customfunctions.md) + +## IExpressionLoaderParams.customFunctions property + +Signature: + +```typescript +customFunctions?: []; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.customrenderers.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.customrenderers.md new file mode 100644 index 0000000000000..72b82e2d41b05 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.customrenderers.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [IExpressionLoaderParams](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.md) > [customRenderers](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.customrenderers.md) + +## IExpressionLoaderParams.customRenderers property + +Signature: + +```typescript +customRenderers?: []; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.disablecaching.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.disablecaching.md new file mode 100644 index 0000000000000..62483016d3aee --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.disablecaching.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [IExpressionLoaderParams](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.md) > [disableCaching](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.disablecaching.md) + +## IExpressionLoaderParams.disableCaching property + +Signature: + +```typescript +disableCaching?: boolean; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.inspectoradapters.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.inspectoradapters.md new file mode 100644 index 0000000000000..52f2a6e56d133 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.inspectoradapters.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [IExpressionLoaderParams](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.md) > [inspectorAdapters](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.inspectoradapters.md) + +## IExpressionLoaderParams.inspectorAdapters property + +Signature: + +```typescript +inspectorAdapters?: Adapters; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.md new file mode 100644 index 0000000000000..b8a174f93fb99 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.md @@ -0,0 +1,26 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [IExpressionLoaderParams](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.md) + +## IExpressionLoaderParams interface + +Signature: + +```typescript +export interface IExpressionLoaderParams +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [context](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.context.md) | ExpressionValue | | +| [customFunctions](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.customfunctions.md) | [] | | +| [customRenderers](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.customrenderers.md) | [] | | +| [disableCaching](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.disablecaching.md) | boolean | | +| [inspectorAdapters](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.inspectoradapters.md) | Adapters | | +| [onRenderError](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.onrendererror.md) | RenderErrorHandlerFnType | | +| [searchContext](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.searchcontext.md) | ExecutionContextSearch | | +| [uiState](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.uistate.md) | unknown | | +| [variables](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.variables.md) | Record<string, any> | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.onrendererror.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.onrendererror.md new file mode 100644 index 0000000000000..f45a9c76242c4 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.onrendererror.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [IExpressionLoaderParams](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.md) > [onRenderError](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.onrendererror.md) + +## IExpressionLoaderParams.onRenderError property + +Signature: + +```typescript +onRenderError?: RenderErrorHandlerFnType; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.searchcontext.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.searchcontext.md new file mode 100644 index 0000000000000..523d0c562f7ca --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.searchcontext.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [IExpressionLoaderParams](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.md) > [searchContext](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.searchcontext.md) + +## IExpressionLoaderParams.searchContext property + +Signature: + +```typescript +searchContext?: ExecutionContextSearch; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.uistate.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.uistate.md new file mode 100644 index 0000000000000..dca5032dabc78 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.uistate.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [IExpressionLoaderParams](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.md) > [uiState](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.uistate.md) + +## IExpressionLoaderParams.uiState property + +Signature: + +```typescript +uiState?: unknown; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.variables.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.variables.md new file mode 100644 index 0000000000000..0a04671919bd0 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iexpressionloaderparams.variables.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [IExpressionLoaderParams](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.md) > [variables](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.variables.md) + +## IExpressionLoaderParams.variables property + +Signature: + +```typescript +variables?: Record; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.done.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.done.md new file mode 100644 index 0000000000000..533cf498d72cf --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.done.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [IInterpreterRenderHandlers](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.md) > [done](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.done.md) + +## IInterpreterRenderHandlers.done property + +Done increments the number of rendering successes + +Signature: + +```typescript +done: () => void; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.event.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.event.md new file mode 100644 index 0000000000000..476167965927d --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.event.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [IInterpreterRenderHandlers](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.md) > [event](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.event.md) + +## IInterpreterRenderHandlers.event property + +Signature: + +```typescript +event: (event: any) => void; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.md new file mode 100644 index 0000000000000..9dbd18ae687b4 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [IInterpreterRenderHandlers](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.md) + +## IInterpreterRenderHandlers interface + +Signature: + +```typescript +export interface IInterpreterRenderHandlers +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [done](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.done.md) | () => void | Done increments the number of rendering successes | +| [event](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.event.md) | (event: any) => void | | +| [onDestroy](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.ondestroy.md) | (fn: () => void) => void | | +| [reload](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.reload.md) | () => void | | +| [update](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.update.md) | (params: any) => void | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.ondestroy.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.ondestroy.md new file mode 100644 index 0000000000000..b68c2023fdc8a --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.ondestroy.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [IInterpreterRenderHandlers](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.md) > [onDestroy](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.ondestroy.md) + +## IInterpreterRenderHandlers.onDestroy property + +Signature: + +```typescript +onDestroy: (fn: () => void) => void; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.reload.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.reload.md new file mode 100644 index 0000000000000..0acd440e84f12 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.reload.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [IInterpreterRenderHandlers](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.md) > [reload](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.reload.md) + +## IInterpreterRenderHandlers.reload property + +Signature: + +```typescript +reload: () => void; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.update.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.update.md new file mode 100644 index 0000000000000..28fcb58fb3c10 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.update.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [IInterpreterRenderHandlers](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.md) > [update](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.update.md) + +## IInterpreterRenderHandlers.update property + +Signature: + +```typescript +update: (params: any) => void; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.interpretererrortype.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.interpretererrortype.md new file mode 100644 index 0000000000000..8cb346eda4d74 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.interpretererrortype.md @@ -0,0 +1,16 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [InterpreterErrorType](./kibana-plugin-plugins-expressions-public.interpretererrortype.md) + +## InterpreterErrorType type + +> Warning: This API is now obsolete. +> +> Exported for backwards compatibility. +> + +Signature: + +```typescript +export declare type InterpreterErrorType = ExpressionValueError; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iregistry.get.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iregistry.get.md new file mode 100644 index 0000000000000..9aa696869eaa3 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iregistry.get.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [IRegistry](./kibana-plugin-plugins-expressions-public.iregistry.md) > [get](./kibana-plugin-plugins-expressions-public.iregistry.get.md) + +## IRegistry.get() method + +Signature: + +```typescript +get(id: string): T | null; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| id | string | | + +Returns: + +`T | null` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iregistry.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iregistry.md new file mode 100644 index 0000000000000..64991d90f2ae0 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iregistry.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [IRegistry](./kibana-plugin-plugins-expressions-public.iregistry.md) + +## IRegistry interface + +Signature: + +```typescript +export interface IRegistry +``` + +## Methods + +| Method | Description | +| --- | --- | +| [get(id)](./kibana-plugin-plugins-expressions-public.iregistry.get.md) | | +| [toArray()](./kibana-plugin-plugins-expressions-public.iregistry.toarray.md) | | +| [toJS()](./kibana-plugin-plugins-expressions-public.iregistry.tojs.md) | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iregistry.toarray.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iregistry.toarray.md new file mode 100644 index 0000000000000..36b16ca48323f --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iregistry.toarray.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [IRegistry](./kibana-plugin-plugins-expressions-public.iregistry.md) > [toArray](./kibana-plugin-plugins-expressions-public.iregistry.toarray.md) + +## IRegistry.toArray() method + +Signature: + +```typescript +toArray(): T[]; +``` +Returns: + +`T[]` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iregistry.tojs.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iregistry.tojs.md new file mode 100644 index 0000000000000..2f7a3597c1f02 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iregistry.tojs.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [IRegistry](./kibana-plugin-plugins-expressions-public.iregistry.md) > [toJS](./kibana-plugin-plugins-expressions-public.iregistry.tojs.md) + +## IRegistry.toJS() method + +Signature: + +```typescript +toJS(): Record; +``` +Returns: + +`Record` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.isexpressionastbuilder.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.isexpressionastbuilder.md new file mode 100644 index 0000000000000..f35e7122caeb5 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.isexpressionastbuilder.md @@ -0,0 +1,28 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [isExpressionAstBuilder](./kibana-plugin-plugins-expressions-public.isexpressionastbuilder.md) + +## isExpressionAstBuilder() function + +Type guard that checks whether a given value is an `ExpressionAstExpressionBuilder`. This is useful when working with subexpressions, where you might be retrieving a function argument, and need to know whether it is an expression builder instance which you can perform operations on. + +Signature: + +```typescript +export declare function isExpressionAstBuilder(val: any): val is ExpressionAstExpressionBuilder; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| val | any | | + +Returns: + +`val is ExpressionAstExpressionBuilder` + +## Example + +const arg = myFunction.getArgument('foo'); if (isExpressionAstBuilder(foo)) { foo.toAst(); } + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibana_context_name.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibana_context_name.md new file mode 100644 index 0000000000000..e568db84f383d --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibana_context_name.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [KIBANA\_CONTEXT\_NAME](./kibana-plugin-plugins-expressions-public.kibana_context_name.md) + +## KIBANA\_CONTEXT\_NAME type + +Signature: + +```typescript +export declare type KIBANA_CONTEXT_NAME = 'kibana_context'; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanacontext.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanacontext.md new file mode 100644 index 0000000000000..108533e8de357 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanacontext.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [KibanaContext](./kibana-plugin-plugins-expressions-public.kibanacontext.md) + +## KibanaContext type + +Signature: + +```typescript +export declare type KibanaContext = ExpressionValueSearchContext; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatable.columns.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatable.columns.md new file mode 100644 index 0000000000000..c8aa768a883d6 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatable.columns.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [KibanaDatatable](./kibana-plugin-plugins-expressions-public.kibanadatatable.md) > [columns](./kibana-plugin-plugins-expressions-public.kibanadatatable.columns.md) + +## KibanaDatatable.columns property + +Signature: + +```typescript +columns: KibanaDatatableColumn[]; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatable.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatable.md new file mode 100644 index 0000000000000..4ea1d6f42b66d --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatable.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [KibanaDatatable](./kibana-plugin-plugins-expressions-public.kibanadatatable.md) + +## KibanaDatatable interface + +Signature: + +```typescript +export interface KibanaDatatable +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [columns](./kibana-plugin-plugins-expressions-public.kibanadatatable.columns.md) | KibanaDatatableColumn[] | | +| [rows](./kibana-plugin-plugins-expressions-public.kibanadatatable.rows.md) | KibanaDatatableRow[] | | +| [type](./kibana-plugin-plugins-expressions-public.kibanadatatable.type.md) | typeof name | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatable.rows.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatable.rows.md new file mode 100644 index 0000000000000..43f3243dc4fa7 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatable.rows.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [KibanaDatatable](./kibana-plugin-plugins-expressions-public.kibanadatatable.md) > [rows](./kibana-plugin-plugins-expressions-public.kibanadatatable.rows.md) + +## KibanaDatatable.rows property + +Signature: + +```typescript +rows: KibanaDatatableRow[]; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatable.type.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatable.type.md new file mode 100644 index 0000000000000..996f59cbb77a1 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatable.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [KibanaDatatable](./kibana-plugin-plugins-expressions-public.kibanadatatable.md) > [type](./kibana-plugin-plugins-expressions-public.kibanadatatable.type.md) + +## KibanaDatatable.type property + +Signature: + +```typescript +type: typeof name; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.formathint.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.formathint.md new file mode 100644 index 0000000000000..b517c1610261b --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.formathint.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [KibanaDatatableColumn](./kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.md) > [formatHint](./kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.formathint.md) + +## KibanaDatatableColumn.formatHint property + +Signature: + +```typescript +formatHint?: SerializedFieldFormat; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.id.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.id.md new file mode 100644 index 0000000000000..e7d43190589a7 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.id.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [KibanaDatatableColumn](./kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.md) > [id](./kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.id.md) + +## KibanaDatatableColumn.id property + +Signature: + +```typescript +id: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.md new file mode 100644 index 0000000000000..138c19f0ec7bd --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [KibanaDatatableColumn](./kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.md) + +## KibanaDatatableColumn interface + +Signature: + +```typescript +export interface KibanaDatatableColumn +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [formatHint](./kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.formathint.md) | SerializedFieldFormat | | +| [id](./kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.id.md) | string | | +| [meta](./kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.meta.md) | KibanaDatatableColumnMeta | | +| [name](./kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.name.md) | string | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.meta.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.meta.md new file mode 100644 index 0000000000000..df2d09bf3cc55 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.meta.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [KibanaDatatableColumn](./kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.md) > [meta](./kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.meta.md) + +## KibanaDatatableColumn.meta property + +Signature: + +```typescript +meta?: KibanaDatatableColumnMeta; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.name.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.name.md new file mode 100644 index 0000000000000..841ad67f3f521 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.name.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [KibanaDatatableColumn](./kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.md) > [name](./kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.name.md) + +## KibanaDatatableColumn.name property + +Signature: + +```typescript +name: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumnmeta.aggconfigparams.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumnmeta.aggconfigparams.md new file mode 100644 index 0000000000000..2ec6edda4cbca --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumnmeta.aggconfigparams.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [KibanaDatatableColumnMeta](./kibana-plugin-plugins-expressions-public.kibanadatatablecolumnmeta.md) > [aggConfigParams](./kibana-plugin-plugins-expressions-public.kibanadatatablecolumnmeta.aggconfigparams.md) + +## KibanaDatatableColumnMeta.aggConfigParams property + +Signature: + +```typescript +aggConfigParams?: Record; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumnmeta.indexpatternid.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumnmeta.indexpatternid.md new file mode 100644 index 0000000000000..2287c28398f7f --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumnmeta.indexpatternid.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [KibanaDatatableColumnMeta](./kibana-plugin-plugins-expressions-public.kibanadatatablecolumnmeta.md) > [indexPatternId](./kibana-plugin-plugins-expressions-public.kibanadatatablecolumnmeta.indexpatternid.md) + +## KibanaDatatableColumnMeta.indexPatternId property + +Signature: + +```typescript +indexPatternId?: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumnmeta.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumnmeta.md new file mode 100644 index 0000000000000..b2f8c9d06a727 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumnmeta.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [KibanaDatatableColumnMeta](./kibana-plugin-plugins-expressions-public.kibanadatatablecolumnmeta.md) + +## KibanaDatatableColumnMeta interface + +Signature: + +```typescript +export interface KibanaDatatableColumnMeta +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [aggConfigParams](./kibana-plugin-plugins-expressions-public.kibanadatatablecolumnmeta.aggconfigparams.md) | Record<string, any> | | +| [indexPatternId](./kibana-plugin-plugins-expressions-public.kibanadatatablecolumnmeta.indexpatternid.md) | string | | +| [type](./kibana-plugin-plugins-expressions-public.kibanadatatablecolumnmeta.type.md) | string | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumnmeta.type.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumnmeta.type.md new file mode 100644 index 0000000000000..98d4a0c2d43c3 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablecolumnmeta.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [KibanaDatatableColumnMeta](./kibana-plugin-plugins-expressions-public.kibanadatatablecolumnmeta.md) > [type](./kibana-plugin-plugins-expressions-public.kibanadatatablecolumnmeta.type.md) + +## KibanaDatatableColumnMeta.type property + +Signature: + +```typescript +type: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablerow.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablerow.md new file mode 100644 index 0000000000000..cb5f1ad70f628 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.kibanadatatablerow.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [KibanaDatatableRow](./kibana-plugin-plugins-expressions-public.kibanadatatablerow.md) + +## KibanaDatatableRow interface + +Signature: + +```typescript +export interface KibanaDatatableRow +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.knowntypetostring.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.knowntypetostring.md new file mode 100644 index 0000000000000..39c24760ca6ca --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.knowntypetostring.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [KnownTypeToString](./kibana-plugin-plugins-expressions-public.knowntypetostring.md) + +## KnownTypeToString type + +Map the type of the generic to a string-based representation of the type. + +If the provided generic is its own type interface, we use the value of the `type` key as a string literal type for it. + +Signature: + +```typescript +export declare type KnownTypeToString = T extends string ? 'string' : T extends boolean ? 'boolean' : T extends number ? 'number' : T extends null ? 'null' : T extends { + type: string; +} ? T['type'] : never; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.md new file mode 100644 index 0000000000000..ead6f14e0d1d7 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.md @@ -0,0 +1,134 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) + +## kibana-plugin-plugins-expressions-public package + +## Classes + +| Class | Description | +| --- | --- | +| [Execution](./kibana-plugin-plugins-expressions-public.execution.md) | | +| [ExecutionContract](./kibana-plugin-plugins-expressions-public.executioncontract.md) | ExecutionContract is a wrapper around Execution class. It provides the same functionality but does not expose Expressions plugin internals. | +| [Executor](./kibana-plugin-plugins-expressions-public.executor.md) | | +| [ExpressionFunction](./kibana-plugin-plugins-expressions-public.expressionfunction.md) | | +| [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-public.expressionfunctionparameter.md) | | +| [ExpressionRenderer](./kibana-plugin-plugins-expressions-public.expressionrenderer.md) | | +| [ExpressionRendererRegistry](./kibana-plugin-plugins-expressions-public.expressionrendererregistry.md) | | +| [ExpressionRenderHandler](./kibana-plugin-plugins-expressions-public.expressionrenderhandler.md) | | +| [ExpressionsPublicPlugin](./kibana-plugin-plugins-expressions-public.expressionspublicplugin.md) | | +| [ExpressionsService](./kibana-plugin-plugins-expressions-public.expressionsservice.md) | ExpressionsService class is used for multiple purposes:1. It implements the same Expressions service that can be used on both: (1) server-side and (2) browser-side. 2. It implements the same Expressions service that users can fork/clone, thus have their own instance of the Expressions plugin. 3. ExpressionsService defines the public contracts of \*setup\* and \*start\* Kibana Platform life-cycles for ease-of-use on server-side and browser-side. 4. ExpressionsService creates a bound version of all exported contract functions. 5. Functions are bound the way there are:\`\`\`ts registerFunction = (...args: Parameters<Executor\['registerFunction'\]> ): ReturnType<Executor\['registerFunction'\]> => this.executor.registerFunction(...args); \`\`\`so that JSDoc appears in developers IDE when they use those plugins.expressions.registerFunction(. | +| [ExpressionType](./kibana-plugin-plugins-expressions-public.expressiontype.md) | | +| [FunctionsRegistry](./kibana-plugin-plugins-expressions-public.functionsregistry.md) | | +| [TypesRegistry](./kibana-plugin-plugins-expressions-public.typesregistry.md) | | + +## Enumerations + +| Enumeration | Description | +| --- | --- | +| [FontStyle](./kibana-plugin-plugins-expressions-public.fontstyle.md) | Enum of supported CSS font-style properties. | +| [FontWeight](./kibana-plugin-plugins-expressions-public.fontweight.md) | Enum of supported CSS font-weight properties. | +| [Overflow](./kibana-plugin-plugins-expressions-public.overflow.md) | Enum of supported CSS overflow properties. | +| [TextAlignment](./kibana-plugin-plugins-expressions-public.textalignment.md) | Enum of supported CSS text-align properties. | +| [TextDecoration](./kibana-plugin-plugins-expressions-public.textdecoration.md) | Enum of supported CSS text-decoration properties. | + +## Functions + +| Function | Description | +| --- | --- | +| [buildExpression(initialState)](./kibana-plugin-plugins-expressions-public.buildexpression.md) | Makes it easy to progressively build, update, and traverse an expression AST. You can either start with an empty AST, or provide an expression string, AST, or array of expression function builders to use as initial state. | +| [buildExpressionFunction(fnName, initialArgs)](./kibana-plugin-plugins-expressions-public.buildexpressionfunction.md) | Manages an AST for a single expression function. The return value can be provided to buildExpression to add this function to an expression.Note that to preserve type safety and ensure no args are missing, all required arguments for the specified function must be provided up front. If desired, they can be changed or removed later. | +| [format(ast, type)](./kibana-plugin-plugins-expressions-public.format.md) | | +| [formatExpression(ast)](./kibana-plugin-plugins-expressions-public.formatexpression.md) | Given expression pipeline AST, returns formatted string. | +| [isExpressionAstBuilder(val)](./kibana-plugin-plugins-expressions-public.isexpressionastbuilder.md) | Type guard that checks whether a given value is an ExpressionAstExpressionBuilder. This is useful when working with subexpressions, where you might be retrieving a function argument, and need to know whether it is an expression builder instance which you can perform operations on. | +| [parse(expression, startRule)](./kibana-plugin-plugins-expressions-public.parse.md) | | +| [parseExpression(expression)](./kibana-plugin-plugins-expressions-public.parseexpression.md) | Given expression pipeline string, returns parsed AST. | +| [plugin(initializerContext)](./kibana-plugin-plugins-expressions-public.plugin.md) | | + +## Interfaces + +| Interface | Description | +| --- | --- | +| [Datatable](./kibana-plugin-plugins-expressions-public.datatable.md) | A Datatable in Canvas is a unique structure that represents tabulated data. | +| [DatatableColumn](./kibana-plugin-plugins-expressions-public.datatablecolumn.md) | This type represents the shape of a column in a Datatable. | +| [ExecutionContext](./kibana-plugin-plugins-expressions-public.executioncontext.md) | ExecutionContext is an object available to all functions during a single execution; it provides various methods to perform side-effects. | +| [ExecutionParams](./kibana-plugin-plugins-expressions-public.executionparams.md) | | +| [ExecutionState](./kibana-plugin-plugins-expressions-public.executionstate.md) | | +| [ExecutorState](./kibana-plugin-plugins-expressions-public.executorstate.md) | | +| [ExpressionAstExpression](./kibana-plugin-plugins-expressions-public.expressionastexpression.md) | | +| [ExpressionAstExpressionBuilder](./kibana-plugin-plugins-expressions-public.expressionastexpressionbuilder.md) | | +| [ExpressionAstFunction](./kibana-plugin-plugins-expressions-public.expressionastfunction.md) | | +| [ExpressionAstFunctionBuilder](./kibana-plugin-plugins-expressions-public.expressionastfunctionbuilder.md) | | +| [ExpressionExecutor](./kibana-plugin-plugins-expressions-public.expressionexecutor.md) | | +| [ExpressionFunctionDefinition](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinition.md) | ExpressionFunctionDefinition is the interface plugins have to implement to register a function in expressions plugin. | +| [ExpressionFunctionDefinitions](./kibana-plugin-plugins-expressions-public.expressionfunctiondefinitions.md) | A mapping of ExpressionFunctionDefinitions for functions which the Expressions services provides out-of-the-box. Any new functions registered by the Expressions plugin should have their types added here. | +| [ExpressionImage](./kibana-plugin-plugins-expressions-public.expressionimage.md) | | +| [ExpressionRenderDefinition](./kibana-plugin-plugins-expressions-public.expressionrenderdefinition.md) | | +| [ExpressionRendererEvent](./kibana-plugin-plugins-expressions-public.expressionrendererevent.md) | | +| [ExpressionRenderError](./kibana-plugin-plugins-expressions-public.expressionrendererror.md) | | +| [ExpressionsServiceStart](./kibana-plugin-plugins-expressions-public.expressionsservicestart.md) | The public contract that ExpressionsService provides to other plugins in Kibana Platform in \*start\* life-cycle. | +| [ExpressionsStart](./kibana-plugin-plugins-expressions-public.expressionsstart.md) | Expressions public start contrect, extends | +| [ExpressionTypeDefinition](./kibana-plugin-plugins-expressions-public.expressiontypedefinition.md) | A generic type which represents a custom Expression Type Definition that's registered to the Interpreter. | +| [ExpressionTypeStyle](./kibana-plugin-plugins-expressions-public.expressiontypestyle.md) | An object that represents style information, typically CSS. | +| [Font](./kibana-plugin-plugins-expressions-public.font.md) | An interface representing a font in Canvas, with a textual label and the CSS font-value. | +| [IExpressionLoaderParams](./kibana-plugin-plugins-expressions-public.iexpressionloaderparams.md) | | +| [IInterpreterRenderHandlers](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.md) | | +| [IRegistry](./kibana-plugin-plugins-expressions-public.iregistry.md) | | +| [KibanaDatatable](./kibana-plugin-plugins-expressions-public.kibanadatatable.md) | | +| [KibanaDatatableColumn](./kibana-plugin-plugins-expressions-public.kibanadatatablecolumn.md) | | +| [KibanaDatatableColumnMeta](./kibana-plugin-plugins-expressions-public.kibanadatatablecolumnmeta.md) | | +| [KibanaDatatableRow](./kibana-plugin-plugins-expressions-public.kibanadatatablerow.md) | | +| [PointSeriesColumn](./kibana-plugin-plugins-expressions-public.pointseriescolumn.md) | Column in a PointSeries | +| [Range](./kibana-plugin-plugins-expressions-public.range.md) | | +| [ReactExpressionRendererProps](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.md) | | +| [SerializedDatatable](./kibana-plugin-plugins-expressions-public.serializeddatatable.md) | | +| [SerializedFieldFormat](./kibana-plugin-plugins-expressions-public.serializedfieldformat.md) | JSON representation of a field formatter configuration. Is used to carry information about how to format data in a data table as part of the column definition. | + +## Variables + +| Variable | Description | +| --- | --- | +| [ReactExpressionRenderer](./kibana-plugin-plugins-expressions-public.reactexpressionrenderer.md) | | + +## Type Aliases + +| Type Alias | Description | +| --- | --- | +| [AnyExpressionFunctionDefinition](./kibana-plugin-plugins-expressions-public.anyexpressionfunctiondefinition.md) | Type to capture every possible expression function definition. | +| [AnyExpressionTypeDefinition](./kibana-plugin-plugins-expressions-public.anyexpressiontypedefinition.md) | | +| [ArgumentType](./kibana-plugin-plugins-expressions-public.argumenttype.md) | This type represents all of the possible combinations of properties of an Argument in an Expression Function. The presence or absence of certain fields influence the shape and presence of others within each arg in the specification. | +| [DatatableColumnType](./kibana-plugin-plugins-expressions-public.datatablecolumntype.md) | This type represents the type of any DatatableColumn in a Datatable. | +| [DatatableRow](./kibana-plugin-plugins-expressions-public.datatablerow.md) | This type represents a row in a Datatable. | +| [ExecutionContainer](./kibana-plugin-plugins-expressions-public.executioncontainer.md) | | +| [ExecutorContainer](./kibana-plugin-plugins-expressions-public.executorcontainer.md) | | +| [ExpressionAstArgument](./kibana-plugin-plugins-expressions-public.expressionastargument.md) | | +| [ExpressionAstNode](./kibana-plugin-plugins-expressions-public.expressionastnode.md) | | +| [ExpressionFunctionKibana](./kibana-plugin-plugins-expressions-public.expressionfunctionkibana.md) | | +| [ExpressionRendererComponent](./kibana-plugin-plugins-expressions-public.expressionrenderercomponent.md) | | +| [ExpressionsServiceSetup](./kibana-plugin-plugins-expressions-public.expressionsservicesetup.md) | The public contract that ExpressionsService provides to other plugins in Kibana Platform in \*setup\* life-cycle. | +| [ExpressionsSetup](./kibana-plugin-plugins-expressions-public.expressionssetup.md) | Expressions public setup contract, extends [ExpressionsServiceSetup](./kibana-plugin-plugins-expressions-public.expressionsservicesetup.md) | +| [ExpressionValue](./kibana-plugin-plugins-expressions-public.expressionvalue.md) | | +| [ExpressionValueBoxed](./kibana-plugin-plugins-expressions-public.expressionvalueboxed.md) | | +| [ExpressionValueConverter](./kibana-plugin-plugins-expressions-public.expressionvalueconverter.md) | | +| [ExpressionValueError](./kibana-plugin-plugins-expressions-public.expressionvalueerror.md) | | +| [ExpressionValueFilter](./kibana-plugin-plugins-expressions-public.expressionvaluefilter.md) | Represents an object that is a Filter. | +| [ExpressionValueNum](./kibana-plugin-plugins-expressions-public.expressionvaluenum.md) | | +| [ExpressionValueRender](./kibana-plugin-plugins-expressions-public.expressionvaluerender.md) | Represents an object that is intended to be rendered. | +| [ExpressionValueSearchContext](./kibana-plugin-plugins-expressions-public.expressionvaluesearchcontext.md) | | +| [ExpressionValueUnboxed](./kibana-plugin-plugins-expressions-public.expressionvalueunboxed.md) | | +| [FontLabel](./kibana-plugin-plugins-expressions-public.fontlabel.md) | This type contains a unions of all supported font labels, or the the name of the font the user would see in a UI. | +| [FontValue](./kibana-plugin-plugins-expressions-public.fontvalue.md) | This type contains a union of all supported font values, equivalent to the CSS font-value property. | +| [InterpreterErrorType](./kibana-plugin-plugins-expressions-public.interpretererrortype.md) | | +| [KIBANA\_CONTEXT\_NAME](./kibana-plugin-plugins-expressions-public.kibana_context_name.md) | | +| [KibanaContext](./kibana-plugin-plugins-expressions-public.kibanacontext.md) | | +| [KnownTypeToString](./kibana-plugin-plugins-expressions-public.knowntypetostring.md) | Map the type of the generic to a string-based representation of the type.If the provided generic is its own type interface, we use the value of the type key as a string literal type for it. | +| [PointSeries](./kibana-plugin-plugins-expressions-public.pointseries.md) | A PointSeries is a unique structure that represents dots on a chart. | +| [PointSeriesColumnName](./kibana-plugin-plugins-expressions-public.pointseriescolumnname.md) | Allowed column names in a PointSeries | +| [PointSeriesColumns](./kibana-plugin-plugins-expressions-public.pointseriescolumns.md) | Represents a collection of valid Columns in a PointSeries | +| [PointSeriesRow](./kibana-plugin-plugins-expressions-public.pointseriesrow.md) | | +| [ReactExpressionRendererType](./kibana-plugin-plugins-expressions-public.reactexpressionrenderertype.md) | | +| [Style](./kibana-plugin-plugins-expressions-public.style.md) | | +| [TypeString](./kibana-plugin-plugins-expressions-public.typestring.md) | If the type extends a Promise, we still need to return the string representation:someArgument: Promise<boolean | string> results in types: ['boolean', 'string'] | +| [TypeToString](./kibana-plugin-plugins-expressions-public.typetostring.md) | This can convert a type into a known Expression string representation of that type. For example, TypeToString<Datatable> will resolve to 'datatable'. This allows Expression Functions to continue to specify their type in a simple string format. | +| [UnmappedTypeStrings](./kibana-plugin-plugins-expressions-public.unmappedtypestrings.md) | Types used in Expressions that don't map to a primitive cleanly:date is typed as a number or string, and represents a date | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.overflow.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.overflow.md new file mode 100644 index 0000000000000..e33f1554a23d3 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.overflow.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Overflow](./kibana-plugin-plugins-expressions-public.overflow.md) + +## Overflow enum + +Enum of supported CSS `overflow` properties. + +Signature: + +```typescript +export declare enum Overflow +``` + +## Enumeration Members + +| Member | Value | Description | +| --- | --- | --- | +| AUTO | "auto" | | +| HIDDEN | "hidden" | | +| SCROLL | "scroll" | | +| VISIBLE | "visible" | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.parse.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.parse.md new file mode 100644 index 0000000000000..0cbc2c15b6f54 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.parse.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [parse](./kibana-plugin-plugins-expressions-public.parse.md) + +## parse() function + +Signature: + +```typescript +export declare function parse(expression: E, startRule: S): S extends 'expression' ? ExpressionAstExpression : ExpressionAstArgument; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| expression | E | | +| startRule | S | | + +Returns: + +`S extends 'expression' ? ExpressionAstExpression : ExpressionAstArgument` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.parseexpression.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.parseexpression.md new file mode 100644 index 0000000000000..c4474b150dcc2 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.parseexpression.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [parseExpression](./kibana-plugin-plugins-expressions-public.parseexpression.md) + +## parseExpression() function + +Given expression pipeline string, returns parsed AST. + +Signature: + +```typescript +export declare function parseExpression(expression: string): ExpressionAstExpression; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| expression | string | | + +Returns: + +`ExpressionAstExpression` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.plugin.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.plugin.md new file mode 100644 index 0000000000000..ef707992a0a54 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.plugin.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [plugin](./kibana-plugin-plugins-expressions-public.plugin.md) + +## plugin() function + +Signature: + +```typescript +export declare function plugin(initializerContext: PluginInitializerContext): ExpressionsPublicPlugin; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| initializerContext | PluginInitializerContext | | + +Returns: + +`ExpressionsPublicPlugin` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.pointseries.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.pointseries.md new file mode 100644 index 0000000000000..14ba955ac2cc2 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.pointseries.md @@ -0,0 +1,16 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [PointSeries](./kibana-plugin-plugins-expressions-public.pointseries.md) + +## PointSeries type + +A `PointSeries` is a unique structure that represents dots on a chart. + +Signature: + +```typescript +export declare type PointSeries = ExpressionValueBoxed<'pointseries', { + columns: PointSeriesColumns; + rows: PointSeriesRow[]; +}>; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.pointseriescolumn.expression.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.pointseriescolumn.expression.md new file mode 100644 index 0000000000000..5c034265f4f94 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.pointseriescolumn.expression.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [PointSeriesColumn](./kibana-plugin-plugins-expressions-public.pointseriescolumn.md) > [expression](./kibana-plugin-plugins-expressions-public.pointseriescolumn.expression.md) + +## PointSeriesColumn.expression property + +Signature: + +```typescript +expression: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.pointseriescolumn.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.pointseriescolumn.md new file mode 100644 index 0000000000000..09ce5444caabf --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.pointseriescolumn.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [PointSeriesColumn](./kibana-plugin-plugins-expressions-public.pointseriescolumn.md) + +## PointSeriesColumn interface + +Column in a PointSeries + +Signature: + +```typescript +export interface PointSeriesColumn +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [expression](./kibana-plugin-plugins-expressions-public.pointseriescolumn.expression.md) | string | | +| [role](./kibana-plugin-plugins-expressions-public.pointseriescolumn.role.md) | 'measure' | 'dimension' | | +| [type](./kibana-plugin-plugins-expressions-public.pointseriescolumn.type.md) | 'number' | 'string' | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.pointseriescolumn.role.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.pointseriescolumn.role.md new file mode 100644 index 0000000000000..715f66a43cd62 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.pointseriescolumn.role.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [PointSeriesColumn](./kibana-plugin-plugins-expressions-public.pointseriescolumn.md) > [role](./kibana-plugin-plugins-expressions-public.pointseriescolumn.role.md) + +## PointSeriesColumn.role property + +Signature: + +```typescript +role: 'measure' | 'dimension'; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.pointseriescolumn.type.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.pointseriescolumn.type.md new file mode 100644 index 0000000000000..36a8128967cdd --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.pointseriescolumn.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [PointSeriesColumn](./kibana-plugin-plugins-expressions-public.pointseriescolumn.md) > [type](./kibana-plugin-plugins-expressions-public.pointseriescolumn.type.md) + +## PointSeriesColumn.type property + +Signature: + +```typescript +type: 'number' | 'string'; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.pointseriescolumnname.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.pointseriescolumnname.md new file mode 100644 index 0000000000000..bc39c694307c0 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.pointseriescolumnname.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [PointSeriesColumnName](./kibana-plugin-plugins-expressions-public.pointseriescolumnname.md) + +## PointSeriesColumnName type + +Allowed column names in a PointSeries + +Signature: + +```typescript +export declare type PointSeriesColumnName = 'x' | 'y' | 'color' | 'size' | 'text'; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.pointseriescolumns.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.pointseriescolumns.md new file mode 100644 index 0000000000000..c920a254645bd --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.pointseriescolumns.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [PointSeriesColumns](./kibana-plugin-plugins-expressions-public.pointseriescolumns.md) + +## PointSeriesColumns type + +Represents a collection of valid Columns in a PointSeries + +Signature: + +```typescript +export declare type PointSeriesColumns = Record | {}; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.pointseriesrow.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.pointseriesrow.md new file mode 100644 index 0000000000000..6e3b29572b6f4 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.pointseriesrow.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [PointSeriesRow](./kibana-plugin-plugins-expressions-public.pointseriesrow.md) + +## PointSeriesRow type + +Signature: + +```typescript +export declare type PointSeriesRow = Record; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.range.from.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.range.from.md new file mode 100644 index 0000000000000..5113a798864e9 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.range.from.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Range](./kibana-plugin-plugins-expressions-public.range.md) > [from](./kibana-plugin-plugins-expressions-public.range.from.md) + +## Range.from property + +Signature: + +```typescript +from: number; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.range.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.range.md new file mode 100644 index 0000000000000..cf0cf4cb50b71 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.range.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Range](./kibana-plugin-plugins-expressions-public.range.md) + +## Range interface + +Signature: + +```typescript +export interface Range +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [from](./kibana-plugin-plugins-expressions-public.range.from.md) | number | | +| [to](./kibana-plugin-plugins-expressions-public.range.to.md) | number | | +| [type](./kibana-plugin-plugins-expressions-public.range.type.md) | typeof name | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.range.to.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.range.to.md new file mode 100644 index 0000000000000..bd79997e65fc7 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.range.to.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Range](./kibana-plugin-plugins-expressions-public.range.md) > [to](./kibana-plugin-plugins-expressions-public.range.to.md) + +## Range.to property + +Signature: + +```typescript +to: number; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.range.type.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.range.type.md new file mode 100644 index 0000000000000..4d5476516655d --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.range.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Range](./kibana-plugin-plugins-expressions-public.range.md) > [type](./kibana-plugin-plugins-expressions-public.range.type.md) + +## Range.type property + +Signature: + +```typescript +type: typeof name; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrenderer.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrenderer.md new file mode 100644 index 0000000000000..66c2e1e3c0c8d --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrenderer.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ReactExpressionRenderer](./kibana-plugin-plugins-expressions-public.reactexpressionrenderer.md) + +## ReactExpressionRenderer variable + +Signature: + +```typescript +ReactExpressionRenderer: ({ className, dataAttrs, padding, renderError, expression, onEvent, reload$, ...expressionLoaderOptions }: ReactExpressionRendererProps) => JSX.Element +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.classname.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.classname.md new file mode 100644 index 0000000000000..b5b1391ae72fd --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.classname.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ReactExpressionRendererProps](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.md) > [className](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.classname.md) + +## ReactExpressionRendererProps.className property + +Signature: + +```typescript +className?: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.dataattrs.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.dataattrs.md new file mode 100644 index 0000000000000..a0914ce37299f --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.dataattrs.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ReactExpressionRendererProps](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.md) > [dataAttrs](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.dataattrs.md) + +## ReactExpressionRendererProps.dataAttrs property + +Signature: + +```typescript +dataAttrs?: string[]; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.expression.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.expression.md new file mode 100644 index 0000000000000..21f4294db5aeb --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.expression.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ReactExpressionRendererProps](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.md) > [expression](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.expression.md) + +## ReactExpressionRendererProps.expression property + +Signature: + +```typescript +expression: string | ExpressionAstExpression; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.md new file mode 100644 index 0000000000000..bd6c8cba5f784 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ReactExpressionRendererProps](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.md) + +## ReactExpressionRendererProps interface + +Signature: + +```typescript +export interface ReactExpressionRendererProps extends IExpressionLoaderParams +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [className](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.classname.md) | string | | +| [dataAttrs](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.dataattrs.md) | string[] | | +| [expression](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.expression.md) | string | ExpressionAstExpression | | +| [onEvent](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.onevent.md) | (event: ExpressionRendererEvent) => void | | +| [padding](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.padding.md) | 'xs' | 's' | 'm' | 'l' | 'xl' | | +| [reload$](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.reload_.md) | Observable<unknown> | An observable which can be used to re-run the expression without destroying the component | +| [renderError](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.rendererror.md) | (error?: string | null) => React.ReactElement | React.ReactElement[] | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.onevent.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.onevent.md new file mode 100644 index 0000000000000..4fe1e158df1b8 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.onevent.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ReactExpressionRendererProps](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.md) > [onEvent](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.onevent.md) + +## ReactExpressionRendererProps.onEvent property + +Signature: + +```typescript +onEvent?: (event: ExpressionRendererEvent) => void; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.padding.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.padding.md new file mode 100644 index 0000000000000..47a23f5c1088b --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.padding.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ReactExpressionRendererProps](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.md) > [padding](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.padding.md) + +## ReactExpressionRendererProps.padding property + +Signature: + +```typescript +padding?: 'xs' | 's' | 'm' | 'l' | 'xl'; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.reload_.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.reload_.md new file mode 100644 index 0000000000000..a7991d559377d --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.reload_.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ReactExpressionRendererProps](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.md) > [reload$](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.reload_.md) + +## ReactExpressionRendererProps.reload$ property + +An observable which can be used to re-run the expression without destroying the component + +Signature: + +```typescript +reload$?: Observable; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.rendererror.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.rendererror.md new file mode 100644 index 0000000000000..48bfe1ee5c7c7 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.rendererror.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ReactExpressionRendererProps](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.md) > [renderError](./kibana-plugin-plugins-expressions-public.reactexpressionrendererprops.rendererror.md) + +## ReactExpressionRendererProps.renderError property + +Signature: + +```typescript +renderError?: (error?: string | null) => React.ReactElement | React.ReactElement[]; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrenderertype.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrenderertype.md new file mode 100644 index 0000000000000..4ca56d534b84a --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.reactexpressionrenderertype.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [ReactExpressionRendererType](./kibana-plugin-plugins-expressions-public.reactexpressionrenderertype.md) + +## ReactExpressionRendererType type + +Signature: + +```typescript +export declare type ReactExpressionRendererType = React.ComponentType; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.serializeddatatable.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.serializeddatatable.md new file mode 100644 index 0000000000000..632cd1de2a0c2 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.serializeddatatable.md @@ -0,0 +1,18 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [SerializedDatatable](./kibana-plugin-plugins-expressions-public.serializeddatatable.md) + +## SerializedDatatable interface + +Signature: + +```typescript +export interface SerializedDatatable extends Datatable +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [rows](./kibana-plugin-plugins-expressions-public.serializeddatatable.rows.md) | string[][] | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.serializeddatatable.rows.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.serializeddatatable.rows.md new file mode 100644 index 0000000000000..00d4323ae7025 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.serializeddatatable.rows.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [SerializedDatatable](./kibana-plugin-plugins-expressions-public.serializeddatatable.md) > [rows](./kibana-plugin-plugins-expressions-public.serializeddatatable.rows.md) + +## SerializedDatatable.rows property + +Signature: + +```typescript +rows: string[][]; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.serializedfieldformat.id.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.serializedfieldformat.id.md new file mode 100644 index 0000000000000..40a45d50e9b19 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.serializedfieldformat.id.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [SerializedFieldFormat](./kibana-plugin-plugins-expressions-public.serializedfieldformat.md) > [id](./kibana-plugin-plugins-expressions-public.serializedfieldformat.id.md) + +## SerializedFieldFormat.id property + +Signature: + +```typescript +id?: string; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.serializedfieldformat.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.serializedfieldformat.md new file mode 100644 index 0000000000000..74fa132ec1189 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.serializedfieldformat.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [SerializedFieldFormat](./kibana-plugin-plugins-expressions-public.serializedfieldformat.md) + +## SerializedFieldFormat interface + +JSON representation of a field formatter configuration. Is used to carry information about how to format data in a data table as part of the column definition. + +Signature: + +```typescript +export interface SerializedFieldFormat> +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [id](./kibana-plugin-plugins-expressions-public.serializedfieldformat.id.md) | string | | +| [params](./kibana-plugin-plugins-expressions-public.serializedfieldformat.params.md) | TParams | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.serializedfieldformat.params.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.serializedfieldformat.params.md new file mode 100644 index 0000000000000..32d7e54cbc884 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.serializedfieldformat.params.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [SerializedFieldFormat](./kibana-plugin-plugins-expressions-public.serializedfieldformat.md) > [params](./kibana-plugin-plugins-expressions-public.serializedfieldformat.params.md) + +## SerializedFieldFormat.params property + +Signature: + +```typescript +params?: TParams; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.style.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.style.md new file mode 100644 index 0000000000000..f42df4b8b314e --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.style.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [Style](./kibana-plugin-plugins-expressions-public.style.md) + +## Style type + +Signature: + +```typescript +export declare type Style = ExpressionTypeStyle; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.textalignment.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.textalignment.md new file mode 100644 index 0000000000000..351a7ba6e1f27 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.textalignment.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [TextAlignment](./kibana-plugin-plugins-expressions-public.textalignment.md) + +## TextAlignment enum + +Enum of supported CSS `text-align` properties. + +Signature: + +```typescript +export declare enum TextAlignment +``` + +## Enumeration Members + +| Member | Value | Description | +| --- | --- | --- | +| CENTER | "center" | | +| JUSTIFY | "justify" | | +| LEFT | "left" | | +| RIGHT | "right" | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.textdecoration.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.textdecoration.md new file mode 100644 index 0000000000000..3cd8e89f4cd8c --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.textdecoration.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [TextDecoration](./kibana-plugin-plugins-expressions-public.textdecoration.md) + +## TextDecoration enum + +Enum of supported CSS `text-decoration` properties. + +Signature: + +```typescript +export declare enum TextDecoration +``` + +## Enumeration Members + +| Member | Value | Description | +| --- | --- | --- | +| NONE | "none" | | +| UNDERLINE | "underline" | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.typesregistry._constructor_.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.typesregistry._constructor_.md new file mode 100644 index 0000000000000..856bf2bf05ad1 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.typesregistry._constructor_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [TypesRegistry](./kibana-plugin-plugins-expressions-public.typesregistry.md) > [(constructor)](./kibana-plugin-plugins-expressions-public.typesregistry._constructor_.md) + +## TypesRegistry.(constructor) + +Constructs a new instance of the `TypesRegistry` class + +Signature: + +```typescript +constructor(executor: Executor); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| executor | Executor<any> | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.typesregistry.get.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.typesregistry.get.md new file mode 100644 index 0000000000000..f83e7435485c5 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.typesregistry.get.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [TypesRegistry](./kibana-plugin-plugins-expressions-public.typesregistry.md) > [get](./kibana-plugin-plugins-expressions-public.typesregistry.get.md) + +## TypesRegistry.get() method + +Signature: + +```typescript +get(id: string): ExpressionType | null; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| id | string | | + +Returns: + +`ExpressionType | null` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.typesregistry.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.typesregistry.md new file mode 100644 index 0000000000000..f1f386ec4210f --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.typesregistry.md @@ -0,0 +1,27 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [TypesRegistry](./kibana-plugin-plugins-expressions-public.typesregistry.md) + +## TypesRegistry class + +Signature: + +```typescript +export declare class TypesRegistry implements IRegistry +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(executor)](./kibana-plugin-plugins-expressions-public.typesregistry._constructor_.md) | | Constructs a new instance of the TypesRegistry class | + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [get(id)](./kibana-plugin-plugins-expressions-public.typesregistry.get.md) | | | +| [register(typeDefinition)](./kibana-plugin-plugins-expressions-public.typesregistry.register.md) | | | +| [toArray()](./kibana-plugin-plugins-expressions-public.typesregistry.toarray.md) | | | +| [toJS()](./kibana-plugin-plugins-expressions-public.typesregistry.tojs.md) | | | + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.typesregistry.register.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.typesregistry.register.md new file mode 100644 index 0000000000000..b328f26aa50e2 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.typesregistry.register.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [TypesRegistry](./kibana-plugin-plugins-expressions-public.typesregistry.md) > [register](./kibana-plugin-plugins-expressions-public.typesregistry.register.md) + +## TypesRegistry.register() method + +Signature: + +```typescript +register(typeDefinition: AnyExpressionTypeDefinition | (() => AnyExpressionTypeDefinition)): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| typeDefinition | AnyExpressionTypeDefinition | (() => AnyExpressionTypeDefinition) | | + +Returns: + +`void` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.typesregistry.toarray.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.typesregistry.toarray.md new file mode 100644 index 0000000000000..2e9c8799cbd61 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.typesregistry.toarray.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [TypesRegistry](./kibana-plugin-plugins-expressions-public.typesregistry.md) > [toArray](./kibana-plugin-plugins-expressions-public.typesregistry.toarray.md) + +## TypesRegistry.toArray() method + +Signature: + +```typescript +toArray(): ExpressionType[]; +``` +Returns: + +`ExpressionType[]` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.typesregistry.tojs.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.typesregistry.tojs.md new file mode 100644 index 0000000000000..14a22a890f0d1 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.typesregistry.tojs.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [TypesRegistry](./kibana-plugin-plugins-expressions-public.typesregistry.md) > [toJS](./kibana-plugin-plugins-expressions-public.typesregistry.tojs.md) + +## TypesRegistry.toJS() method + +Signature: + +```typescript +toJS(): Record; +``` +Returns: + +`Record` + diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.typestring.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.typestring.md new file mode 100644 index 0000000000000..1e85625907bb0 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.typestring.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [TypeString](./kibana-plugin-plugins-expressions-public.typestring.md) + +## TypeString type + +If the type extends a Promise, we still need to return the string representation: + +`someArgument: Promise` results in `types: ['boolean', 'string']` + +Signature: + +```typescript +export declare type TypeString = KnownTypeToString>; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.typetostring.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.typetostring.md new file mode 100644 index 0000000000000..78f350a0c06ec --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.typetostring.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [TypeToString](./kibana-plugin-plugins-expressions-public.typetostring.md) + +## TypeToString type + +This can convert a type into a known Expression string representation of that type. For example, `TypeToString` will resolve to `'datatable'`. This allows Expression Functions to continue to specify their type in a simple string format. + +Signature: + +```typescript +export declare type TypeToString = KnownTypeToString | UnmappedTypeStrings; +``` diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.unmappedtypestrings.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.unmappedtypestrings.md new file mode 100644 index 0000000000000..6455d6520bcec --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.unmappedtypestrings.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [UnmappedTypeStrings](./kibana-plugin-plugins-expressions-public.unmappedtypestrings.md) + +## UnmappedTypeStrings type + +Types used in Expressions that don't map to a primitive cleanly: + +`date` is typed as a number or string, and represents a date + +Signature: + +```typescript +export declare type UnmappedTypeStrings = 'date' | 'filter'; +``` diff --git a/docs/development/plugins/expressions/server/index.md b/docs/development/plugins/expressions/server/index.md new file mode 100644 index 0000000000000..8c35c1631ba04 --- /dev/null +++ b/docs/development/plugins/expressions/server/index.md @@ -0,0 +1,12 @@ + + +[Home](./index.md) + +## API Reference + +## Packages + +| Package | Description | +| --- | --- | +| [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.anyexpressionfunctiondefinition.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.anyexpressionfunctiondefinition.md new file mode 100644 index 0000000000000..04e652a66aa5c --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.anyexpressionfunctiondefinition.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [AnyExpressionFunctionDefinition](./kibana-plugin-plugins-expressions-server.anyexpressionfunctiondefinition.md) + +## AnyExpressionFunctionDefinition type + +Type to capture every possible expression function definition. + +Signature: + +```typescript +export declare type AnyExpressionFunctionDefinition = ExpressionFunctionDefinition, any>; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.anyexpressiontypedefinition.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.anyexpressiontypedefinition.md new file mode 100644 index 0000000000000..c28e1aa411a34 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.anyexpressiontypedefinition.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [AnyExpressionTypeDefinition](./kibana-plugin-plugins-expressions-server.anyexpressiontypedefinition.md) + +## AnyExpressionTypeDefinition type + +Signature: + +```typescript +export declare type AnyExpressionTypeDefinition = ExpressionTypeDefinition; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.argumenttype.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.argumenttype.md new file mode 100644 index 0000000000000..360b8999f2053 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.argumenttype.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ArgumentType](./kibana-plugin-plugins-expressions-server.argumenttype.md) + +## ArgumentType type + +This type represents all of the possible combinations of properties of an Argument in an Expression Function. The presence or absence of certain fields influence the shape and presence of others within each `arg` in the specification. + +Signature: + +```typescript +export declare type ArgumentType = SingleArgumentType | MultipleArgumentType | UnresolvedSingleArgumentType | UnresolvedMultipleArgumentType; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.buildexpression.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.buildexpression.md new file mode 100644 index 0000000000000..2e84c2b706bfc --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.buildexpression.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [buildExpression](./kibana-plugin-plugins-expressions-server.buildexpression.md) + +## buildExpression() function + +Makes it easy to progressively build, update, and traverse an expression AST. You can either start with an empty AST, or provide an expression string, AST, or array of expression function builders to use as initial state. + +Signature: + +```typescript +export declare function buildExpression(initialState?: ExpressionAstFunctionBuilder[] | ExpressionAstExpression | string): ExpressionAstExpressionBuilder; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| initialState | ExpressionAstFunctionBuilder[] | ExpressionAstExpression | string | | + +Returns: + +`ExpressionAstExpressionBuilder` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.buildexpressionfunction.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.buildexpressionfunction.md new file mode 100644 index 0000000000000..09afd3d59a070 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.buildexpressionfunction.md @@ -0,0 +1,30 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [buildExpressionFunction](./kibana-plugin-plugins-expressions-server.buildexpressionfunction.md) + +## buildExpressionFunction() function + +Manages an AST for a single expression function. The return value can be provided to `buildExpression` to add this function to an expression. + +Note that to preserve type safety and ensure no args are missing, all required arguments for the specified function must be provided up front. If desired, they can be changed or removed later. + +Signature: + +```typescript +export declare function buildExpressionFunction(fnName: InferFunctionDefinition['name'], +initialArgs: { + [K in keyof FunctionArgs]: FunctionArgs[K] | ExpressionAstExpressionBuilder | ExpressionAstExpressionBuilder[]; +}): ExpressionAstFunctionBuilder; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| fnName | InferFunctionDefinition<FnDef>['name'] | | +| initialArgs | {
[K in keyof FunctionArgs<FnDef>]: FunctionArgs<FnDef>[K] | ExpressionAstExpressionBuilder | ExpressionAstExpressionBuilder[];
} | | + +Returns: + +`ExpressionAstFunctionBuilder` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatable.columns.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatable.columns.md new file mode 100644 index 0000000000000..1bd089af13c6c --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatable.columns.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Datatable](./kibana-plugin-plugins-expressions-server.datatable.md) > [columns](./kibana-plugin-plugins-expressions-server.datatable.columns.md) + +## Datatable.columns property + +Signature: + +```typescript +columns: DatatableColumn[]; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatable.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatable.md new file mode 100644 index 0000000000000..7dc2ab2596e12 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatable.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Datatable](./kibana-plugin-plugins-expressions-server.datatable.md) + +## Datatable interface + +A `Datatable` in Canvas is a unique structure that represents tabulated data. + +Signature: + +```typescript +export interface Datatable +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [columns](./kibana-plugin-plugins-expressions-server.datatable.columns.md) | DatatableColumn[] | | +| [rows](./kibana-plugin-plugins-expressions-server.datatable.rows.md) | DatatableRow[] | | +| [type](./kibana-plugin-plugins-expressions-server.datatable.type.md) | typeof name | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatable.rows.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatable.rows.md new file mode 100644 index 0000000000000..75bd8e2f56bde --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatable.rows.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Datatable](./kibana-plugin-plugins-expressions-server.datatable.md) > [rows](./kibana-plugin-plugins-expressions-server.datatable.rows.md) + +## Datatable.rows property + +Signature: + +```typescript +rows: DatatableRow[]; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatable.type.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatable.type.md new file mode 100644 index 0000000000000..bcd250c5a9f9e --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatable.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Datatable](./kibana-plugin-plugins-expressions-server.datatable.md) > [type](./kibana-plugin-plugins-expressions-server.datatable.type.md) + +## Datatable.type property + +Signature: + +```typescript +type: typeof name; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatablecolumn.id.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatablecolumn.id.md new file mode 100644 index 0000000000000..1f246825fa30a --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatablecolumn.id.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [DatatableColumn](./kibana-plugin-plugins-expressions-server.datatablecolumn.md) > [id](./kibana-plugin-plugins-expressions-server.datatablecolumn.id.md) + +## DatatableColumn.id property + +Signature: + +```typescript +id: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatablecolumn.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatablecolumn.md new file mode 100644 index 0000000000000..662f65d6fad21 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatablecolumn.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [DatatableColumn](./kibana-plugin-plugins-expressions-server.datatablecolumn.md) + +## DatatableColumn interface + +This type represents the shape of a column in a `Datatable`. + +Signature: + +```typescript +export interface DatatableColumn +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [id](./kibana-plugin-plugins-expressions-server.datatablecolumn.id.md) | string | | +| [meta](./kibana-plugin-plugins-expressions-server.datatablecolumn.meta.md) | DatatableColumnMeta | | +| [name](./kibana-plugin-plugins-expressions-server.datatablecolumn.name.md) | string | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatablecolumn.meta.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatablecolumn.meta.md new file mode 100644 index 0000000000000..ef47c67a8d606 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatablecolumn.meta.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [DatatableColumn](./kibana-plugin-plugins-expressions-server.datatablecolumn.md) > [meta](./kibana-plugin-plugins-expressions-server.datatablecolumn.meta.md) + +## DatatableColumn.meta property + +Signature: + +```typescript +meta: DatatableColumnMeta; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatablecolumn.name.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatablecolumn.name.md new file mode 100644 index 0000000000000..112b4ac3b9941 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatablecolumn.name.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [DatatableColumn](./kibana-plugin-plugins-expressions-server.datatablecolumn.md) > [name](./kibana-plugin-plugins-expressions-server.datatablecolumn.name.md) + +## DatatableColumn.name property + +Signature: + +```typescript +name: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatablecolumntype.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatablecolumntype.md new file mode 100644 index 0000000000000..4afce913526de --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatablecolumntype.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [DatatableColumnType](./kibana-plugin-plugins-expressions-server.datatablecolumntype.md) + +## DatatableColumnType type + +This type represents the `type` of any `DatatableColumn` in a `Datatable`. + +Signature: + +```typescript +export declare type DatatableColumnType = 'string' | 'number' | 'boolean' | 'date' | 'null'; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatablerow.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatablerow.md new file mode 100644 index 0000000000000..56ef342b22a28 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.datatablerow.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [DatatableRow](./kibana-plugin-plugins-expressions-server.datatablerow.md) + +## DatatableRow type + +This type represents a row in a `Datatable`. + +Signature: + +```typescript +export declare type DatatableRow = Record; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution._constructor_.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution._constructor_.md new file mode 100644 index 0000000000000..75f4cc4c2a017 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution._constructor_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Execution](./kibana-plugin-plugins-expressions-server.execution.md) > [(constructor)](./kibana-plugin-plugins-expressions-server.execution._constructor_.md) + +## Execution.(constructor) + +Constructs a new instance of the `Execution` class + +Signature: + +```typescript +constructor(params: ExecutionParams); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| params | ExecutionParams<ExtraContext> | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.cancel.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.cancel.md new file mode 100644 index 0000000000000..2ee091da80504 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.cancel.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Execution](./kibana-plugin-plugins-expressions-server.execution.md) > [cancel](./kibana-plugin-plugins-expressions-server.execution.cancel.md) + +## Execution.cancel() method + +Stop execution of expression. + +Signature: + +```typescript +cancel(): void; +``` +Returns: + +`void` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.cast.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.cast.md new file mode 100644 index 0000000000000..22b876332efb4 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.cast.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Execution](./kibana-plugin-plugins-expressions-server.execution.md) > [cast](./kibana-plugin-plugins-expressions-server.execution.cast.md) + +## Execution.cast() method + +Signature: + +```typescript +cast(value: any, toTypeNames?: string[]): any; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| value | any | | +| toTypeNames | string[] | | + +Returns: + +`any` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.context.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.context.md new file mode 100644 index 0000000000000..d1969fb0859b7 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.context.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Execution](./kibana-plugin-plugins-expressions-server.execution.md) > [context](./kibana-plugin-plugins-expressions-server.execution.context.md) + +## Execution.context property + +Execution context - object that allows to do side-effects. Context is passed to every function. + +Signature: + +```typescript +readonly context: ExecutionContext & ExtraContext; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.contract.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.contract.md new file mode 100644 index 0000000000000..149b5a7ced9cb --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.contract.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Execution](./kibana-plugin-plugins-expressions-server.execution.md) > [contract](./kibana-plugin-plugins-expressions-server.execution.contract.md) + +## Execution.contract property + +Contract is a public representation of `Execution` instances. Contract we can return to other plugins for their consumption. + +Signature: + +```typescript +readonly contract: ExecutionContract; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.expression.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.expression.md new file mode 100644 index 0000000000000..0487378ce1bba --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.expression.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Execution](./kibana-plugin-plugins-expressions-server.execution.md) > [expression](./kibana-plugin-plugins-expressions-server.execution.expression.md) + +## Execution.expression property + +Signature: + +```typescript +readonly expression: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.input.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.input.md new file mode 100644 index 0000000000000..ea411523a2b0b --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.input.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Execution](./kibana-plugin-plugins-expressions-server.execution.md) > [input](./kibana-plugin-plugins-expressions-server.execution.input.md) + +## Execution.input property + +Initial input of the execution. + +N.B. It is initialized to `null` rather than `undefined` for legacy reasons, because in legacy interpreter it was set to `null` by default. + +Signature: + +```typescript +input: Input; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.inspectoradapters.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.inspectoradapters.md new file mode 100644 index 0000000000000..99bcca267f8ed --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.inspectoradapters.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Execution](./kibana-plugin-plugins-expressions-server.execution.md) > [inspectorAdapters](./kibana-plugin-plugins-expressions-server.execution.inspectoradapters.md) + +## Execution.inspectorAdapters property + +Signature: + +```typescript +get inspectorAdapters(): InspectorAdapters; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.interpret.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.interpret.md new file mode 100644 index 0000000000000..cf59e796e6120 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.interpret.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Execution](./kibana-plugin-plugins-expressions-server.execution.md) > [interpret](./kibana-plugin-plugins-expressions-server.execution.interpret.md) + +## Execution.interpret() method + +Signature: + +```typescript +interpret(ast: ExpressionAstNode, input: T, options?: ExpressionExecOptions): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| ast | ExpressionAstNode | | +| input | T | | +| options | ExpressionExecOptions | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.invokechain.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.invokechain.md new file mode 100644 index 0000000000000..9ada611f32bf2 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.invokechain.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Execution](./kibana-plugin-plugins-expressions-server.execution.md) > [invokeChain](./kibana-plugin-plugins-expressions-server.execution.invokechain.md) + +## Execution.invokeChain() method + +Signature: + +```typescript +invokeChain(chainArr: ExpressionAstFunction[], input: unknown): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| chainArr | ExpressionAstFunction[] | | +| input | unknown | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.invokefunction.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.invokefunction.md new file mode 100644 index 0000000000000..4519d21ee250a --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.invokefunction.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Execution](./kibana-plugin-plugins-expressions-server.execution.md) > [invokeFunction](./kibana-plugin-plugins-expressions-server.execution.invokefunction.md) + +## Execution.invokeFunction() method + +Signature: + +```typescript +invokeFunction(fn: ExpressionFunction, input: unknown, args: Record): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| fn | ExpressionFunction | | +| input | unknown | | +| args | Record<string, unknown> | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.md new file mode 100644 index 0000000000000..fc663dd115580 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.md @@ -0,0 +1,43 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Execution](./kibana-plugin-plugins-expressions-server.execution.md) + +## Execution class + +Signature: + +```typescript +export declare class Execution = Record, Input = unknown, Output = unknown, InspectorAdapters extends Adapters = ExtraContext['inspectorAdapters'] extends object ? ExtraContext['inspectorAdapters'] : DefaultInspectorAdapters> +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(params)](./kibana-plugin-plugins-expressions-server.execution._constructor_.md) | | Constructs a new instance of the Execution class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [context](./kibana-plugin-plugins-expressions-server.execution.context.md) | | ExecutionContext<Input, InspectorAdapters> & ExtraContext | Execution context - object that allows to do side-effects. Context is passed to every function. | +| [contract](./kibana-plugin-plugins-expressions-server.execution.contract.md) | | ExecutionContract<ExtraContext, Input, Output, InspectorAdapters> | Contract is a public representation of Execution instances. Contract we can return to other plugins for their consumption. | +| [expression](./kibana-plugin-plugins-expressions-server.execution.expression.md) | | string | | +| [input](./kibana-plugin-plugins-expressions-server.execution.input.md) | | Input | Initial input of the execution.N.B. It is initialized to null rather than undefined for legacy reasons, because in legacy interpreter it was set to null by default. | +| [inspectorAdapters](./kibana-plugin-plugins-expressions-server.execution.inspectoradapters.md) | | InspectorAdapters | | +| [params](./kibana-plugin-plugins-expressions-server.execution.params.md) | | ExecutionParams<ExtraContext> | | +| [result](./kibana-plugin-plugins-expressions-server.execution.result.md) | | Promise<Output | ExpressionValueError> | | +| [state](./kibana-plugin-plugins-expressions-server.execution.state.md) | | ExecutionContainer<Output | ExpressionValueError> | Dynamic state of the execution. | + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [cancel()](./kibana-plugin-plugins-expressions-server.execution.cancel.md) | | Stop execution of expression. | +| [cast(value, toTypeNames)](./kibana-plugin-plugins-expressions-server.execution.cast.md) | | | +| [interpret(ast, input, options)](./kibana-plugin-plugins-expressions-server.execution.interpret.md) | | | +| [invokeChain(chainArr, input)](./kibana-plugin-plugins-expressions-server.execution.invokechain.md) | | | +| [invokeFunction(fn, input, args)](./kibana-plugin-plugins-expressions-server.execution.invokefunction.md) | | | +| [resolveArgs(fnDef, input, argAsts)](./kibana-plugin-plugins-expressions-server.execution.resolveargs.md) | | | +| [start(input)](./kibana-plugin-plugins-expressions-server.execution.start.md) | | Call this method to start execution.N.B. input is initialized to null rather than undefined for legacy reasons, because in legacy interpreter it was set to null by default. | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.params.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.params.md new file mode 100644 index 0000000000000..498f9bbfccfa4 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.params.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Execution](./kibana-plugin-plugins-expressions-server.execution.md) > [params](./kibana-plugin-plugins-expressions-server.execution.params.md) + +## Execution.params property + +Signature: + +```typescript +readonly params: ExecutionParams; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.resolveargs.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.resolveargs.md new file mode 100644 index 0000000000000..48cc43b2d7767 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.resolveargs.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Execution](./kibana-plugin-plugins-expressions-server.execution.md) > [resolveArgs](./kibana-plugin-plugins-expressions-server.execution.resolveargs.md) + +## Execution.resolveArgs() method + +Signature: + +```typescript +resolveArgs(fnDef: ExpressionFunction, input: unknown, argAsts: any): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| fnDef | ExpressionFunction | | +| input | unknown | | +| argAsts | any | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.result.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.result.md new file mode 100644 index 0000000000000..be0134cd2542e --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.result.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Execution](./kibana-plugin-plugins-expressions-server.execution.md) > [result](./kibana-plugin-plugins-expressions-server.execution.result.md) + +## Execution.result property + +Signature: + +```typescript +get result(): Promise; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.start.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.start.md new file mode 100644 index 0000000000000..9a4e93fe6a9af --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.start.md @@ -0,0 +1,26 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Execution](./kibana-plugin-plugins-expressions-server.execution.md) > [start](./kibana-plugin-plugins-expressions-server.execution.start.md) + +## Execution.start() method + +Call this method to start execution. + +N.B. `input` is initialized to `null` rather than `undefined` for legacy reasons, because in legacy interpreter it was set to `null` by default. + +Signature: + +```typescript +start(input?: Input): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| input | Input | | + +Returns: + +`void` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.state.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.state.md new file mode 100644 index 0000000000000..41e7e693a1da4 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.execution.state.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Execution](./kibana-plugin-plugins-expressions-server.execution.md) > [state](./kibana-plugin-plugins-expressions-server.execution.state.md) + +## Execution.state property + +Dynamic state of the execution. + +Signature: + +```typescript +readonly state: ExecutionContainer; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontainer.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontainer.md new file mode 100644 index 0000000000000..5dc82fcbb9dd8 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontainer.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExecutionContainer](./kibana-plugin-plugins-expressions-server.executioncontainer.md) + +## ExecutionContainer type + +Signature: + +```typescript +export declare type ExecutionContainer = StateContainer, ExecutionPureTransitions>; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.abortsignal.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.abortsignal.md new file mode 100644 index 0000000000000..5c43623c8e603 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.abortsignal.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExecutionContext](./kibana-plugin-plugins-expressions-server.executioncontext.md) > [abortSignal](./kibana-plugin-plugins-expressions-server.executioncontext.abortsignal.md) + +## ExecutionContext.abortSignal property + +Adds ability to abort current execution. + +Signature: + +```typescript +abortSignal: AbortSignal; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.getinitialinput.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.getinitialinput.md new file mode 100644 index 0000000000000..b5f9b91e1c7b7 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.getinitialinput.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExecutionContext](./kibana-plugin-plugins-expressions-server.executioncontext.md) > [getInitialInput](./kibana-plugin-plugins-expressions-server.executioncontext.getinitialinput.md) + +## ExecutionContext.getInitialInput property + +Get initial input with which execution started. + +Signature: + +```typescript +getInitialInput: () => Input; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.getsavedobject.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.getsavedobject.md new file mode 100644 index 0000000000000..b8c8f4f3bb067 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.getsavedobject.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExecutionContext](./kibana-plugin-plugins-expressions-server.executioncontext.md) > [getSavedObject](./kibana-plugin-plugins-expressions-server.executioncontext.getsavedobject.md) + +## ExecutionContext.getSavedObject property + +Allows to fetch saved objects from ElasticSearch. In browser `getSavedObject` function is provided automatically by the Expressions plugin. On the server the caller of the expression has to provide this context function. The reason is because on the browser we always know the user who tries to fetch a saved object, thus saved object client is scoped automatically to that user. However, on the server we can scope that saved object client to any user, or even not scope it at all and execute it as an "internal" user. + +Signature: + +```typescript +getSavedObject?: (type: string, id: string) => Promise>; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.inspectoradapters.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.inspectoradapters.md new file mode 100644 index 0000000000000..b937432e4c180 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.inspectoradapters.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExecutionContext](./kibana-plugin-plugins-expressions-server.executioncontext.md) > [inspectorAdapters](./kibana-plugin-plugins-expressions-server.executioncontext.inspectoradapters.md) + +## ExecutionContext.inspectorAdapters property + +Adapters for `inspector` plugin. + +Signature: + +```typescript +inspectorAdapters: InspectorAdapters; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.md new file mode 100644 index 0000000000000..0128ba934da73 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.md @@ -0,0 +1,26 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExecutionContext](./kibana-plugin-plugins-expressions-server.executioncontext.md) + +## ExecutionContext interface + +`ExecutionContext` is an object available to all functions during a single execution; it provides various methods to perform side-effects. + +Signature: + +```typescript +export interface ExecutionContext +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [abortSignal](./kibana-plugin-plugins-expressions-server.executioncontext.abortsignal.md) | AbortSignal | Adds ability to abort current execution. | +| [getInitialInput](./kibana-plugin-plugins-expressions-server.executioncontext.getinitialinput.md) | () => Input | Get initial input with which execution started. | +| [getSavedObject](./kibana-plugin-plugins-expressions-server.executioncontext.getsavedobject.md) | <T extends SavedObjectAttributes = SavedObjectAttributes>(type: string, id: string) => Promise<SavedObject<T>> | Allows to fetch saved objects from ElasticSearch. In browser getSavedObject function is provided automatically by the Expressions plugin. On the server the caller of the expression has to provide this context function. The reason is because on the browser we always know the user who tries to fetch a saved object, thus saved object client is scoped automatically to that user. However, on the server we can scope that saved object client to any user, or even not scope it at all and execute it as an "internal" user. | +| [inspectorAdapters](./kibana-plugin-plugins-expressions-server.executioncontext.inspectoradapters.md) | InspectorAdapters | Adapters for inspector plugin. | +| [search](./kibana-plugin-plugins-expressions-server.executioncontext.search.md) | ExecutionContextSearch | Search context in which expression should operate. | +| [types](./kibana-plugin-plugins-expressions-server.executioncontext.types.md) | Record<string, ExpressionType> | A map of available expression types. | +| [variables](./kibana-plugin-plugins-expressions-server.executioncontext.variables.md) | Record<string, unknown> | Context variables that can be consumed using var and var_set functions. | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.search.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.search.md new file mode 100644 index 0000000000000..641e50696f6e0 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.search.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExecutionContext](./kibana-plugin-plugins-expressions-server.executioncontext.md) > [search](./kibana-plugin-plugins-expressions-server.executioncontext.search.md) + +## ExecutionContext.search property + +Search context in which expression should operate. + +Signature: + +```typescript +search?: ExecutionContextSearch; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.types.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.types.md new file mode 100644 index 0000000000000..9f594a588b200 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.types.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExecutionContext](./kibana-plugin-plugins-expressions-server.executioncontext.md) > [types](./kibana-plugin-plugins-expressions-server.executioncontext.types.md) + +## ExecutionContext.types property + +A map of available expression types. + +Signature: + +```typescript +types: Record; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.variables.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.variables.md new file mode 100644 index 0000000000000..bce3b7bb1bc4d --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executioncontext.variables.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExecutionContext](./kibana-plugin-plugins-expressions-server.executioncontext.md) > [variables](./kibana-plugin-plugins-expressions-server.executioncontext.variables.md) + +## ExecutionContext.variables property + +Context variables that can be consumed using `var` and `var_set` functions. + +Signature: + +```typescript +variables: Record; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionparams.ast.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionparams.ast.md new file mode 100644 index 0000000000000..adaccf091bc5e --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionparams.ast.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExecutionParams](./kibana-plugin-plugins-expressions-server.executionparams.md) > [ast](./kibana-plugin-plugins-expressions-server.executionparams.ast.md) + +## ExecutionParams.ast property + +Signature: + +```typescript +ast?: ExpressionAstExpression; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionparams.context.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionparams.context.md new file mode 100644 index 0000000000000..8b9a210416dd6 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionparams.context.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExecutionParams](./kibana-plugin-plugins-expressions-server.executionparams.md) > [context](./kibana-plugin-plugins-expressions-server.executionparams.context.md) + +## ExecutionParams.context property + +Signature: + +```typescript +context?: ExtraContext; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionparams.debug.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionparams.debug.md new file mode 100644 index 0000000000000..b3631e0aeebe6 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionparams.debug.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExecutionParams](./kibana-plugin-plugins-expressions-server.executionparams.md) > [debug](./kibana-plugin-plugins-expressions-server.executionparams.debug.md) + +## ExecutionParams.debug property + +Whether to execute expression in \*debug mode\*. In \*debug mode\* inputs and outputs as well as all resolved arguments and time it took to execute each function are saved and are available for introspection. + +Signature: + +```typescript +debug?: boolean; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionparams.executor.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionparams.executor.md new file mode 100644 index 0000000000000..fef0f6f8e2495 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionparams.executor.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExecutionParams](./kibana-plugin-plugins-expressions-server.executionparams.md) > [executor](./kibana-plugin-plugins-expressions-server.executionparams.executor.md) + +## ExecutionParams.executor property + +Signature: + +```typescript +executor: Executor; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionparams.expression.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionparams.expression.md new file mode 100644 index 0000000000000..7d75bd51a611b --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionparams.expression.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExecutionParams](./kibana-plugin-plugins-expressions-server.executionparams.md) > [expression](./kibana-plugin-plugins-expressions-server.executionparams.expression.md) + +## ExecutionParams.expression property + +Signature: + +```typescript +expression?: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionparams.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionparams.md new file mode 100644 index 0000000000000..a7594bff48c1a --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionparams.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExecutionParams](./kibana-plugin-plugins-expressions-server.executionparams.md) + +## ExecutionParams interface + +Signature: + +```typescript +export interface ExecutionParams = Record> +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [ast](./kibana-plugin-plugins-expressions-server.executionparams.ast.md) | ExpressionAstExpression | | +| [context](./kibana-plugin-plugins-expressions-server.executionparams.context.md) | ExtraContext | | +| [debug](./kibana-plugin-plugins-expressions-server.executionparams.debug.md) | boolean | Whether to execute expression in \*debug mode\*. In \*debug mode\* inputs and outputs as well as all resolved arguments and time it took to execute each function are saved and are available for introspection. | +| [executor](./kibana-plugin-plugins-expressions-server.executionparams.executor.md) | Executor<any> | | +| [expression](./kibana-plugin-plugins-expressions-server.executionparams.expression.md) | string | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionstate.ast.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionstate.ast.md new file mode 100644 index 0000000000000..0eab94589a75e --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionstate.ast.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExecutionState](./kibana-plugin-plugins-expressions-server.executionstate.md) > [ast](./kibana-plugin-plugins-expressions-server.executionstate.ast.md) + +## ExecutionState.ast property + +Signature: + +```typescript +ast: ExpressionAstExpression; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionstate.error.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionstate.error.md new file mode 100644 index 0000000000000..350d38697571a --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionstate.error.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExecutionState](./kibana-plugin-plugins-expressions-server.executionstate.md) > [error](./kibana-plugin-plugins-expressions-server.executionstate.error.md) + +## ExecutionState.error property + +Error happened during the execution. + +Signature: + +```typescript +error?: Error; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionstate.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionstate.md new file mode 100644 index 0000000000000..a3b28bda8c864 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionstate.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExecutionState](./kibana-plugin-plugins-expressions-server.executionstate.md) + +## ExecutionState interface + +Signature: + +```typescript +export interface ExecutionState extends ExecutorState +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [ast](./kibana-plugin-plugins-expressions-server.executionstate.ast.md) | ExpressionAstExpression | | +| [error](./kibana-plugin-plugins-expressions-server.executionstate.error.md) | Error | Error happened during the execution. | +| [result](./kibana-plugin-plugins-expressions-server.executionstate.result.md) | Output | Result of the expression execution. | +| [state](./kibana-plugin-plugins-expressions-server.executionstate.state.md) | 'not-started' | 'pending' | 'result' | 'error' | Tracks state of execution.- not-started - before .start() method was called. - pending - immediately after .start() method is called. - result - when expression execution completed. - error - when execution failed with error. | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionstate.result.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionstate.result.md new file mode 100644 index 0000000000000..b23ba17172a10 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionstate.result.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExecutionState](./kibana-plugin-plugins-expressions-server.executionstate.md) > [result](./kibana-plugin-plugins-expressions-server.executionstate.result.md) + +## ExecutionState.result property + +Result of the expression execution. + +Signature: + +```typescript +result?: Output; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionstate.state.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionstate.state.md new file mode 100644 index 0000000000000..6dcfca1a4fa0e --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executionstate.state.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExecutionState](./kibana-plugin-plugins-expressions-server.executionstate.md) > [state](./kibana-plugin-plugins-expressions-server.executionstate.state.md) + +## ExecutionState.state property + +Tracks state of execution. + +- `not-started` - before .start() method was called. - `pending` - immediately after .start() method is called. - `result` - when expression execution completed. - `error` - when execution failed with error. + +Signature: + +```typescript +state: 'not-started' | 'pending' | 'result' | 'error'; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor._constructor_.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor._constructor_.md new file mode 100644 index 0000000000000..f9b6759ef5529 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor._constructor_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Executor](./kibana-plugin-plugins-expressions-server.executor.md) > [(constructor)](./kibana-plugin-plugins-expressions-server.executor._constructor_.md) + +## Executor.(constructor) + +Constructs a new instance of the `Executor` class + +Signature: + +```typescript +constructor(state?: ExecutorState); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| state | ExecutorState<Context> | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.context.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.context.md new file mode 100644 index 0000000000000..d53401c6d0419 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.context.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Executor](./kibana-plugin-plugins-expressions-server.executor.md) > [context](./kibana-plugin-plugins-expressions-server.executor.context.md) + +## Executor.context property + +Signature: + +```typescript +get context(): Record; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.createexecution.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.createexecution.md new file mode 100644 index 0000000000000..8ed228d70ff37 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.createexecution.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Executor](./kibana-plugin-plugins-expressions-server.executor.md) > [createExecution](./kibana-plugin-plugins-expressions-server.executor.createexecution.md) + +## Executor.createExecution() method + +Signature: + +```typescript +createExecution = Record, Input = unknown, Output = unknown>(ast: string | ExpressionAstExpression, context?: ExtraContext, { debug }?: ExpressionExecOptions): Execution; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| ast | string | ExpressionAstExpression | | +| context | ExtraContext | | +| { debug } | ExpressionExecOptions | | + +Returns: + +`Execution` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.createwithdefaults.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.createwithdefaults.md new file mode 100644 index 0000000000000..67863cc9e9ebe --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.createwithdefaults.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Executor](./kibana-plugin-plugins-expressions-server.executor.md) > [createWithDefaults](./kibana-plugin-plugins-expressions-server.executor.createwithdefaults.md) + +## Executor.createWithDefaults() method + +Signature: + +```typescript +static createWithDefaults = Record>(state?: ExecutorState): Executor; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| state | ExecutorState<Ctx> | | + +Returns: + +`Executor` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.extendcontext.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.extendcontext.md new file mode 100644 index 0000000000000..d78b4193b62fa --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.extendcontext.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Executor](./kibana-plugin-plugins-expressions-server.executor.md) > [extendContext](./kibana-plugin-plugins-expressions-server.executor.extendcontext.md) + +## Executor.extendContext() method + +Signature: + +```typescript +extendContext(extraContext: Record): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| extraContext | Record<string, unknown> | | + +Returns: + +`void` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.fork.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.fork.md new file mode 100644 index 0000000000000..8cfec983e6cbd --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.fork.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Executor](./kibana-plugin-plugins-expressions-server.executor.md) > [fork](./kibana-plugin-plugins-expressions-server.executor.fork.md) + +## Executor.fork() method + +Signature: + +```typescript +fork(): Executor; +``` +Returns: + +`Executor` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.functions.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.functions.md new file mode 100644 index 0000000000000..36cbe8608c872 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.functions.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Executor](./kibana-plugin-plugins-expressions-server.executor.md) > [functions](./kibana-plugin-plugins-expressions-server.executor.functions.md) + +## Executor.functions property + +> Warning: This API is now obsolete. +> +> + +Signature: + +```typescript +readonly functions: FunctionsRegistry; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.getfunction.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.getfunction.md new file mode 100644 index 0000000000000..0c3f307214d01 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.getfunction.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Executor](./kibana-plugin-plugins-expressions-server.executor.md) > [getFunction](./kibana-plugin-plugins-expressions-server.executor.getfunction.md) + +## Executor.getFunction() method + +Signature: + +```typescript +getFunction(name: string): ExpressionFunction | undefined; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| name | string | | + +Returns: + +`ExpressionFunction | undefined` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.getfunctions.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.getfunctions.md new file mode 100644 index 0000000000000..9f4132e30297d --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.getfunctions.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Executor](./kibana-plugin-plugins-expressions-server.executor.md) > [getFunctions](./kibana-plugin-plugins-expressions-server.executor.getfunctions.md) + +## Executor.getFunctions() method + +Signature: + +```typescript +getFunctions(): Record; +``` +Returns: + +`Record` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.gettype.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.gettype.md new file mode 100644 index 0000000000000..ccff4bc632284 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.gettype.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Executor](./kibana-plugin-plugins-expressions-server.executor.md) > [getType](./kibana-plugin-plugins-expressions-server.executor.gettype.md) + +## Executor.getType() method + +Signature: + +```typescript +getType(name: string): ExpressionType | undefined; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| name | string | | + +Returns: + +`ExpressionType | undefined` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.gettypes.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.gettypes.md new file mode 100644 index 0000000000000..8658f36867971 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.gettypes.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Executor](./kibana-plugin-plugins-expressions-server.executor.md) > [getTypes](./kibana-plugin-plugins-expressions-server.executor.gettypes.md) + +## Executor.getTypes() method + +Signature: + +```typescript +getTypes(): Record; +``` +Returns: + +`Record` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.md new file mode 100644 index 0000000000000..7e6bb8c7ded5e --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.md @@ -0,0 +1,43 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Executor](./kibana-plugin-plugins-expressions-server.executor.md) + +## Executor class + +Signature: + +```typescript +export declare class Executor = Record> +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(state)](./kibana-plugin-plugins-expressions-server.executor._constructor_.md) | | Constructs a new instance of the Executor class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [context](./kibana-plugin-plugins-expressions-server.executor.context.md) | | Record<string, unknown> | | +| [functions](./kibana-plugin-plugins-expressions-server.executor.functions.md) | | FunctionsRegistry | | +| [state](./kibana-plugin-plugins-expressions-server.executor.state.md) | | ExecutorContainer<Context> | | +| [types](./kibana-plugin-plugins-expressions-server.executor.types.md) | | TypesRegistry | | + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [createExecution(ast, context, { debug })](./kibana-plugin-plugins-expressions-server.executor.createexecution.md) | | | +| [createWithDefaults(state)](./kibana-plugin-plugins-expressions-server.executor.createwithdefaults.md) | static | | +| [extendContext(extraContext)](./kibana-plugin-plugins-expressions-server.executor.extendcontext.md) | | | +| [fork()](./kibana-plugin-plugins-expressions-server.executor.fork.md) | | | +| [getFunction(name)](./kibana-plugin-plugins-expressions-server.executor.getfunction.md) | | | +| [getFunctions()](./kibana-plugin-plugins-expressions-server.executor.getfunctions.md) | | | +| [getType(name)](./kibana-plugin-plugins-expressions-server.executor.gettype.md) | | | +| [getTypes()](./kibana-plugin-plugins-expressions-server.executor.gettypes.md) | | | +| [registerFunction(functionDefinition)](./kibana-plugin-plugins-expressions-server.executor.registerfunction.md) | | | +| [registerType(typeDefinition)](./kibana-plugin-plugins-expressions-server.executor.registertype.md) | | | +| [run(ast, input, context)](./kibana-plugin-plugins-expressions-server.executor.run.md) | | Execute expression and return result. | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.registerfunction.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.registerfunction.md new file mode 100644 index 0000000000000..0cdd62735980c --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.registerfunction.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Executor](./kibana-plugin-plugins-expressions-server.executor.md) > [registerFunction](./kibana-plugin-plugins-expressions-server.executor.registerfunction.md) + +## Executor.registerFunction() method + +Signature: + +```typescript +registerFunction(functionDefinition: AnyExpressionFunctionDefinition | (() => AnyExpressionFunctionDefinition)): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| functionDefinition | AnyExpressionFunctionDefinition | (() => AnyExpressionFunctionDefinition) | | + +Returns: + +`void` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.registertype.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.registertype.md new file mode 100644 index 0000000000000..355ff92921f10 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.registertype.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Executor](./kibana-plugin-plugins-expressions-server.executor.md) > [registerType](./kibana-plugin-plugins-expressions-server.executor.registertype.md) + +## Executor.registerType() method + +Signature: + +```typescript +registerType(typeDefinition: AnyExpressionTypeDefinition | (() => AnyExpressionTypeDefinition)): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| typeDefinition | AnyExpressionTypeDefinition | (() => AnyExpressionTypeDefinition) | | + +Returns: + +`void` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.run.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.run.md new file mode 100644 index 0000000000000..784a1df5d3ac2 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.run.md @@ -0,0 +1,26 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Executor](./kibana-plugin-plugins-expressions-server.executor.md) > [run](./kibana-plugin-plugins-expressions-server.executor.run.md) + +## Executor.run() method + +Execute expression and return result. + +Signature: + +```typescript +run = Record>(ast: string | ExpressionAstExpression, input: Input, context?: ExtraContext): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| ast | string | ExpressionAstExpression | | +| input | Input | | +| context | ExtraContext | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.state.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.state.md new file mode 100644 index 0000000000000..2c3041484712a --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.state.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Executor](./kibana-plugin-plugins-expressions-server.executor.md) > [state](./kibana-plugin-plugins-expressions-server.executor.state.md) + +## Executor.state property + +Signature: + +```typescript +readonly state: ExecutorContainer; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.types.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.types.md new file mode 100644 index 0000000000000..2082917cf0624 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executor.types.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Executor](./kibana-plugin-plugins-expressions-server.executor.md) > [types](./kibana-plugin-plugins-expressions-server.executor.types.md) + +## Executor.types property + +> Warning: This API is now obsolete. +> +> + +Signature: + +```typescript +readonly types: TypesRegistry; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executorcontainer.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executorcontainer.md new file mode 100644 index 0000000000000..a3847c5ad9a77 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executorcontainer.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExecutorContainer](./kibana-plugin-plugins-expressions-server.executorcontainer.md) + +## ExecutorContainer type + +Signature: + +```typescript +export declare type ExecutorContainer = Record> = StateContainer, ExecutorPureTransitions, ExecutorPureSelectors>; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executorstate.context.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executorstate.context.md new file mode 100644 index 0000000000000..0829f2d6caf04 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executorstate.context.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExecutorState](./kibana-plugin-plugins-expressions-server.executorstate.md) > [context](./kibana-plugin-plugins-expressions-server.executorstate.context.md) + +## ExecutorState.context property + +Signature: + +```typescript +context: Context; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executorstate.functions.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executorstate.functions.md new file mode 100644 index 0000000000000..92a0865a7bb2f --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executorstate.functions.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExecutorState](./kibana-plugin-plugins-expressions-server.executorstate.md) > [functions](./kibana-plugin-plugins-expressions-server.executorstate.functions.md) + +## ExecutorState.functions property + +Signature: + +```typescript +functions: Record; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executorstate.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executorstate.md new file mode 100644 index 0000000000000..5faa326ee3534 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executorstate.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExecutorState](./kibana-plugin-plugins-expressions-server.executorstate.md) + +## ExecutorState interface + +Signature: + +```typescript +export interface ExecutorState = Record> +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [context](./kibana-plugin-plugins-expressions-server.executorstate.context.md) | Context | | +| [functions](./kibana-plugin-plugins-expressions-server.executorstate.functions.md) | Record<string, ExpressionFunction> | | +| [types](./kibana-plugin-plugins-expressions-server.executorstate.types.md) | Record<string, ExpressionType> | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executorstate.types.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executorstate.types.md new file mode 100644 index 0000000000000..a435fabfedf92 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.executorstate.types.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExecutorState](./kibana-plugin-plugins-expressions-server.executorstate.md) > [types](./kibana-plugin-plugins-expressions-server.executorstate.types.md) + +## ExecutorState.types property + +Signature: + +```typescript +types: Record; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastargument.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastargument.md new file mode 100644 index 0000000000000..0518949ad612f --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastargument.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstArgument](./kibana-plugin-plugins-expressions-server.expressionastargument.md) + +## ExpressionAstArgument type + +Signature: + +```typescript +export declare type ExpressionAstArgument = string | boolean | number | ExpressionAstExpression; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpression.chain.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpression.chain.md new file mode 100644 index 0000000000000..cc8006b918dec --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpression.chain.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstExpression](./kibana-plugin-plugins-expressions-server.expressionastexpression.md) > [chain](./kibana-plugin-plugins-expressions-server.expressionastexpression.chain.md) + +## ExpressionAstExpression.chain property + +Signature: + +```typescript +chain: ExpressionAstFunction[]; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpression.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpression.md new file mode 100644 index 0000000000000..b5f83d1af7cb7 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpression.md @@ -0,0 +1,19 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstExpression](./kibana-plugin-plugins-expressions-server.expressionastexpression.md) + +## ExpressionAstExpression interface + +Signature: + +```typescript +export interface ExpressionAstExpression +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [chain](./kibana-plugin-plugins-expressions-server.expressionastexpression.chain.md) | ExpressionAstFunction[] | | +| [type](./kibana-plugin-plugins-expressions-server.expressionastexpression.type.md) | 'expression' | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpression.type.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpression.type.md new file mode 100644 index 0000000000000..46cd60cecaa84 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpression.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstExpression](./kibana-plugin-plugins-expressions-server.expressionastexpression.md) > [type](./kibana-plugin-plugins-expressions-server.expressionastexpression.type.md) + +## ExpressionAstExpression.type property + +Signature: + +```typescript +type: 'expression'; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.findfunction.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.findfunction.md new file mode 100644 index 0000000000000..28cf8707c17d6 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.findfunction.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstExpressionBuilder](./kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.md) > [findFunction](./kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.findfunction.md) + +## ExpressionAstExpressionBuilder.findFunction property + +Recursively searches expression for all ocurrences of the function, including in subexpressions. + +Useful when performing migrations on a specific function, as you can iterate over the array of references and update all functions at once. + +Signature: + +```typescript +findFunction: (fnName: InferFunctionDefinition['name']) => Array> | []; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.functions.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.functions.md new file mode 100644 index 0000000000000..c3e1add70511b --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.functions.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstExpressionBuilder](./kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.md) > [functions](./kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.functions.md) + +## ExpressionAstExpressionBuilder.functions property + +Array of each of the `buildExpressionFunction()` instances in this expression. Use this to remove or reorder functions in the expression. + +Signature: + +```typescript +functions: ExpressionAstFunctionBuilder[]; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.md new file mode 100644 index 0000000000000..50a9c76daaa2b --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstExpressionBuilder](./kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.md) + +## ExpressionAstExpressionBuilder interface + +Signature: + +```typescript +export interface ExpressionAstExpressionBuilder +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [findFunction](./kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.findfunction.md) | <FnDef extends AnyExpressionFunctionDefinition = AnyExpressionFunctionDefinition>(fnName: InferFunctionDefinition<FnDef>['name']) => Array<ExpressionAstFunctionBuilder<FnDef>> | [] | Recursively searches expression for all ocurrences of the function, including in subexpressions.Useful when performing migrations on a specific function, as you can iterate over the array of references and update all functions at once. | +| [functions](./kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.functions.md) | ExpressionAstFunctionBuilder[] | Array of each of the buildExpressionFunction() instances in this expression. Use this to remove or reorder functions in the expression. | +| [toAst](./kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.toast.md) | () => ExpressionAstExpression | Converts expression to an AST. ExpressionAstExpression | +| [toString](./kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.tostring.md) | () => string | Converts expression to an expression string. string | +| [type](./kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.type.md) | 'expression_builder' | Used to identify expression builder objects. | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.toast.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.toast.md new file mode 100644 index 0000000000000..5c6189e6a46c4 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.toast.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstExpressionBuilder](./kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.md) > [toAst](./kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.toast.md) + +## ExpressionAstExpressionBuilder.toAst property + +Converts expression to an AST. + + `ExpressionAstExpression` + +Signature: + +```typescript +toAst: () => ExpressionAstExpression; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.tostring.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.tostring.md new file mode 100644 index 0000000000000..80aaeef1700c3 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.tostring.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstExpressionBuilder](./kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.md) > [toString](./kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.tostring.md) + +## ExpressionAstExpressionBuilder.toString property + +Converts expression to an expression string. + + `string` + +Signature: + +```typescript +toString: () => string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.type.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.type.md new file mode 100644 index 0000000000000..401b2e3725e84 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.type.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstExpressionBuilder](./kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.md) > [type](./kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.type.md) + +## ExpressionAstExpressionBuilder.type property + +Used to identify expression builder objects. + +Signature: + +```typescript +type: 'expression_builder'; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunction.arguments.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunction.arguments.md new file mode 100644 index 0000000000000..052cadffb9bdb --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunction.arguments.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstFunction](./kibana-plugin-plugins-expressions-server.expressionastfunction.md) > [arguments](./kibana-plugin-plugins-expressions-server.expressionastfunction.arguments.md) + +## ExpressionAstFunction.arguments property + +Signature: + +```typescript +arguments: Record; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunction.debug.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunction.debug.md new file mode 100644 index 0000000000000..b3227c2ac5822 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunction.debug.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstFunction](./kibana-plugin-plugins-expressions-server.expressionastfunction.md) > [debug](./kibana-plugin-plugins-expressions-server.expressionastfunction.debug.md) + +## ExpressionAstFunction.debug property + +Debug information added to each function when expression is executed in \*debug mode\*. + +Signature: + +```typescript +debug?: ExpressionAstFunctionDebug; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunction.function.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunction.function.md new file mode 100644 index 0000000000000..9964409f49119 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunction.function.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstFunction](./kibana-plugin-plugins-expressions-server.expressionastfunction.md) > [function](./kibana-plugin-plugins-expressions-server.expressionastfunction.function.md) + +## ExpressionAstFunction.function property + +Signature: + +```typescript +function: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunction.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunction.md new file mode 100644 index 0000000000000..1d49de44b571d --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunction.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstFunction](./kibana-plugin-plugins-expressions-server.expressionastfunction.md) + +## ExpressionAstFunction interface + +Signature: + +```typescript +export interface ExpressionAstFunction +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [arguments](./kibana-plugin-plugins-expressions-server.expressionastfunction.arguments.md) | Record<string, ExpressionAstArgument[]> | | +| [debug](./kibana-plugin-plugins-expressions-server.expressionastfunction.debug.md) | ExpressionAstFunctionDebug | Debug information added to each function when expression is executed in \*debug mode\*. | +| [function](./kibana-plugin-plugins-expressions-server.expressionastfunction.function.md) | string | | +| [type](./kibana-plugin-plugins-expressions-server.expressionastfunction.type.md) | 'function' | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunction.type.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunction.type.md new file mode 100644 index 0000000000000..3fd10524c1599 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunction.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstFunction](./kibana-plugin-plugins-expressions-server.expressionastfunction.md) > [type](./kibana-plugin-plugins-expressions-server.expressionastfunction.type.md) + +## ExpressionAstFunction.type property + +Signature: + +```typescript +type: 'function'; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.addargument.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.addargument.md new file mode 100644 index 0000000000000..29e3baec18a2e --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.addargument.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstFunctionBuilder](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.md) > [addArgument](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.addargument.md) + +## ExpressionAstFunctionBuilder.addArgument property + +Adds an additional argument to the function. For multi-args, this should be called once for each new arg. Note that TS will not enforce whether multi-args are available, so only use this to update an existing arg if you are certain it is a multi-arg. + +Signature: + +```typescript +addArgument:
>(name: A, value: FunctionArgs[A] | ExpressionAstExpressionBuilder) => this; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.arguments.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.arguments.md new file mode 100644 index 0000000000000..4c0eee637b3e1 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.arguments.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstFunctionBuilder](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.md) > [arguments](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.arguments.md) + +## ExpressionAstFunctionBuilder.arguments property + +Object of all args currently added to the function. This is structured similarly to `ExpressionAstFunction['arguments']`, however any subexpressions are returned as expression builder instances instead of expression ASTs. + +Signature: + +```typescript +arguments: FunctionBuilderArguments; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.getargument.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.getargument.md new file mode 100644 index 0000000000000..09b76ccbf23d9 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.getargument.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstFunctionBuilder](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.md) > [getArgument](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.getargument.md) + +## ExpressionAstFunctionBuilder.getArgument property + +Retrieves an existing argument by name. Useful when you want to retrieve the current array of args and add something to it before calling `replaceArgument`. Any subexpression arguments will be returned as expression builder instances. + +Signature: + +```typescript +getArgument: >(name: A) => Array[A] | ExpressionAstExpressionBuilder> | undefined; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.md new file mode 100644 index 0000000000000..2a502d6f05e0b --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.md @@ -0,0 +1,26 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstFunctionBuilder](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.md) + +## ExpressionAstFunctionBuilder interface + +Signature: + +```typescript +export interface ExpressionAstFunctionBuilder +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [addArgument](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.addargument.md) | <A extends FunctionArgName<FnDef>>(name: A, value: FunctionArgs<FnDef>[A] | ExpressionAstExpressionBuilder) => this | Adds an additional argument to the function. For multi-args, this should be called once for each new arg. Note that TS will not enforce whether multi-args are available, so only use this to update an existing arg if you are certain it is a multi-arg. | +| [arguments](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.arguments.md) | FunctionBuilderArguments<FnDef> | Object of all args currently added to the function. This is structured similarly to ExpressionAstFunction['arguments'], however any subexpressions are returned as expression builder instances instead of expression ASTs. | +| [getArgument](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.getargument.md) | <A extends FunctionArgName<FnDef>>(name: A) => Array<FunctionArgs<FnDef>[A] | ExpressionAstExpressionBuilder> | undefined | Retrieves an existing argument by name. Useful when you want to retrieve the current array of args and add something to it before calling replaceArgument. Any subexpression arguments will be returned as expression builder instances. | +| [name](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.name.md) | InferFunctionDefinition<FnDef>['name'] | Name of this expression function. | +| [removeArgument](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.removeargument.md) | <A extends OptionalKeys<FunctionArgs<FnDef>>>(name: A) => this | Removes an (optional) argument from the function.TypeScript will enforce that you only remove optional arguments. For manipulating required args, use replaceArgument. | +| [replaceArgument](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.replaceargument.md) | <A extends FunctionArgName<FnDef>>(name: A, value: Array<FunctionArgs<FnDef>[A] | ExpressionAstExpressionBuilder>) => this | Overwrites an existing argument with a new value. In order to support multi-args, the value given must always be an array. | +| [toAst](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.toast.md) | () => ExpressionAstFunction | Converts function to an AST. ExpressionAstFunction | +| [toString](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.tostring.md) | () => string | Converts function to an expression string. string | +| [type](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.type.md) | 'expression_function_builder' | Used to identify expression function builder objects. | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.name.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.name.md new file mode 100644 index 0000000000000..a2b6a4128549f --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.name.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstFunctionBuilder](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.md) > [name](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.name.md) + +## ExpressionAstFunctionBuilder.name property + +Name of this expression function. + +Signature: + +```typescript +name: InferFunctionDefinition['name']; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.removeargument.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.removeargument.md new file mode 100644 index 0000000000000..b5fd0cc7e3727 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.removeargument.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstFunctionBuilder](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.md) > [removeArgument](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.removeargument.md) + +## ExpressionAstFunctionBuilder.removeArgument property + +Removes an (optional) argument from the function. + +TypeScript will enforce that you only remove optional arguments. For manipulating required args, use `replaceArgument`. + +Signature: + +```typescript +removeArgument: >>(name: A) => this; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.replaceargument.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.replaceargument.md new file mode 100644 index 0000000000000..943d8ea235763 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.replaceargument.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstFunctionBuilder](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.md) > [replaceArgument](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.replaceargument.md) + +## ExpressionAstFunctionBuilder.replaceArgument property + +Overwrites an existing argument with a new value. In order to support multi-args, the value given must always be an array. + +Signature: + +```typescript +replaceArgument: >(name: A, value: Array[A] | ExpressionAstExpressionBuilder>) => this; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.toast.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.toast.md new file mode 100644 index 0000000000000..a8e9205610501 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.toast.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstFunctionBuilder](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.md) > [toAst](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.toast.md) + +## ExpressionAstFunctionBuilder.toAst property + +Converts function to an AST. + + `ExpressionAstFunction` + +Signature: + +```typescript +toAst: () => ExpressionAstFunction; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.tostring.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.tostring.md new file mode 100644 index 0000000000000..af307cbc84c9f --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.tostring.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstFunctionBuilder](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.md) > [toString](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.tostring.md) + +## ExpressionAstFunctionBuilder.toString property + +Converts function to an expression string. + + `string` + +Signature: + +```typescript +toString: () => string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.type.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.type.md new file mode 100644 index 0000000000000..ed1db54c6eeaa --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.type.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstFunctionBuilder](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.md) > [type](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.type.md) + +## ExpressionAstFunctionBuilder.type property + +Used to identify expression function builder objects. + +Signature: + +```typescript +type: 'expression_function_builder'; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastnode.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastnode.md new file mode 100644 index 0000000000000..d04c5556ff0ff --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionastnode.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionAstNode](./kibana-plugin-plugins-expressions-server.expressionastnode.md) + +## ExpressionAstNode type + +Signature: + +```typescript +export declare type ExpressionAstNode = ExpressionAstExpression | ExpressionAstFunction | ExpressionAstArgument; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction._constructor_.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction._constructor_.md new file mode 100644 index 0000000000000..96ed22f3277b4 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction._constructor_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunction](./kibana-plugin-plugins-expressions-server.expressionfunction.md) > [(constructor)](./kibana-plugin-plugins-expressions-server.expressionfunction._constructor_.md) + +## ExpressionFunction.(constructor) + +Constructs a new instance of the `ExpressionFunction` class + +Signature: + +```typescript +constructor(functionDefinition: AnyExpressionFunctionDefinition); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| functionDefinition | AnyExpressionFunctionDefinition | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.accepts.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.accepts.md new file mode 100644 index 0000000000000..25008a56e0465 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.accepts.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunction](./kibana-plugin-plugins-expressions-server.expressionfunction.md) > [accepts](./kibana-plugin-plugins-expressions-server.expressionfunction.accepts.md) + +## ExpressionFunction.accepts property + +Signature: + +```typescript +accepts: (type: string) => boolean; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.aliases.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.aliases.md new file mode 100644 index 0000000000000..6e11246275d04 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.aliases.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunction](./kibana-plugin-plugins-expressions-server.expressionfunction.md) > [aliases](./kibana-plugin-plugins-expressions-server.expressionfunction.aliases.md) + +## ExpressionFunction.aliases property + +Aliases that can be used instead of `name`. + +Signature: + +```typescript +aliases: string[]; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.args.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.args.md new file mode 100644 index 0000000000000..ffa8cd0d11f7a --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.args.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunction](./kibana-plugin-plugins-expressions-server.expressionfunction.md) > [args](./kibana-plugin-plugins-expressions-server.expressionfunction.args.md) + +## ExpressionFunction.args property + +Specification of expression function parameters. + +Signature: + +```typescript +args: Record; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.fn.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.fn.md new file mode 100644 index 0000000000000..12056cac12cce --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.fn.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunction](./kibana-plugin-plugins-expressions-server.expressionfunction.md) > [fn](./kibana-plugin-plugins-expressions-server.expressionfunction.fn.md) + +## ExpressionFunction.fn property + +Function to run function (context, args) + +Signature: + +```typescript +fn: (input: ExpressionValue, params: Record, handlers: object) => ExpressionValue; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.help.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.help.md new file mode 100644 index 0000000000000..0a20a1ec60860 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.help.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunction](./kibana-plugin-plugins-expressions-server.expressionfunction.md) > [help](./kibana-plugin-plugins-expressions-server.expressionfunction.help.md) + +## ExpressionFunction.help property + +A short help text. + +Signature: + +```typescript +help: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.inputtypes.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.inputtypes.md new file mode 100644 index 0000000000000..1fa11bbb77416 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.inputtypes.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunction](./kibana-plugin-plugins-expressions-server.expressionfunction.md) > [inputTypes](./kibana-plugin-plugins-expressions-server.expressionfunction.inputtypes.md) + +## ExpressionFunction.inputTypes property + +Type of inputs that this function supports. + +Signature: + +```typescript +inputTypes: string[] | undefined; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.md new file mode 100644 index 0000000000000..aac3878b8c859 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.md @@ -0,0 +1,31 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunction](./kibana-plugin-plugins-expressions-server.expressionfunction.md) + +## ExpressionFunction class + +Signature: + +```typescript +export declare class ExpressionFunction +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(functionDefinition)](./kibana-plugin-plugins-expressions-server.expressionfunction._constructor_.md) | | Constructs a new instance of the ExpressionFunction class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [accepts](./kibana-plugin-plugins-expressions-server.expressionfunction.accepts.md) | | (type: string) => boolean | | +| [aliases](./kibana-plugin-plugins-expressions-server.expressionfunction.aliases.md) | | string[] | Aliases that can be used instead of name. | +| [args](./kibana-plugin-plugins-expressions-server.expressionfunction.args.md) | | Record<string, ExpressionFunctionParameter> | Specification of expression function parameters. | +| [fn](./kibana-plugin-plugins-expressions-server.expressionfunction.fn.md) | | (input: ExpressionValue, params: Record<string, any>, handlers: object) => ExpressionValue | Function to run function (context, args) | +| [help](./kibana-plugin-plugins-expressions-server.expressionfunction.help.md) | | string | A short help text. | +| [inputTypes](./kibana-plugin-plugins-expressions-server.expressionfunction.inputtypes.md) | | string[] | undefined | Type of inputs that this function supports. | +| [name](./kibana-plugin-plugins-expressions-server.expressionfunction.name.md) | | string | Name of function | +| [type](./kibana-plugin-plugins-expressions-server.expressionfunction.type.md) | | string | Return type of function. This SHOULD be supplied. We use it for UI and autocomplete hinting. We may also use it for optimizations in the future. | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.name.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.name.md new file mode 100644 index 0000000000000..46115c10c79ad --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.name.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunction](./kibana-plugin-plugins-expressions-server.expressionfunction.md) > [name](./kibana-plugin-plugins-expressions-server.expressionfunction.name.md) + +## ExpressionFunction.name property + +Name of function + +Signature: + +```typescript +name: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.type.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.type.md new file mode 100644 index 0000000000000..82bfff184b7cf --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunction.type.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunction](./kibana-plugin-plugins-expressions-server.expressionfunction.md) > [type](./kibana-plugin-plugins-expressions-server.expressionfunction.type.md) + +## ExpressionFunction.type property + +Return type of function. This SHOULD be supplied. We use it for UI and autocomplete hinting. We may also use it for optimizations in the future. + +Signature: + +```typescript +type: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.aliases.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.aliases.md new file mode 100644 index 0000000000000..3f5a608cc9bd2 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.aliases.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionDefinition](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.md) > [aliases](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.aliases.md) + +## ExpressionFunctionDefinition.aliases property + + What is this? + +Signature: + +```typescript +aliases?: string[]; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.args.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.args.md new file mode 100644 index 0000000000000..4ceb1d92bf8eb --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.args.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionDefinition](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.md) > [args](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.args.md) + +## ExpressionFunctionDefinition.args property + +Specification of arguments that function supports. This list will also be used for autocomplete functionality when your function is being edited. + +Signature: + +```typescript +args: { + [key in keyof Arguments]: ArgumentType; + }; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.context.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.context.md new file mode 100644 index 0000000000000..54d5c7c8a688d --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.context.md @@ -0,0 +1,18 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionDefinition](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.md) > [context](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.context.md) + +## ExpressionFunctionDefinition.context property + +> Warning: This API is now obsolete. +> +> Use `inputTypes` instead. +> + +Signature: + +```typescript +context?: { + types: AnyExpressionFunctionDefinition['inputTypes']; + }; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.fn.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.fn.md new file mode 100644 index 0000000000000..41f85be7141be --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.fn.md @@ -0,0 +1,26 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionDefinition](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.md) > [fn](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.fn.md) + +## ExpressionFunctionDefinition.fn() method + +The actual implementation of the function. + +Signature: + +```typescript +fn(input: Input, args: Arguments, context: Context): Output; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| input | Input | | +| args | Arguments | | +| context | Context | | + +Returns: + +`Output` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.help.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.help.md new file mode 100644 index 0000000000000..594cb768f3caa --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.help.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionDefinition](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.md) > [help](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.help.md) + +## ExpressionFunctionDefinition.help property + +Help text displayed in the Expression editor. This text should be internationalized. + +Signature: + +```typescript +help: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.inputtypes.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.inputtypes.md new file mode 100644 index 0000000000000..b47dc915cc72e --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.inputtypes.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionDefinition](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.md) > [inputTypes](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.inputtypes.md) + +## ExpressionFunctionDefinition.inputTypes property + +List of allowed type names for input value of this function. If this property is set the input of function will be cast to the first possible type in this list. If this property is missing the input will be provided to the function as-is. + +Signature: + +```typescript +inputTypes?: Array>; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.md new file mode 100644 index 0000000000000..6463c6ac537b9 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.md @@ -0,0 +1,32 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionDefinition](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.md) + +## ExpressionFunctionDefinition interface + +`ExpressionFunctionDefinition` is the interface plugins have to implement to register a function in `expressions` plugin. + +Signature: + +```typescript +export interface ExpressionFunctionDefinition, Output, Context extends ExecutionContext = ExecutionContext> +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [aliases](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.aliases.md) | string[] | What is this? | +| [args](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.args.md) | {
[key in keyof Arguments]: ArgumentType<Arguments[key]>;
} | Specification of arguments that function supports. This list will also be used for autocomplete functionality when your function is being edited. | +| [context](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.context.md) | {
types: AnyExpressionFunctionDefinition['inputTypes'];
} | | +| [help](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.help.md) | string | Help text displayed in the Expression editor. This text should be internationalized. | +| [inputTypes](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.inputtypes.md) | Array<TypeToString<Input>> | List of allowed type names for input value of this function. If this property is set the input of function will be cast to the first possible type in this list. If this property is missing the input will be provided to the function as-is. | +| [name](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.name.md) | Name | The name of the function, as will be used in expression. | +| [type](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.type.md) | TypeToString<UnwrapPromiseOrReturn<Output>> | Name of type of value this function outputs. | + +## Methods + +| Method | Description | +| --- | --- | +| [fn(input, args, context)](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.fn.md) | The actual implementation of the function. | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.name.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.name.md new file mode 100644 index 0000000000000..177b44aab4ce8 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.name.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionDefinition](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.md) > [name](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.name.md) + +## ExpressionFunctionDefinition.name property + +The name of the function, as will be used in expression. + +Signature: + +```typescript +name: Name; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.type.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.type.md new file mode 100644 index 0000000000000..a73ded342f053 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.type.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionDefinition](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.md) > [type](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.type.md) + +## ExpressionFunctionDefinition.type property + +Name of type of value this function outputs. + +Signature: + +```typescript +type?: TypeToString>; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.clog.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.clog.md new file mode 100644 index 0000000000000..0c01e93152c75 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.clog.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionDefinitions](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.md) > [clog](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.clog.md) + +## ExpressionFunctionDefinitions.clog property + +Signature: + +```typescript +clog: ExpressionFunctionClog; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.font.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.font.md new file mode 100644 index 0000000000000..842e3e069d91e --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.font.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionDefinitions](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.md) > [font](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.font.md) + +## ExpressionFunctionDefinitions.font property + +Signature: + +```typescript +font: ExpressionFunctionFont; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.kibana.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.kibana.md new file mode 100644 index 0000000000000..8e6d189f8f450 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.kibana.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionDefinitions](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.md) > [kibana](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.kibana.md) + +## ExpressionFunctionDefinitions.kibana property + +Signature: + +```typescript +kibana: ExpressionFunctionKibana; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.kibana_context.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.kibana_context.md new file mode 100644 index 0000000000000..f9e248ad6d913 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.kibana_context.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionDefinitions](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.md) > [kibana\_context](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.kibana_context.md) + +## ExpressionFunctionDefinitions.kibana\_context property + +Signature: + +```typescript +kibana_context: ExpressionFunctionKibanaContext; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.md new file mode 100644 index 0000000000000..71cd0b98a68c2 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.md @@ -0,0 +1,26 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionDefinitions](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.md) + +## ExpressionFunctionDefinitions interface + +A mapping of `ExpressionFunctionDefinition`s for functions which the Expressions services provides out-of-the-box. Any new functions registered by the Expressions plugin should have their types added here. + +Signature: + +```typescript +export interface ExpressionFunctionDefinitions +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [clog](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.clog.md) | ExpressionFunctionClog | | +| [font](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.font.md) | ExpressionFunctionFont | | +| [kibana\_context](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.kibana_context.md) | ExpressionFunctionKibanaContext | | +| [kibana](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.kibana.md) | ExpressionFunctionKibana | | +| [theme](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.theme.md) | ExpressionFunctionTheme | | +| [var\_set](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.var_set.md) | ExpressionFunctionVarSet | | +| [var](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.var.md) | ExpressionFunctionVar | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.theme.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.theme.md new file mode 100644 index 0000000000000..98291fe35c1aa --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.theme.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionDefinitions](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.md) > [theme](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.theme.md) + +## ExpressionFunctionDefinitions.theme property + +Signature: + +```typescript +theme: ExpressionFunctionTheme; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.var.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.var.md new file mode 100644 index 0000000000000..55d576193ba9c --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.var.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionDefinitions](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.md) > [var](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.var.md) + +## ExpressionFunctionDefinitions.var property + +Signature: + +```typescript +var: ExpressionFunctionVar; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.var_set.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.var_set.md new file mode 100644 index 0000000000000..3163cf1accab1 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.var_set.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionDefinitions](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.md) > [var\_set](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.var_set.md) + +## ExpressionFunctionDefinitions.var\_set property + +Signature: + +```typescript +var_set: ExpressionFunctionVarSet; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionkibana.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionkibana.md new file mode 100644 index 0000000000000..aac2ae1c3ca4e --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionkibana.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionKibana](./kibana-plugin-plugins-expressions-server.expressionfunctionkibana.md) + +## ExpressionFunctionKibana type + +Signature: + +```typescript +export declare type ExpressionFunctionKibana = ExpressionFunctionDefinition<'kibana', ExpressionValueSearchContext | null, object, ExpressionValueSearchContext>; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter._constructor_.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter._constructor_.md new file mode 100644 index 0000000000000..a9ad2069cfe15 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter._constructor_.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.md) > [(constructor)](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter._constructor_.md) + +## ExpressionFunctionParameter.(constructor) + +Constructs a new instance of the `ExpressionFunctionParameter` class + +Signature: + +```typescript +constructor(name: string, arg: ArgumentType); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| name | string | | +| arg | ArgumentType<any> | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.accepts.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.accepts.md new file mode 100644 index 0000000000000..083bbdf1da4e7 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.accepts.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.md) > [accepts](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.accepts.md) + +## ExpressionFunctionParameter.accepts() method + +Signature: + +```typescript +accepts(type: string): boolean; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| type | string | | + +Returns: + +`boolean` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.aliases.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.aliases.md new file mode 100644 index 0000000000000..c7d27a48bdad5 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.aliases.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.md) > [aliases](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.aliases.md) + +## ExpressionFunctionParameter.aliases property + +Signature: + +```typescript +aliases: string[]; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.default.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.default.md new file mode 100644 index 0000000000000..d4105febffe86 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.default.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.md) > [default](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.default.md) + +## ExpressionFunctionParameter.default property + +Signature: + +```typescript +default: any; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.help.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.help.md new file mode 100644 index 0000000000000..b21626df64121 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.help.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.md) > [help](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.help.md) + +## ExpressionFunctionParameter.help property + +Signature: + +```typescript +help: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.md new file mode 100644 index 0000000000000..e9e35183e4e76 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.md @@ -0,0 +1,38 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.md) + +## ExpressionFunctionParameter class + +Signature: + +```typescript +export declare class ExpressionFunctionParameter +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(name, arg)](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter._constructor_.md) | | Constructs a new instance of the ExpressionFunctionParameter class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [aliases](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.aliases.md) | | string[] | | +| [default](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.default.md) | | any | | +| [help](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.help.md) | | string | | +| [multi](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.multi.md) | | boolean | | +| [name](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.name.md) | | string | | +| [options](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.options.md) | | any[] | | +| [required](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.required.md) | | boolean | | +| [resolve](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.resolve.md) | | boolean | | +| [types](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.types.md) | | string[] | | + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [accepts(type)](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.accepts.md) | | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.multi.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.multi.md new file mode 100644 index 0000000000000..86e1921910a30 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.multi.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.md) > [multi](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.multi.md) + +## ExpressionFunctionParameter.multi property + +Signature: + +```typescript +multi: boolean; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.name.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.name.md new file mode 100644 index 0000000000000..8aab81d92e65a --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.name.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.md) > [name](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.name.md) + +## ExpressionFunctionParameter.name property + +Signature: + +```typescript +name: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.options.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.options.md new file mode 100644 index 0000000000000..95369ebd5ce88 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.options.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.md) > [options](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.options.md) + +## ExpressionFunctionParameter.options property + +Signature: + +```typescript +options: any[]; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.required.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.required.md new file mode 100644 index 0000000000000..0e58b41e2a22c --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.required.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.md) > [required](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.required.md) + +## ExpressionFunctionParameter.required property + +Signature: + +```typescript +required: boolean; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.resolve.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.resolve.md new file mode 100644 index 0000000000000..3415c5f6a7639 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.resolve.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.md) > [resolve](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.resolve.md) + +## ExpressionFunctionParameter.resolve property + +Signature: + +```typescript +resolve: boolean; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.types.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.types.md new file mode 100644 index 0000000000000..f7d6079705e8e --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionfunctionparameter.types.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.md) > [types](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.types.md) + +## ExpressionFunctionParameter.types property + +Signature: + +```typescript +types: string[]; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionimage.dataurl.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionimage.dataurl.md new file mode 100644 index 0000000000000..a51dc1eaea66f --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionimage.dataurl.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionImage](./kibana-plugin-plugins-expressions-server.expressionimage.md) > [dataurl](./kibana-plugin-plugins-expressions-server.expressionimage.dataurl.md) + +## ExpressionImage.dataurl property + +Signature: + +```typescript +dataurl: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionimage.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionimage.md new file mode 100644 index 0000000000000..7f323fba7bfe1 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionimage.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionImage](./kibana-plugin-plugins-expressions-server.expressionimage.md) + +## ExpressionImage interface + +Signature: + +```typescript +export interface ExpressionImage +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [dataurl](./kibana-plugin-plugins-expressions-server.expressionimage.dataurl.md) | string | | +| [mode](./kibana-plugin-plugins-expressions-server.expressionimage.mode.md) | string | | +| [type](./kibana-plugin-plugins-expressions-server.expressionimage.type.md) | 'image' | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionimage.mode.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionimage.mode.md new file mode 100644 index 0000000000000..9aae0ed3ea8b4 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionimage.mode.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionImage](./kibana-plugin-plugins-expressions-server.expressionimage.md) > [mode](./kibana-plugin-plugins-expressions-server.expressionimage.mode.md) + +## ExpressionImage.mode property + +Signature: + +```typescript +mode: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionimage.type.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionimage.type.md new file mode 100644 index 0000000000000..0cc0418228281 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionimage.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionImage](./kibana-plugin-plugins-expressions-server.expressionimage.md) > [type](./kibana-plugin-plugins-expressions-server.expressionimage.type.md) + +## ExpressionImage.type property + +Signature: + +```typescript +type: 'image'; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderdefinition.displayname.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderdefinition.displayname.md new file mode 100644 index 0000000000000..8ae5aa2f1790e --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderdefinition.displayname.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionRenderDefinition](./kibana-plugin-plugins-expressions-server.expressionrenderdefinition.md) > [displayName](./kibana-plugin-plugins-expressions-server.expressionrenderdefinition.displayname.md) + +## ExpressionRenderDefinition.displayName property + +A user friendly name of the renderer as will be displayed to user in UI. + +Signature: + +```typescript +displayName?: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderdefinition.help.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderdefinition.help.md new file mode 100644 index 0000000000000..971abba04fdf9 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderdefinition.help.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionRenderDefinition](./kibana-plugin-plugins-expressions-server.expressionrenderdefinition.md) > [help](./kibana-plugin-plugins-expressions-server.expressionrenderdefinition.help.md) + +## ExpressionRenderDefinition.help property + +Help text as will be displayed to user. A sentence or few about what this element does. + +Signature: + +```typescript +help?: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderdefinition.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderdefinition.md new file mode 100644 index 0000000000000..9cefb6ef196cf --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderdefinition.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionRenderDefinition](./kibana-plugin-plugins-expressions-server.expressionrenderdefinition.md) + +## ExpressionRenderDefinition interface + +Signature: + +```typescript +export interface ExpressionRenderDefinition +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [displayName](./kibana-plugin-plugins-expressions-server.expressionrenderdefinition.displayname.md) | string | A user friendly name of the renderer as will be displayed to user in UI. | +| [help](./kibana-plugin-plugins-expressions-server.expressionrenderdefinition.help.md) | string | Help text as will be displayed to user. A sentence or few about what this element does. | +| [name](./kibana-plugin-plugins-expressions-server.expressionrenderdefinition.name.md) | string | Technical name of the renderer, used as ID to identify renderer in expression renderer registry. This must match the name of the expression function that is used to create the type: render object. | +| [render](./kibana-plugin-plugins-expressions-server.expressionrenderdefinition.render.md) | (domNode: HTMLElement, config: Config, handlers: IInterpreterRenderHandlers) => void | Promise<void> | The function called to render the output data of an expression. | +| [reuseDomNode](./kibana-plugin-plugins-expressions-server.expressionrenderdefinition.reusedomnode.md) | boolean | Tell the renderer if the dom node should be reused, it's recreated each time by default. | +| [validate](./kibana-plugin-plugins-expressions-server.expressionrenderdefinition.validate.md) | () => undefined | Error | Used to validate the data before calling the render function. | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderdefinition.name.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderdefinition.name.md new file mode 100644 index 0000000000000..62eec0109c374 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderdefinition.name.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionRenderDefinition](./kibana-plugin-plugins-expressions-server.expressionrenderdefinition.md) > [name](./kibana-plugin-plugins-expressions-server.expressionrenderdefinition.name.md) + +## ExpressionRenderDefinition.name property + +Technical name of the renderer, used as ID to identify renderer in expression renderer registry. This must match the name of the expression function that is used to create the `type: render` object. + +Signature: + +```typescript +name: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderdefinition.render.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderdefinition.render.md new file mode 100644 index 0000000000000..99698e1828637 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderdefinition.render.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionRenderDefinition](./kibana-plugin-plugins-expressions-server.expressionrenderdefinition.md) > [render](./kibana-plugin-plugins-expressions-server.expressionrenderdefinition.render.md) + +## ExpressionRenderDefinition.render property + +The function called to render the output data of an expression. + +Signature: + +```typescript +render: (domNode: HTMLElement, config: Config, handlers: IInterpreterRenderHandlers) => void | Promise; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderdefinition.reusedomnode.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderdefinition.reusedomnode.md new file mode 100644 index 0000000000000..435920cccc642 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderdefinition.reusedomnode.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionRenderDefinition](./kibana-plugin-plugins-expressions-server.expressionrenderdefinition.md) > [reuseDomNode](./kibana-plugin-plugins-expressions-server.expressionrenderdefinition.reusedomnode.md) + +## ExpressionRenderDefinition.reuseDomNode property + +Tell the renderer if the dom node should be reused, it's recreated each time by default. + +Signature: + +```typescript +reuseDomNode: boolean; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderdefinition.validate.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderdefinition.validate.md new file mode 100644 index 0000000000000..f640744374eda --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderdefinition.validate.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionRenderDefinition](./kibana-plugin-plugins-expressions-server.expressionrenderdefinition.md) > [validate](./kibana-plugin-plugins-expressions-server.expressionrenderdefinition.validate.md) + +## ExpressionRenderDefinition.validate property + +Used to validate the data before calling the render function. + +Signature: + +```typescript +validate?: () => undefined | Error; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderer._constructor_.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderer._constructor_.md new file mode 100644 index 0000000000000..5db39853728af --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderer._constructor_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionRenderer](./kibana-plugin-plugins-expressions-server.expressionrenderer.md) > [(constructor)](./kibana-plugin-plugins-expressions-server.expressionrenderer._constructor_.md) + +## ExpressionRenderer.(constructor) + +Constructs a new instance of the `ExpressionRenderer` class + +Signature: + +```typescript +constructor(config: ExpressionRenderDefinition); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| config | ExpressionRenderDefinition<Config> | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderer.displayname.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderer.displayname.md new file mode 100644 index 0000000000000..41846bf41997f --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderer.displayname.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionRenderer](./kibana-plugin-plugins-expressions-server.expressionrenderer.md) > [displayName](./kibana-plugin-plugins-expressions-server.expressionrenderer.displayname.md) + +## ExpressionRenderer.displayName property + +Signature: + +```typescript +readonly displayName: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderer.help.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderer.help.md new file mode 100644 index 0000000000000..9cf60c832fb95 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderer.help.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionRenderer](./kibana-plugin-plugins-expressions-server.expressionrenderer.md) > [help](./kibana-plugin-plugins-expressions-server.expressionrenderer.help.md) + +## ExpressionRenderer.help property + +Signature: + +```typescript +readonly help: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderer.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderer.md new file mode 100644 index 0000000000000..6f5c336a89e5c --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderer.md @@ -0,0 +1,29 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionRenderer](./kibana-plugin-plugins-expressions-server.expressionrenderer.md) + +## ExpressionRenderer class + +Signature: + +```typescript +export declare class ExpressionRenderer +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(config)](./kibana-plugin-plugins-expressions-server.expressionrenderer._constructor_.md) | | Constructs a new instance of the ExpressionRenderer class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [displayName](./kibana-plugin-plugins-expressions-server.expressionrenderer.displayname.md) | | string | | +| [help](./kibana-plugin-plugins-expressions-server.expressionrenderer.help.md) | | string | | +| [name](./kibana-plugin-plugins-expressions-server.expressionrenderer.name.md) | | string | | +| [render](./kibana-plugin-plugins-expressions-server.expressionrenderer.render.md) | | ExpressionRenderDefinition<Config>['render'] | | +| [reuseDomNode](./kibana-plugin-plugins-expressions-server.expressionrenderer.reusedomnode.md) | | boolean | | +| [validate](./kibana-plugin-plugins-expressions-server.expressionrenderer.validate.md) | | () => void | Error | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderer.name.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderer.name.md new file mode 100644 index 0000000000000..f320fcd8408ab --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderer.name.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionRenderer](./kibana-plugin-plugins-expressions-server.expressionrenderer.md) > [name](./kibana-plugin-plugins-expressions-server.expressionrenderer.name.md) + +## ExpressionRenderer.name property + +Signature: + +```typescript +readonly name: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderer.render.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderer.render.md new file mode 100644 index 0000000000000..d7cf04e6d8bfa --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderer.render.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionRenderer](./kibana-plugin-plugins-expressions-server.expressionrenderer.md) > [render](./kibana-plugin-plugins-expressions-server.expressionrenderer.render.md) + +## ExpressionRenderer.render property + +Signature: + +```typescript +readonly render: ExpressionRenderDefinition['render']; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderer.reusedomnode.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderer.reusedomnode.md new file mode 100644 index 0000000000000..8fd9c5fa8e6ff --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderer.reusedomnode.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionRenderer](./kibana-plugin-plugins-expressions-server.expressionrenderer.md) > [reuseDomNode](./kibana-plugin-plugins-expressions-server.expressionrenderer.reusedomnode.md) + +## ExpressionRenderer.reuseDomNode property + +Signature: + +```typescript +readonly reuseDomNode: boolean; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderer.validate.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderer.validate.md new file mode 100644 index 0000000000000..d40945cfb88f1 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrenderer.validate.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionRenderer](./kibana-plugin-plugins-expressions-server.expressionrenderer.md) > [validate](./kibana-plugin-plugins-expressions-server.expressionrenderer.validate.md) + +## ExpressionRenderer.validate property + +Signature: + +```typescript +readonly validate: () => void | Error; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrendererregistry.get.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrendererregistry.get.md new file mode 100644 index 0000000000000..6f8e6c868ac9b --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrendererregistry.get.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionRendererRegistry](./kibana-plugin-plugins-expressions-server.expressionrendererregistry.md) > [get](./kibana-plugin-plugins-expressions-server.expressionrendererregistry.get.md) + +## ExpressionRendererRegistry.get() method + +Signature: + +```typescript +get(id: string): ExpressionRenderer | null; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| id | string | | + +Returns: + +`ExpressionRenderer | null` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrendererregistry.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrendererregistry.md new file mode 100644 index 0000000000000..d4a34ab140854 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrendererregistry.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionRendererRegistry](./kibana-plugin-plugins-expressions-server.expressionrendererregistry.md) + +## ExpressionRendererRegistry class + +Signature: + +```typescript +export declare class ExpressionRendererRegistry implements IRegistry +``` + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [get(id)](./kibana-plugin-plugins-expressions-server.expressionrendererregistry.get.md) | | | +| [register(definition)](./kibana-plugin-plugins-expressions-server.expressionrendererregistry.register.md) | | | +| [toArray()](./kibana-plugin-plugins-expressions-server.expressionrendererregistry.toarray.md) | | | +| [toJS()](./kibana-plugin-plugins-expressions-server.expressionrendererregistry.tojs.md) | | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrendererregistry.register.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrendererregistry.register.md new file mode 100644 index 0000000000000..d5411a327fbcd --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrendererregistry.register.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionRendererRegistry](./kibana-plugin-plugins-expressions-server.expressionrendererregistry.md) > [register](./kibana-plugin-plugins-expressions-server.expressionrendererregistry.register.md) + +## ExpressionRendererRegistry.register() method + +Signature: + +```typescript +register(definition: AnyExpressionRenderDefinition | (() => AnyExpressionRenderDefinition)): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| definition | AnyExpressionRenderDefinition | (() => AnyExpressionRenderDefinition) | | + +Returns: + +`void` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrendererregistry.toarray.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrendererregistry.toarray.md new file mode 100644 index 0000000000000..edb153000b458 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrendererregistry.toarray.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionRendererRegistry](./kibana-plugin-plugins-expressions-server.expressionrendererregistry.md) > [toArray](./kibana-plugin-plugins-expressions-server.expressionrendererregistry.toarray.md) + +## ExpressionRendererRegistry.toArray() method + +Signature: + +```typescript +toArray(): ExpressionRenderer[]; +``` +Returns: + +`ExpressionRenderer[]` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrendererregistry.tojs.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrendererregistry.tojs.md new file mode 100644 index 0000000000000..f7230e9102c8f --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionrendererregistry.tojs.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionRendererRegistry](./kibana-plugin-plugins-expressions-server.expressionrendererregistry.md) > [toJS](./kibana-plugin-plugins-expressions-server.expressionrendererregistry.tojs.md) + +## ExpressionRendererRegistry.toJS() method + +Signature: + +```typescript +toJS(): Record; +``` +Returns: + +`Record` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserverplugin._constructor_.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserverplugin._constructor_.md new file mode 100644 index 0000000000000..639ae379f0ed7 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserverplugin._constructor_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionsServerPlugin](./kibana-plugin-plugins-expressions-server.expressionsserverplugin.md) > [(constructor)](./kibana-plugin-plugins-expressions-server.expressionsserverplugin._constructor_.md) + +## ExpressionsServerPlugin.(constructor) + +Constructs a new instance of the `ExpressionsServerPlugin` class + +Signature: + +```typescript +constructor(initializerContext: PluginInitializerContext); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| initializerContext | PluginInitializerContext | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserverplugin.expressions.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserverplugin.expressions.md new file mode 100644 index 0000000000000..a391220a6349e --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserverplugin.expressions.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionsServerPlugin](./kibana-plugin-plugins-expressions-server.expressionsserverplugin.md) > [expressions](./kibana-plugin-plugins-expressions-server.expressionsserverplugin.expressions.md) + +## ExpressionsServerPlugin.expressions property + +Signature: + +```typescript +readonly expressions: ExpressionsService; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserverplugin.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserverplugin.md new file mode 100644 index 0000000000000..f92d572b1111a --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserverplugin.md @@ -0,0 +1,32 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionsServerPlugin](./kibana-plugin-plugins-expressions-server.expressionsserverplugin.md) + +## ExpressionsServerPlugin class + +Signature: + +```typescript +export declare class ExpressionsServerPlugin implements Plugin +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(initializerContext)](./kibana-plugin-plugins-expressions-server.expressionsserverplugin._constructor_.md) | | Constructs a new instance of the ExpressionsServerPlugin class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [expressions](./kibana-plugin-plugins-expressions-server.expressionsserverplugin.expressions.md) | | ExpressionsService | | + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [setup(core)](./kibana-plugin-plugins-expressions-server.expressionsserverplugin.setup.md) | | | +| [start(core)](./kibana-plugin-plugins-expressions-server.expressionsserverplugin.start.md) | | | +| [stop()](./kibana-plugin-plugins-expressions-server.expressionsserverplugin.stop.md) | | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserverplugin.setup.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserverplugin.setup.md new file mode 100644 index 0000000000000..18e33d4e0bc60 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserverplugin.setup.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionsServerPlugin](./kibana-plugin-plugins-expressions-server.expressionsserverplugin.md) > [setup](./kibana-plugin-plugins-expressions-server.expressionsserverplugin.setup.md) + +## ExpressionsServerPlugin.setup() method + +Signature: + +```typescript +setup(core: CoreSetup): ExpressionsServerSetup; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| core | CoreSetup | | + +Returns: + +`ExpressionsServerSetup` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserverplugin.start.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserverplugin.start.md new file mode 100644 index 0000000000000..31578685ff386 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserverplugin.start.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionsServerPlugin](./kibana-plugin-plugins-expressions-server.expressionsserverplugin.md) > [start](./kibana-plugin-plugins-expressions-server.expressionsserverplugin.start.md) + +## ExpressionsServerPlugin.start() method + +Signature: + +```typescript +start(core: CoreStart): ExpressionsServerStart; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| core | CoreStart | | + +Returns: + +`ExpressionsServerStart` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserverplugin.stop.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserverplugin.stop.md new file mode 100644 index 0000000000000..2f6abade901b1 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserverplugin.stop.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionsServerPlugin](./kibana-plugin-plugins-expressions-server.expressionsserverplugin.md) > [stop](./kibana-plugin-plugins-expressions-server.expressionsserverplugin.stop.md) + +## ExpressionsServerPlugin.stop() method + +Signature: + +```typescript +stop(): void; +``` +Returns: + +`void` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserversetup.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserversetup.md new file mode 100644 index 0000000000000..2cf591a59c4f6 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserversetup.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionsServerSetup](./kibana-plugin-plugins-expressions-server.expressionsserversetup.md) + +## ExpressionsServerSetup type + +Signature: + +```typescript +export declare type ExpressionsServerSetup = ExpressionsServiceSetup; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserverstart.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserverstart.md new file mode 100644 index 0000000000000..9ceb261a7f689 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionsserverstart.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionsServerStart](./kibana-plugin-plugins-expressions-server.expressionsserverstart.md) + +## ExpressionsServerStart type + +Signature: + +```typescript +export declare type ExpressionsServerStart = ExpressionsServiceStart; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype._constructor_.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype._constructor_.md new file mode 100644 index 0000000000000..966955c03ff08 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype._constructor_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionType](./kibana-plugin-plugins-expressions-server.expressiontype.md) > [(constructor)](./kibana-plugin-plugins-expressions-server.expressiontype._constructor_.md) + +## ExpressionType.(constructor) + +Constructs a new instance of the `ExpressionType` class + +Signature: + +```typescript +constructor(definition: AnyExpressionTypeDefinition); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| definition | AnyExpressionTypeDefinition | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.castsfrom.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.castsfrom.md new file mode 100644 index 0000000000000..57758e8fa7788 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.castsfrom.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionType](./kibana-plugin-plugins-expressions-server.expressiontype.md) > [castsFrom](./kibana-plugin-plugins-expressions-server.expressiontype.castsfrom.md) + +## ExpressionType.castsFrom property + +Signature: + +```typescript +castsFrom: (value: ExpressionValue) => boolean; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.caststo.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.caststo.md new file mode 100644 index 0000000000000..eec17f8606817 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.caststo.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionType](./kibana-plugin-plugins-expressions-server.expressiontype.md) > [castsTo](./kibana-plugin-plugins-expressions-server.expressiontype.caststo.md) + +## ExpressionType.castsTo property + +Signature: + +```typescript +castsTo: (value: ExpressionValue) => boolean; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.create.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.create.md new file mode 100644 index 0000000000000..3fbd1f7986254 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.create.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionType](./kibana-plugin-plugins-expressions-server.expressiontype.md) > [create](./kibana-plugin-plugins-expressions-server.expressiontype.create.md) + +## ExpressionType.create property + +Signature: + +```typescript +create: unknown; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.deserialize.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.deserialize.md new file mode 100644 index 0000000000000..232d70b846092 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.deserialize.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionType](./kibana-plugin-plugins-expressions-server.expressiontype.md) > [deserialize](./kibana-plugin-plugins-expressions-server.expressiontype.deserialize.md) + +## ExpressionType.deserialize property + +Signature: + +```typescript +deserialize?: (serialized: any) => ExpressionValue; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.from.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.from.md new file mode 100644 index 0000000000000..4d24a4162c096 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.from.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionType](./kibana-plugin-plugins-expressions-server.expressiontype.md) > [from](./kibana-plugin-plugins-expressions-server.expressiontype.from.md) + +## ExpressionType.from property + +Signature: + +```typescript +from: (value: ExpressionValue, types: Record) => any; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.getfromfn.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.getfromfn.md new file mode 100644 index 0000000000000..092227af92a19 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.getfromfn.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionType](./kibana-plugin-plugins-expressions-server.expressiontype.md) > [getFromFn](./kibana-plugin-plugins-expressions-server.expressiontype.getfromfn.md) + +## ExpressionType.getFromFn property + +Signature: + +```typescript +getFromFn: (typeName: string) => undefined | ExpressionValueConverter; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.gettofn.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.gettofn.md new file mode 100644 index 0000000000000..8454116f50ac8 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.gettofn.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionType](./kibana-plugin-plugins-expressions-server.expressiontype.md) > [getToFn](./kibana-plugin-plugins-expressions-server.expressiontype.gettofn.md) + +## ExpressionType.getToFn property + +Signature: + +```typescript +getToFn: (typeName: string) => undefined | ExpressionValueConverter; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.help.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.help.md new file mode 100644 index 0000000000000..bd5be7329d6a4 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.help.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionType](./kibana-plugin-plugins-expressions-server.expressiontype.md) > [help](./kibana-plugin-plugins-expressions-server.expressiontype.help.md) + +## ExpressionType.help property + +A short help text. + +Signature: + +```typescript +help: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.md new file mode 100644 index 0000000000000..49f3f504c9419 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.md @@ -0,0 +1,35 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionType](./kibana-plugin-plugins-expressions-server.expressiontype.md) + +## ExpressionType class + +Signature: + +```typescript +export declare class ExpressionType +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(definition)](./kibana-plugin-plugins-expressions-server.expressiontype._constructor_.md) | | Constructs a new instance of the ExpressionType class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [castsFrom](./kibana-plugin-plugins-expressions-server.expressiontype.castsfrom.md) | | (value: ExpressionValue) => boolean | | +| [castsTo](./kibana-plugin-plugins-expressions-server.expressiontype.caststo.md) | | (value: ExpressionValue) => boolean | | +| [create](./kibana-plugin-plugins-expressions-server.expressiontype.create.md) | | unknown | | +| [deserialize](./kibana-plugin-plugins-expressions-server.expressiontype.deserialize.md) | | (serialized: any) => ExpressionValue | | +| [from](./kibana-plugin-plugins-expressions-server.expressiontype.from.md) | | (value: ExpressionValue, types: Record<string, ExpressionType>) => any | | +| [getFromFn](./kibana-plugin-plugins-expressions-server.expressiontype.getfromfn.md) | | (typeName: string) => undefined | ExpressionValueConverter<ExpressionValue, ExpressionValue> | | +| [getToFn](./kibana-plugin-plugins-expressions-server.expressiontype.gettofn.md) | | (typeName: string) => undefined | ExpressionValueConverter<ExpressionValue, ExpressionValue> | | +| [help](./kibana-plugin-plugins-expressions-server.expressiontype.help.md) | | string | A short help text. | +| [name](./kibana-plugin-plugins-expressions-server.expressiontype.name.md) | | string | | +| [serialize](./kibana-plugin-plugins-expressions-server.expressiontype.serialize.md) | | (value: ExpressionValue) => any | Optional serialization (used when passing context around client/server). | +| [to](./kibana-plugin-plugins-expressions-server.expressiontype.to.md) | | (value: ExpressionValue, toTypeName: string, types: Record<string, ExpressionType>) => any | | +| [validate](./kibana-plugin-plugins-expressions-server.expressiontype.validate.md) | | (type: any) => void | Error | Type validation, useful for checking function output. | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.name.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.name.md new file mode 100644 index 0000000000000..44e0e18270b14 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.name.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionType](./kibana-plugin-plugins-expressions-server.expressiontype.md) > [name](./kibana-plugin-plugins-expressions-server.expressiontype.name.md) + +## ExpressionType.name property + +Signature: + +```typescript +name: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.serialize.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.serialize.md new file mode 100644 index 0000000000000..013b95bf2d0ce --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.serialize.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionType](./kibana-plugin-plugins-expressions-server.expressiontype.md) > [serialize](./kibana-plugin-plugins-expressions-server.expressiontype.serialize.md) + +## ExpressionType.serialize property + +Optional serialization (used when passing context around client/server). + +Signature: + +```typescript +serialize?: (value: ExpressionValue) => any; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.to.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.to.md new file mode 100644 index 0000000000000..70e4504324f22 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.to.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionType](./kibana-plugin-plugins-expressions-server.expressiontype.md) > [to](./kibana-plugin-plugins-expressions-server.expressiontype.to.md) + +## ExpressionType.to property + +Signature: + +```typescript +to: (value: ExpressionValue, toTypeName: string, types: Record) => any; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.validate.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.validate.md new file mode 100644 index 0000000000000..6e1fd681a732b --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontype.validate.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionType](./kibana-plugin-plugins-expressions-server.expressiontype.md) > [validate](./kibana-plugin-plugins-expressions-server.expressiontype.validate.md) + +## ExpressionType.validate property + +Type validation, useful for checking function output. + +Signature: + +```typescript +validate: (type: any) => void | Error; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypedefinition.deserialize.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypedefinition.deserialize.md new file mode 100644 index 0000000000000..71e9ecd7270d9 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypedefinition.deserialize.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionTypeDefinition](./kibana-plugin-plugins-expressions-server.expressiontypedefinition.md) > [deserialize](./kibana-plugin-plugins-expressions-server.expressiontypedefinition.deserialize.md) + +## ExpressionTypeDefinition.deserialize property + +Signature: + +```typescript +deserialize?: (type: SerializedType) => Value; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypedefinition.from.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypedefinition.from.md new file mode 100644 index 0000000000000..f3ad8791c7bac --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypedefinition.from.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionTypeDefinition](./kibana-plugin-plugins-expressions-server.expressiontypedefinition.md) > [from](./kibana-plugin-plugins-expressions-server.expressiontypedefinition.from.md) + +## ExpressionTypeDefinition.from property + +Signature: + +```typescript +from?: { + [type: string]: ExpressionValueConverter; + }; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypedefinition.help.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypedefinition.help.md new file mode 100644 index 0000000000000..f1c4d48599da6 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypedefinition.help.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionTypeDefinition](./kibana-plugin-plugins-expressions-server.expressiontypedefinition.md) > [help](./kibana-plugin-plugins-expressions-server.expressiontypedefinition.help.md) + +## ExpressionTypeDefinition.help property + +Signature: + +```typescript +help?: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypedefinition.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypedefinition.md new file mode 100644 index 0000000000000..5179bd1df7311 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypedefinition.md @@ -0,0 +1,26 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionTypeDefinition](./kibana-plugin-plugins-expressions-server.expressiontypedefinition.md) + +## ExpressionTypeDefinition interface + +A generic type which represents a custom Expression Type Definition that's registered to the Interpreter. + +Signature: + +```typescript +export interface ExpressionTypeDefinition +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [deserialize](./kibana-plugin-plugins-expressions-server.expressiontypedefinition.deserialize.md) | (type: SerializedType) => Value | | +| [from](./kibana-plugin-plugins-expressions-server.expressiontypedefinition.from.md) | {
[type: string]: ExpressionValueConverter<any, Value>;
} | | +| [help](./kibana-plugin-plugins-expressions-server.expressiontypedefinition.help.md) | string | | +| [name](./kibana-plugin-plugins-expressions-server.expressiontypedefinition.name.md) | Name | | +| [serialize](./kibana-plugin-plugins-expressions-server.expressiontypedefinition.serialize.md) | (type: Value) => SerializedType | | +| [to](./kibana-plugin-plugins-expressions-server.expressiontypedefinition.to.md) | {
[type: string]: ExpressionValueConverter<Value, any>;
} | | +| [validate](./kibana-plugin-plugins-expressions-server.expressiontypedefinition.validate.md) | (type: any) => void | Error | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypedefinition.name.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypedefinition.name.md new file mode 100644 index 0000000000000..cfc1cebac16da --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypedefinition.name.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionTypeDefinition](./kibana-plugin-plugins-expressions-server.expressiontypedefinition.md) > [name](./kibana-plugin-plugins-expressions-server.expressiontypedefinition.name.md) + +## ExpressionTypeDefinition.name property + +Signature: + +```typescript +name: Name; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypedefinition.serialize.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypedefinition.serialize.md new file mode 100644 index 0000000000000..05ec569f62638 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypedefinition.serialize.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionTypeDefinition](./kibana-plugin-plugins-expressions-server.expressiontypedefinition.md) > [serialize](./kibana-plugin-plugins-expressions-server.expressiontypedefinition.serialize.md) + +## ExpressionTypeDefinition.serialize property + +Signature: + +```typescript +serialize?: (type: Value) => SerializedType; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypedefinition.to.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypedefinition.to.md new file mode 100644 index 0000000000000..6c2c22fc902c6 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypedefinition.to.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionTypeDefinition](./kibana-plugin-plugins-expressions-server.expressiontypedefinition.md) > [to](./kibana-plugin-plugins-expressions-server.expressiontypedefinition.to.md) + +## ExpressionTypeDefinition.to property + +Signature: + +```typescript +to?: { + [type: string]: ExpressionValueConverter; + }; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypedefinition.validate.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypedefinition.validate.md new file mode 100644 index 0000000000000..acdcf089fcbe0 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypedefinition.validate.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionTypeDefinition](./kibana-plugin-plugins-expressions-server.expressiontypedefinition.md) > [validate](./kibana-plugin-plugins-expressions-server.expressiontypedefinition.validate.md) + +## ExpressionTypeDefinition.validate property + +Signature: + +```typescript +validate?: (type: any) => void | Error; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypestyle.css.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypestyle.css.md new file mode 100644 index 0000000000000..7cb6e9bc8b45d --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypestyle.css.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionTypeStyle](./kibana-plugin-plugins-expressions-server.expressiontypestyle.md) > [css](./kibana-plugin-plugins-expressions-server.expressiontypestyle.css.md) + +## ExpressionTypeStyle.css property + +Signature: + +```typescript +css: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypestyle.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypestyle.md new file mode 100644 index 0000000000000..274e9b7b6772c --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypestyle.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionTypeStyle](./kibana-plugin-plugins-expressions-server.expressiontypestyle.md) + +## ExpressionTypeStyle interface + +An object that represents style information, typically CSS. + +Signature: + +```typescript +export interface ExpressionTypeStyle +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [css](./kibana-plugin-plugins-expressions-server.expressiontypestyle.css.md) | string | | +| [spec](./kibana-plugin-plugins-expressions-server.expressiontypestyle.spec.md) | CSSStyle | | +| [type](./kibana-plugin-plugins-expressions-server.expressiontypestyle.type.md) | 'style' | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypestyle.spec.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypestyle.spec.md new file mode 100644 index 0000000000000..95f3edbc2b725 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypestyle.spec.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionTypeStyle](./kibana-plugin-plugins-expressions-server.expressiontypestyle.md) > [spec](./kibana-plugin-plugins-expressions-server.expressiontypestyle.spec.md) + +## ExpressionTypeStyle.spec property + +Signature: + +```typescript +spec: CSSStyle; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypestyle.type.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypestyle.type.md new file mode 100644 index 0000000000000..be3b476cb8b53 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressiontypestyle.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionTypeStyle](./kibana-plugin-plugins-expressions-server.expressiontypestyle.md) > [type](./kibana-plugin-plugins-expressions-server.expressiontypestyle.type.md) + +## ExpressionTypeStyle.type property + +Signature: + +```typescript +type: 'style'; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvalue.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvalue.md new file mode 100644 index 0000000000000..fc9af5fbc6695 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvalue.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionValue](./kibana-plugin-plugins-expressions-server.expressionvalue.md) + +## ExpressionValue type + +Signature: + +```typescript +export declare type ExpressionValue = ExpressionValueUnboxed | ExpressionValueBoxed; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvalueboxed.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvalueboxed.md new file mode 100644 index 0000000000000..ad84aec0dc6d5 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvalueboxed.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionValueBoxed](./kibana-plugin-plugins-expressions-server.expressionvalueboxed.md) + +## ExpressionValueBoxed type + +Signature: + +```typescript +export declare type ExpressionValueBoxed = { + type: Type; +} & Value; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvalueconverter.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvalueconverter.md new file mode 100644 index 0000000000000..d1b69590141cb --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvalueconverter.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionValueConverter](./kibana-plugin-plugins-expressions-server.expressionvalueconverter.md) + +## ExpressionValueConverter type + +Signature: + +```typescript +export declare type ExpressionValueConverter = (input: I, availableTypes: Record) => O; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvalueerror.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvalueerror.md new file mode 100644 index 0000000000000..b90e4360e055a --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvalueerror.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionValueError](./kibana-plugin-plugins-expressions-server.expressionvalueerror.md) + +## ExpressionValueError type + +Signature: + +```typescript +export declare type ExpressionValueError = ExpressionValueBoxed<'error', { + error: { + message: string; + type?: string; + name?: string; + stack?: string; + original?: Error; + }; + info?: unknown; +}>; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvaluefilter.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvaluefilter.md new file mode 100644 index 0000000000000..fb65bc2550513 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvaluefilter.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionValueFilter](./kibana-plugin-plugins-expressions-server.expressionvaluefilter.md) + +## ExpressionValueFilter type + +Represents an object that is a Filter. + +Signature: + +```typescript +export declare type ExpressionValueFilter = ExpressionValueBoxed<'filter', { + filterType?: string; + value?: string; + column?: string; + and: ExpressionValueFilter[]; + to?: string; + from?: string; + query?: string | null; +}>; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvaluenum.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvaluenum.md new file mode 100644 index 0000000000000..b109a23dc7259 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvaluenum.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionValueNum](./kibana-plugin-plugins-expressions-server.expressionvaluenum.md) + +## ExpressionValueNum type + +Signature: + +```typescript +export declare type ExpressionValueNum = ExpressionValueBoxed<'num', { + value: number; +}>; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvaluerender.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvaluerender.md new file mode 100644 index 0000000000000..96958d753a78e --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvaluerender.md @@ -0,0 +1,16 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionValueRender](./kibana-plugin-plugins-expressions-server.expressionvaluerender.md) + +## ExpressionValueRender type + +Represents an object that is intended to be rendered. + +Signature: + +```typescript +export declare type ExpressionValueRender = ExpressionValueBoxed; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvaluesearchcontext.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvaluesearchcontext.md new file mode 100644 index 0000000000000..6e38adde3ba91 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvaluesearchcontext.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionValueSearchContext](./kibana-plugin-plugins-expressions-server.expressionvaluesearchcontext.md) + +## ExpressionValueSearchContext type + +Signature: + +```typescript +export declare type ExpressionValueSearchContext = ExpressionValueBoxed<'kibana_context', ExecutionContextSearch>; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvalueunboxed.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvalueunboxed.md new file mode 100644 index 0000000000000..2393b2bb70e6b --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.expressionvalueunboxed.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [ExpressionValueUnboxed](./kibana-plugin-plugins-expressions-server.expressionvalueunboxed.md) + +## ExpressionValueUnboxed type + +Signature: + +```typescript +export declare type ExpressionValueUnboxed = any; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.font.label.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.font.label.md new file mode 100644 index 0000000000000..5f11f866be2f6 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.font.label.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Font](./kibana-plugin-plugins-expressions-server.font.md) > [label](./kibana-plugin-plugins-expressions-server.font.label.md) + +## Font.label property + +Signature: + +```typescript +label: FontLabel; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.font.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.font.md new file mode 100644 index 0000000000000..f3ff25e034624 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.font.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Font](./kibana-plugin-plugins-expressions-server.font.md) + +## Font interface + +An interface representing a font in Canvas, with a textual label and the CSS `font-value`. + +Signature: + +```typescript +export interface Font +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [label](./kibana-plugin-plugins-expressions-server.font.label.md) | FontLabel | | +| [value](./kibana-plugin-plugins-expressions-server.font.value.md) | FontValue | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.font.value.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.font.value.md new file mode 100644 index 0000000000000..1bb1fac163661 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.font.value.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Font](./kibana-plugin-plugins-expressions-server.font.md) > [value](./kibana-plugin-plugins-expressions-server.font.value.md) + +## Font.value property + +Signature: + +```typescript +value: FontValue; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.fontlabel.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.fontlabel.md new file mode 100644 index 0000000000000..4837abb7542fa --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.fontlabel.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [FontLabel](./kibana-plugin-plugins-expressions-server.fontlabel.md) + +## FontLabel type + +This type contains a unions of all supported font labels, or the the name of the font the user would see in a UI. + +Signature: + +```typescript +export declare type FontLabel = typeof fonts[number]['label']; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.fontstyle.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.fontstyle.md new file mode 100644 index 0000000000000..26588096666df --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.fontstyle.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [FontStyle](./kibana-plugin-plugins-expressions-server.fontstyle.md) + +## FontStyle enum + +Enum of supported CSS `font-style` properties. + +Signature: + +```typescript +export declare enum FontStyle +``` + +## Enumeration Members + +| Member | Value | Description | +| --- | --- | --- | +| ITALIC | "italic" | | +| NORMAL | "normal" | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.fontvalue.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.fontvalue.md new file mode 100644 index 0000000000000..6c0332067a369 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.fontvalue.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [FontValue](./kibana-plugin-plugins-expressions-server.fontvalue.md) + +## FontValue type + +This type contains a union of all supported font values, equivalent to the CSS `font-value` property. + +Signature: + +```typescript +export declare type FontValue = typeof fonts[number]['value']; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.fontweight.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.fontweight.md new file mode 100644 index 0000000000000..314e4b17df01e --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.fontweight.md @@ -0,0 +1,32 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [FontWeight](./kibana-plugin-plugins-expressions-server.fontweight.md) + +## FontWeight enum + +Enum of supported CSS `font-weight` properties. + +Signature: + +```typescript +export declare enum FontWeight +``` + +## Enumeration Members + +| Member | Value | Description | +| --- | --- | --- | +| BOLD | "bold" | | +| BOLDER | "bolder" | | +| EIGHT | "800" | | +| FIVE | "500" | | +| FOUR | "400" | | +| LIGHTER | "lighter" | | +| NINE | "900" | | +| NORMAL | "normal" | | +| ONE | "100" | | +| SEVEN | "700" | | +| SIX | "600" | | +| THREE | "300" | | +| TWO | "200" | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.format.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.format.md new file mode 100644 index 0000000000000..aae8498bce03f --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.format.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [format](./kibana-plugin-plugins-expressions-server.format.md) + +## format() function + +Signature: + +```typescript +export declare function format(ast: T, type: T extends ExpressionAstExpression ? 'expression' : 'argument'): string; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| ast | T | | +| type | T extends ExpressionAstExpression ? 'expression' : 'argument' | | + +Returns: + +`string` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.formatexpression.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.formatexpression.md new file mode 100644 index 0000000000000..701d7b448f69f --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.formatexpression.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [formatExpression](./kibana-plugin-plugins-expressions-server.formatexpression.md) + +## formatExpression() function + +Given expression pipeline AST, returns formatted string. + +Signature: + +```typescript +export declare function formatExpression(ast: ExpressionAstExpression): string; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| ast | ExpressionAstExpression | | + +Returns: + +`string` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.functionsregistry._constructor_.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.functionsregistry._constructor_.md new file mode 100644 index 0000000000000..c3dc8b8e9b16f --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.functionsregistry._constructor_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [FunctionsRegistry](./kibana-plugin-plugins-expressions-server.functionsregistry.md) > [(constructor)](./kibana-plugin-plugins-expressions-server.functionsregistry._constructor_.md) + +## FunctionsRegistry.(constructor) + +Constructs a new instance of the `FunctionsRegistry` class + +Signature: + +```typescript +constructor(executor: Executor); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| executor | Executor<any> | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.functionsregistry.get.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.functionsregistry.get.md new file mode 100644 index 0000000000000..795b3a87eac09 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.functionsregistry.get.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [FunctionsRegistry](./kibana-plugin-plugins-expressions-server.functionsregistry.md) > [get](./kibana-plugin-plugins-expressions-server.functionsregistry.get.md) + +## FunctionsRegistry.get() method + +Signature: + +```typescript +get(id: string): ExpressionFunction | null; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| id | string | | + +Returns: + +`ExpressionFunction | null` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.functionsregistry.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.functionsregistry.md new file mode 100644 index 0000000000000..790105c68241a --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.functionsregistry.md @@ -0,0 +1,27 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [FunctionsRegistry](./kibana-plugin-plugins-expressions-server.functionsregistry.md) + +## FunctionsRegistry class + +Signature: + +```typescript +export declare class FunctionsRegistry implements IRegistry +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(executor)](./kibana-plugin-plugins-expressions-server.functionsregistry._constructor_.md) | | Constructs a new instance of the FunctionsRegistry class | + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [get(id)](./kibana-plugin-plugins-expressions-server.functionsregistry.get.md) | | | +| [register(functionDefinition)](./kibana-plugin-plugins-expressions-server.functionsregistry.register.md) | | | +| [toArray()](./kibana-plugin-plugins-expressions-server.functionsregistry.toarray.md) | | | +| [toJS()](./kibana-plugin-plugins-expressions-server.functionsregistry.tojs.md) | | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.functionsregistry.register.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.functionsregistry.register.md new file mode 100644 index 0000000000000..7da47937e80f0 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.functionsregistry.register.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [FunctionsRegistry](./kibana-plugin-plugins-expressions-server.functionsregistry.md) > [register](./kibana-plugin-plugins-expressions-server.functionsregistry.register.md) + +## FunctionsRegistry.register() method + +Signature: + +```typescript +register(functionDefinition: AnyExpressionFunctionDefinition | (() => AnyExpressionFunctionDefinition)): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| functionDefinition | AnyExpressionFunctionDefinition | (() => AnyExpressionFunctionDefinition) | | + +Returns: + +`void` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.functionsregistry.toarray.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.functionsregistry.toarray.md new file mode 100644 index 0000000000000..5f9ca38990076 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.functionsregistry.toarray.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [FunctionsRegistry](./kibana-plugin-plugins-expressions-server.functionsregistry.md) > [toArray](./kibana-plugin-plugins-expressions-server.functionsregistry.toarray.md) + +## FunctionsRegistry.toArray() method + +Signature: + +```typescript +toArray(): ExpressionFunction[]; +``` +Returns: + +`ExpressionFunction[]` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.functionsregistry.tojs.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.functionsregistry.tojs.md new file mode 100644 index 0000000000000..35751bb534e58 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.functionsregistry.tojs.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [FunctionsRegistry](./kibana-plugin-plugins-expressions-server.functionsregistry.md) > [toJS](./kibana-plugin-plugins-expressions-server.functionsregistry.tojs.md) + +## FunctionsRegistry.toJS() method + +Signature: + +```typescript +toJS(): Record; +``` +Returns: + +`Record` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.done.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.done.md new file mode 100644 index 0000000000000..c6204769e893c --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.done.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [IInterpreterRenderHandlers](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.md) > [done](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.done.md) + +## IInterpreterRenderHandlers.done property + +Done increments the number of rendering successes + +Signature: + +```typescript +done: () => void; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.event.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.event.md new file mode 100644 index 0000000000000..6a011aaf7f132 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.event.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [IInterpreterRenderHandlers](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.md) > [event](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.event.md) + +## IInterpreterRenderHandlers.event property + +Signature: + +```typescript +event: (event: any) => void; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.md new file mode 100644 index 0000000000000..cbaffa04bae8f --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [IInterpreterRenderHandlers](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.md) + +## IInterpreterRenderHandlers interface + +Signature: + +```typescript +export interface IInterpreterRenderHandlers +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [done](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.done.md) | () => void | Done increments the number of rendering successes | +| [event](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.event.md) | (event: any) => void | | +| [onDestroy](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.ondestroy.md) | (fn: () => void) => void | | +| [reload](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.reload.md) | () => void | | +| [update](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.update.md) | (params: any) => void | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.ondestroy.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.ondestroy.md new file mode 100644 index 0000000000000..14ef98d17769c --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.ondestroy.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [IInterpreterRenderHandlers](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.md) > [onDestroy](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.ondestroy.md) + +## IInterpreterRenderHandlers.onDestroy property + +Signature: + +```typescript +onDestroy: (fn: () => void) => void; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.reload.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.reload.md new file mode 100644 index 0000000000000..c5e74e79f652b --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.reload.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [IInterpreterRenderHandlers](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.md) > [reload](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.reload.md) + +## IInterpreterRenderHandlers.reload property + +Signature: + +```typescript +reload: () => void; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.update.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.update.md new file mode 100644 index 0000000000000..2649ea99b3386 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.update.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [IInterpreterRenderHandlers](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.md) > [update](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.update.md) + +## IInterpreterRenderHandlers.update property + +Signature: + +```typescript +update: (params: any) => void; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.interpretererrortype.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.interpretererrortype.md new file mode 100644 index 0000000000000..032cea643c5bf --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.interpretererrortype.md @@ -0,0 +1,16 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [InterpreterErrorType](./kibana-plugin-plugins-expressions-server.interpretererrortype.md) + +## InterpreterErrorType type + +> Warning: This API is now obsolete. +> +> Exported for backwards compatibility. +> + +Signature: + +```typescript +export declare type InterpreterErrorType = ExpressionValueError; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iregistry.get.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iregistry.get.md new file mode 100644 index 0000000000000..b0b4524afe40a --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iregistry.get.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [IRegistry](./kibana-plugin-plugins-expressions-server.iregistry.md) > [get](./kibana-plugin-plugins-expressions-server.iregistry.get.md) + +## IRegistry.get() method + +Signature: + +```typescript +get(id: string): T | null; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| id | string | | + +Returns: + +`T | null` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iregistry.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iregistry.md new file mode 100644 index 0000000000000..71aafe2db2dd1 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iregistry.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [IRegistry](./kibana-plugin-plugins-expressions-server.iregistry.md) + +## IRegistry interface + +Signature: + +```typescript +export interface IRegistry +``` + +## Methods + +| Method | Description | +| --- | --- | +| [get(id)](./kibana-plugin-plugins-expressions-server.iregistry.get.md) | | +| [toArray()](./kibana-plugin-plugins-expressions-server.iregistry.toarray.md) | | +| [toJS()](./kibana-plugin-plugins-expressions-server.iregistry.tojs.md) | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iregistry.toarray.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iregistry.toarray.md new file mode 100644 index 0000000000000..73718cd036c85 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iregistry.toarray.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [IRegistry](./kibana-plugin-plugins-expressions-server.iregistry.md) > [toArray](./kibana-plugin-plugins-expressions-server.iregistry.toarray.md) + +## IRegistry.toArray() method + +Signature: + +```typescript +toArray(): T[]; +``` +Returns: + +`T[]` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iregistry.tojs.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iregistry.tojs.md new file mode 100644 index 0000000000000..af83efbd99aa7 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iregistry.tojs.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [IRegistry](./kibana-plugin-plugins-expressions-server.iregistry.md) > [toJS](./kibana-plugin-plugins-expressions-server.iregistry.tojs.md) + +## IRegistry.toJS() method + +Signature: + +```typescript +toJS(): Record; +``` +Returns: + +`Record` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.isexpressionastbuilder.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.isexpressionastbuilder.md new file mode 100644 index 0000000000000..7692ff21ae934 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.isexpressionastbuilder.md @@ -0,0 +1,28 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [isExpressionAstBuilder](./kibana-plugin-plugins-expressions-server.isexpressionastbuilder.md) + +## isExpressionAstBuilder() function + +Type guard that checks whether a given value is an `ExpressionAstExpressionBuilder`. This is useful when working with subexpressions, where you might be retrieving a function argument, and need to know whether it is an expression builder instance which you can perform operations on. + +Signature: + +```typescript +export declare function isExpressionAstBuilder(val: any): val is ExpressionAstExpressionBuilder; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| val | any | | + +Returns: + +`val is ExpressionAstExpressionBuilder` + +## Example + +const arg = myFunction.getArgument('foo'); if (isExpressionAstBuilder(foo)) { foo.toAst(); } + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibana_context_name.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibana_context_name.md new file mode 100644 index 0000000000000..bd47c52e0d5ce --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibana_context_name.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [KIBANA\_CONTEXT\_NAME](./kibana-plugin-plugins-expressions-server.kibana_context_name.md) + +## KIBANA\_CONTEXT\_NAME type + +Signature: + +```typescript +export declare type KIBANA_CONTEXT_NAME = 'kibana_context'; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanacontext.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanacontext.md new file mode 100644 index 0000000000000..023748173e7dd --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanacontext.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [KibanaContext](./kibana-plugin-plugins-expressions-server.kibanacontext.md) + +## KibanaContext type + +Signature: + +```typescript +export declare type KibanaContext = ExpressionValueSearchContext; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatable.columns.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatable.columns.md new file mode 100644 index 0000000000000..423e543e4307a --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatable.columns.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [KibanaDatatable](./kibana-plugin-plugins-expressions-server.kibanadatatable.md) > [columns](./kibana-plugin-plugins-expressions-server.kibanadatatable.columns.md) + +## KibanaDatatable.columns property + +Signature: + +```typescript +columns: KibanaDatatableColumn[]; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatable.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatable.md new file mode 100644 index 0000000000000..30ee3ac2fcd13 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatable.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [KibanaDatatable](./kibana-plugin-plugins-expressions-server.kibanadatatable.md) + +## KibanaDatatable interface + +Signature: + +```typescript +export interface KibanaDatatable +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [columns](./kibana-plugin-plugins-expressions-server.kibanadatatable.columns.md) | KibanaDatatableColumn[] | | +| [rows](./kibana-plugin-plugins-expressions-server.kibanadatatable.rows.md) | KibanaDatatableRow[] | | +| [type](./kibana-plugin-plugins-expressions-server.kibanadatatable.type.md) | typeof name | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatable.rows.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatable.rows.md new file mode 100644 index 0000000000000..42170a83fc3c8 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatable.rows.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [KibanaDatatable](./kibana-plugin-plugins-expressions-server.kibanadatatable.md) > [rows](./kibana-plugin-plugins-expressions-server.kibanadatatable.rows.md) + +## KibanaDatatable.rows property + +Signature: + +```typescript +rows: KibanaDatatableRow[]; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatable.type.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatable.type.md new file mode 100644 index 0000000000000..c36674540a1ba --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatable.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [KibanaDatatable](./kibana-plugin-plugins-expressions-server.kibanadatatable.md) > [type](./kibana-plugin-plugins-expressions-server.kibanadatatable.type.md) + +## KibanaDatatable.type property + +Signature: + +```typescript +type: typeof name; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.formathint.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.formathint.md new file mode 100644 index 0000000000000..a1e6949019dcb --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.formathint.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [KibanaDatatableColumn](./kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.md) > [formatHint](./kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.formathint.md) + +## KibanaDatatableColumn.formatHint property + +Signature: + +```typescript +formatHint?: SerializedFieldFormat; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.id.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.id.md new file mode 100644 index 0000000000000..6f90da1ac9c94 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.id.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [KibanaDatatableColumn](./kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.md) > [id](./kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.id.md) + +## KibanaDatatableColumn.id property + +Signature: + +```typescript +id: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.md new file mode 100644 index 0000000000000..171477911502f --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [KibanaDatatableColumn](./kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.md) + +## KibanaDatatableColumn interface + +Signature: + +```typescript +export interface KibanaDatatableColumn +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [formatHint](./kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.formathint.md) | SerializedFieldFormat | | +| [id](./kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.id.md) | string | | +| [meta](./kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.meta.md) | KibanaDatatableColumnMeta | | +| [name](./kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.name.md) | string | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.meta.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.meta.md new file mode 100644 index 0000000000000..40b20d51e6ec6 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.meta.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [KibanaDatatableColumn](./kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.md) > [meta](./kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.meta.md) + +## KibanaDatatableColumn.meta property + +Signature: + +```typescript +meta?: KibanaDatatableColumnMeta; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.name.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.name.md new file mode 100644 index 0000000000000..3a85e2325483a --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.name.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [KibanaDatatableColumn](./kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.md) > [name](./kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.name.md) + +## KibanaDatatableColumn.name property + +Signature: + +```typescript +name: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumnmeta.aggconfigparams.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumnmeta.aggconfigparams.md new file mode 100644 index 0000000000000..539b24174f725 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumnmeta.aggconfigparams.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [KibanaDatatableColumnMeta](./kibana-plugin-plugins-expressions-server.kibanadatatablecolumnmeta.md) > [aggConfigParams](./kibana-plugin-plugins-expressions-server.kibanadatatablecolumnmeta.aggconfigparams.md) + +## KibanaDatatableColumnMeta.aggConfigParams property + +Signature: + +```typescript +aggConfigParams?: Record; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumnmeta.indexpatternid.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumnmeta.indexpatternid.md new file mode 100644 index 0000000000000..2704915a15071 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumnmeta.indexpatternid.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [KibanaDatatableColumnMeta](./kibana-plugin-plugins-expressions-server.kibanadatatablecolumnmeta.md) > [indexPatternId](./kibana-plugin-plugins-expressions-server.kibanadatatablecolumnmeta.indexpatternid.md) + +## KibanaDatatableColumnMeta.indexPatternId property + +Signature: + +```typescript +indexPatternId?: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumnmeta.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumnmeta.md new file mode 100644 index 0000000000000..d9a96e665f010 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumnmeta.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [KibanaDatatableColumnMeta](./kibana-plugin-plugins-expressions-server.kibanadatatablecolumnmeta.md) + +## KibanaDatatableColumnMeta interface + +Signature: + +```typescript +export interface KibanaDatatableColumnMeta +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [aggConfigParams](./kibana-plugin-plugins-expressions-server.kibanadatatablecolumnmeta.aggconfigparams.md) | Record<string, any> | | +| [indexPatternId](./kibana-plugin-plugins-expressions-server.kibanadatatablecolumnmeta.indexpatternid.md) | string | | +| [type](./kibana-plugin-plugins-expressions-server.kibanadatatablecolumnmeta.type.md) | string | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumnmeta.type.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumnmeta.type.md new file mode 100644 index 0000000000000..56e3757ef621a --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablecolumnmeta.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [KibanaDatatableColumnMeta](./kibana-plugin-plugins-expressions-server.kibanadatatablecolumnmeta.md) > [type](./kibana-plugin-plugins-expressions-server.kibanadatatablecolumnmeta.type.md) + +## KibanaDatatableColumnMeta.type property + +Signature: + +```typescript +type: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablerow.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablerow.md new file mode 100644 index 0000000000000..dd0f3f4cb2f60 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.kibanadatatablerow.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [KibanaDatatableRow](./kibana-plugin-plugins-expressions-server.kibanadatatablerow.md) + +## KibanaDatatableRow interface + +Signature: + +```typescript +export interface KibanaDatatableRow +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.knowntypetostring.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.knowntypetostring.md new file mode 100644 index 0000000000000..ed536ac3b7173 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.knowntypetostring.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [KnownTypeToString](./kibana-plugin-plugins-expressions-server.knowntypetostring.md) + +## KnownTypeToString type + +Map the type of the generic to a string-based representation of the type. + +If the provided generic is its own type interface, we use the value of the `type` key as a string literal type for it. + +Signature: + +```typescript +export declare type KnownTypeToString = T extends string ? 'string' : T extends boolean ? 'boolean' : T extends number ? 'number' : T extends null ? 'null' : T extends { + type: string; +} ? T['type'] : never; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.md new file mode 100644 index 0000000000000..c9fed2e00c66c --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.md @@ -0,0 +1,116 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) + +## kibana-plugin-plugins-expressions-server package + +## Classes + +| Class | Description | +| --- | --- | +| [Execution](./kibana-plugin-plugins-expressions-server.execution.md) | | +| [Executor](./kibana-plugin-plugins-expressions-server.executor.md) | | +| [ExpressionFunction](./kibana-plugin-plugins-expressions-server.expressionfunction.md) | | +| [ExpressionFunctionParameter](./kibana-plugin-plugins-expressions-server.expressionfunctionparameter.md) | | +| [ExpressionRenderer](./kibana-plugin-plugins-expressions-server.expressionrenderer.md) | | +| [ExpressionRendererRegistry](./kibana-plugin-plugins-expressions-server.expressionrendererregistry.md) | | +| [ExpressionsServerPlugin](./kibana-plugin-plugins-expressions-server.expressionsserverplugin.md) | | +| [ExpressionType](./kibana-plugin-plugins-expressions-server.expressiontype.md) | | +| [FunctionsRegistry](./kibana-plugin-plugins-expressions-server.functionsregistry.md) | | +| [TypesRegistry](./kibana-plugin-plugins-expressions-server.typesregistry.md) | | + +## Enumerations + +| Enumeration | Description | +| --- | --- | +| [FontStyle](./kibana-plugin-plugins-expressions-server.fontstyle.md) | Enum of supported CSS font-style properties. | +| [FontWeight](./kibana-plugin-plugins-expressions-server.fontweight.md) | Enum of supported CSS font-weight properties. | +| [Overflow](./kibana-plugin-plugins-expressions-server.overflow.md) | Enum of supported CSS overflow properties. | +| [TextAlignment](./kibana-plugin-plugins-expressions-server.textalignment.md) | Enum of supported CSS text-align properties. | +| [TextDecoration](./kibana-plugin-plugins-expressions-server.textdecoration.md) | Enum of supported CSS text-decoration properties. | + +## Functions + +| Function | Description | +| --- | --- | +| [buildExpression(initialState)](./kibana-plugin-plugins-expressions-server.buildexpression.md) | Makes it easy to progressively build, update, and traverse an expression AST. You can either start with an empty AST, or provide an expression string, AST, or array of expression function builders to use as initial state. | +| [buildExpressionFunction(fnName, initialArgs)](./kibana-plugin-plugins-expressions-server.buildexpressionfunction.md) | Manages an AST for a single expression function. The return value can be provided to buildExpression to add this function to an expression.Note that to preserve type safety and ensure no args are missing, all required arguments for the specified function must be provided up front. If desired, they can be changed or removed later. | +| [format(ast, type)](./kibana-plugin-plugins-expressions-server.format.md) | | +| [formatExpression(ast)](./kibana-plugin-plugins-expressions-server.formatexpression.md) | Given expression pipeline AST, returns formatted string. | +| [isExpressionAstBuilder(val)](./kibana-plugin-plugins-expressions-server.isexpressionastbuilder.md) | Type guard that checks whether a given value is an ExpressionAstExpressionBuilder. This is useful when working with subexpressions, where you might be retrieving a function argument, and need to know whether it is an expression builder instance which you can perform operations on. | +| [parse(expression, startRule)](./kibana-plugin-plugins-expressions-server.parse.md) | | +| [parseExpression(expression)](./kibana-plugin-plugins-expressions-server.parseexpression.md) | Given expression pipeline string, returns parsed AST. | +| [plugin(initializerContext)](./kibana-plugin-plugins-expressions-server.plugin.md) | | + +## Interfaces + +| Interface | Description | +| --- | --- | +| [Datatable](./kibana-plugin-plugins-expressions-server.datatable.md) | A Datatable in Canvas is a unique structure that represents tabulated data. | +| [DatatableColumn](./kibana-plugin-plugins-expressions-server.datatablecolumn.md) | This type represents the shape of a column in a Datatable. | +| [ExecutionContext](./kibana-plugin-plugins-expressions-server.executioncontext.md) | ExecutionContext is an object available to all functions during a single execution; it provides various methods to perform side-effects. | +| [ExecutionParams](./kibana-plugin-plugins-expressions-server.executionparams.md) | | +| [ExecutionState](./kibana-plugin-plugins-expressions-server.executionstate.md) | | +| [ExecutorState](./kibana-plugin-plugins-expressions-server.executorstate.md) | | +| [ExpressionAstExpression](./kibana-plugin-plugins-expressions-server.expressionastexpression.md) | | +| [ExpressionAstExpressionBuilder](./kibana-plugin-plugins-expressions-server.expressionastexpressionbuilder.md) | | +| [ExpressionAstFunction](./kibana-plugin-plugins-expressions-server.expressionastfunction.md) | | +| [ExpressionAstFunctionBuilder](./kibana-plugin-plugins-expressions-server.expressionastfunctionbuilder.md) | | +| [ExpressionFunctionDefinition](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinition.md) | ExpressionFunctionDefinition is the interface plugins have to implement to register a function in expressions plugin. | +| [ExpressionFunctionDefinitions](./kibana-plugin-plugins-expressions-server.expressionfunctiondefinitions.md) | A mapping of ExpressionFunctionDefinitions for functions which the Expressions services provides out-of-the-box. Any new functions registered by the Expressions plugin should have their types added here. | +| [ExpressionImage](./kibana-plugin-plugins-expressions-server.expressionimage.md) | | +| [ExpressionRenderDefinition](./kibana-plugin-plugins-expressions-server.expressionrenderdefinition.md) | | +| [ExpressionTypeDefinition](./kibana-plugin-plugins-expressions-server.expressiontypedefinition.md) | A generic type which represents a custom Expression Type Definition that's registered to the Interpreter. | +| [ExpressionTypeStyle](./kibana-plugin-plugins-expressions-server.expressiontypestyle.md) | An object that represents style information, typically CSS. | +| [Font](./kibana-plugin-plugins-expressions-server.font.md) | An interface representing a font in Canvas, with a textual label and the CSS font-value. | +| [IInterpreterRenderHandlers](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.md) | | +| [IRegistry](./kibana-plugin-plugins-expressions-server.iregistry.md) | | +| [KibanaDatatable](./kibana-plugin-plugins-expressions-server.kibanadatatable.md) | | +| [KibanaDatatableColumn](./kibana-plugin-plugins-expressions-server.kibanadatatablecolumn.md) | | +| [KibanaDatatableColumnMeta](./kibana-plugin-plugins-expressions-server.kibanadatatablecolumnmeta.md) | | +| [KibanaDatatableRow](./kibana-plugin-plugins-expressions-server.kibanadatatablerow.md) | | +| [PointSeriesColumn](./kibana-plugin-plugins-expressions-server.pointseriescolumn.md) | Column in a PointSeries | +| [Range](./kibana-plugin-plugins-expressions-server.range.md) | | +| [SerializedDatatable](./kibana-plugin-plugins-expressions-server.serializeddatatable.md) | | +| [SerializedFieldFormat](./kibana-plugin-plugins-expressions-server.serializedfieldformat.md) | JSON representation of a field formatter configuration. Is used to carry information about how to format data in a data table as part of the column definition. | + +## Type Aliases + +| Type Alias | Description | +| --- | --- | +| [AnyExpressionFunctionDefinition](./kibana-plugin-plugins-expressions-server.anyexpressionfunctiondefinition.md) | Type to capture every possible expression function definition. | +| [AnyExpressionTypeDefinition](./kibana-plugin-plugins-expressions-server.anyexpressiontypedefinition.md) | | +| [ArgumentType](./kibana-plugin-plugins-expressions-server.argumenttype.md) | This type represents all of the possible combinations of properties of an Argument in an Expression Function. The presence or absence of certain fields influence the shape and presence of others within each arg in the specification. | +| [DatatableColumnType](./kibana-plugin-plugins-expressions-server.datatablecolumntype.md) | This type represents the type of any DatatableColumn in a Datatable. | +| [DatatableRow](./kibana-plugin-plugins-expressions-server.datatablerow.md) | This type represents a row in a Datatable. | +| [ExecutionContainer](./kibana-plugin-plugins-expressions-server.executioncontainer.md) | | +| [ExecutorContainer](./kibana-plugin-plugins-expressions-server.executorcontainer.md) | | +| [ExpressionAstArgument](./kibana-plugin-plugins-expressions-server.expressionastargument.md) | | +| [ExpressionAstNode](./kibana-plugin-plugins-expressions-server.expressionastnode.md) | | +| [ExpressionFunctionKibana](./kibana-plugin-plugins-expressions-server.expressionfunctionkibana.md) | | +| [ExpressionsServerSetup](./kibana-plugin-plugins-expressions-server.expressionsserversetup.md) | | +| [ExpressionsServerStart](./kibana-plugin-plugins-expressions-server.expressionsserverstart.md) | | +| [ExpressionValue](./kibana-plugin-plugins-expressions-server.expressionvalue.md) | | +| [ExpressionValueBoxed](./kibana-plugin-plugins-expressions-server.expressionvalueboxed.md) | | +| [ExpressionValueConverter](./kibana-plugin-plugins-expressions-server.expressionvalueconverter.md) | | +| [ExpressionValueError](./kibana-plugin-plugins-expressions-server.expressionvalueerror.md) | | +| [ExpressionValueFilter](./kibana-plugin-plugins-expressions-server.expressionvaluefilter.md) | Represents an object that is a Filter. | +| [ExpressionValueNum](./kibana-plugin-plugins-expressions-server.expressionvaluenum.md) | | +| [ExpressionValueRender](./kibana-plugin-plugins-expressions-server.expressionvaluerender.md) | Represents an object that is intended to be rendered. | +| [ExpressionValueSearchContext](./kibana-plugin-plugins-expressions-server.expressionvaluesearchcontext.md) | | +| [ExpressionValueUnboxed](./kibana-plugin-plugins-expressions-server.expressionvalueunboxed.md) | | +| [FontLabel](./kibana-plugin-plugins-expressions-server.fontlabel.md) | This type contains a unions of all supported font labels, or the the name of the font the user would see in a UI. | +| [FontValue](./kibana-plugin-plugins-expressions-server.fontvalue.md) | This type contains a union of all supported font values, equivalent to the CSS font-value property. | +| [InterpreterErrorType](./kibana-plugin-plugins-expressions-server.interpretererrortype.md) | | +| [KIBANA\_CONTEXT\_NAME](./kibana-plugin-plugins-expressions-server.kibana_context_name.md) | | +| [KibanaContext](./kibana-plugin-plugins-expressions-server.kibanacontext.md) | | +| [KnownTypeToString](./kibana-plugin-plugins-expressions-server.knowntypetostring.md) | Map the type of the generic to a string-based representation of the type.If the provided generic is its own type interface, we use the value of the type key as a string literal type for it. | +| [PointSeries](./kibana-plugin-plugins-expressions-server.pointseries.md) | A PointSeries is a unique structure that represents dots on a chart. | +| [PointSeriesColumnName](./kibana-plugin-plugins-expressions-server.pointseriescolumnname.md) | Allowed column names in a PointSeries | +| [PointSeriesColumns](./kibana-plugin-plugins-expressions-server.pointseriescolumns.md) | Represents a collection of valid Columns in a PointSeries | +| [PointSeriesRow](./kibana-plugin-plugins-expressions-server.pointseriesrow.md) | | +| [Style](./kibana-plugin-plugins-expressions-server.style.md) | | +| [TypeString](./kibana-plugin-plugins-expressions-server.typestring.md) | If the type extends a Promise, we still need to return the string representation:someArgument: Promise<boolean | string> results in types: ['boolean', 'string'] | +| [TypeToString](./kibana-plugin-plugins-expressions-server.typetostring.md) | This can convert a type into a known Expression string representation of that type. For example, TypeToString<Datatable> will resolve to 'datatable'. This allows Expression Functions to continue to specify their type in a simple string format. | +| [UnmappedTypeStrings](./kibana-plugin-plugins-expressions-server.unmappedtypestrings.md) | Types used in Expressions that don't map to a primitive cleanly:date is typed as a number or string, and represents a date | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.overflow.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.overflow.md new file mode 100644 index 0000000000000..2b1d1a34cd46a --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.overflow.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Overflow](./kibana-plugin-plugins-expressions-server.overflow.md) + +## Overflow enum + +Enum of supported CSS `overflow` properties. + +Signature: + +```typescript +export declare enum Overflow +``` + +## Enumeration Members + +| Member | Value | Description | +| --- | --- | --- | +| AUTO | "auto" | | +| HIDDEN | "hidden" | | +| SCROLL | "scroll" | | +| VISIBLE | "visible" | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.parse.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.parse.md new file mode 100644 index 0000000000000..ec2534986006f --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.parse.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [parse](./kibana-plugin-plugins-expressions-server.parse.md) + +## parse() function + +Signature: + +```typescript +export declare function parse(expression: E, startRule: S): S extends 'expression' ? ExpressionAstExpression : ExpressionAstArgument; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| expression | E | | +| startRule | S | | + +Returns: + +`S extends 'expression' ? ExpressionAstExpression : ExpressionAstArgument` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.parseexpression.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.parseexpression.md new file mode 100644 index 0000000000000..0d8547fd5243b --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.parseexpression.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [parseExpression](./kibana-plugin-plugins-expressions-server.parseexpression.md) + +## parseExpression() function + +Given expression pipeline string, returns parsed AST. + +Signature: + +```typescript +export declare function parseExpression(expression: string): ExpressionAstExpression; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| expression | string | | + +Returns: + +`ExpressionAstExpression` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.plugin.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.plugin.md new file mode 100644 index 0000000000000..79a7100ebf540 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.plugin.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [plugin](./kibana-plugin-plugins-expressions-server.plugin.md) + +## plugin() function + +Signature: + +```typescript +export declare function plugin(initializerContext: PluginInitializerContext): ExpressionsServerPlugin; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| initializerContext | PluginInitializerContext | | + +Returns: + +`ExpressionsServerPlugin` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.pointseries.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.pointseries.md new file mode 100644 index 0000000000000..f65efd705666d --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.pointseries.md @@ -0,0 +1,16 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [PointSeries](./kibana-plugin-plugins-expressions-server.pointseries.md) + +## PointSeries type + +A `PointSeries` is a unique structure that represents dots on a chart. + +Signature: + +```typescript +export declare type PointSeries = ExpressionValueBoxed<'pointseries', { + columns: PointSeriesColumns; + rows: PointSeriesRow[]; +}>; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.pointseriescolumn.expression.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.pointseriescolumn.expression.md new file mode 100644 index 0000000000000..c857a9f29fa60 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.pointseriescolumn.expression.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [PointSeriesColumn](./kibana-plugin-plugins-expressions-server.pointseriescolumn.md) > [expression](./kibana-plugin-plugins-expressions-server.pointseriescolumn.expression.md) + +## PointSeriesColumn.expression property + +Signature: + +```typescript +expression: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.pointseriescolumn.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.pointseriescolumn.md new file mode 100644 index 0000000000000..5aec683421dd1 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.pointseriescolumn.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [PointSeriesColumn](./kibana-plugin-plugins-expressions-server.pointseriescolumn.md) + +## PointSeriesColumn interface + +Column in a PointSeries + +Signature: + +```typescript +export interface PointSeriesColumn +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [expression](./kibana-plugin-plugins-expressions-server.pointseriescolumn.expression.md) | string | | +| [role](./kibana-plugin-plugins-expressions-server.pointseriescolumn.role.md) | 'measure' | 'dimension' | | +| [type](./kibana-plugin-plugins-expressions-server.pointseriescolumn.type.md) | 'number' | 'string' | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.pointseriescolumn.role.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.pointseriescolumn.role.md new file mode 100644 index 0000000000000..1f6b770ecba15 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.pointseriescolumn.role.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [PointSeriesColumn](./kibana-plugin-plugins-expressions-server.pointseriescolumn.md) > [role](./kibana-plugin-plugins-expressions-server.pointseriescolumn.role.md) + +## PointSeriesColumn.role property + +Signature: + +```typescript +role: 'measure' | 'dimension'; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.pointseriescolumn.type.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.pointseriescolumn.type.md new file mode 100644 index 0000000000000..5cb51f460d722 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.pointseriescolumn.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [PointSeriesColumn](./kibana-plugin-plugins-expressions-server.pointseriescolumn.md) > [type](./kibana-plugin-plugins-expressions-server.pointseriescolumn.type.md) + +## PointSeriesColumn.type property + +Signature: + +```typescript +type: 'number' | 'string'; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.pointseriescolumnname.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.pointseriescolumnname.md new file mode 100644 index 0000000000000..2d8522b30903c --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.pointseriescolumnname.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [PointSeriesColumnName](./kibana-plugin-plugins-expressions-server.pointseriescolumnname.md) + +## PointSeriesColumnName type + +Allowed column names in a PointSeries + +Signature: + +```typescript +export declare type PointSeriesColumnName = 'x' | 'y' | 'color' | 'size' | 'text'; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.pointseriescolumns.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.pointseriescolumns.md new file mode 100644 index 0000000000000..f6eee6e2bc9d1 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.pointseriescolumns.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [PointSeriesColumns](./kibana-plugin-plugins-expressions-server.pointseriescolumns.md) + +## PointSeriesColumns type + +Represents a collection of valid Columns in a PointSeries + +Signature: + +```typescript +export declare type PointSeriesColumns = Record | {}; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.pointseriesrow.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.pointseriesrow.md new file mode 100644 index 0000000000000..d9a77305e9f99 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.pointseriesrow.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [PointSeriesRow](./kibana-plugin-plugins-expressions-server.pointseriesrow.md) + +## PointSeriesRow type + +Signature: + +```typescript +export declare type PointSeriesRow = Record; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.range.from.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.range.from.md new file mode 100644 index 0000000000000..f349681c1472f --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.range.from.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Range](./kibana-plugin-plugins-expressions-server.range.md) > [from](./kibana-plugin-plugins-expressions-server.range.from.md) + +## Range.from property + +Signature: + +```typescript +from: number; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.range.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.range.md new file mode 100644 index 0000000000000..d369d882757fc --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.range.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Range](./kibana-plugin-plugins-expressions-server.range.md) + +## Range interface + +Signature: + +```typescript +export interface Range +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [from](./kibana-plugin-plugins-expressions-server.range.from.md) | number | | +| [to](./kibana-plugin-plugins-expressions-server.range.to.md) | number | | +| [type](./kibana-plugin-plugins-expressions-server.range.type.md) | typeof name | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.range.to.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.range.to.md new file mode 100644 index 0000000000000..c5a1fe2fe2080 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.range.to.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Range](./kibana-plugin-plugins-expressions-server.range.md) > [to](./kibana-plugin-plugins-expressions-server.range.to.md) + +## Range.to property + +Signature: + +```typescript +to: number; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.range.type.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.range.type.md new file mode 100644 index 0000000000000..dd856dc0eb713 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.range.type.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Range](./kibana-plugin-plugins-expressions-server.range.md) > [type](./kibana-plugin-plugins-expressions-server.range.type.md) + +## Range.type property + +Signature: + +```typescript +type: typeof name; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.serializeddatatable.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.serializeddatatable.md new file mode 100644 index 0000000000000..12951f9323503 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.serializeddatatable.md @@ -0,0 +1,18 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [SerializedDatatable](./kibana-plugin-plugins-expressions-server.serializeddatatable.md) + +## SerializedDatatable interface + +Signature: + +```typescript +export interface SerializedDatatable extends Datatable +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [rows](./kibana-plugin-plugins-expressions-server.serializeddatatable.rows.md) | string[][] | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.serializeddatatable.rows.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.serializeddatatable.rows.md new file mode 100644 index 0000000000000..e82504f153f6b --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.serializeddatatable.rows.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [SerializedDatatable](./kibana-plugin-plugins-expressions-server.serializeddatatable.md) > [rows](./kibana-plugin-plugins-expressions-server.serializeddatatable.rows.md) + +## SerializedDatatable.rows property + +Signature: + +```typescript +rows: string[][]; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.serializedfieldformat.id.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.serializedfieldformat.id.md new file mode 100644 index 0000000000000..def3296aedcf7 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.serializedfieldformat.id.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [SerializedFieldFormat](./kibana-plugin-plugins-expressions-server.serializedfieldformat.md) > [id](./kibana-plugin-plugins-expressions-server.serializedfieldformat.id.md) + +## SerializedFieldFormat.id property + +Signature: + +```typescript +id?: string; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.serializedfieldformat.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.serializedfieldformat.md new file mode 100644 index 0000000000000..c62e830ccf7b9 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.serializedfieldformat.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [SerializedFieldFormat](./kibana-plugin-plugins-expressions-server.serializedfieldformat.md) + +## SerializedFieldFormat interface + +JSON representation of a field formatter configuration. Is used to carry information about how to format data in a data table as part of the column definition. + +Signature: + +```typescript +export interface SerializedFieldFormat> +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [id](./kibana-plugin-plugins-expressions-server.serializedfieldformat.id.md) | string | | +| [params](./kibana-plugin-plugins-expressions-server.serializedfieldformat.params.md) | TParams | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.serializedfieldformat.params.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.serializedfieldformat.params.md new file mode 100644 index 0000000000000..8861f729aa2b1 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.serializedfieldformat.params.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [SerializedFieldFormat](./kibana-plugin-plugins-expressions-server.serializedfieldformat.md) > [params](./kibana-plugin-plugins-expressions-server.serializedfieldformat.params.md) + +## SerializedFieldFormat.params property + +Signature: + +```typescript +params?: TParams; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.style.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.style.md new file mode 100644 index 0000000000000..e43addfd5ff30 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.style.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [Style](./kibana-plugin-plugins-expressions-server.style.md) + +## Style type + +Signature: + +```typescript +export declare type Style = ExpressionTypeStyle; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.textalignment.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.textalignment.md new file mode 100644 index 0000000000000..2adc12371b4be --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.textalignment.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [TextAlignment](./kibana-plugin-plugins-expressions-server.textalignment.md) + +## TextAlignment enum + +Enum of supported CSS `text-align` properties. + +Signature: + +```typescript +export declare enum TextAlignment +``` + +## Enumeration Members + +| Member | Value | Description | +| --- | --- | --- | +| CENTER | "center" | | +| JUSTIFY | "justify" | | +| LEFT | "left" | | +| RIGHT | "right" | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.textdecoration.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.textdecoration.md new file mode 100644 index 0000000000000..98d9b38547baf --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.textdecoration.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [TextDecoration](./kibana-plugin-plugins-expressions-server.textdecoration.md) + +## TextDecoration enum + +Enum of supported CSS `text-decoration` properties. + +Signature: + +```typescript +export declare enum TextDecoration +``` + +## Enumeration Members + +| Member | Value | Description | +| --- | --- | --- | +| NONE | "none" | | +| UNDERLINE | "underline" | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.typesregistry._constructor_.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.typesregistry._constructor_.md new file mode 100644 index 0000000000000..87290d88214d0 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.typesregistry._constructor_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [TypesRegistry](./kibana-plugin-plugins-expressions-server.typesregistry.md) > [(constructor)](./kibana-plugin-plugins-expressions-server.typesregistry._constructor_.md) + +## TypesRegistry.(constructor) + +Constructs a new instance of the `TypesRegistry` class + +Signature: + +```typescript +constructor(executor: Executor); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| executor | Executor<any> | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.typesregistry.get.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.typesregistry.get.md new file mode 100644 index 0000000000000..c8d674eab50cd --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.typesregistry.get.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [TypesRegistry](./kibana-plugin-plugins-expressions-server.typesregistry.md) > [get](./kibana-plugin-plugins-expressions-server.typesregistry.get.md) + +## TypesRegistry.get() method + +Signature: + +```typescript +get(id: string): ExpressionType | null; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| id | string | | + +Returns: + +`ExpressionType | null` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.typesregistry.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.typesregistry.md new file mode 100644 index 0000000000000..2c4d75e020035 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.typesregistry.md @@ -0,0 +1,27 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [TypesRegistry](./kibana-plugin-plugins-expressions-server.typesregistry.md) + +## TypesRegistry class + +Signature: + +```typescript +export declare class TypesRegistry implements IRegistry +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(executor)](./kibana-plugin-plugins-expressions-server.typesregistry._constructor_.md) | | Constructs a new instance of the TypesRegistry class | + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [get(id)](./kibana-plugin-plugins-expressions-server.typesregistry.get.md) | | | +| [register(typeDefinition)](./kibana-plugin-plugins-expressions-server.typesregistry.register.md) | | | +| [toArray()](./kibana-plugin-plugins-expressions-server.typesregistry.toarray.md) | | | +| [toJS()](./kibana-plugin-plugins-expressions-server.typesregistry.tojs.md) | | | + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.typesregistry.register.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.typesregistry.register.md new file mode 100644 index 0000000000000..935a862407dfe --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.typesregistry.register.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [TypesRegistry](./kibana-plugin-plugins-expressions-server.typesregistry.md) > [register](./kibana-plugin-plugins-expressions-server.typesregistry.register.md) + +## TypesRegistry.register() method + +Signature: + +```typescript +register(typeDefinition: AnyExpressionTypeDefinition | (() => AnyExpressionTypeDefinition)): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| typeDefinition | AnyExpressionTypeDefinition | (() => AnyExpressionTypeDefinition) | | + +Returns: + +`void` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.typesregistry.toarray.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.typesregistry.toarray.md new file mode 100644 index 0000000000000..e3c6b13a22a58 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.typesregistry.toarray.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [TypesRegistry](./kibana-plugin-plugins-expressions-server.typesregistry.md) > [toArray](./kibana-plugin-plugins-expressions-server.typesregistry.toarray.md) + +## TypesRegistry.toArray() method + +Signature: + +```typescript +toArray(): ExpressionType[]; +``` +Returns: + +`ExpressionType[]` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.typesregistry.tojs.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.typesregistry.tojs.md new file mode 100644 index 0000000000000..2ff258bd54e44 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.typesregistry.tojs.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [TypesRegistry](./kibana-plugin-plugins-expressions-server.typesregistry.md) > [toJS](./kibana-plugin-plugins-expressions-server.typesregistry.tojs.md) + +## TypesRegistry.toJS() method + +Signature: + +```typescript +toJS(): Record; +``` +Returns: + +`Record` + diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.typestring.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.typestring.md new file mode 100644 index 0000000000000..af4d5ae0bf814 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.typestring.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [TypeString](./kibana-plugin-plugins-expressions-server.typestring.md) + +## TypeString type + +If the type extends a Promise, we still need to return the string representation: + +`someArgument: Promise` results in `types: ['boolean', 'string']` + +Signature: + +```typescript +export declare type TypeString = KnownTypeToString>; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.typetostring.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.typetostring.md new file mode 100644 index 0000000000000..578438c03a0e5 --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.typetostring.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [TypeToString](./kibana-plugin-plugins-expressions-server.typetostring.md) + +## TypeToString type + +This can convert a type into a known Expression string representation of that type. For example, `TypeToString` will resolve to `'datatable'`. This allows Expression Functions to continue to specify their type in a simple string format. + +Signature: + +```typescript +export declare type TypeToString = KnownTypeToString | UnmappedTypeStrings; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.unmappedtypestrings.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.unmappedtypestrings.md new file mode 100644 index 0000000000000..da872bfabce4f --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.unmappedtypestrings.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [UnmappedTypeStrings](./kibana-plugin-plugins-expressions-server.unmappedtypestrings.md) + +## UnmappedTypeStrings type + +Types used in Expressions that don't map to a primitive cleanly: + +`date` is typed as a number or string, and represents a date + +Signature: + +```typescript +export declare type UnmappedTypeStrings = 'date' | 'filter'; +``` diff --git a/docs/development/plugins/ui_actions/public/index.md b/docs/development/plugins/ui_actions/public/index.md new file mode 100644 index 0000000000000..cbc7035b880fa --- /dev/null +++ b/docs/development/plugins/ui_actions/public/index.md @@ -0,0 +1,12 @@ + + +[Home](./index.md) + +## API Reference + +## Packages + +| Package | Description | +| --- | --- | +| [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) | | + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.execute.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.execute.md new file mode 100644 index 0000000000000..22a520123cf3f --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.execute.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [Action](./kibana-plugin-plugins-ui_actions-public.action.md) > [execute](./kibana-plugin-plugins-ui_actions-public.action.execute.md) + +## Action.execute() method + +Executes the action. + +Signature: + +```typescript +execute(context: ActionExecutionContext): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| context | ActionExecutionContext<Context> | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.getdisplayname.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.getdisplayname.md new file mode 100644 index 0000000000000..cd8cc527e96ec --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.getdisplayname.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [Action](./kibana-plugin-plugins-ui_actions-public.action.md) > [getDisplayName](./kibana-plugin-plugins-ui_actions-public.action.getdisplayname.md) + +## Action.getDisplayName() method + +Returns a title to be displayed to the user. + +Signature: + +```typescript +getDisplayName(context: ActionExecutionContext): string; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| context | ActionExecutionContext<Context> | | + +Returns: + +`string` + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.gethref.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.gethref.md new file mode 100644 index 0000000000000..5ad9d5e24cf87 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.gethref.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [Action](./kibana-plugin-plugins-ui_actions-public.action.md) > [getHref](./kibana-plugin-plugins-ui_actions-public.action.gethref.md) + +## Action.getHref() method + +This method should return a link if this item can be clicked on. The link is used to navigate user if user middle-clicks it or Ctrl + clicks or right-clicks and selects "Open in new tab". + +Signature: + +```typescript +getHref?(context: ActionExecutionContext): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| context | ActionExecutionContext<Context> | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.geticontype.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.geticontype.md new file mode 100644 index 0000000000000..34d45c4ec75c2 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.geticontype.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [Action](./kibana-plugin-plugins-ui_actions-public.action.md) > [getIconType](./kibana-plugin-plugins-ui_actions-public.action.geticontype.md) + +## Action.getIconType() method + +Optional EUI icon type that can be displayed along with the title. + +Signature: + +```typescript +getIconType(context: ActionExecutionContext): string | undefined; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| context | ActionExecutionContext<Context> | | + +Returns: + +`string | undefined` + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.id.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.id.md new file mode 100644 index 0000000000000..e32a5c8592cce --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.id.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [Action](./kibana-plugin-plugins-ui_actions-public.action.md) > [id](./kibana-plugin-plugins-ui_actions-public.action.id.md) + +## Action.id property + +A unique identifier for this action instance. + +Signature: + +```typescript +id: string; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.iscompatible.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.iscompatible.md new file mode 100644 index 0000000000000..7a1f6cd23be17 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.iscompatible.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [Action](./kibana-plugin-plugins-ui_actions-public.action.md) > [isCompatible](./kibana-plugin-plugins-ui_actions-public.action.iscompatible.md) + +## Action.isCompatible() method + +Returns a promise that resolves to true if this action is compatible given the context, otherwise resolves to false. + +Signature: + +```typescript +isCompatible(context: ActionExecutionContext): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| context | ActionExecutionContext<Context> | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.md new file mode 100644 index 0000000000000..19af63a679de8 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.md @@ -0,0 +1,32 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [Action](./kibana-plugin-plugins-ui_actions-public.action.md) + +## Action interface + +Signature: + +```typescript +export interface Action extends Partial>> +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [id](./kibana-plugin-plugins-ui_actions-public.action.id.md) | string | A unique identifier for this action instance. | +| [MenuItem](./kibana-plugin-plugins-ui_actions-public.action.menuitem.md) | UiComponent<{
context: ActionExecutionContext<Context>;
}> | UiComponent to render when displaying this action as a context menu item. If not provided, getDisplayName will be used instead. | +| [order](./kibana-plugin-plugins-ui_actions-public.action.order.md) | number | Determined the order when there is more than one action matched to a trigger. Higher numbers are displayed first. | +| [type](./kibana-plugin-plugins-ui_actions-public.action.type.md) | T | The action type is what determines the context shape. | + +## Methods + +| Method | Description | +| --- | --- | +| [execute(context)](./kibana-plugin-plugins-ui_actions-public.action.execute.md) | Executes the action. | +| [getDisplayName(context)](./kibana-plugin-plugins-ui_actions-public.action.getdisplayname.md) | Returns a title to be displayed to the user. | +| [getHref(context)](./kibana-plugin-plugins-ui_actions-public.action.gethref.md) | This method should return a link if this item can be clicked on. The link is used to navigate user if user middle-clicks it or Ctrl + clicks or right-clicks and selects "Open in new tab". | +| [getIconType(context)](./kibana-plugin-plugins-ui_actions-public.action.geticontype.md) | Optional EUI icon type that can be displayed along with the title. | +| [isCompatible(context)](./kibana-plugin-plugins-ui_actions-public.action.iscompatible.md) | Returns a promise that resolves to true if this action is compatible given the context, otherwise resolves to false. | +| [shouldAutoExecute(context)](./kibana-plugin-plugins-ui_actions-public.action.shouldautoexecute.md) | Determines if action should be executed automatically, without first showing up in context menu. false by default. | + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.menuitem.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.menuitem.md new file mode 100644 index 0000000000000..ac2168b88e3be --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.menuitem.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [Action](./kibana-plugin-plugins-ui_actions-public.action.md) > [MenuItem](./kibana-plugin-plugins-ui_actions-public.action.menuitem.md) + +## Action.MenuItem property + +`UiComponent` to render when displaying this action as a context menu item. If not provided, `getDisplayName` will be used instead. + +Signature: + +```typescript +MenuItem?: UiComponent<{ + context: ActionExecutionContext; + }>; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.order.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.order.md new file mode 100644 index 0000000000000..ce9f66cfe5143 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.order.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [Action](./kibana-plugin-plugins-ui_actions-public.action.md) > [order](./kibana-plugin-plugins-ui_actions-public.action.order.md) + +## Action.order property + +Determined the order when there is more than one action matched to a trigger. Higher numbers are displayed first. + +Signature: + +```typescript +order?: number; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.shouldautoexecute.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.shouldautoexecute.md new file mode 100644 index 0000000000000..1a784f5dad2d5 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.shouldautoexecute.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [Action](./kibana-plugin-plugins-ui_actions-public.action.md) > [shouldAutoExecute](./kibana-plugin-plugins-ui_actions-public.action.shouldautoexecute.md) + +## Action.shouldAutoExecute() method + +Determines if action should be executed automatically, without first showing up in context menu. false by default. + +Signature: + +```typescript +shouldAutoExecute?(context: ActionExecutionContext): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| context | ActionExecutionContext<Context> | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.type.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.type.md new file mode 100644 index 0000000000000..c423df9d1324c --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action.type.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [Action](./kibana-plugin-plugins-ui_actions-public.action.md) > [type](./kibana-plugin-plugins-ui_actions-public.action.type.md) + +## Action.type property + +The action type is what determines the context shape. + +Signature: + +```typescript +readonly type: T; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action_visualize_field.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action_visualize_field.md new file mode 100644 index 0000000000000..25788d7aecc9f --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action_visualize_field.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [ACTION\_VISUALIZE\_FIELD](./kibana-plugin-plugins-ui_actions-public.action_visualize_field.md) + +## ACTION\_VISUALIZE\_FIELD variable + +Signature: + +```typescript +ACTION_VISUALIZE_FIELD = "ACTION_VISUALIZE_FIELD" +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action_visualize_geo_field.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action_visualize_geo_field.md new file mode 100644 index 0000000000000..c9ef93eff934b --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.action_visualize_geo_field.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [ACTION\_VISUALIZE\_GEO\_FIELD](./kibana-plugin-plugins-ui_actions-public.action_visualize_geo_field.md) + +## ACTION\_VISUALIZE\_GEO\_FIELD variable + +Signature: + +```typescript +ACTION_VISUALIZE_GEO_FIELD = "ACTION_VISUALIZE_GEO_FIELD" +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actionbytype.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actionbytype.md new file mode 100644 index 0000000000000..3ceb96adadb1a --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actionbytype.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [ActionByType](./kibana-plugin-plugins-ui_actions-public.actionbytype.md) + +## ActionByType type + +Signature: + +```typescript +export declare type ActionByType = Action; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actioncontextmapping.__.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actioncontextmapping.__.md new file mode 100644 index 0000000000000..eb7b1e5954ed2 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actioncontextmapping.__.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [ActionContextMapping](./kibana-plugin-plugins-ui_actions-public.actioncontextmapping.md) > [""](./kibana-plugin-plugins-ui_actions-public.actioncontextmapping.__.md) + +## ActionContextMapping."" property + +Signature: + +```typescript +[DEFAULT_ACTION]: BaseContext; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actioncontextmapping.action_visualize_field.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actioncontextmapping.action_visualize_field.md new file mode 100644 index 0000000000000..eb0547bbf8261 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actioncontextmapping.action_visualize_field.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [ActionContextMapping](./kibana-plugin-plugins-ui_actions-public.actioncontextmapping.md) > [ACTION\_VISUALIZE\_FIELD](./kibana-plugin-plugins-ui_actions-public.actioncontextmapping.action_visualize_field.md) + +## ActionContextMapping.ACTION\_VISUALIZE\_FIELD property + +Signature: + +```typescript +[ACTION_VISUALIZE_FIELD]: VisualizeFieldContext; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actioncontextmapping.action_visualize_geo_field.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actioncontextmapping.action_visualize_geo_field.md new file mode 100644 index 0000000000000..b44ed75106423 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actioncontextmapping.action_visualize_geo_field.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [ActionContextMapping](./kibana-plugin-plugins-ui_actions-public.actioncontextmapping.md) > [ACTION\_VISUALIZE\_GEO\_FIELD](./kibana-plugin-plugins-ui_actions-public.actioncontextmapping.action_visualize_geo_field.md) + +## ActionContextMapping.ACTION\_VISUALIZE\_GEO\_FIELD property + +Signature: + +```typescript +[ACTION_VISUALIZE_GEO_FIELD]: VisualizeFieldContext; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actioncontextmapping.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actioncontextmapping.md new file mode 100644 index 0000000000000..740e6ac63bfba --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actioncontextmapping.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [ActionContextMapping](./kibana-plugin-plugins-ui_actions-public.actioncontextmapping.md) + +## ActionContextMapping interface + +Signature: + +```typescript +export interface ActionContextMapping +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [""](./kibana-plugin-plugins-ui_actions-public.actioncontextmapping.__.md) | BaseContext | | +| [ACTION\_VISUALIZE\_FIELD](./kibana-plugin-plugins-ui_actions-public.actioncontextmapping.action_visualize_field.md) | VisualizeFieldContext | | +| [ACTION\_VISUALIZE\_GEO\_FIELD](./kibana-plugin-plugins-ui_actions-public.actioncontextmapping.action_visualize_geo_field.md) | VisualizeFieldContext | | + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actiondefinitionbytype.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actiondefinitionbytype.md new file mode 100644 index 0000000000000..ba4dc39088fe4 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actiondefinitionbytype.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [ActionDefinitionByType](./kibana-plugin-plugins-ui_actions-public.actiondefinitionbytype.md) + +## ActionDefinitionByType type + +Signature: + +```typescript +export declare type ActionDefinitionByType = ActionDefinition; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actionexecutioncontext.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actionexecutioncontext.md new file mode 100644 index 0000000000000..3271d86779959 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actionexecutioncontext.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [ActionExecutionContext](./kibana-plugin-plugins-ui_actions-public.actionexecutioncontext.md) + +## ActionExecutionContext type + +Action methods are executed with Context from trigger + [ActionExecutionMeta](./kibana-plugin-plugins-ui_actions-public.actionexecutionmeta.md) + +Signature: + +```typescript +export declare type ActionExecutionContext = Context & ActionExecutionMeta; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actionexecutionmeta.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actionexecutionmeta.md new file mode 100644 index 0000000000000..2056d8f9c7fc6 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actionexecutionmeta.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [ActionExecutionMeta](./kibana-plugin-plugins-ui_actions-public.actionexecutionmeta.md) + +## ActionExecutionMeta interface + +During action execution we can provide additional information, for example, trigger, that caused the action execution + +Signature: + +```typescript +export interface ActionExecutionMeta +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [trigger](./kibana-plugin-plugins-ui_actions-public.actionexecutionmeta.trigger.md) | Trigger | Trigger that executed the action | + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actionexecutionmeta.trigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actionexecutionmeta.trigger.md new file mode 100644 index 0000000000000..530c2fe514d2c --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actionexecutionmeta.trigger.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [ActionExecutionMeta](./kibana-plugin-plugins-ui_actions-public.actionexecutionmeta.md) > [trigger](./kibana-plugin-plugins-ui_actions-public.actionexecutionmeta.trigger.md) + +## ActionExecutionMeta.trigger property + +Trigger that executed the action + +Signature: + +```typescript +trigger: Trigger; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actiontype.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actiontype.md new file mode 100644 index 0000000000000..4916585531004 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.actiontype.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [ActionType](./kibana-plugin-plugins-ui_actions-public.actiontype.md) + +## ActionType type + +Signature: + +```typescript +export declare type ActionType = keyof ActionContextMapping; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.apply_filter_trigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.apply_filter_trigger.md new file mode 100644 index 0000000000000..94e66bf404f5c --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.apply_filter_trigger.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [APPLY\_FILTER\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.apply_filter_trigger.md) + +## APPLY\_FILTER\_TRIGGER variable + +Signature: + +```typescript +APPLY_FILTER_TRIGGER = "FILTER_TRIGGER" +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.applyfiltertrigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.applyfiltertrigger.md new file mode 100644 index 0000000000000..e1fb6d342457e --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.applyfiltertrigger.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [applyFilterTrigger](./kibana-plugin-plugins-ui_actions-public.applyfiltertrigger.md) + +## applyFilterTrigger variable + +Signature: + +```typescript +applyFilterTrigger: Trigger<'FILTER_TRIGGER'> +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.buildcontextmenuforactions.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.buildcontextmenuforactions.md new file mode 100644 index 0000000000000..2d6c0ff106072 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.buildcontextmenuforactions.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [buildContextMenuForActions](./kibana-plugin-plugins-ui_actions-public.buildcontextmenuforactions.md) + +## buildContextMenuForActions() function + +Transforms an array of Actions to the shape EuiContextMenuPanel expects. + +Signature: + +```typescript +export declare function buildContextMenuForActions({ actions, title, closeMenu, }: BuildContextMenuParams): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| { actions, title, closeMenu, } | BuildContextMenuParams | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.createaction.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.createaction.md new file mode 100644 index 0000000000000..04ab36c2e3f58 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.createaction.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [createAction](./kibana-plugin-plugins-ui_actions-public.createaction.md) + +## createAction() function + +Signature: + +```typescript +export declare function createAction(action: ActionDefinitionByType): ActionByType; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| action | ActionDefinitionByType<T> | | + +Returns: + +`ActionByType` + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.incompatibleactionerror._constructor_.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.incompatibleactionerror._constructor_.md new file mode 100644 index 0000000000000..f06bb05270ff0 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.incompatibleactionerror._constructor_.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [IncompatibleActionError](./kibana-plugin-plugins-ui_actions-public.incompatibleactionerror.md) > [(constructor)](./kibana-plugin-plugins-ui_actions-public.incompatibleactionerror._constructor_.md) + +## IncompatibleActionError.(constructor) + +Constructs a new instance of the `IncompatibleActionError` class + +Signature: + +```typescript +constructor(); +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.incompatibleactionerror.code.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.incompatibleactionerror.code.md new file mode 100644 index 0000000000000..f16aa47438d72 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.incompatibleactionerror.code.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [IncompatibleActionError](./kibana-plugin-plugins-ui_actions-public.incompatibleactionerror.md) > [code](./kibana-plugin-plugins-ui_actions-public.incompatibleactionerror.code.md) + +## IncompatibleActionError.code property + +Signature: + +```typescript +code: string; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.incompatibleactionerror.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.incompatibleactionerror.md new file mode 100644 index 0000000000000..7c9943a53c2bb --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.incompatibleactionerror.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [IncompatibleActionError](./kibana-plugin-plugins-ui_actions-public.incompatibleactionerror.md) + +## IncompatibleActionError class + +Signature: + +```typescript +export declare class IncompatibleActionError extends Error +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)()](./kibana-plugin-plugins-ui_actions-public.incompatibleactionerror._constructor_.md) | | Constructs a new instance of the IncompatibleActionError class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [code](./kibana-plugin-plugins-ui_actions-public.incompatibleactionerror.code.md) | | string | | + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.md new file mode 100644 index 0000000000000..ce4e8c17b9dff --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.md @@ -0,0 +1,66 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) + +## kibana-plugin-plugins-ui\_actions-public package + +## Classes + +| Class | Description | +| --- | --- | +| [IncompatibleActionError](./kibana-plugin-plugins-ui_actions-public.incompatibleactionerror.md) | | +| [UiActionsService](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.md) | | + +## Functions + +| Function | Description | +| --- | --- | +| [buildContextMenuForActions({ actions, title, closeMenu, })](./kibana-plugin-plugins-ui_actions-public.buildcontextmenuforactions.md) | Transforms an array of Actions to the shape EuiContextMenuPanel expects. | +| [createAction(action)](./kibana-plugin-plugins-ui_actions-public.createaction.md) | | +| [plugin(initializerContext)](./kibana-plugin-plugins-ui_actions-public.plugin.md) | | + +## Interfaces + +| Interface | Description | +| --- | --- | +| [Action](./kibana-plugin-plugins-ui_actions-public.action.md) | | +| [ActionContextMapping](./kibana-plugin-plugins-ui_actions-public.actioncontextmapping.md) | | +| [ActionExecutionMeta](./kibana-plugin-plugins-ui_actions-public.actionexecutionmeta.md) | During action execution we can provide additional information, for example, trigger, that caused the action execution | +| [Trigger](./kibana-plugin-plugins-ui_actions-public.trigger.md) | This is a convenience interface used to register a \*trigger\*.Trigger specifies a named anchor to which Action can be attached. When Trigger is being \*called\* it creates a Context object and passes it to the execute method of an Action.More than one action can be attached to a single trigger, in which case when trigger is \*called\* it first displays a context menu for user to pick a single action to execute. | +| [TriggerContextMapping](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.md) | | +| [UiActionsActionDefinition](./kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.md) | A convenience interface used to register an action. | +| [UiActionsPresentable](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.md) | Represents something that can be displayed to user in UI. | +| [UiActionsServiceParams](./kibana-plugin-plugins-ui_actions-public.uiactionsserviceparams.md) | | +| [VisualizeFieldContext](./kibana-plugin-plugins-ui_actions-public.visualizefieldcontext.md) | | + +## Variables + +| Variable | Description | +| --- | --- | +| [ACTION\_VISUALIZE\_FIELD](./kibana-plugin-plugins-ui_actions-public.action_visualize_field.md) | | +| [ACTION\_VISUALIZE\_GEO\_FIELD](./kibana-plugin-plugins-ui_actions-public.action_visualize_geo_field.md) | | +| [APPLY\_FILTER\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.apply_filter_trigger.md) | | +| [applyFilterTrigger](./kibana-plugin-plugins-ui_actions-public.applyfiltertrigger.md) | | +| [SELECT\_RANGE\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.select_range_trigger.md) | | +| [selectRangeTrigger](./kibana-plugin-plugins-ui_actions-public.selectrangetrigger.md) | | +| [VALUE\_CLICK\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.value_click_trigger.md) | | +| [valueClickTrigger](./kibana-plugin-plugins-ui_actions-public.valueclicktrigger.md) | | +| [VISUALIZE\_FIELD\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.visualize_field_trigger.md) | | +| [VISUALIZE\_GEO\_FIELD\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.visualize_geo_field_trigger.md) | | +| [visualizeFieldTrigger](./kibana-plugin-plugins-ui_actions-public.visualizefieldtrigger.md) | | +| [visualizeGeoFieldTrigger](./kibana-plugin-plugins-ui_actions-public.visualizegeofieldtrigger.md) | | + +## Type Aliases + +| Type Alias | Description | +| --- | --- | +| [ActionByType](./kibana-plugin-plugins-ui_actions-public.actionbytype.md) | | +| [ActionDefinitionByType](./kibana-plugin-plugins-ui_actions-public.actiondefinitionbytype.md) | | +| [ActionExecutionContext](./kibana-plugin-plugins-ui_actions-public.actionexecutioncontext.md) | Action methods are executed with Context from trigger + [ActionExecutionMeta](./kibana-plugin-plugins-ui_actions-public.actionexecutionmeta.md) | +| [ActionType](./kibana-plugin-plugins-ui_actions-public.actiontype.md) | | +| [TriggerContext](./kibana-plugin-plugins-ui_actions-public.triggercontext.md) | | +| [TriggerId](./kibana-plugin-plugins-ui_actions-public.triggerid.md) | | +| [UiActionsPresentableGrouping](./kibana-plugin-plugins-ui_actions-public.uiactionspresentablegrouping.md) | | +| [UiActionsSetup](./kibana-plugin-plugins-ui_actions-public.uiactionssetup.md) | | +| [UiActionsStart](./kibana-plugin-plugins-ui_actions-public.uiactionsstart.md) | | + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.plugin.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.plugin.md new file mode 100644 index 0000000000000..d9427317d4fc6 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.plugin.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [plugin](./kibana-plugin-plugins-ui_actions-public.plugin.md) + +## plugin() function + +Signature: + +```typescript +export declare function plugin(initializerContext: PluginInitializerContext): UiActionsPlugin; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| initializerContext | PluginInitializerContext | | + +Returns: + +`UiActionsPlugin` + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.select_range_trigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.select_range_trigger.md new file mode 100644 index 0000000000000..fd784ff17fa84 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.select_range_trigger.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [SELECT\_RANGE\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.select_range_trigger.md) + +## SELECT\_RANGE\_TRIGGER variable + +Signature: + +```typescript +SELECT_RANGE_TRIGGER = "SELECT_RANGE_TRIGGER" +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.selectrangetrigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.selectrangetrigger.md new file mode 100644 index 0000000000000..0d9fa2d83ee57 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.selectrangetrigger.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [selectRangeTrigger](./kibana-plugin-plugins-ui_actions-public.selectrangetrigger.md) + +## selectRangeTrigger variable + +Signature: + +```typescript +selectRangeTrigger: Trigger<'SELECT_RANGE_TRIGGER'> +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.trigger.description.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.trigger.description.md new file mode 100644 index 0000000000000..76faaf8e1a691 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.trigger.description.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [Trigger](./kibana-plugin-plugins-ui_actions-public.trigger.md) > [description](./kibana-plugin-plugins-ui_actions-public.trigger.description.md) + +## Trigger.description property + +A longer user friendly description of the trigger. + +Signature: + +```typescript +description?: string; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.trigger.id.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.trigger.id.md new file mode 100644 index 0000000000000..426f17f9a0352 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.trigger.id.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [Trigger](./kibana-plugin-plugins-ui_actions-public.trigger.md) > [id](./kibana-plugin-plugins-ui_actions-public.trigger.id.md) + +## Trigger.id property + +Unique name of the trigger as identified in `ui_actions` plugin trigger registry, such as "SELECT\_RANGE\_TRIGGER" or "VALUE\_CLICK\_TRIGGER". + +Signature: + +```typescript +id: ID; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.trigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.trigger.md new file mode 100644 index 0000000000000..b69bba892f475 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.trigger.md @@ -0,0 +1,26 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [Trigger](./kibana-plugin-plugins-ui_actions-public.trigger.md) + +## Trigger interface + +This is a convenience interface used to register a \*trigger\*. + +`Trigger` specifies a named anchor to which `Action` can be attached. When `Trigger` is being \*called\* it creates a `Context` object and passes it to the `execute` method of an `Action`. + +More than one action can be attached to a single trigger, in which case when trigger is \*called\* it first displays a context menu for user to pick a single action to execute. + +Signature: + +```typescript +export interface Trigger +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [description](./kibana-plugin-plugins-ui_actions-public.trigger.description.md) | string | A longer user friendly description of the trigger. | +| [id](./kibana-plugin-plugins-ui_actions-public.trigger.id.md) | ID | Unique name of the trigger as identified in ui_actions plugin trigger registry, such as "SELECT\_RANGE\_TRIGGER" or "VALUE\_CLICK\_TRIGGER". | +| [title](./kibana-plugin-plugins-ui_actions-public.trigger.title.md) | string | User friendly name of the trigger. | + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.trigger.title.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.trigger.title.md new file mode 100644 index 0000000000000..ded71c8d0c437 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.trigger.title.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [Trigger](./kibana-plugin-plugins-ui_actions-public.trigger.md) > [title](./kibana-plugin-plugins-ui_actions-public.trigger.title.md) + +## Trigger.title property + +User friendly name of the trigger. + +Signature: + +```typescript +title?: string; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontext.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontext.md new file mode 100644 index 0000000000000..4ce95d27ecffa --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontext.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [TriggerContext](./kibana-plugin-plugins-ui_actions-public.triggercontext.md) + +## TriggerContext type + +Signature: + +```typescript +export declare type TriggerContext = T extends TriggerId ? TriggerContextMapping[T] : never; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.__.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.__.md new file mode 100644 index 0000000000000..17ad926f8ee82 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.__.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [TriggerContextMapping](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.md) > [""](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.__.md) + +## TriggerContextMapping."" property + +Signature: + +```typescript +[DEFAULT_TRIGGER]: TriggerContext; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.filter_trigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.filter_trigger.md new file mode 100644 index 0000000000000..0ccf8aa3d7415 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.filter_trigger.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [TriggerContextMapping](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.md) > [FILTER\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.filter_trigger.md) + +## TriggerContextMapping.FILTER\_TRIGGER property + +Signature: + +```typescript +[APPLY_FILTER_TRIGGER]: ApplyGlobalFilterActionContext; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.md new file mode 100644 index 0000000000000..9db44d4dc7b05 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [TriggerContextMapping](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.md) + +## TriggerContextMapping interface + +Signature: + +```typescript +export interface TriggerContextMapping +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [""](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.__.md) | TriggerContext | | +| [FILTER\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.filter_trigger.md) | ApplyGlobalFilterActionContext | | +| [SELECT\_RANGE\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.select_range_trigger.md) | RangeSelectContext | | +| [VALUE\_CLICK\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.value_click_trigger.md) | ValueClickContext | | +| [VISUALIZE\_FIELD\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.visualize_field_trigger.md) | VisualizeFieldContext | | +| [VISUALIZE\_GEO\_FIELD\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.visualize_geo_field_trigger.md) | VisualizeFieldContext | | + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.select_range_trigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.select_range_trigger.md new file mode 100644 index 0000000000000..c5ef6843390b3 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.select_range_trigger.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [TriggerContextMapping](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.md) > [SELECT\_RANGE\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.select_range_trigger.md) + +## TriggerContextMapping.SELECT\_RANGE\_TRIGGER property + +Signature: + +```typescript +[SELECT_RANGE_TRIGGER]: RangeSelectContext; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.value_click_trigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.value_click_trigger.md new file mode 100644 index 0000000000000..129144a66cee5 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.value_click_trigger.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [TriggerContextMapping](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.md) > [VALUE\_CLICK\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.value_click_trigger.md) + +## TriggerContextMapping.VALUE\_CLICK\_TRIGGER property + +Signature: + +```typescript +[VALUE_CLICK_TRIGGER]: ValueClickContext; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.visualize_field_trigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.visualize_field_trigger.md new file mode 100644 index 0000000000000..feaaffac8a234 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.visualize_field_trigger.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [TriggerContextMapping](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.md) > [VISUALIZE\_FIELD\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.visualize_field_trigger.md) + +## TriggerContextMapping.VISUALIZE\_FIELD\_TRIGGER property + +Signature: + +```typescript +[VISUALIZE_FIELD_TRIGGER]: VisualizeFieldContext; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.visualize_geo_field_trigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.visualize_geo_field_trigger.md new file mode 100644 index 0000000000000..023490a2ae027 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggercontextmapping.visualize_geo_field_trigger.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [TriggerContextMapping](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.md) > [VISUALIZE\_GEO\_FIELD\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.triggercontextmapping.visualize_geo_field_trigger.md) + +## TriggerContextMapping.VISUALIZE\_GEO\_FIELD\_TRIGGER property + +Signature: + +```typescript +[VISUALIZE_GEO_FIELD_TRIGGER]: VisualizeFieldContext; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggerid.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggerid.md new file mode 100644 index 0000000000000..6e5a234e286f9 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.triggerid.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [TriggerId](./kibana-plugin-plugins-ui_actions-public.triggerid.md) + +## TriggerId type + +Signature: + +```typescript +export declare type TriggerId = keyof TriggerContextMapping; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.execute.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.execute.md new file mode 100644 index 0000000000000..a2cf61ecc1306 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.execute.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsActionDefinition](./kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.md) > [execute](./kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.execute.md) + +## UiActionsActionDefinition.execute() method + +Executes the action. + +Signature: + +```typescript +execute(context: ActionDefinitionContext): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| context | ActionDefinitionContext<Context> | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.gethref.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.gethref.md new file mode 100644 index 0000000000000..83fee1233a206 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.gethref.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsActionDefinition](./kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.md) > [getHref](./kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.gethref.md) + +## UiActionsActionDefinition.getHref() method + +This method should return a link if this item can be clicked on. The link is used to navigate user if user middle-clicks it or Ctrl + clicks or right-clicks and selects "Open in new tab". + +Signature: + +```typescript +getHref?(context: ActionDefinitionContext): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| context | ActionDefinitionContext<Context> | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.id.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.id.md new file mode 100644 index 0000000000000..01fa6abce3b4a --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.id.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsActionDefinition](./kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.md) > [id](./kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.id.md) + +## UiActionsActionDefinition.id property + +ID of the action that uniquely identifies this action in the actions registry. + +Signature: + +```typescript +readonly id: string; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.iscompatible.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.iscompatible.md new file mode 100644 index 0000000000000..736cc40c4243f --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.iscompatible.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsActionDefinition](./kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.md) > [isCompatible](./kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.iscompatible.md) + +## UiActionsActionDefinition.isCompatible() method + +Returns a promise that resolves to true if this item is compatible given the context and should be displayed to user, otherwise resolves to false. + +Signature: + +```typescript +isCompatible?(context: ActionDefinitionContext): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| context | ActionDefinitionContext<Context> | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.md new file mode 100644 index 0000000000000..7c873715795e9 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.md @@ -0,0 +1,30 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsActionDefinition](./kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.md) + +## UiActionsActionDefinition interface + +A convenience interface used to register an action. + +Signature: + +```typescript +export interface ActionDefinition extends Partial>> +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [id](./kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.id.md) | string | ID of the action that uniquely identifies this action in the actions registry. | +| [type](./kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.type.md) | ActionType | ID of the factory for this action. Used to construct dynamic actions. | + +## Methods + +| Method | Description | +| --- | --- | +| [execute(context)](./kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.execute.md) | Executes the action. | +| [getHref(context)](./kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.gethref.md) | This method should return a link if this item can be clicked on. The link is used to navigate user if user middle-clicks it or Ctrl + clicks or right-clicks and selects "Open in new tab". | +| [isCompatible(context)](./kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.iscompatible.md) | Returns a promise that resolves to true if this item is compatible given the context and should be displayed to user, otherwise resolves to false. | +| [shouldAutoExecute(context)](./kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.shouldautoexecute.md) | Determines if action should be executed automatically, without first showing up in context menu. false by default. | + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.shouldautoexecute.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.shouldautoexecute.md new file mode 100644 index 0000000000000..04b9975f3b92e --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.shouldautoexecute.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsActionDefinition](./kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.md) > [shouldAutoExecute](./kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.shouldautoexecute.md) + +## UiActionsActionDefinition.shouldAutoExecute() method + +Determines if action should be executed automatically, without first showing up in context menu. false by default. + +Signature: + +```typescript +shouldAutoExecute?(context: ActionDefinitionContext): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| context | ActionDefinitionContext<Context> | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.type.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.type.md new file mode 100644 index 0000000000000..125f834e9036e --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.type.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsActionDefinition](./kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.md) > [type](./kibana-plugin-plugins-ui_actions-public.uiactionsactiondefinition.type.md) + +## UiActionsActionDefinition.type property + +ID of the factory for this action. Used to construct dynamic actions. + +Signature: + +```typescript +readonly type?: ActionType; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.getdisplayname.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.getdisplayname.md new file mode 100644 index 0000000000000..986ad4afa5a48 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.getdisplayname.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsPresentable](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.md) > [getDisplayName](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.getdisplayname.md) + +## UiActionsPresentable.getDisplayName() method + +Returns a title to be displayed to the user. + +Signature: + +```typescript +getDisplayName(context: Context): string; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| context | Context | | + +Returns: + +`string` + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.getdisplaynametooltip.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.getdisplaynametooltip.md new file mode 100644 index 0000000000000..8fc859d5713e6 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.getdisplaynametooltip.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsPresentable](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.md) > [getDisplayNameTooltip](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.getdisplaynametooltip.md) + +## UiActionsPresentable.getDisplayNameTooltip() method + +Returns tooltip text which should be displayed when user hovers this object. Should return empty string if tooltip should not be displayed. + +Signature: + +```typescript +getDisplayNameTooltip(context: Context): string; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| context | Context | | + +Returns: + +`string` + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.gethref.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.gethref.md new file mode 100644 index 0000000000000..0c9bd434ff331 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.gethref.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsPresentable](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.md) > [getHref](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.gethref.md) + +## UiActionsPresentable.getHref() method + +This method should return a link if this item can be clicked on. The link is used to navigate user if user middle-clicks it or Ctrl + clicks or right-clicks and selects "Open in new tab". + +Signature: + +```typescript +getHref?(context: Context): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| context | Context | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.geticontype.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.geticontype.md new file mode 100644 index 0000000000000..8bf5af0f3b7e2 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.geticontype.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsPresentable](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.md) > [getIconType](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.geticontype.md) + +## UiActionsPresentable.getIconType() method + +Optional EUI icon type that can be displayed along with the title. + +Signature: + +```typescript +getIconType(context: Context): string | undefined; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| context | Context | | + +Returns: + +`string | undefined` + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.grouping.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.grouping.md new file mode 100644 index 0000000000000..6b160becf1afc --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.grouping.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsPresentable](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.md) > [grouping](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.grouping.md) + +## UiActionsPresentable.grouping property + +Grouping where this item should appear as a submenu. Each entry is a new sub-menu level. For example, used to show drilldowns and sharing options in panel context menu in a sub-menu. + +Signature: + +```typescript +readonly grouping?: PresentableGrouping; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.id.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.id.md new file mode 100644 index 0000000000000..e98401d95cba8 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.id.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsPresentable](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.md) > [id](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.id.md) + +## UiActionsPresentable.id property + +ID that uniquely identifies this object. + +Signature: + +```typescript +readonly id: string; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.iscompatible.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.iscompatible.md new file mode 100644 index 0000000000000..073f75c840bcd --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.iscompatible.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsPresentable](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.md) > [isCompatible](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.iscompatible.md) + +## UiActionsPresentable.isCompatible() method + +Returns a promise that resolves to true if this item is compatible given the context and should be displayed to user, otherwise resolves to false. + +Signature: + +```typescript +isCompatible(context: Context): Promise; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| context | Context | | + +Returns: + +`Promise` + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.md new file mode 100644 index 0000000000000..03fa7fb6e447e --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.md @@ -0,0 +1,33 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsPresentable](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.md) + +## UiActionsPresentable interface + +Represents something that can be displayed to user in UI. + +Signature: + +```typescript +export interface Presentable +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [grouping](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.grouping.md) | PresentableGrouping<Context> | Grouping where this item should appear as a submenu. Each entry is a new sub-menu level. For example, used to show drilldowns and sharing options in panel context menu in a sub-menu. | +| [id](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.id.md) | string | ID that uniquely identifies this object. | +| [MenuItem](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.menuitem.md) | UiComponent<{
context: Context;
}> | UiComponent to render when displaying this entity as a context menu item. If not provided, getDisplayName will be used instead. | +| [order](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.order.md) | number | Determines the display order in relation to other items. Higher numbers are displayed first. | + +## Methods + +| Method | Description | +| --- | --- | +| [getDisplayName(context)](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.getdisplayname.md) | Returns a title to be displayed to the user. | +| [getDisplayNameTooltip(context)](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.getdisplaynametooltip.md) | Returns tooltip text which should be displayed when user hovers this object. Should return empty string if tooltip should not be displayed. | +| [getHref(context)](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.gethref.md) | This method should return a link if this item can be clicked on. The link is used to navigate user if user middle-clicks it or Ctrl + clicks or right-clicks and selects "Open in new tab". | +| [getIconType(context)](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.geticontype.md) | Optional EUI icon type that can be displayed along with the title. | +| [isCompatible(context)](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.iscompatible.md) | Returns a promise that resolves to true if this item is compatible given the context and should be displayed to user, otherwise resolves to false. | + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.menuitem.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.menuitem.md new file mode 100644 index 0000000000000..42afe6b8361f0 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.menuitem.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsPresentable](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.md) > [MenuItem](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.menuitem.md) + +## UiActionsPresentable.MenuItem property + +`UiComponent` to render when displaying this entity as a context menu item. If not provided, `getDisplayName` will be used instead. + +Signature: + +```typescript +readonly MenuItem?: UiComponent<{ + context: Context; + }>; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.order.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.order.md new file mode 100644 index 0000000000000..0bbf80dc89211 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentable.order.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsPresentable](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.md) > [order](./kibana-plugin-plugins-ui_actions-public.uiactionspresentable.order.md) + +## UiActionsPresentable.order property + +Determines the display order in relation to other items. Higher numbers are displayed first. + +Signature: + +```typescript +readonly order: number; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentablegrouping.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentablegrouping.md new file mode 100644 index 0000000000000..a61ff65e39c69 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionspresentablegrouping.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsPresentableGrouping](./kibana-plugin-plugins-ui_actions-public.uiactionspresentablegrouping.md) + +## UiActionsPresentableGrouping type + +Signature: + +```typescript +export declare type PresentableGrouping = Array>; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice._constructor_.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice._constructor_.md new file mode 100644 index 0000000000000..ff272245dbbf9 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice._constructor_.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsService](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.md) > [(constructor)](./kibana-plugin-plugins-ui_actions-public.uiactionsservice._constructor_.md) + +## UiActionsService.(constructor) + +Constructs a new instance of the `UiActionsService` class + +Signature: + +```typescript +constructor({ triggers, actions, triggerToActions, }?: UiActionsServiceParams); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| { triggers, actions, triggerToActions, } | UiActionsServiceParams | | + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.actions.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.actions.md new file mode 100644 index 0000000000000..aaf4cebaf841c --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.actions.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsService](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.md) > [actions](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.actions.md) + +## UiActionsService.actions property + +Signature: + +```typescript +protected readonly actions: ActionRegistry; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.addtriggeraction.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.addtriggeraction.md new file mode 100644 index 0000000000000..1782eef92442c --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.addtriggeraction.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsService](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.md) > [addTriggerAction](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.addtriggeraction.md) + +## UiActionsService.addTriggerAction property + +`addTriggerAction` is similar to `attachAction` as it attaches action to a trigger, but it also registers the action, if it has not been registered, yet. + +`addTriggerAction` also infers better typing of the `action` argument. + +Signature: + +```typescript +readonly addTriggerAction: (triggerId: T, action: ActionDefinition | Action) => void; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.attachaction.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.attachaction.md new file mode 100644 index 0000000000000..19f215a96b23b --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.attachaction.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsService](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.md) > [attachAction](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.attachaction.md) + +## UiActionsService.attachAction property + +Signature: + +```typescript +readonly attachAction: (triggerId: T, actionId: string) => void; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.clear.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.clear.md new file mode 100644 index 0000000000000..024c7e3c3f85a --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.clear.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsService](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.md) > [clear](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.clear.md) + +## UiActionsService.clear property + +Removes all registered triggers and actions. + +Signature: + +```typescript +readonly clear: () => void; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.detachaction.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.detachaction.md new file mode 100644 index 0000000000000..a6ff2489c6f0e --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.detachaction.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsService](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.md) > [detachAction](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.detachaction.md) + +## UiActionsService.detachAction property + +Signature: + +```typescript +readonly detachAction: (triggerId: TriggerId, actionId: string) => void; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.executetriggeractions.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.executetriggeractions.md new file mode 100644 index 0000000000000..1bb6ca1115248 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.executetriggeractions.md @@ -0,0 +1,16 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsService](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.md) > [executeTriggerActions](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.executetriggeractions.md) + +## UiActionsService.executeTriggerActions property + +> Warning: This API is now obsolete. +> +> Use `plugins.uiActions.getTrigger(triggerId).exec(params)` instead. +> + +Signature: + +```typescript +readonly executeTriggerActions: (triggerId: T, context: TriggerContext) => Promise; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.executionservice.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.executionservice.md new file mode 100644 index 0000000000000..06384cc110a59 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.executionservice.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsService](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.md) > [executionService](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.executionservice.md) + +## UiActionsService.executionService property + +Signature: + +```typescript +readonly executionService: UiActionsExecutionService; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.fork.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.fork.md new file mode 100644 index 0000000000000..2b7a43a44cca6 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.fork.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsService](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.md) > [fork](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.fork.md) + +## UiActionsService.fork property + +"Fork" a separate instance of `UiActionsService` that inherits all existing triggers and actions, but going forward all new triggers and actions added to this instance of `UiActionsService` are only available within this instance. + +Signature: + +```typescript +readonly fork: () => UiActionsService; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.getaction.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.getaction.md new file mode 100644 index 0000000000000..0c4584a07b569 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.getaction.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsService](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.md) > [getAction](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.getaction.md) + +## UiActionsService.getAction property + +Signature: + +```typescript +readonly getAction: >(id: string) => Action, "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel" | "togglePanel" | "replacePanel" | "clonePanel" | "addToFromLibrary" | "unlinkFromLibrary" | "ACTION_LIBRARY_NOTIFICATION" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK">; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettrigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettrigger.md new file mode 100644 index 0000000000000..d44dc4e43a52e --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettrigger.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsService](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.md) > [getTrigger](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettrigger.md) + +## UiActionsService.getTrigger property + +Signature: + +```typescript +readonly getTrigger: (triggerId: T) => TriggerContract; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettriggeractions.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettriggeractions.md new file mode 100644 index 0000000000000..c65a9a992da2e --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettriggeractions.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsService](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.md) > [getTriggerActions](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettriggeractions.md) + +## UiActionsService.getTriggerActions property + +Signature: + +```typescript +readonly getTriggerActions: (triggerId: T) => Action[]; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettriggercompatibleactions.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettriggercompatibleactions.md new file mode 100644 index 0000000000000..751abe332b08e --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettriggercompatibleactions.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsService](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.md) > [getTriggerCompatibleActions](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettriggercompatibleactions.md) + +## UiActionsService.getTriggerCompatibleActions property + +Signature: + +```typescript +readonly getTriggerCompatibleActions: (triggerId: T, context: TriggerContextMapping[T]) => Promise[]>; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.hasaction.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.hasaction.md new file mode 100644 index 0000000000000..2287cb3052864 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.hasaction.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsService](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.md) > [hasAction](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.hasaction.md) + +## UiActionsService.hasAction property + +Signature: + +```typescript +readonly hasAction: (actionId: string) => boolean; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.md new file mode 100644 index 0000000000000..c372eb113d682 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.md @@ -0,0 +1,41 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsService](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.md) + +## UiActionsService class + +Signature: + +```typescript +export declare class UiActionsService +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)({ triggers, actions, triggerToActions, })](./kibana-plugin-plugins-ui_actions-public.uiactionsservice._constructor_.md) | | Constructs a new instance of the UiActionsService class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [actions](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.actions.md) | | ActionRegistry | | +| [addTriggerAction](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.addtriggeraction.md) | | <T extends "" | "SELECT_RANGE_TRIGGER" | "VALUE_CLICK_TRIGGER" | "FILTER_TRIGGER" | "VISUALIZE_FIELD_TRIGGER" | "VISUALIZE_GEO_FIELD_TRIGGER" | "CONTEXT_MENU_TRIGGER" | "PANEL_BADGE_TRIGGER" | "PANEL_NOTIFICATION_TRIGGER">(triggerId: T, action: ActionDefinition<TriggerContextMapping[T]> | Action<TriggerContextMapping[T], "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel" | "togglePanel" | "replacePanel" | "clonePanel" | "addToFromLibrary" | "unlinkFromLibrary" | "ACTION_LIBRARY_NOTIFICATION" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK">) => void | addTriggerAction is similar to attachAction as it attaches action to a trigger, but it also registers the action, if it has not been registered, yet.addTriggerAction also infers better typing of the action argument. | +| [attachAction](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.attachaction.md) | | <T extends "" | "SELECT_RANGE_TRIGGER" | "VALUE_CLICK_TRIGGER" | "FILTER_TRIGGER" | "VISUALIZE_FIELD_TRIGGER" | "VISUALIZE_GEO_FIELD_TRIGGER" | "CONTEXT_MENU_TRIGGER" | "PANEL_BADGE_TRIGGER" | "PANEL_NOTIFICATION_TRIGGER">(triggerId: T, actionId: string) => void | | +| [clear](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.clear.md) | | () => void | Removes all registered triggers and actions. | +| [detachAction](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.detachaction.md) | | (triggerId: TriggerId, actionId: string) => void | | +| [executeTriggerActions](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.executetriggeractions.md) | | <T extends "" | "SELECT_RANGE_TRIGGER" | "VALUE_CLICK_TRIGGER" | "FILTER_TRIGGER" | "VISUALIZE_FIELD_TRIGGER" | "VISUALIZE_GEO_FIELD_TRIGGER" | "CONTEXT_MENU_TRIGGER" | "PANEL_BADGE_TRIGGER" | "PANEL_NOTIFICATION_TRIGGER">(triggerId: T, context: TriggerContext<T>) => Promise<void> | | +| [executionService](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.executionservice.md) | | UiActionsExecutionService | | +| [fork](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.fork.md) | | () => UiActionsService | "Fork" a separate instance of UiActionsService that inherits all existing triggers and actions, but going forward all new triggers and actions added to this instance of UiActionsService are only available within this instance. | +| [getAction](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.getaction.md) | | <T extends ActionDefinition<{}>>(id: string) => Action<ActionContext<T>, "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel" | "togglePanel" | "replacePanel" | "clonePanel" | "addToFromLibrary" | "unlinkFromLibrary" | "ACTION_LIBRARY_NOTIFICATION" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK"> | | +| [getTrigger](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettrigger.md) | | <T extends "" | "SELECT_RANGE_TRIGGER" | "VALUE_CLICK_TRIGGER" | "FILTER_TRIGGER" | "VISUALIZE_FIELD_TRIGGER" | "VISUALIZE_GEO_FIELD_TRIGGER" | "CONTEXT_MENU_TRIGGER" | "PANEL_BADGE_TRIGGER" | "PANEL_NOTIFICATION_TRIGGER">(triggerId: T) => TriggerContract<T> | | +| [getTriggerActions](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettriggeractions.md) | | <T extends "" | "SELECT_RANGE_TRIGGER" | "VALUE_CLICK_TRIGGER" | "FILTER_TRIGGER" | "VISUALIZE_FIELD_TRIGGER" | "VISUALIZE_GEO_FIELD_TRIGGER" | "CONTEXT_MENU_TRIGGER" | "PANEL_BADGE_TRIGGER" | "PANEL_NOTIFICATION_TRIGGER">(triggerId: T) => Action<TriggerContextMapping[T], "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel" | "togglePanel" | "replacePanel" | "clonePanel" | "addToFromLibrary" | "unlinkFromLibrary" | "ACTION_LIBRARY_NOTIFICATION" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK">[] | | +| [getTriggerCompatibleActions](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.gettriggercompatibleactions.md) | | <T extends "" | "SELECT_RANGE_TRIGGER" | "VALUE_CLICK_TRIGGER" | "FILTER_TRIGGER" | "VISUALIZE_FIELD_TRIGGER" | "VISUALIZE_GEO_FIELD_TRIGGER" | "CONTEXT_MENU_TRIGGER" | "PANEL_BADGE_TRIGGER" | "PANEL_NOTIFICATION_TRIGGER">(triggerId: T, context: TriggerContextMapping[T]) => Promise<Action<TriggerContextMapping[T], "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel" | "togglePanel" | "replacePanel" | "clonePanel" | "addToFromLibrary" | "unlinkFromLibrary" | "ACTION_LIBRARY_NOTIFICATION" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK">[]> | | +| [hasAction](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.hasaction.md) | | (actionId: string) => boolean | | +| [registerAction](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.registeraction.md) | | <A extends ActionDefinition<{}>>(definition: A) => Action<ActionContext<A>, "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel" | "togglePanel" | "replacePanel" | "clonePanel" | "addToFromLibrary" | "unlinkFromLibrary" | "ACTION_LIBRARY_NOTIFICATION" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK"> | | +| [registerTrigger](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.registertrigger.md) | | (trigger: Trigger) => void | | +| [triggers](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.triggers.md) | | TriggerRegistry | | +| [triggerToActions](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.triggertoactions.md) | | TriggerToActionsRegistry | | +| [unregisterAction](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.unregisteraction.md) | | (actionId: string) => void | | + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.registeraction.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.registeraction.md new file mode 100644 index 0000000000000..c71e86fc09dc7 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.registeraction.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsService](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.md) > [registerAction](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.registeraction.md) + +## UiActionsService.registerAction property + +Signature: + +```typescript +readonly registerAction:
>(definition: A) => Action, "" | "ACTION_VISUALIZE_FIELD" | "ACTION_VISUALIZE_GEO_FIELD" | "ACTION_CUSTOMIZE_PANEL" | "ACTION_ADD_PANEL" | "openInspector" | "deletePanel" | "editPanel" | "togglePanel" | "replacePanel" | "clonePanel" | "addToFromLibrary" | "unlinkFromLibrary" | "ACTION_LIBRARY_NOTIFICATION" | "ACTION_GLOBAL_APPLY_FILTER" | "ACTION_SELECT_RANGE" | "ACTION_VALUE_CLICK">; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.registertrigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.registertrigger.md new file mode 100644 index 0000000000000..3002409c02304 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.registertrigger.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsService](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.md) > [registerTrigger](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.registertrigger.md) + +## UiActionsService.registerTrigger property + +Signature: + +```typescript +readonly registerTrigger: (trigger: Trigger) => void; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.triggers.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.triggers.md new file mode 100644 index 0000000000000..07d480286e771 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.triggers.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsService](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.md) > [triggers](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.triggers.md) + +## UiActionsService.triggers property + +Signature: + +```typescript +protected readonly triggers: TriggerRegistry; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.triggertoactions.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.triggertoactions.md new file mode 100644 index 0000000000000..1b79a1dd84593 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.triggertoactions.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsService](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.md) > [triggerToActions](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.triggertoactions.md) + +## UiActionsService.triggerToActions property + +Signature: + +```typescript +protected readonly triggerToActions: TriggerToActionsRegistry; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.unregisteraction.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.unregisteraction.md new file mode 100644 index 0000000000000..0e0eb971c1a7b --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsservice.unregisteraction.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsService](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.md) > [unregisterAction](./kibana-plugin-plugins-ui_actions-public.uiactionsservice.unregisteraction.md) + +## UiActionsService.unregisterAction property + +Signature: + +```typescript +readonly unregisterAction: (actionId: string) => void; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsserviceparams.actions.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsserviceparams.actions.md new file mode 100644 index 0000000000000..44d2957b0f8ba --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsserviceparams.actions.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsServiceParams](./kibana-plugin-plugins-ui_actions-public.uiactionsserviceparams.md) > [actions](./kibana-plugin-plugins-ui_actions-public.uiactionsserviceparams.actions.md) + +## UiActionsServiceParams.actions property + +Signature: + +```typescript +readonly actions?: ActionRegistry; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsserviceparams.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsserviceparams.md new file mode 100644 index 0000000000000..756cd3de92ef8 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsserviceparams.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsServiceParams](./kibana-plugin-plugins-ui_actions-public.uiactionsserviceparams.md) + +## UiActionsServiceParams interface + +Signature: + +```typescript +export interface UiActionsServiceParams +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [actions](./kibana-plugin-plugins-ui_actions-public.uiactionsserviceparams.actions.md) | ActionRegistry | | +| [triggers](./kibana-plugin-plugins-ui_actions-public.uiactionsserviceparams.triggers.md) | TriggerRegistry | | +| [triggerToActions](./kibana-plugin-plugins-ui_actions-public.uiactionsserviceparams.triggertoactions.md) | TriggerToActionsRegistry | A 1-to-N mapping from Trigger to zero or more Action. | + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsserviceparams.triggers.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsserviceparams.triggers.md new file mode 100644 index 0000000000000..061aa5eb68c5d --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsserviceparams.triggers.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsServiceParams](./kibana-plugin-plugins-ui_actions-public.uiactionsserviceparams.md) > [triggers](./kibana-plugin-plugins-ui_actions-public.uiactionsserviceparams.triggers.md) + +## UiActionsServiceParams.triggers property + +Signature: + +```typescript +readonly triggers?: TriggerRegistry; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsserviceparams.triggertoactions.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsserviceparams.triggertoactions.md new file mode 100644 index 0000000000000..bdf1acba484e6 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsserviceparams.triggertoactions.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsServiceParams](./kibana-plugin-plugins-ui_actions-public.uiactionsserviceparams.md) > [triggerToActions](./kibana-plugin-plugins-ui_actions-public.uiactionsserviceparams.triggertoactions.md) + +## UiActionsServiceParams.triggerToActions property + +A 1-to-N mapping from `Trigger` to zero or more `Action`. + +Signature: + +```typescript +readonly triggerToActions?: TriggerToActionsRegistry; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionssetup.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionssetup.md new file mode 100644 index 0000000000000..d03d4cf9f1ee2 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionssetup.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsSetup](./kibana-plugin-plugins-ui_actions-public.uiactionssetup.md) + +## UiActionsSetup type + +Signature: + +```typescript +export declare type UiActionsSetup = Pick; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsstart.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsstart.md new file mode 100644 index 0000000000000..41f5bbf705e20 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.uiactionsstart.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [UiActionsStart](./kibana-plugin-plugins-ui_actions-public.uiactionsstart.md) + +## UiActionsStart type + +Signature: + +```typescript +export declare type UiActionsStart = PublicMethodsOf; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.value_click_trigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.value_click_trigger.md new file mode 100644 index 0000000000000..bd8d4dc50b8fd --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.value_click_trigger.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [VALUE\_CLICK\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.value_click_trigger.md) + +## VALUE\_CLICK\_TRIGGER variable + +Signature: + +```typescript +VALUE_CLICK_TRIGGER = "VALUE_CLICK_TRIGGER" +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.valueclicktrigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.valueclicktrigger.md new file mode 100644 index 0000000000000..5c4fc284d83b1 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.valueclicktrigger.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [valueClickTrigger](./kibana-plugin-plugins-ui_actions-public.valueclicktrigger.md) + +## valueClickTrigger variable + +Signature: + +```typescript +valueClickTrigger: Trigger<'VALUE_CLICK_TRIGGER'> +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.visualize_field_trigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.visualize_field_trigger.md new file mode 100644 index 0000000000000..c5d9f53557d6f --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.visualize_field_trigger.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [VISUALIZE\_FIELD\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.visualize_field_trigger.md) + +## VISUALIZE\_FIELD\_TRIGGER variable + +Signature: + +```typescript +VISUALIZE_FIELD_TRIGGER = "VISUALIZE_FIELD_TRIGGER" +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.visualize_geo_field_trigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.visualize_geo_field_trigger.md new file mode 100644 index 0000000000000..a9396c1905485 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.visualize_geo_field_trigger.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [VISUALIZE\_GEO\_FIELD\_TRIGGER](./kibana-plugin-plugins-ui_actions-public.visualize_geo_field_trigger.md) + +## VISUALIZE\_GEO\_FIELD\_TRIGGER variable + +Signature: + +```typescript +VISUALIZE_GEO_FIELD_TRIGGER = "VISUALIZE_GEO_FIELD_TRIGGER" +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.visualizefieldcontext.contextualfields.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.visualizefieldcontext.contextualfields.md new file mode 100644 index 0000000000000..681d4127e4030 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.visualizefieldcontext.contextualfields.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [VisualizeFieldContext](./kibana-plugin-plugins-ui_actions-public.visualizefieldcontext.md) > [contextualFields](./kibana-plugin-plugins-ui_actions-public.visualizefieldcontext.contextualfields.md) + +## VisualizeFieldContext.contextualFields property + +Signature: + +```typescript +contextualFields?: string[]; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.visualizefieldcontext.fieldname.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.visualizefieldcontext.fieldname.md new file mode 100644 index 0000000000000..95f45b1fbee4a --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.visualizefieldcontext.fieldname.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [VisualizeFieldContext](./kibana-plugin-plugins-ui_actions-public.visualizefieldcontext.md) > [fieldName](./kibana-plugin-plugins-ui_actions-public.visualizefieldcontext.fieldname.md) + +## VisualizeFieldContext.fieldName property + +Signature: + +```typescript +fieldName: string; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.visualizefieldcontext.indexpatternid.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.visualizefieldcontext.indexpatternid.md new file mode 100644 index 0000000000000..588c115cd9885 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.visualizefieldcontext.indexpatternid.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [VisualizeFieldContext](./kibana-plugin-plugins-ui_actions-public.visualizefieldcontext.md) > [indexPatternId](./kibana-plugin-plugins-ui_actions-public.visualizefieldcontext.indexpatternid.md) + +## VisualizeFieldContext.indexPatternId property + +Signature: + +```typescript +indexPatternId: string; +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.visualizefieldcontext.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.visualizefieldcontext.md new file mode 100644 index 0000000000000..7aeb254db7771 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.visualizefieldcontext.md @@ -0,0 +1,20 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [VisualizeFieldContext](./kibana-plugin-plugins-ui_actions-public.visualizefieldcontext.md) + +## VisualizeFieldContext interface + +Signature: + +```typescript +export interface VisualizeFieldContext +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [contextualFields](./kibana-plugin-plugins-ui_actions-public.visualizefieldcontext.contextualfields.md) | string[] | | +| [fieldName](./kibana-plugin-plugins-ui_actions-public.visualizefieldcontext.fieldname.md) | string | | +| [indexPatternId](./kibana-plugin-plugins-ui_actions-public.visualizefieldcontext.indexpatternid.md) | string | | + diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.visualizefieldtrigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.visualizefieldtrigger.md new file mode 100644 index 0000000000000..15510bd3eb4a3 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.visualizefieldtrigger.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [visualizeFieldTrigger](./kibana-plugin-plugins-ui_actions-public.visualizefieldtrigger.md) + +## visualizeFieldTrigger variable + +Signature: + +```typescript +visualizeFieldTrigger: Trigger<'VISUALIZE_FIELD_TRIGGER'> +``` diff --git a/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.visualizegeofieldtrigger.md b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.visualizegeofieldtrigger.md new file mode 100644 index 0000000000000..faec6a69b71f9 --- /dev/null +++ b/docs/development/plugins/ui_actions/public/kibana-plugin-plugins-ui_actions-public.visualizegeofieldtrigger.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-ui\_actions-public](./kibana-plugin-plugins-ui_actions-public.md) > [visualizeGeoFieldTrigger](./kibana-plugin-plugins-ui_actions-public.visualizegeofieldtrigger.md) + +## visualizeGeoFieldTrigger variable + +Signature: + +```typescript +visualizeGeoFieldTrigger: Trigger<'VISUALIZE_GEO_FIELD_TRIGGER'> +``` diff --git a/docs/discover/images/kql-autocomplete.png b/docs/discover/images/kql-autocomplete.png new file mode 100644 index 0000000000000..60e2290c0bad7 Binary files /dev/null and b/docs/discover/images/kql-autocomplete.png differ diff --git a/docs/discover/kuery.asciidoc b/docs/discover/kuery.asciidoc index 1a481c46b3816..f306f2b8f763f 100644 --- a/docs/discover/kuery.asciidoc +++ b/docs/discover/kuery.asciidoc @@ -1,90 +1,170 @@ [[kuery-query]] === Kibana Query Language -In Kibana 6.3, we introduced a number of exciting experimental query language enhancements. These -features are now available by default in 7.0. Out of the box, Kibana's query language now includes scripted field support and a -simplified, easier to use syntax. If you have a Basic license or above, autocomplete functionality will also be enabled. +The Kibana Query Language (KQL) makes it easy to find +the fields and syntax for your {es} query. If you have the +https://www.elastic.co/subscriptions[Basic tier] or above, +simply place your cursor in the *Search* field. As you type, you’ll get suggestions for fields, +values, and operators. -==== Language syntax +[role="screenshot"] +image::images/kql-autocomplete.png[Autocomplete in Search bar] -If you're familiar with Kibana's old Lucene query syntax, you should feel right at home with the new syntax. The basics -stay the same, we've simply refined things to make the query language easier to use. +If you prefer to use Kibana’s legacy query language, based on the +<>, click *KQL* next to the *Search* field, and then turn off KQL. -`response:200` will match documents where the response field matches the value 200. +[discrete] +=== Terms query -Quotes around a search term will initiate a phrase search. For example, `message:"Quick brown fox"` will search -for the phrase "quick brown fox" in the message field. Without the quotes, your query will get broken down into tokens via -the message field's configured analyzer and will match documents that contain those tokens, regardless of the order in which -they appear. This means documents with "quick brown fox" will match, but so will "quick fox brown". Remember to use quotes if you want -to search for a phrase. +A terms query matches documents that contain one or more *exact* terms in a field. -The query parser will no longer split on whitespace. Multiple search terms must be separated by explicit -boolean operators. Lucene will combine search terms with an `or` by default, so `response:200 extension:php` would -become `response:200 or extension:php` in KQL. This will match documents where response matches 200, extension matches php, or both. -Note that boolean operators are not case sensitive. +To match documents where the response field is `200`: -We can make terms required by using `and`. +[source,yaml] +------------------- +response:200 +------------------- -`response:200 and extension:php` will match documents where response matches 200 and extension matches php. +To match documents with the phrase "quick brown fox" in the `message` field. -By default, `and` has a higher precedence than `or`. +[source,yaml] +------------------- +message:"quick brown fox" +------------------- -`response:200 and extension:php or extension:css` will match documents where response is 200 and extension is php OR documents where extension is css and response is anything. +Without the quotes, +the query matches documents regardless of the order in which +they appear. Documents with "quick brown fox" match, +and so does "quick fox brown". -We can override the default precedence with grouping. +NOTE: Terms without fields are matched against the default field in your index settings. +If a default field is not +set, terms are matched against all fields. For example, a query +for `response:200` searches for the value 200 +in the response field, but a query for just `200` searches for 200 +across all fields in your index. -`response:200 and (extension:php or extension:css)` will match documents where response is 200 and extension is either php or css. -A shorthand exists that allows us to easily search a single field for multiple values. +[discrete] +=== Boolean queries -`response:(200 or 404)` searches for docs where the `response` field matches 200 or 404. We can also search for docs -with multi-value fields that contain a list of terms, for example: `tags:(success and info and security)` +KQL supports `or`, `and`, and `not`. By default, `and` has a higher precedence than `or`. +To override the default precedence, group operators in parentheses. -Terms can be inverted by prefixing them with `not`. +To match documents where response is `200`, extension is `php`, or both: -`not response:200` will match all documents where response is not 200. +[source,yaml] +------------------- +response:200 or extension:php +------------------- -Entire groups can also be inverted. +To match documents where response is `200` and extension is `php`: -`response:200 and not (extension:php or extension:css)` +[source,yaml] +------------------- +response:200 and extension:php +------------------- -Ranges are similar to lucene with a small syntactical difference. +To match documents where response is `200` or `404`. -Instead of `bytes:>1000`, we omit the colon: `bytes > 1000`. +[source,yaml] +------------------- +response:(200 or 404) +------------------- -`>, >=, <, <=` are all valid range operators. +To match documents where response is `200` and extension is either `php` or `css`: -Exist queries are simple and do not require a special operator. `response:*` will find all docs where the response -field exists. +[source,yaml] +------------------- +response:200 and (extension:php or extension:css) +------------------- -Wildcard queries are available. `machine.os:win*` would match docs where the machine.os field starts with "win", which -would match values like "windows 7" and "windows 10". +To match documents where `response` is 200 and `extension` is +`php` or extension is `css`, and response is anything: -Wildcards also allow us to search multiple fields at once. This can come in handy when you have both `text` and `keyword` -versions of a field. Let's say we have `machine.os` and `machine.os.keyword` fields and we want to check both for the term -"windows 10". We can do it like this: `machine.os*:windows 10". +[source,yaml] +------------------- +response:200 and extension:php or extension:css +------------------- +To match documents where response is not `200`: -[NOTE] -============ -Terms without fields will be matched against the default field in your index settings. If a default field is not -set these terms will be matched against all fields. For example, a query for `response:200` will search for the value 200 -in the response field, but a query for just `200` will search for 200 across all fields in your index. -============ +[source,yaml] +------------------- +not response:200 +------------------- -==== Nested field support +To match documents where response is `200` but extension is not `php` or `css`. -KQL supports querying on {ref}/nested.html[nested fields] through a special syntax. You can query nested fields in subtly different -ways, depending on the results you want, so crafting nested queries requires extra thought. +[source,yaml] +------------------- +response:200 and not (extension:php or extension:css) +------------------- -One main consideration is how to match parts of the nested query to the individual nested documents. -There are two main approaches to take: +To match multi-value fields that contain a list of terms: -* *Parts of the query may only match a single nested document.* This is what most users want when querying on a nested field. -* *Parts of the query can match different nested documents.* This is how a regular object field works. - Although generally less useful, there might be occasions where you want to query a nested field in this way. +[source,yaml] +------------------- +tags:(success and info and security) +------------------- -Let's take a look at the first approach. In the following document, `items` is a nested field. Each document in the nested +[discrete] +=== Range queries + +KQL supports `>`, `>=`, `<`, and `<=`. For example: + +[source,yaml] +------------------- +account_number:>=100 and items_sold:<=200 +------------------- + +[discrete] +=== Exist queries + +An exist query matches documents that contain a value for a field, in this case, +response: + +[source,yaml] +------------------- +response:* +------------------- + +[discrete] +=== Wildcard queries + +To match documents where machine.os starts with `win`, such +as "windows 7" and "windows 10": + +[source,yaml] +------------------- +machine.os:win* +------------------- + +To match multiple fields: + +[source,yaml] +------------------- +machine.os*:windows 10 +------------------- + +This sytax is handy when you have text and keyword +versions of a field. The query checks machine.os and machine.os.keyword +for the term +`windows 10`. + + +[discrete] +=== Nested field queries + +A main consideration for querying {ref}/nested.html[nested fields] is how to +match parts of the nested query to the individual nested documents. +You can: + +* *Match parts of the query to a single nested document only.* This is what most users want when querying on a nested field. +* *Match parts of the query to different nested documents.* This is how a regular object field works. + This query is generally less useful than matching to a single document. + +In the following document, `items` is a nested field. Each document in the nested field contains a name, stock, and category. [source,json] @@ -116,40 +196,61 @@ field contains a name, stock, and category. } ---------------------------------- -===== Match a single nested document +[discrete] +==== Match a single document -To find stores that have more than 10 bananas in stock, you would write a query like this: +To match stores that have more than 10 bananas in stock: -`items:{ name:banana and stock > 10 }` +[source,yaml] +------------------- +items:{ name:banana and stock > 10 } +------------------- -`items` is the "nested path". Everything inside the curly braces (the "nested group") must match a single nested document. +`items` is the nested path. Everything inside the curly braces (the nested group) +must match a single nested document. -The following example returns no matches because no single nested document has bananas with a stock of 9. +The following query does not return any matches because no single nested +document has bananas with a stock of 9. -`items:{ name:banana and stock:9 }` +[source,yaml] +------------------- +items:{ name:banana and stock:9 } +------------------- -==== Match different nested documents +[discrete] +==== Match different documents -The subqueries in this example are in separate nested groups and can match different nested documents. +The following subqueries are in separate nested groups +and can match different nested documents: -`items:{ name:banana } and items:{ stock:9 }` +[source,yaml] +------------------- +items:{ name:banana } and items:{ stock:9 } +------------------- -`name:banana` matches the first document in the array and `stock:9` matches the third document in the array. +`name:banana` matches the first document in the array and `stock:9` +matches the third document in the array. -==== Combine approaches +[discrete] +==== Match single and different documents -You can combine these two approaches to create complex queries. What if you wanted to find a store with more than 10 -bananas that *also* stocks vegetables? You could do this: +To find a store with more than 10 +bananas that *also* stocks vegetables: -`items:{ name:banana and stock > 10 } and items:{ category:vegetable }` +[source,yaml] +------------------- +items:{ name:banana and stock > 10 } and items:{ category:vegetable } +------------------- -The first nested group (`name:banana and stock > 10`) must still match a single document, but the `category:vegetables` +The first nested group (`name:banana and stock > 10`) must match a single document, but the `category:vegetables` subquery can match a different nested document because it is in a separate group. +[discrete] ==== Nested fields inside other nested fields -KQL's syntax also supports nested fields inside of other nested fields—you simply have to specify the full path. Suppose you -have a document where `level1` and `level2` are both nested fields: +KQL supports nested fields inside other nested fields—you have to +specify the full path. In this document, +`level1` and `level2` are nested fields: [source,json] ---------------------------------- @@ -171,6 +272,9 @@ have a document where `level1` and `level2` are both nested fields: } ---------------------------------- -You can match on a single nested document by specifying the full path: +To match on a single nested document: -`level1.level2:{ prop1:foo and prop2:bar }` +[source,yaml] +------------------- +level1.level2:{ prop1:foo and prop2:bar } +------------------- diff --git a/docs/setup/production.asciidoc b/docs/setup/production.asciidoc index 3075220e3a47c..e097704e05d40 100644 --- a/docs/setup/production.asciidoc +++ b/docs/setup/production.asciidoc @@ -135,6 +135,7 @@ Settings that must be the same: xpack.security.encryptionKey //decrypting session information xpack.reporting.encryptionKey //decrypting reports xpack.encryptedSavedObjects.encryptionKey // decrypting saved objects +xpack.encryptedSavedObjects.keyRotation.decryptionOnlyKeys // saved objects encryption key rotation, if any -------- Separate configuration files can be used from the command line by using the `-c` flag: diff --git a/docs/setup/settings.asciidoc b/docs/setup/settings.asciidoc index af68f3e541628..903bb59cef380 100644 --- a/docs/setup/settings.asciidoc +++ b/docs/setup/settings.asciidoc @@ -68,11 +68,6 @@ currently do not have an inspector, for example Timelion and Monitoring. | Time in milliseconds to wait for {es} to respond to pings. *Default: the value of the <> setting* -| `elasticsearch.preserveHost:` - | When the value is `true`, {kib} uses the hostname specified in the -<> setting. When the value is `false`, {kib} uses -the hostname of the host that connects to this {kib} instance. *Default: `true`* - |[[elasticsearch-requestHeadersWhitelist]] `elasticsearch.requestHeadersWhitelist:` | List of {kib} client-side headers to send to {es}. To send *no* client-side headers, set this value to [] (an empty list). Removing the `authorization` @@ -204,10 +199,6 @@ making an outbound SSL/TLS connection to {es}. Valid values are `"full"`, using `"certificate"` skips hostname verification, and using `"none"` skips verification entirely. *Default: `"full"`* -| `elasticsearch.startupTimeout:` - | Time in milliseconds to wait for {es} at {kib} startup before retrying. -*Default: `5000`* - |[[elasticsearch-user-passwd]] `elasticsearch.username:` and `elasticsearch.password:` | If your {es} is protected with basic authentication, these settings provide the username and password that the {kib} server uses to perform maintenance diff --git a/docs/user/alerting/action-types/jira.asciidoc b/docs/user/alerting/action-types/jira.asciidoc index 48bd6c8501b9f..65e5ee4fc4a01 100644 --- a/docs/user/alerting/action-types/jira.asciidoc +++ b/docs/user/alerting/action-types/jira.asciidoc @@ -69,6 +69,8 @@ Priority:: The priority of the incident. Labels:: The labels of the incident. Title:: A title for the issue, used for searching the contents of the knowledge base. Description:: The details about the incident. +Parent:: The parent issue id or key. Only for `Sub-task` issue types. +Priority:: The priority of the incident. Additional comments:: Additional information for the client, such as how to troubleshoot the issue. [[configuring-jira]] diff --git a/docs/user/dashboard/dashboard-drilldown.asciidoc b/docs/user/dashboard/dashboard-drilldown.asciidoc index 84701cae2ecc6..e50c1281beede 100644 --- a/docs/user/dashboard/dashboard-drilldown.asciidoc +++ b/docs/user/dashboard/dashboard-drilldown.asciidoc @@ -11,6 +11,26 @@ This example shows a dashboard panel that contains a pie chart with a configured [role="screenshot"] image::images/drilldown_on_piechart.gif[Drilldown on pie chart that navigates to another dashboard] +[float] +[[dashboard-drilldown-supported-panels]] +==== Supported panels + +The following panels support dashboard drilldowns: + +* Lens +* Area +* Data table +* Heat map +* Horizontal bar +* Line +* Maps +* Pie +* TSVB +* Tag cloud +* Timelion +* Vega +* Vertical bar + [float] [[drilldowns-example]] ==== Try it: Create a dashboard drilldown @@ -74,3 +94,4 @@ image::images/drilldown_on_panel.png[Drilldown on pie chart that navigates to an + You are navigated to your destination dashboard. Verify that the search query, filters, and time range are carried over. + diff --git a/docs/user/dashboard/url-drilldown.asciidoc b/docs/user/dashboard/url-drilldown.asciidoc index ee879256a1fae..620a2d2056bf1 100644 --- a/docs/user/dashboard/url-drilldown.asciidoc +++ b/docs/user/dashboard/url-drilldown.asciidoc @@ -14,6 +14,22 @@ image:images/url_drilldown_go_to_github.gif[Drilldown on pie chart that navigate NOTE: URL drilldown is available with the https://www.elastic.co/subscriptions[Gold subscription] and higher. +[float] +[[url-drilldown-supported-panels]] +==== Supported panels + +The following panels support URL drilldowns: + +* Lens +* Area +* Data table +* Heat map +* Horizontal bar +* Line +* Pie +* Tag cloud +* Vertical bar + [float] [[try-it]] ==== Try it: Create a URL drilldown diff --git a/docs/user/dashboard/vega-reference.asciidoc b/docs/user/dashboard/vega-reference.asciidoc index eed8d9a35b874..0bc77ab0a417e 100644 --- a/docs/user/dashboard/vega-reference.asciidoc +++ b/docs/user/dashboard/vega-reference.asciidoc @@ -11,7 +11,7 @@ For additional *Vega* and *Vega-Lite* information, refer to the reference sectio {kib} has extended Vega and Vega-Lite with extensions that support: -* Default height and width +* Automatic sizing * Default theme to match {kib} * Writing {es} queries using the time range and filters from dashboards * Using the Elastic Map Service in Vega maps @@ -22,12 +22,35 @@ For additional *Vega* and *Vega-Lite* information, refer to the reference sectio [float] [[vega-sizing-and-positioning]] -==== Default height and width +==== Automatic sizing -By default, Vega visualizations use the `autosize = { type: 'fit', contains: 'padding' }` layout. -`fit` uses all available space, ignores `width` and `height` values, -and respects the padding values. To override this behavior, change the -`autosize` value. +Most users will want their Vega visualizations to take the full available space, so unlike +Vega examples, `width` and `height` are not required parameters in {kib}. To set the width +or height manually, set `autosize: none`. For example, to set the height to a specific pixel value: + +``` +autosize: none +width: container +height: 200 +``` + +The default {kib} settings which are inherited by your visualizations are: + +``` +autosize: { + type: fit + contains: padding +} +width: container +height: container +``` + +{kib} is able to merge your custom `autosize` settings with the defaults. The options `fit-x` +and `fit-y` are supported but not recommended over the default `fit` setting. + +To learn more, read about +https://vega.github.io/vega/docs/specification/#autosize[autosize] +in the Vega documentation. [float] [[vega-theme]] diff --git a/docs/user/reporting/reporting-troubleshooting.asciidoc b/docs/user/reporting/reporting-troubleshooting.asciidoc index 82f0aa7ca0f19..1f07b0b57d8c7 100644 --- a/docs/user/reporting/reporting-troubleshooting.asciidoc +++ b/docs/user/reporting/reporting-troubleshooting.asciidoc @@ -18,8 +18,11 @@ Having trouble? Here are solutions to common problems you might encounter while [float] [[reporting-diagnostics]] -=== Reporting Diagnostics -Reporting comes with a built-in utility to try to automatically find common issues. When Kibana is running, navigate to the Report Listing page, and click the "Run reporting diagnostics..." button. This will open up a diagnostic tool that checks various parts of the Kibana deployment to come up with any relevant recommendations. +=== Reporting diagnostics +Reporting comes with a built-in utility to try to automatically find common issues. +When {kib} is running, navigate to the Report Listing page, and click *Run reporting diagnostics*. +This will open up a diagnostic tool that checks various parts of the {kib} deployment and +come up with any relevant recommendations. [float] [[reporting-troubleshooting-system-dependencies]] diff --git a/docs/user/security/api-keys/index.asciidoc b/docs/user/security/api-keys/index.asciidoc index c93d7caec1b7d..7cf1b964082d9 100644 --- a/docs/user/security/api-keys/index.asciidoc +++ b/docs/user/security/api-keys/index.asciidoc @@ -72,9 +72,9 @@ The response should look something like this: "api_key" : "FD6P5UA4QCWlZZQhYF3YGw" } -Now, you can use the API key to request {kib} roles. You will need -to base64-encode the `id` and `api_key` provided in the response -and add it to your request as an authorization header. For example: +Now, you can use the API key to request {kib} roles. You'll need to send a request with a +`Authorization` header with a value having the prefix `ApiKey` followed by the credentials, +where credentials is the base64 encoding of `id` and `api_key` joined by a colon. For example: [source,js] curl --location --request GET 'http://localhost:5601/api/security/role' \ diff --git a/docs/user/security/authorization/index.asciidoc b/docs/user/security/authorization/index.asciidoc index 44ca96e4aece5..3af49753db664 100644 --- a/docs/user/security/authorization/index.asciidoc +++ b/docs/user/security/authorization/index.asciidoc @@ -2,11 +2,11 @@ [[xpack-security-authorization]] === Granting access to {kib} -The Elastic Stack comes with the `kibana_admin` {ref}/built-in-roles.html[built-in role], which you can use to grant access to all Kibana features in all spaces. To grant users access to a subset of spaces or features, you can create a custom role that grants the desired Kibana privileges. +The Elastic Stack comes with the `kibana_admin` {ref}/built-in-roles.html[built-in role], which you can use to grant access to all {kib} features in all spaces. To grant users access to a subset of spaces or features, you can create a custom role that grants the desired {kib} privileges. -When you assign a user multiple roles, the user receives a union of the roles’ privileges. Therefore, assigning the `kibana_admin` role in addition to a custom role that grants Kibana privileges is ineffective because `kibana_admin` has access to all the features in all spaces. +When you assign a user multiple roles, the user receives a union of the roles’ privileges. Therefore, assigning the `kibana_admin` role in addition to a custom role that grants {kib} privileges is ineffective because `kibana_admin` has access to all the features in all spaces. -NOTE: When running multiple tenants of Kibana by changing the `kibana.index` in your `kibana.yml`, you cannot use `kibana_admin` to grant access. You must create custom roles that authorize the user for that specific tenant. Although multi-tenant installations are supported, the recommended approach to securing access to Kibana segments is to grant users access to specific spaces. +NOTE: When running multiple tenants of {kib} by changing the `kibana.index` in your `kibana.yml`, you cannot use `kibana_admin` to grant access. You must create custom roles that authorize the user for that specific tenant. Although multi-tenant installations are supported, the recommended approach to securing access to {kib} segments is to grant users access to specific spaces. [role="xpack"] [[xpack-kibana-role-management]] @@ -17,26 +17,26 @@ To create a role that grants {kib} privileges, open the menu, go to *Stack Manag [[adding_kibana_privileges]] ==== Adding {kib} privileges -To assign {kib} privileges to the role, click **Add space privilege** in the Kibana section. +To assign {kib} privileges to the role, click **Add {kib} privilege** in the {kib} section. [role="screenshot"] -image::user/security/images/add-space-privileges.png[Add space privileges] +image::user/security/images/add-space-privileges.png[Add {kib} privileges] Open the **Spaces** selection control to specify whether to grant the role access to all spaces *** Global (all spaces)** or one or more individual spaces. If you select *** Global (all spaces)**, you can’t select individual spaces until you clear your selection. Use the **Privilege** menu to grant access to features. The default is **Custom**, which you can use to grant access to individual features. Otherwise, you can grant read and write access to all current and future features by selecting **All**, or grant read access to all current and future features by selecting **Read**. -When using the **Customize by feature** option, you can choose either **All**, **Read** or **None** for access to each feature. As new features are added to Kibana, roles that use the custom option do not automatically get access to the new features. You must manually update the roles. +When using the **Customize by feature** option, you can choose either **All**, **Read** or **None** for access to each feature. As new features are added to {kib}, roles that use the custom option do not automatically get access to the new features. You must manually update the roles. NOTE: *{stack-monitor-app}* relies on built-in roles to grant access. When a user is assigned the appropriate roles, the *{stack-monitor-app}* application is available; otherwise, it is not visible. -To apply your changes, click **Create space privilege**. The space privilege shows up under the Kibana privileges section of the role. +To apply your changes, click **Add {kib} privilege**. The privilege shows up under the {kib} privileges section of the role. [role="screenshot"] -image::user/security/images/create-space-privilege.png[Create space privilege] +image::user/security/images/create-space-privilege.png[Add {kib} privilege] ==== Feature availability @@ -64,9 +64,9 @@ Features are available to users when their roles grant access to the features, * ==== Assigning different privileges to different spaces -Using the same role, it’s possible to assign different privileges to different spaces. After you’ve added space privileges, click **Add space privilege**. If you’ve already added privileges for either *** Global (all spaces)** or an individual space, you will not be able to select these in the **Spaces** selection control. +Using the same role, it’s possible to assign different privileges to different spaces. After you’ve added privileges, click **Add {kib} privilege**. If you’ve already added privileges for either *** Global (all spaces)** or an individual space, you will not be able to select these in the **Spaces** selection control. -Additionally, if you’ve already assigned privileges at *** Global (all spaces)**, you are only able to assign additional privileges to individual spaces. Similar to the behavior of multiple roles granting the union of all privileges, space privileges are also a union. If you’ve already granted the user the **All** privilege at *** Global (all spaces)**, you’re not able to restrict the role to only the **Read** privilege at an individual space. +Additionally, if you’ve already assigned privileges at *** Global (all spaces)**, you are only able to assign additional privileges to individual spaces. Similar to the behavior of multiple roles granting the union of all privileges, {kib} privileges are also a union. If you’ve already granted the user the **All** privilege at *** Global (all spaces)**, you’re not able to restrict the role to only the **Read** privilege at an individual space. ==== Privilege summary @@ -78,39 +78,37 @@ image::user/security/images/view-privilege-summary.png[View privilege summary] ==== Example 1: Grant all access to Dashboard at an individual space -. Click **Add space privilege**. +. Click **Add {kib} privilege**. . For **Spaces**, select an individual space. . For **Privilege**, leave the default selection of **Custom**. . For the Dashboard feature, select **All** -. Click **Create space privilege**. +. Click **Add {kib} privilege**. [role="screenshot"] image::user/security/images/privilege-example-1.png[Privilege example 1] ==== Example 2: Grant all access to one space and read access to another -. Click **Add space privilege**. +. Click **Add {kib} privilege**. . For **Spaces**, select the first space. . For **Privilege**, select **All**. -. Click **Create space privilege**. -. Click **Add space privilege**. +. Click **Add {kib} privilege**. . For **Spaces**, select the second space. . For **Privilege**, select **Read**. -. Click **Create space privilege**. +. Click **Add {kib} privilege**. [role="screenshot"] image::user/security/images/privilege-example-2.png[Privilege example 2] ==== Example 3: Grant read access to all spaces and write access to an individual space -. Click **Add space privilege**. +. Click **Add {kib} privilege**. . For **Spaces**, select *** Global (all spaces)**. . For **Privilege**, select **Read**. -. Click **Create space privilege**. -. Click **Add space privilege**. +. Click **Add {kib} privilege**. . For **Spaces**, select the individual space. . For **Privilege**, select **All**. -. Click **Create space privilege**. +. Click **Add {kib} privilege**. [role="screenshot"] image::user/security/images/privilege-example-3.png[Privilege example 3] diff --git a/examples/alerting_example/common/constants.ts b/examples/alerting_example/common/constants.ts deleted file mode 100644 index 5884eb3220519..0000000000000 --- a/examples/alerting_example/common/constants.ts +++ /dev/null @@ -1,34 +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 const ALERTING_EXAMPLE_APP_ID = 'AlertingExample'; - -// always firing -export const DEFAULT_INSTANCES_TO_GENERATE = 5; - -// Astros -export enum Craft { - OuterSpace = 'Outer Space', - ISS = 'ISS', -} -export enum Operator { - AreAbove = 'Are above', - AreBelow = 'Are below', - AreExactly = 'Are exactly', -} diff --git a/examples/alerting_example/public/alert_types/always_firing.tsx b/examples/alerting_example/public/alert_types/always_firing.tsx deleted file mode 100644 index 130519308d3c3..0000000000000 --- a/examples/alerting_example/public/alert_types/always_firing.tsx +++ /dev/null @@ -1,83 +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 React, { Fragment } from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiFieldNumber, EuiFormRow } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { AlertTypeModel } from '../../../../x-pack/plugins/triggers_actions_ui/public'; -import { DEFAULT_INSTANCES_TO_GENERATE } from '../../common/constants'; - -interface AlwaysFiringParamsProps { - alertParams: { instances?: number }; - setAlertParams: (property: string, value: any) => void; - errors: { [key: string]: string[] }; -} - -export function getAlertType(): AlertTypeModel { - return { - id: 'example.always-firing', - name: 'Always Fires', - iconClass: 'bolt', - alertParamsExpression: AlwaysFiringExpression, - validate: (alertParams: AlwaysFiringParamsProps['alertParams']) => { - const { instances } = alertParams; - const validationResult = { - errors: { - instances: new Array(), - }, - }; - if (instances && instances < 0) { - validationResult.errors.instances.push( - i18n.translate('AlertingExample.addAlert.error.invalidRandomInstances', { - defaultMessage: 'instances must be equal or greater than zero.', - }) - ); - } - return validationResult; - }, - requiresAppContext: false, - }; -} - -export const AlwaysFiringExpression: React.FunctionComponent = ({ - alertParams, - setAlertParams, -}) => { - const { instances = DEFAULT_INSTANCES_TO_GENERATE } = alertParams; - return ( - - - - - { - setAlertParams('instances', event.target.valueAsNumber); - }} - /> - - - - - ); -}; diff --git a/examples/alerting_example/public/alert_types/index.ts b/examples/alerting_example/public/alert_types/index.ts deleted file mode 100644 index db9f855b573e8..0000000000000 --- a/examples/alerting_example/public/alert_types/index.ts +++ /dev/null @@ -1,33 +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 { registerNavigation as registerPeopleInSpaceNavigation } from './astros'; -import { ALERTING_EXAMPLE_APP_ID } from '../../common/constants'; -import { SanitizedAlert } from '../../../../x-pack/plugins/alerts/common'; -import { PluginSetupContract as AlertingSetup } from '../../../../x-pack/plugins/alerts/public'; - -export function registerNavigation(alerts: AlertingSetup) { - // register default navigation - alerts.registerDefaultNavigation( - ALERTING_EXAMPLE_APP_ID, - (alert: SanitizedAlert) => `/alert/${alert.id}` - ); - - registerPeopleInSpaceNavigation(alerts); -} diff --git a/examples/alerting_example/public/application.tsx b/examples/alerting_example/public/application.tsx deleted file mode 100644 index 23e9d19441002..0000000000000 --- a/examples/alerting_example/public/application.tsx +++ /dev/null @@ -1,114 +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 React from 'react'; -import ReactDOM from 'react-dom'; -import { BrowserRouter as Router, Route, RouteComponentProps } from 'react-router-dom'; -import { EuiPage } from '@elastic/eui'; -import { - AppMountParameters, - CoreStart, - IUiSettingsClient, - DocLinksStart, - ToastsSetup, - ApplicationStart, -} from '../../../src/core/public'; -import { DataPublicPluginStart } from '../../../src/plugins/data/public'; -import { ChartsPluginStart } from '../../../src/plugins/charts/public'; - -import { Page } from './components/page'; -import { DocumentationPage } from './components/documentation'; -import { ViewAlertPage } from './components/view_alert'; -import { TriggersAndActionsUIPublicPluginStart } from '../../../x-pack/plugins/triggers_actions_ui/public'; -import { AlertingExamplePublicStartDeps } from './plugin'; -import { ViewPeopleInSpaceAlertPage } from './components/view_astros_alert'; - -export interface AlertingExampleComponentParams { - application: CoreStart['application']; - http: CoreStart['http']; - basename: string; - triggers_actions_ui: TriggersAndActionsUIPublicPluginStart; - data: DataPublicPluginStart; - charts: ChartsPluginStart; - uiSettings: IUiSettingsClient; - docLinks: DocLinksStart; - toastNotifications: ToastsSetup; - capabilities: ApplicationStart['capabilities']; -} - -const AlertingExampleApp = (deps: AlertingExampleComponentParams) => { - const { basename, http } = deps; - return ( - - - ( - - - - )} - /> - ) => { - return ( - - - - ); - }} - /> - ) => { - return ( - - - - ); - }} - /> - - - ); -}; - -export const renderApp = ( - { application, notifications, http, uiSettings, docLinks }: CoreStart, - deps: AlertingExamplePublicStartDeps, - { appBasePath, element }: AppMountParameters -) => { - ReactDOM.render( - , - element - ); - - return () => ReactDOM.unmountComponentAtNode(element); -}; diff --git a/examples/alerting_example/public/components/create_alert.tsx b/examples/alerting_example/public/components/create_alert.tsx deleted file mode 100644 index 72e3835b100fe..0000000000000 --- a/examples/alerting_example/public/components/create_alert.tsx +++ /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 React, { useState } from 'react'; - -import { EuiIcon, EuiFlexItem, EuiCard, EuiFlexGroup } from '@elastic/eui'; - -import { - AlertsContextProvider, - AlertAdd, -} from '../../../../x-pack/plugins/triggers_actions_ui/public'; -import { AlertingExampleComponentParams } from '../application'; -import { ALERTING_EXAMPLE_APP_ID } from '../../common/constants'; - -export const CreateAlert = ({ - http, - // eslint-disable-next-line @typescript-eslint/naming-convention - triggers_actions_ui, - charts, - uiSettings, - docLinks, - data, - toastNotifications, - capabilities, -}: AlertingExampleComponentParams) => { - const [alertFlyoutVisible, setAlertFlyoutVisibility] = useState(false); - - return ( - - - } - title={`Create Alert`} - description="Create an new Alert based on one of our example Alert Types ." - onClick={() => setAlertFlyoutVisibility(true)} - /> - - - - - - - - ); -}; diff --git a/examples/alerting_example/public/components/documentation.tsx b/examples/alerting_example/public/components/documentation.tsx deleted file mode 100644 index 17cc34959b010..0000000000000 --- a/examples/alerting_example/public/components/documentation.tsx +++ /dev/null @@ -1,67 +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 React from 'react'; - -import { - EuiText, - EuiPageBody, - EuiPageContent, - EuiPageContentBody, - EuiPageContentHeader, - EuiPageContentHeaderSection, - EuiPageHeader, - EuiPageHeaderSection, - EuiTitle, - EuiSpacer, -} from '@elastic/eui'; -import { CreateAlert } from './create_alert'; -import { AlertingExampleComponentParams } from '../application'; - -export const DocumentationPage = (deps: AlertingExampleComponentParams) => ( - - - - -